[JASS] [SOLVED] Multiple instances of the same trigger call is crashing the game

Level 6
Joined
Mar 9, 2023
Messages
75
Hi! Due to popular demand, I'm considering re-adding enemies that broke the game. However I'm pretty uncertain how to proceed. The system spawns murlocs that blow up and deal damage to nearby enemies. It previously used to only deal damage to the killing unit and only if it was close enough, thus the Distance debug. It still crashed in that manner.

The following function is an ability attached to a Murloc Hut. It spawns two Murlocs whenever it's cast. Up to 20 units at once might cast it, but that is not my concern.
JASS:
function MurlocUnitSpawn_Actions takes nothing returns nothing
    local unit uc = GetSpellAbilityUnit()
    local unit u
    local real x = GetUnitX(uc)
    local real y = GetUnitY(uc)
    local integer i = 0

    loop
    exitwhen i == 2  
    set u = CreateUnit(Player(11),'h01U',x,y,GetRandomReal(0.0,360.0))
    call DestroyEffect(AddSpecialEffect("Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl",x,y))
    call GroupAddUnit(udg_G,u)
    call TriggerRegisterUnitEvent(gg_trg_DamageEvent,u,EVENT_UNIT_DAMAGED)
    set u = null
    set i = i + 1
    endloop
endfunction

The following trigger is called whenever the spawned Murloc dies. This should be why the map is crashing. It could be how I handle/refer to units, or maybe its frequency coupled with its calculations.
JASS:
function MurlocBaby_Conditions takes nothing returns boolean
return GetUnitTypeId(GetDyingUnit()) == 'h01U'
endfunction

function Trig_MurlocBaby_Actions takes nothing returns nothing
local unit uc = GetDyingUnit()
local unit ut
local group g = CreateGroup()
local unit dammy
local real damage
local real x1 = GetUnitX(uc)
local real y1 = GetUnitY(uc)
local real x2
local real y2
call DestroyEffect(AddSpecialEffect("Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl", x1, y1))
call BlzSetSpecialEffectScale(GetLastCreatedEffectBJ(), 0.2)

call GroupEnumUnitsInRange(g,x1,y1,300.0,function AGRO2)
loop
set ut = FirstOfGroup(g)
exitwhen ut == null
set x2 = GetUnitX(ut)
set y2 = GetUnitY(ut)
set damage = RoomPassed*0.33 + GetWidgetLife(ut) * 0.03
set dammy = CreateUnit(GetOwningPlayer(uc),'n00S',x1,y1,GetUnitFacing(uc))
call UnitApplyTimedLife(dammy,'BTLF',2.0)
call CreateTextTagUnit(I2S(R2I(damage)),ut, 0.00, 12.00, 255, 0, 0, 255, 0, 0.03, 1.00, false, true)
call UnitDamageTarget(dammy,ut,damage,true,false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC,WEAPON_TYPE_WHOKNOWS )
//call BJDebugMsg(I2S(R2I(Distance(x1, y1, x2, y2))))
endloop

call DestroyGroup(g)
set uc = null
set ut = null
set dammy = null
endfunction
function InitTrig_MurlocBaby takes nothing returns nothing
    set gg_trg_MurlocBaby = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_MurlocBaby, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition(gg_trg_MurlocBaby, Condition (function MurlocBaby_Conditions))
    call TriggerAddAction( gg_trg_MurlocBaby, function Trig_MurlocBaby_Actions )
endfunction

Spawning a dummy and through it dealing damage (referered in my map as dammies, because of reasons) was created as a way to fix the ongoing crashes and continously referencing dead units since they're removed upon dying. The AGRO2 filter just groups units once and it's a somewhat less specific filter to perform less checks.

Hopefully the answer is really simple and I just look dumb :D

EDIT: the solution was simply to add this quirkly little line at the end of the damage loop.
JASS:
call GroupRemoveUnit(g, ut)
 
Last edited:
Level 45
Joined
Feb 27, 2007
Messages
5,578
You registered a damage event for the spawned murlocs but then didn’t show that trigger. (Also why are you doing that yourself manually when there are great Damage Detection systems already and also new natives for it in the modern editor?) The only thing that makes sense is an infinite loop caused by AGRO2 not properly filtering out those murlocs from the GroupEnum.

A function running a lot will not just cause a game crash. There is an actual cause. You need to find a way to reproduce a bug like this reliably so that you can investigate what causes it. So, do a little testing and figure that out.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
A unit takes damage -> Deal damage -> A unit takes damage -> Deal damage -> Repeat infinity times.

Similar to something like this:
  • Events
    • Unit - A unit Dies
  • Conditions
  • Actions
    • Unit - Create 1 Footman...
    • Unit - Kill (Last created unit)
Damage Engine prevents this issue from happening (up to a certain point) using some trickery.
 
A function running a lot will not just cause a game crash. There is an actual cause. You need to find a way to reproduce a bug like this reliably so that you can investigate what causes it. So, do a little testing and figure that out.
I mean, the function itself could, if enough leaks are happening.

I don't know JASS all that well as I use LUA and GUI, but I can tell you you have all sorts of leaks going on, location leaks, unitgroup leaks, I'd imagine that you have things firing referencing things that no longer exist, maybe a loop somewhere causing an "Infinite Loop" crash.
 
Level 6
Joined
Mar 9, 2023
Messages
75
I mean, the function itself could, if enough leaks are happening.

I don't know JASS all that well as I use LUA and GUI, but I can tell you you have all sorts of leaks going on, location leaks, unitgroup leaks, I'd imagine that you have things firing referencing things that no longer exist, maybe a loop somewhere causing an "Infinite Loop" crash.
Unless I've been learnt incorrectly as a joke, I don't see any issues with locations and unitgroups. udg_G is a global group which represents the enemy forces, all local groups used during filtering are destroyed. Coordinates aren't locations and I'm not using any location handles. HOWEVER, your comment made me realise that I'm not removing units from the Trig_MurlocBaby_Actions loop, so that's an infinite loop and more than likely the issue, so thanks I'll fix it and try it out.
 
Level 45
Joined
Feb 27, 2007
Messages
5,578
You cannot remove events from a trigger (for all the units that die permanently), which has always been a limitation for using the specific unit events like this. You can destroy the current instance of that trigger, then create a new trigger object from the same TriggerAction and TriggerCondition and add any relevant events.
 
Top