• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[JASS] Always returning 2

Status
Not open for further replies.
Level 12
Joined
Mar 23, 2008
Messages
942
The Sacrifice_Connect function is always returning 2, why?

JASS:
scope Sacrifice initializer In_Sacrifice 

globals
    private unit array Caster[10]
    private unit array Target[10]
endglobals

private struct SAC
    unit caster
    unit target
    real tx
    real ty
    real x
    real y
    lightning lig
    integer range
endstruct

private function Sacrifice_Connect takes unit c, unit t returns integer
    local integer i = 0
    
    loop      
        if (Caster[i] == c) and (Target[i] == t) then
            set i = 10
            return 2
        endif
        exitwhen i == 10
        set i = i + 1
    endloop
    
    if GetUnitUserData(c) >= GetUnitAbilityLevel(c, 'A03S') then
        return 0
    else
    
    loop        
        if Caster[i] == null then
            set Caster[i] = c
            set Target[i] = t
            set i = 10
            return 1
        endif
        exitwhen i == 10
        set i = i + 1
    endloop
    
    endif
    return 0
endfunction

function Sacrifice_Link takes unit t, unit s, real d returns nothing
    local integer i = 0
    loop
        exitwhen Target[i] == t
        set i = i + 1
    endloop
    call UnitDamageTargetEx(s, Caster[i], d, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_EXTRA, false)
endfunction

private function Sacrifice_Break takes unit c, unit t returns nothing
    local integer i = 0
    loop
        exitwhen (Caster[i] == c) and (Target[i] == t)
        set i = i + 1
    endloop
    set Caster[i] = null
    set Target[i] = null
    call SetUnitUserData(c, GetUnitUserData(c)-1)
endfunction

private function Sacrifice_Conditions takes nothing returns boolean
    return (GetSpellAbilityId() == 'A03S')
endfunction

private function Sacrifice_Defense takes nothing returns nothing
    local SAC s = GetTimerData(GetExpiredTimer())
    local real templife = GetUnitState(s.target, UNIT_STATE_LIFE)
    if GetUnitAbilityLevel(s.target, 'B00B') > 0 and IsUnitInRange(s.target, s.caster, s.range) then
        set s.x = GetUnitX(s.caster)
        set s.y = GetUnitY(s.caster)
        set s.tx = GetUnitX(s.target)
        set s.ty = GetUnitY(s.target)
        call MoveLightning(s.lig, true, s.x, s.y, s.tx, s.ty)
        if GetUnitAbilityLevel(s.caster, 'A056') > 0 then
            call UnitAddAbility(s.target, 'A057')
            call SetUnitAbilityLevel(s.target, 'A056', GetUnitAbilityLevel(s.caster, 'A056'))
            call SetPlayerAbilityAvailable(GetOwningPlayer(s.target), 'A057', false)
            call SetUnitMoveSpeed(s.target, GetUnitMoveSpeed(s.target)/3)
        else
            call SetUnitMoveSpeed(s.target, GetUnitMoveSpeed(s.target))
            call UnitRemoveAbility(s.target, 'A057')
        endif
    else
        call Sacrifice_Break(s.caster, s.target)
        call UnitRemoveAbility(s.target, 'A058')
        call UnitRemoveAbility(s.target, 'A057')
        call UnitRemoveAbility(s.target, 'B00B')
        set s.target = null
        call DestroyLightning(s.lig)
        set s.lig = null
        set s.caster = null
        call ReleaseTimer(GetExpiredTimer())
        call s.destroy()
    endif
endfunction

private function Sacrifice_Actions takes nothing returns nothing
    local SAC s = SAC.create()
    local timer t = NewTimer()
    local unit dummy
    local integer ver = Sacrifice_Connect(s.caster, s.target)
    set s.caster = GetTriggerUnit()
    set s.target = GetSpellTargetUnit()
    call BJDebugMsg(I2S(ver))
        if ver >= 1 then
            set s.range = 700 + GetUnitAbilityLevel(s.caster, 'A03S') * 100
            set s.tx = GetUnitX(s.target)
            set s.ty = GetUnitY(s.target)
            set s.x = GetUnitX(s.caster)
            set s.y = GetUnitY(s.caster)
            if ver == 1 then
                set s.lig = AddLightning("DRAM", true, s.x, s.y, s.tx, s.ty)
                call SetUnitUserData(s.caster, GetUnitUserData(s.caster)+1)
                call UnitAddAbility(s.target, 'A058')
                //call UnitAddAbility(s.target, 'A05A')
                call SetPlayerAbilityAvailable(GetOwningPlayer(s.target), 'A058', false)
                //call SetPlayerAbilityAvailable(GetOwningPlayer(s.target), 'A05A', false)
            endif
            set dummy = CreateUnit(GetOwningPlayer(s.caster), 'h00E', s.tx, s.ty, 0)
            call UnitAddAbility(dummy, 'A05B')
            call IssueTargetOrder(dummy, "bloodlust", s.target)
            call UnitApplyTimedLife(dummy, 'BTLF', 1.00)
            call SetTimerData(t,s)
            call TimerStart(t, 0.05, true, function Sacrifice_Defense)
        else
            set s.target = null
            set s.caster = null
            call ReleaseTimer(t)
            call s.destroy()
        endif
endfunction

//==== Init Trigger NewScope ====
private function In_Sacrifice takes nothing returns nothing
    local trigger t_Sacrifice = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t_Sacrifice, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition(t_Sacrifice, Condition(function Sacrifice_Conditions))
    call TriggerAddAction(t_Sacrifice, function Sacrifice_Actions)
    set t_Sacrifice = null
endfunction

endscope
 
Level 14
Joined
Nov 23, 2008
Messages
187
I think, it happens due to s.caster and s.target equal to null, when Sacrifice_Connect function runs. You should try placing that function call after setting values to your structure:

JASS:
private function Sacrifice_Actions takes nothing returns nothing
    local SAC s = SAC.create()
    local timer t = NewTimer()
    local unit dummy
    local integer ver = 0
    set s.caster = GetTriggerUnit()
    set s.target = GetSpellTargetUnit()
    set ver = Sacrifice_Connect(s.caster, s.target)
    call BJDebugMsg(I2S(ver))
    // . . .
 
Level 12
Joined
Mar 23, 2008
Messages
942
I think, it happens due to s.caster and s.target equal to null, when Sacrifice_Connect function runs. You should try placing that function call after setting values to your structure:

JASS:
private function Sacrifice_Actions takes nothing returns nothing
    local SAC s = SAC.create()
    local timer t = NewTimer()
    local unit dummy
    local integer ver = 0
    set s.caster = GetTriggerUnit()
    set s.target = GetSpellTargetUnit()
    set ver = Sacrifice_Connect(s.caster, s.target)
    call BJDebugMsg(I2S(ver))
    // . . .

mj3h4k.jpg


thanks...



-------------------------------------
Edit: Now its returning always 0 when I try to cast a second time on a different target.
It should allow up to 3 targets at level 3...
 
Level 14
Joined
Nov 23, 2008
Messages
187
JASS:
private function Sacrifice_Connect takes unit c, unit t returns integer
    local integer i = 0
    loop
        if (Caster[i] == c) and (Target[i] == t) then
            set i = 10
            return 2
        endif
        exitwhen i == 10
        set i = i + 1
    endloop
    // If we are in function yet (no "return 2" called), value of "i" will be 10
    // so looping through arrays values is stupid without something...

    if GetUnitUserData(c) >= GetUnitAbilityLevel(c, 'A03S') then
        return 0
    else
        // Well, I think, you've forgot something...
        set i = 0 // << ... something useful
        loop
            if Caster[i] == null then
                set Caster[i] = c
                set Target[i] = t
                set i = 10
                return 1
            endif
            exitwhen i == 10
            set i = i + 1
        endloop
    endif
endfunction

If that not helped, I recommend you to analyze debug output values for ver and value of GetUnitUserData(s.caster)
 
Status
Not open for further replies.
Top