• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[JASS] Spell Problem

Status
Not open for further replies.
Level 8
Joined
Jul 28, 2008
Messages
211
I'm in need of your help again.

Causes all enemies in the area to bleed, dealing 100\140\180 damage and healing the Bloodthirster for half of that damage. Units damaged by Blood Bath will take 10\15\20 damage per second for 2.5 seconds.


JASS:
scope Bath initializer Init

globals

    private constant integer SPELL_ID = 'A000'
    private constant real PERIOD = 0.25
    private constant real DAMAGE_TO_HEAL = 1.0
    private constant string BLOOD_EFFECT = "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"
    private constant string BLEED_EFFECT = "Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl"
    private boolexpr b
    private group G = CreateGroup()
    private timer TIMER = CreateTimer()

endglobals

private function Range takes integer lvl returns real
    return I2R(lvl * 50 + 150)
endfunction

private function BleedDamage takes integer lvl returns real
    return I2R(lvl * 5 + 5)
endfunction

private function Damage takes integer lvl returns real
    return I2R(lvl * 40 + 60)
endfunction

private function BathFilter takes nothing returns boolean
    return (IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL) == false) and GetWidgetLife(GetFilterUnit()) > 0.405
endfunction

private struct Bleed

    unit caster
    unit target
    integer level
    integer count = 10
    
    static Bleed array ar
    static integer Total
    
endstruct

private function Loop takes nothing returns nothing
    local integer i = 0
    local Bleed bl
    loop
        exitwhen i >= Bleed.Total
        set bl = Bleed.ar[i]
        call DestroyEffect(AddSpecialEffectTarget(BLEED_EFFECT, bl.target, "chest"))
        call UnitDamageTarget(bl.caster, bl.target, BleedDamage(bl.level) / PERIOD, false, true, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
        call BJDebugMsg("Bleed Damage Done!")
        set bl.count = bl.count - 1
        if bl.count <= 0 or GetUnitState(bl.target, UNIT_STATE_LIFE) < 0.405 then
            set bl.caster = null
            set bl.target = null
            call bl.destroy()
            call BJDebugMsg("Struct Instance Destroyed!")
            set Bleed.Total = Bleed.Total - 1
            set Bleed.ar[i] = Bleed.ar[Bleed.Total]
            set i = i - 1
        endif
        set i = i + 1
    endloop
    if Bleed.Total == 0 then
        call PauseTimer(TIMER)
    endif
endfunction

private function BleedStart takes unit target, unit caster returns nothing
    local Bleed bl = Bleed.create()
    set bl.caster = caster
    set bl.target = target
    set bl.level = GetUnitAbilityLevel(caster, SPELL_ID)
    if Bleed.Total == 0 then
        call TimerStart(TIMER, PERIOD, true, function Loop)
    endif
    set Bleed.ar[Bleed.Total] = bl
    set Bleed.Total = Bleed.Total + 1
endfunction

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == SPELL_ID
endfunction

private function Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local integer level = GetUnitAbilityLevel(caster, SPELL_ID)
    local unit temp
    call GroupEnumUnitsInRange(G, GetUnitX(caster), GetUnitY(caster), Range(level), b)
    loop
        set temp = FirstOfGroup(G)
        exitwhen temp == null
        if IsUnitEnemy(temp, GetOwningPlayer(caster)) then
            call BJDebugMsg("First Blood!")
            call DestroyEffect(AddSpecialEffectTarget(BLOOD_EFFECT, temp, "chest"))
            call UnitDamageTarget(caster, temp, Damage(level), false, true, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
            call BleedStart(temp, caster)
            call BJDebugMsg("Bleed Started!")
            call SetUnitState(caster, UNIT_STATE_LIFE, GetUnitState(caster, UNIT_STATE_LIFE) + Damage(level) * DAMAGE_TO_HEAL)
            call BJDebugMsg("Unit Healed!")
        endif
        call GroupRemoveUnit(G, temp)
    endloop
    set caster = null
endfunction

private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t, Condition(function Conditions))
    call TriggerAddAction(t, function Actions)
    
    set b = Filter(function BathFilter)
endfunction

endscope

The spell doesn't work. It damages ONLY 1 unit near the caster. That's all it does. The spell seems to stop after the damage or more precicley, before the BleedStart. When I tried to move the BJDebugMsg("Bleed Started!") and put it before BleedStart, it was displayed but now it's not. So what seems to be the problem?

Thanks in advance!

NOTE: I haven't been working with structs since I learned about hashtables so the indexing could be the problem.

{EDIT}
Solved!
 
Last edited by a moderator:
Status
Not open for further replies.
Top