1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. The Lich King demands your service! We've reached the 19th edition of the Icon Contest. Come along and make some chilling servants for the one true king.
    Dismiss Notice
  4. The 4th SFX Contest has started. Be sure to participate and have a fun factor in it.
    Dismiss Notice
  5. The poll for the 21st Terraining Contest is LIVE. Be sure to check out the entries and vote for one.
    Dismiss Notice
  6. The results are out! Check them out.
    Dismiss Notice
  7. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  8. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  9. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[JASS] Always returning 2

Discussion in 'Triggers & Scripts' started by Saishy, Feb 10, 2009.

  1. Saishy

    Saishy

    Joined:
    Mar 23, 2008
    Messages:
    947
    Resources:
    0
    Resources:
    0
    The Sacrifice_Connect function is always returning 2, why?

    Code (vJASS):

    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
     
     
  2. Shadow Daemon

    Shadow Daemon

    Joined:
    Nov 23, 2008
    Messages:
    184
    Resources:
    3
    Tools:
    3
    Resources:
    3
    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:

    Code (vJASS):
    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))
        // . . .
     
  3. Saishy

    Saishy

    Joined:
    Mar 23, 2008
    Messages:
    947
    Resources:
    0
    Resources:
    0
    [​IMG]

    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...
     
  4. Shadow Daemon

    Shadow Daemon

    Joined:
    Nov 23, 2008
    Messages:
    184
    Resources:
    3
    Tools:
    3
    Resources:
    3
    Code (vJASS):
    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)
     
  5. Saishy

    Saishy

    Joined:
    Mar 23, 2008
    Messages:
    947
    Resources:
    0
    Resources:
    0
    Oh god! Its working superb!

    Thanks!

    Edit: Can't give you another rep xD