Trigger causes crash (Jass trigger uses Damage Detection)

ThePlague

New Member
Reaction score
14
Why in the world is this causing a crash? when I test map Wc3 gives an error message and crashes as soon as the projectile impacts the unit

JASS:
function Trig_Damage takes unit Ranger, unit Target, location RangerLoc returns nothing
local location TargetLoc=GetUnitLoc(Target)
local unit Source=GetEventDamageSource()
local real AtkDmg=GetEventDamage()
local real Damage
     if (Source!=Ranger)then
return
     endif
if (GetUnitAbilityLevel(Ranger, 'A021')==0) then
     set Damage= (900-DistanceBetweenPoints(RangerLoc, TargetLoc))/8500
         if (Damage<.1)then
                            set Damage=.05
         endif
endif
if (GetUnitAbilityLevel(Ranger, 'A021')==1) then
     set Damage= (1250-DistanceBetweenPoints(RangerLoc, TargetLoc))/6000
         if (Damage<.05)then
                            set Damage=.1
         endif
endif
if (GetUnitAbilityLevel(Ranger, 'A021')==2) then
     set Damage= (1600-DistanceBetweenPoints(RangerLoc, TargetLoc))/3875
         if (Damage<.05)then
                            set Damage=.2
         endif
endif
if (GetUnitAbilityLevel(Ranger, 'A021')==3) then
     set Damage= (1950-DistanceBetweenPoints(RangerLoc, TargetLoc))*3/9500
         if (Damage<.05)then
                            set Damage=.3
         endif
endif
    call UnitDamageTarget( Ranger, Target,  Damage ,false,false , ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL,null )
    set Damage=AtkDmg + Damage
    set udg_String=R2S(Damage)
    call CreateTextTagUnitBJ( udg_String, Target, 100.00, 15, 100, 0.00, 0.00, 0 )
call DestroyTrigger (GetTriggeringTrigger())
call RemoveLocation (RangerLoc)
call RemoveLocation (TargetLoc)
set Ranger=null
set Target=null
set Source=null
endfunction

function Trig_R_Actions takes nothing returns nothing
local trigger Damage=CreateTrigger()
local unit Ranger=GetAttacker()
local unit Target=GetTriggerUnit()
local location RangerLoc=GetUnitLoc(Ranger)
    if (GetUnitTypeId(Ranger) == 'E006') then
         call TriggerRegisterUnitEvent( Damage, Target, EVENT_UNIT_DAMAGED )
         call TriggerAddAction( Damage, function Trig_Damage )
    endif
call TriggerSleepAction (3.0)
call DestroyTrigger (Damage)
call RemoveLocation (RangerLoc)
set Ranger=null
set Target=null
endfunction

//===========================================================================
function InitTrig_R takes nothing returns nothing
    set gg_trg_R = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_R, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddAction( gg_trg_R, function Trig_R_Actions )
endfunction


erm also I think i got all the leaks but if there are any i missed please point those out too
 

trb92

Throwing science at the wall to see what sticks
Reaction score
142
JASS:
         call TriggerRegisterUnitEvent( Damage, Target, EVENT_UNIT_DAMAGED )
         call TriggerAddAction( Damage, function Trig_Damage )

You detect for damage, alright...
Then, in the Trig_Damage function...
JASS:
call UnitDamageTarget( Ranger, Target,  Damage ,false,false , ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL,null)

You damage a unit... Which fires the trigger, damages the unit, fires the trigger, and so on forever. Warcraft crashes when this happens. It's called an Infinite Loop, as it will just loop forever.

And it should syntax error, I don't belive that actions can take arguments...
 

ThePlague

New Member
Reaction score
14
erm just crashed again
I changed the trigger to
JASS:
function Trig_Damage takes unit Ranger, unit Target, location RangerLoc returns nothing
local location TargetLoc=GetUnitLoc(Target)
local unit Source=GetEventDamageSource()
local real AtkDmg=GetEventDamage()
local real Damage
     if (Source!=Ranger)then
return
     endif
call DestroyTrigger (GetTriggeringTrigger())
if (GetUnitAbilityLevel(Ranger, 'A021')==0) then
     set Damage= (900-DistanceBetweenPoints(RangerLoc, TargetLoc))/8500
         if (Damage<.1)then
                            set Damage=.05
         endif
endif
if (GetUnitAbilityLevel(Ranger, 'A021')==1) then
     set Damage= (1250-DistanceBetweenPoints(RangerLoc, TargetLoc))/6000
         if (Damage<.05)then
                            set Damage=.1
         endif
endif
if (GetUnitAbilityLevel(Ranger, 'A021')==2) then
     set Damage= (1600-DistanceBetweenPoints(RangerLoc, TargetLoc))/3875
         if (Damage<.05)then
                            set Damage=.2
         endif
endif
if (GetUnitAbilityLevel(Ranger, 'A021')==3) then
     set Damage= (1950-DistanceBetweenPoints(RangerLoc, TargetLoc))*3/9500
         if (Damage<.05)then
                            set Damage=.3
         endif
endif
    call UnitDamageTarget( Ranger, Target,  Damage ,false,false , ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL,null )
    set Damage=AtkDmg + Damage
    set udg_String=R2S(Damage)
    call CreateTextTagUnitBJ( udg_String, Target, 100.00, 15, 100, 0.00, 0.00, 0 )
call RemoveLocation (RangerLoc)
call RemoveLocation (TargetLoc)
set Ranger=null
set Target=null
set Source=null
endfunction

function Trig_R_Actions takes nothing returns nothing
local trigger Damage=CreateTrigger()
local unit Ranger=GetAttacker()
local unit Target=GetTriggerUnit()
local location RangerLoc=GetUnitLoc(Ranger)
    if (GetUnitTypeId(Ranger) == 'E006') then
         call TriggerRegisterUnitEvent( Damage, Target, EVENT_UNIT_DAMAGED )
         call TriggerAddAction( Damage, function Trig_Damage )
    endif
call TriggerSleepAction (3.0)
call DestroyTrigger (Damage)
call RemoveLocation (RangerLoc)
set Ranger=null
set Target=null
endfunction

//===========================================================================
function InitTrig_R takes nothing returns nothing
    set gg_trg_R = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_R, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddAction( gg_trg_R, function Trig_R_Actions )
endfunction

(I just moved the Destroy trigger comman)


Also Shouldnt this have destroyed the infiite loop problem after 3 secs?
JASS:
call TriggerSleepAction (3.0)
call DestroyTrigger (Damage)
call RemoveLocation (RangerLoc)
set Ranger=null
set Target=null
endfunction
 

ThePlague

New Member
Reaction score
14
ok i did a few more tests and heres what happened:

1.set projectile speed to 10 (so projectile took over 3 seconds to hit) and when it hit it did not crash, but also no extra damage was done

2.I changed this
JASS:
call UnitDamageTarget( Ranger, Target,  Damage ,false,false , ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL,null)
to this
JASS:
call UnitDamageTarget( Target, Target,  Damage ,false,false , ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL,null)


so in this one Ranger is not doing the extra damage and instead the unit is doing extra damage to itself, but it still crashed even though when the unit hurting itself ran the trigger this should have stopped an infinite loop:
JASS:
     if (Source!=Ranger)then
return
     endif

(Ranger would not be the damage source so all remaining actions would be skipped)

Edit:

3.COmpletely removed the line
JASS:
call UnitDamageTarget( Ranger, Target,  Damage ,false,false , ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL,null)
and it still crashed
 

trb92

Throwing science at the wall to see what sticks
Reaction score
142
JASS:
function Trig_Damage takes unit Ranger, unit Target, location RangerLoc returns nothing

That function is not able to have any arguments, since it's used as an action and not used as call Trig_Damage(whatever).
 

ThePlague

New Member
Reaction score
14
hmm ok in that case
I can check if the damage source is ranger in a condition
I can use triggering unit instead of Target
but is there anyway I can use the location of 'Ranger' when the actual attack was fired?


ps thanks for all the help +rep
 

vypur85

Hibernate
Reaction score
803
Don't know JASS but just turn off trigger in the beggining and turn it on again at the end.


Code:
Event
Condition
Actions
 Trigger - Turn off (This trigger)
 Unit - Cause (Damage source) to damage (Triggering unit) etc etc...
 Trigger - Turn on (This trigger)
 

Flare

Stops copies me!
Reaction score
662

ThePlague

New Member
Reaction score
14
I know how to do that, but I want the location of the attacker when the attack is fired, not when the target takes damage. Anyway I can do that other than making a large enough global array that I wont have to worry about values being overwritten?
 

vypur85

Hibernate
Reaction score
803
> location of the attacker when the attack is fired, not when the target takes damage

Then why would you want a damage detection event? Just use the 'A unit is attacked' event. As to when the missile will land, just use:

Code:
ImpactTime = (Distance between Attacking unit and Attacked unit)/([I]YourMissileSpeed[/I])

Wait till that 'ImpactTime' then do your actions. Or use a timer.
 

ThePlague

New Member
Reaction score
14
well, if the unit moves theres a problem. I need to get the location of the local unit Ranger from the other function. Is there a way to that or should i just use a big array so nothing will be overwritten?

Edit: can functions called by a timer take arguments?
 

ThePlague

New Member
Reaction score
14
heres my work around:

udg_Ranger
unit arry with size 40

udg_RangerTarget
unit array with size 40

udg_RangerLoc
point array with size 40

udg_string
string with no initial value
JASS:
function Trig_R_Conditions takes nothing returns boolean
local unit Ranger=GetAttacker()
    if (GetUnitTypeId(Ranger) == 'E006') then
set Ranger=null
    return true
endif
set Ranger=null
    return false
endfunction

function Damage_Cond takes nothing returns boolean
local unit Source=GetEventDamageSource()
local unit Target=GetTriggerUnit()
local integer x
    loop
    exitwhen x==41
        if (GetBooleanAnd(udg_Ranger[x]==Source, udg_RangerTarget[x]==Target)) then
             set Source=null
             set Target=null
             return true
        else
               if (x==40) then
                    set Source=null
                    set Target=null
                    return false
               endif
             set x=x+1
        endif
    endloop
endfunction

function Trig_Damage takes nothing returns nothing
local unit Target=GetTriggerUnit()
local location TargetLoc=GetUnitLoc(Target)
local unit Ranger=GetEventDamageSource()
local location RangerLoc
local real AtkDmg=GetEventDamage()
local real Damage
local integer x
  call DestroyTrigger(GetTriggeringTrigger())
    loop
    exitwhen x==41
        if (GetBooleanAnd(udg_Ranger[x]==Ranger, udg_RangerTarget[x]==Target)) then
             set RangerLoc=udg_RangerLoc[x]
             set udg_Ranger[x]=null
             set udg_RangerTarget[x]=null
             set x=41
        else
             set x=x+1
        endif
    endloop
if (GetUnitAbilityLevel(Ranger, 'A021')==0) then
     set Damage= (900-DistanceBetweenPoints(RangerLoc, TargetLoc))/8500
         if (Damage<.1)then
                            set Damage=.05
         endif
endif
if (GetUnitAbilityLevel(Ranger, 'A021')==1) then
     set Damage= (1250-DistanceBetweenPoints(RangerLoc, TargetLoc))/6000
         if (Damage<.05)then
                            set Damage=.1
         endif
endif
if (GetUnitAbilityLevel(Ranger, 'A021')==2) then
     set Damage= (1600-DistanceBetweenPoints(RangerLoc, TargetLoc))/3875
         if (Damage<.05)then
                            set Damage=.2
         endif
endif
if (GetUnitAbilityLevel(Ranger, 'A021')==3) then
     set Damage= (1950-DistanceBetweenPoints(RangerLoc, TargetLoc))*3/9500
         if (Damage<.05)then
                            set Damage=.3
         endif
endif
    set Damage=Damage*AtkDmg
    call UnitDamageTarget( Ranger, Target,  Damage ,false,false , ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL,null)
    set Damage=AtkDmg + Damage
    set udg_String=I2S(R2I(Damage))
    call CreateTextTagUnitBJ( udg_String, Target, 100.00, 13, 0, 0.00, 100, 0 )
    call SetTextTagPermanentBJ( GetLastCreatedTextTag(), false )
    call SetTextTagLifespanBJ( GetLastCreatedTextTag(), 3.00 )
call RemoveLocation (RangerLoc)
call RemoveLocation (TargetLoc)
set Ranger=null
set Target=null
endfunction

function Trig_R_Actions takes nothing returns nothing
local trigger RangerDamage=CreateTrigger()
local integer x
    loop
    exitwhen x==41
          if (udg_Ranger[x]==null) then
    set udg_Ranger[x]=GetAttacker()
    set udg_RangerLoc[x]=GetUnitLoc(udg_Ranger[x])
         call TriggerRegisterUnitEvent( RangerDamage, Target, EVENT_UNIT_DAMAGED )
         call TriggerAddCondition (RangerDamage, Condition(function Damage_Cond))
         call TriggerAddAction(RangerDamage, function Trig_Damage )
    set x=41
          else
    set x=x+1
          endif
    endloop
call TriggerSleepAction (3)
call DestroyTrigger(RangerDamage)
endfunction

//===========================================================================
function InitTrig_R takes nothing returns nothing
    set gg_trg_R = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_R, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddCondition( gg_trg_R, Condition( function Trig_R_Conditions ) )
    call TriggerAddAction( gg_trg_R, function Trig_R_Actions )
endfunction


But I havent been able to test it because i keep getting a compile error "Invalid type for specified operator"

Whats wrong now?
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top