Weird execution problem

Darius34

New Member
Reaction score
30
I'm having this really weird problem with a trigger. I've debugged extensively and yet I can't find a solution.

For some reason, the execution of a particular bit of code in that trigger stops at one point. Stops, just like that. I'm using a local trigger with a periodic event, and after that aforementioned point, it runs normally.

A simple example to illustrate the circumstances:

JASS:
local trigger t = GetTriggeringTrigger()
local unit UnitA = (something)
local unit UnitB

call Function1()
call Damage(UnitA)
loop
  exitwhen (some conditions)
  If (some conditions) then // Block 1
    set UnitB = (something)
  endif
endloop
set UnitA = UnitB // Line in question
if UnitA == null then
  call DestroyTrigger(t)
endif

My spell works by damaging a fixed number of unique units one after another, and the part labelled Block 1 has some priority conditions for picking targets. If there are insufficient targets in the AoE, UnitB and UnitA both are set to null.

If, for instance, there are 3 targets and the spell targets on 5, UnitA and UnitB would be nulled after the third time the trigger runs, since UnitA and UnitB cannot be damaged again. That's where the problem is: at "Line in question", the execution stops. Everything after that line is bypassed, but yet the trigger runs normally after that and continuously damages UnitA. No new target is picked.

I'll clarify if you don't understand the problem. It seems to have something to do with UnitA and UnitB being null at that point. I've added all sorts of code before and after the line in question, and concluded that execution just stops there.

I remember this happening with the functions SetUnitX() and SetUnitY(), some time back. To correct the problem then, I replaced both with SetUnitPosition(); I've yet to find out why the latter worked.

I've spent a few days cracking my head over this and am incredibly frustrated. Any help at all would be appreciated.
 

~GaLs~

† Ғσſ ŧħə ѕαĸε Φƒ ~Ğ䣚~ †
Reaction score
180
Add a TriggerSleepAction(0.1) inside your loop. Your loop is hitting OP.
 

Darius34

New Member
Reaction score
30
Add a TriggerSleepAction(0.1) inside your loop. Your loop is hitting OP.
OP? What's OP? And how would the wait help? It'd cause visible delay I don't want, in this case; my spell moves a projectile like that of Moon Glaive.
 

AceHart

Your Friendly Neighborhood Admin
Reaction score
1,495
Operation limit.
You're loop will not run forever.
Sooner or later, the game will just stop it... around 12000+ (or somewhat more, don't remember) actions.

Adding a wait will reset that limit.
 

Darius34

New Member
Reaction score
30
Operation limit.
You're loop will not run forever.
Sooner or later, the game will just stop it... around 12000+ (or somewhat more, don't remember) actions.

Adding a wait will reset that limit.
Hmm. I added the wait (tried various values, from 0 to 0.1) and didn't seem to have any effect; the spell still doesn't work. My code can't possibly be executing over 200 times, even. Could this problem still be caused exclusively by this operation limit?
 

Terrabull

Veteran Member (Done that)
Reaction score
38
Can we see the full trigger? Maybe it's something you didn't think of w/ conditions, or actions that were mistaken. With that bit of psuedo code we can't tell those.
 

Darius34

New Member
Reaction score
30
Okay, here's the part where there are problems. The rest of it isn't too relevant, so I omitted it. Suffice to say that upon damage being detected by a damage event attached to a trigger with an attack event, the function MoonGlaiveHitActions() executes, and that in turn calls MoonGlaiveMovement() periodically to move the glaive.

JASS:
function MoonGlaiveMovement takes nothing returns nothing
    local trigger movementtrig = GetTriggeringTrigger()
    local unit source = GetHandleUnit(movementtrig, "source")
    local unit dummy = GetHandleUnit(movementtrig, "dummy")
    local real damage = GetHandleReal(movementtrig, "damage") * .35
    local integer bouncesleft = GetHandleInt(movementtrig, "bouncesleft")
    local unit nexttarget = GetHandleUnit(movementtrig, "nexttarget")
    local group alreadyhit = GetHandleGroup(movementtrig, "alreadyhit")
    local group targets = CreateGroup()
    local group temptargets = CreateGroup()
    local unit picked
    local unit temppicked
    local real prevdist = 99999.
    local real dist
    local real dx = GetUnitX(nexttarget) - GetUnitX(dummy)
    local real dy = GetUnitY(nexttarget) - GetUnitY(dummy)
    local real angle = Atan2(dy, dx)
    local real x = GetUnitX(dummy) + 18 * Cos(angle)
    local real y = GetUnitY(dummy) + 18 * Sin(angle)

    if SquareRoot(dx * dx + dy * dy) > 18. then
        call SetUnitPosition(dummy, x, y)
    else
        call UnitDamageTarget(source, nexttarget, damage, true, true, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
        call GroupEnumUnitsInRange(targets, GetUnitX(nexttarget), GetUnitY(nexttarget), 500., Condition(function MoonGlaiveBounceTargetConditions))

        call GroupAddGroup(targets, temptargets)
        loop
            set picked = FirstOfGroup(temptargets)
            exitwhen picked == null
            set dx = GetUnitX(picked) - GetUnitX(nexttarget)
            set dy = GetUnitY(picked) - GetUnitY(nexttarget)
            set dist = SquareRoot(dx * dx + dy * dy)

            if dist < prevdist then
                set prevdist = dist
                set temppicked = picked
            endif
            call GroupRemoveUnit(temptargets, picked)
            call TriggerSleepAction(.1)
        endloop
        set nexttarget = temppicked // The line in question
        set bouncesleft = bouncesleft - 1

        if bouncesleft < 1 or CountUnitsInGroup(targets) < 1 or nexttarget == null then
            call DisableTrigger(movementtrig)
            call KillUnit(dummy)
            call DestroyGroup(alreadyhit)
            call FlushHandleLocals(movementtrig)
            call DestroyTrigger(movementtrig)
        else        
            call GroupAddUnit(alreadyhit, nexttarget)
            call SetHandleReal(movementtrig, "damage", damage)
            call SetHandleInt(movementtrig, "bouncesleft", bouncesleft)
            call SetHandleHandle(movementtrig, "nexttarget", nexttarget)
        endif
    endif
    set movementtrig = null
    set source = null
    set dummy = null
    set nexttarget = null
    set picked = null
    set temppicked = null
    set alreadyhit = null
    call DestroyGroup(targets)
    set targets = null
    call DestroyGroup(temptargets)
    set temptargets = null
endfunction

function MoonGlaiveHitActions takes nothing returns nothing
    local trigger t = GetTriggeringTrigger()
    local unit target
    local unit source = GetEventDamageSource()
    local trigger movementtrig
    local unit dummy
    local group alreadyhit
    local group targets
    local unit nexttarget

    if GetTriggerEventId() != EVENT_UNIT_DAMAGED then
        call DisableTrigger(t)
        call FlushHandleLocals(t)
        call DestroyTrigger(t)
    elseif GetTriggerEventId() == EVENT_UNIT_DAMAGED and source == GetHandleUnit(t, "source") then
        call DisableTrigger(t)
        call FlushHandleLocals(t)
        call DestroyTrigger(t)

        set target = GetTriggerUnit()
        set movementtrig = CreateTrigger()
        set dummy = CreateUnit(GetOwningPlayer(source), 'e000', GetUnitX(target), GetUnitY(target), 0.)
        set targets = CreateGroup()
        set alreadyhit = CreateGroup()
        
        call GroupAddUnit(alreadyhit, target)
        call GroupEnumUnitsInRange(targets, GetUnitX(target), GetUnitY(target), 500., Condition(function MoonGlaiveTargetConditions))
        set nexttarget = GroupPickClosestUnit(targets, GetUnitX(target), GetUnitY(target))
        call SetHandleHandle(movementtrig, "nexttarget", nexttarget)
        call GroupAddUnit(alreadyhit, nexttarget)
        
        call SetHandleHandle(movementtrig, "alreadyhit", alreadyhit)
        call SetHandleHandle(movementtrig, "dummy", dummy)
        call SetHandleHandle(movementtrig, "source", source)
        call SetHandleInt(movementtrig, "bouncesleft", GetUnitAbilityLevel(source, MoonGlaiveId()))
        call SetHandleReal(movementtrig, "damage", GetEventDamage())
        call TriggerRegisterTimerEvent(movementtrig, 0.02, true)
        call TriggerAddAction(movementtrig, function MoonGlaiveMovement)        
        
        set target = null
        set movementtrig = null
        set dummy = null
        call DestroyGroup(targets)
        set targets = null
        set alreadyhit = null
    endif

    set t = null
    set source = null
endfunction

Haven't gotten round to learning about structs, so I'm still using old-school methods. Point out any bugs if you see any, please; that would be appreciated too. :)
 

Darius34

New Member
Reaction score
30
Oh, wow, I never would have thought of that. It worked like a charm. Thanks a lot, phyrex1an. :)
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • WildTurkey WildTurkey:
    is there a stephen green in the house?
    +1
  • The Helper The Helper:
    What is up WildTurkey?
  • The Helper The Helper:
    Looks like Google fixed whatever mistake that made the recipes on the site go crazy and we are no longer trending towards a recipe site lol - I don't care though because it motivated me to spend alot of time on the site improving it and at least now the content people are looking at is not stupid and embarrassing like it was when I first got back into this like 5 years ago.
  • The Helper The Helper:
    Plus - I have a pretty bad ass recipe collection now! That section of the site is 10 thousand times better than it was before
  • The Helper The Helper:
    We now have a web designer at my job. A legit talented professional! I am going to get him to redesign the site theme. It is time.
  • Varine Varine:
    I got one more day of community service and then I'm free from this nonsense! I polished a cop car today for a funeral or something I guess
  • Varine Varine:
    They also were digging threw old shit at the sheriff's office and I tried to get them to give me the old electronic stuff, but they said no. They can't give it to people because they might use it to impersonate a cop or break into their network or some shit? idk but it was a shame to see them take a whole bunch of radios and shit to get shredded and landfilled
  • The Helper The Helper:
    whatever at least you are free
  • Monovertex Monovertex:
    How are you all? :D
    +1
  • Ghan Ghan:
    Howdy
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top