Two questions-ifs

Tar-Quaeron

New Member
Reaction score
0
I have two related questions.

1st: Do triggers which are triggered when something related to a specific unit happens get destroyed when the specific unit gets destroyed? I'm talking about TriggerRegisterUnitEvent and TriggerRegisterUnitInRange. I mean obviously (hopefully) the trigger won't fire if the specific unit in their arguments doesn't exist anymore but the handle trigger to which the event is attached would still exist and take up space in the RAM right? Which means it would be necessary to destroy those triggers if the unit to which they pertain was destroyed.

This brings me to my 2nd question: How much time do ifs statements take to execute? I mean how bad are they in terms of lag/memory usage? The question I'm asking is whether it would be worth it, in order to disable the triggers mentioned above to add a 2nd event in the triggers which would detect when the specific unit is destroyed and then callDestroyTrigger(GetTriggeringTrigger) (because they're local I couldn't find another way). But this would require ifs and else ifs in the actions function which could be called up to several times a second at some moments in the game. So is it worth it to add those ifs?

In one case actually the trigger is TriggerRegisterUnitLeaveRectSimple which would keep firing even after the unit originally used to define the region is gone. I guess in that case it would really be worth it.
 

Jesus4Lyf

Good Idea™
Reaction score
397
1st: Do triggers which are triggered when something related to a specific unit happens get destroyed when the specific unit gets destroyed?
No. Easily accomplished using AIDS, which was designed for it. :)
See the way this script does it. (This bit):
JASS:
    private struct Detector extends array // Uses AIDS.
        //! runtextmacro AIDS()
        
        private static conditionfunc ACTIONS_COND
        
        private trigger t
        
        private method AIDS_onCreate takes nothing returns nothing
            set this.t=CreateTrigger()
            call TriggerAddCondition(this.t,thistype.ACTIONS_COND)
            call TriggerRegisterUnitEvent(this.t,this.unit,EVENT_UNIT_DAMAGED)
        endmethod
        
        private method AIDS_onDestroy takes nothing returns nothing
            call DestroyTrigger(this.t)
        endmethod
        
        private static method AIDS_onInit takes nothing returns nothing
            set thistype.ACTIONS_COND=Condition(function OnDamageActions)
        endmethod
    endstruct

This is the best way (I know of) to remove data related specifically to a unit as it is removed from the game. :)
Hope that helps! ;)
 

Tar-Quaeron

New Member
Reaction score
0
Why does every thing have to NewGen, or is this vJass (I can't remember which one is scopes and which is structs)? I don't feel like learning or even downloading all those, well I guess you have to choose one. My question applies specifically to vanilla Jass (is that the term for classic unaltered Jass?). I mean I think it's a valid question from a purely theoretical point of view: how bad are ifs (or even extra code lines)? A question I've always asked myself is: is it better to use ifs at the beginning of an action function or is it better to use condition functions. People talk and talk about leaks with variables but it would also be good to know (at least personally) what the most efficient code is (it's happened fairly often to me now that I can think of 2-3 ways of doing something and I never know which one is fastest/most efficient).
 

Jesus4Lyf

Good Idea™
Reaction score
397
Why does every thing have to NewGen, or is this vJass (I can't remember which one is scopes and which is structs)? I don't feel like learning or even downloading all those, well I guess you have to choose one.
You had best state that at the start of every question you post, as the assumption on these forums is that you have a vJass compiler, unless stated otherwise. (vJass is the language, JassHelper is the "compiler", and NewGen is an IDE that drives JassHelper.)
My question applies specifically to vanilla Jass (is that the term for classic unaltered Jass?)
Yes. "Vanilla" Jass is stock-standard Jass. :)
how bad are ifs (or even extra code lines)?
How bad is a piece of string? Depends how many you use, and what alternatives there are. I answered with a better alternative to "if" statements.
is it better to use ifs at the beginning of an action function or is it better to use condition functions. People talk and talk about leaks with variables but it would also be good to know (at least personally) what the most efficient code is (it's happened fairly often to me now that I can think of 2-3 ways of doing something and I never know which one is fastest/most efficient).
Good efficiency: Use conditions and actions as normal.
Better efficiency: Forget actions and [LJASS]TriggerSleepAction[/LJASS], put all conditions and actions into the conditions function.
Best efficiency: Hash on something to jump to a trigger containing the actions (see GTrigger). Do this in the conditions func. Example:
JASS:
function MyCondition takes nothing returns boolean
    local integer abil = GetSpellAbilityId()
    local trigger toLaunch = MyTrigArray[abil-(abil/8191)*8191]
    if toLaunch != null then
        call TriggerEvaluate(toLaunch) // put only conditions on this trigger, or use TriggerExecute, which is marginally slower in theory.
    endif
    return false
endfunction

Then, on map init, you store triggers associated with whatever you hash for, in this case, spell id.
All of this can be done with GUI, in theory. But it would then be in actions, instead of conditions. :)
 

Kajik

New Member
Reaction score
4
Attach a triggeraction and triggercondition to your trigger and trigger itself to unit. When unit dies, simpy use
JASS:

function removeTrigger takes trigger trig returns nothing
    call DisableTrigger(trig)
    call TriggerRemoveAction(trig, GetHandleTriggerAction(trig, "trig_action"))
    call TriggerRemoveCondition(trig, GetHandleTriggerCondition(trig, "trig_condition"))
    call FlushHandleVars(trig)
    call DestroyTrigger(trig)
    set trig = null
endfunction
 

Tar-Quaeron

New Member
Reaction score
0
Oh so you have to use DisableTrigger, Remove Action/Condition, FlushHandleVars before you destroy a trigger to remove all memory leaks? I mean unnecessary use of a trigger? What does flush handle vars do exactly? Remove all the handles in the Actions and Condition functions? Or just destroy the variables, i.e. the pointers not the objects themselves, does it also null them?
@ Jesus4Lyf I didn't understand the two other better possibilities. ^^ I've never used hashtables. Yes I really really should. Maybe i'll understand your system. I mean I sort of understand the idea. You preset a global trigger array. But you can use ability ids as an index??? I mean GetAbilityId() returns an integer but aren't there letters? What integer does JASS transform A000 into? And why do (abil/8191) * 8191? Is that "-" represent a minus sign? Anyway if the abili you have does not correspond to a preset trigger then you call the... conditions function??? So if the ability does not correspond to a preset trigger, i.e. if you don't want the trigger to trigger, you call TriggerEvaluate the trigger? ... Yeah I don't understand. ^^

But how do you use actions in the condition (2nd way)? With ifs? (this is probably at least part of the reason I don't understand the 3rd way).

Yeah about the ifs, I understand that my question was pretty stupid as a general question as it obviously depends on what the if/what functions your adding is. Here's what I had, although this only detects when the unit is sold (the ability in question). I need to add one that detects when the unit is killed by another unit. The thing is, this unit, it's a tower in a tower defense is the last in a race. That means it's gonna be pretty rare. But it has the ability to poison (death gas) units in a area around it. So the trigger itself will fire quite often (up to several times a second for fast moving creeps). If the tower is sold or killed then the TriggerRegisterUnitInRange won't trigger. The unit leave region will still though, even if it won't do anything. So I guess I will have to destroy at least that trigger. So my question was, is it worth it to add those if statements which will possibly slow down the computer, just to recuperate that little space taken up by the handle the trigger, it's actions, conditions, etc for the RegisterUnitInRange Trigger which won't fire anymore anyway.

JASS:

function DeathGasBuff_Place takes nothing returns nothing
    if GetUnitTypeId(GetTrainedUnit()) == 'nC57' or GetUnitState(GetTriggerUnit(), UNIT_STATE_LIFE) <=0 then
        call DestroyTrigger(GetTriggeringTrigger())
        call DisplayTextToForce(GetPlayersAll(), "TriggerDestroyed-BAD")
    else    
        call UnitAddAbility(GetTriggerUnit(), 'A02F')
        call UnitAddAbility(GetTriggerUnit(), 'A02H')
    endif    
endfunction

function DeathGasBuff_Remove takes nothing returns nothing
    if GetUnitTypeId(GetTrainedUnit()) == 'nC57' or GetUnitState(GetTriggerUnit(), UNIT_STATE_LIFE) <=0 then
        call DestroyTrigger(GetTriggeringTrigger())
    elseif not(GetOwningPlayer(GetTriggerUnit()) == GetLocalPlayer()) then
        call UnitRemoveAbility(GetTriggerUnit(), 'A02F')
        call UnitRemoveAbility(GetTriggerUnit(), 'A02H')
    endif
endfunction

function Cond_CreateDeathBuffTriggers takes nothing returns boolean
    return GetUnitTypeId(GetTriggerUnit()) == 'o00Z'
endfunction 

function CreateDeathBuffTriggers takes nothing returns nothing
    local trigger enter = CreateTrigger()
    local trigger leave = CreateTrigger()
    call TriggerRegisterUnitInRange(enter, GetTriggerUnit(), 200, Condition(function IsTriggerUnitEnemy))
    call TriggerRegisterUnitEvent(enter, GetTriggerUnit(), EVENT_UNIT_TRAIN_FINISH)
    call TriggerRegisterUnitEvent(enter, GetTriggerUnit(), EVENT_UNIT_DEATH)  
    call TriggerAddAction(enter, function DeathGasBuff_Place)
    call TriggerRegisterLeaveRectSimple(leave, Rect(GetLocationX(GetUnitLoc(GetTriggerUnit())) - 140.42, GetLocationY(GetUnitLoc(GetTriggerUnit())) - 140.42, GetLocationX(GetUnitLoc(GetTriggerUnit())) + 140.42, GetLocationY(GetUnitLoc(GetTriggerUnit())) + 140.42))
    call TriggerRegisterUnitEvent(leave, GetTriggerUnit(), EVENT_UNIT_TRAIN_FINISH)
    call TriggerRegisterUnitEvent(leave, GetTriggerUnit(), EVENT_UNIT_DEATH) 
    call TriggerAddAction(leave, function DeathGasBuff_Remove)
    call AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Immolation\\ImmolationTarget.mdl", GetTriggerUnit(), "origin")
    call AddSpecialEffectTarget("Abilities\\Spells\\Undead\\Curse\\CurseTarget.mdl", GetTriggerUnit(), "overhead")
    set enter = null
    set leave = null
endfunction

//===========================================================================

function InitTrig_DeathGasBuff takes nothing returns nothing
    set gg_trg_DeathGasBuff = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_DeathGasBuff, EVENT_PLAYER_UNIT_UPGRADE_FINISH)
    call TriggerAddCondition(gg_trg_DeathGasBuff, Condition(function Cond_CreateDeathBuffTriggers))   
    call TriggerAddAction( gg_trg_DeathGasBuff, function CreateDeathBuffTriggers)
    set gg_trg_DeathGasBuff = null
endfunction
 

Tar-Quaeron

New Member
Reaction score
0
Oh right I've been wondering, what happens if you add several TriggerAddAction and TriggerAddConditions to one trigger? Do all of the conditions have to return true for all of the action functions to be called?
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
conditions have to return true
All conditions are linked up by "and".
1 trigger returns false, the next triggers will not be fired.

all of the action functions to be called
Actions will be fired. But adding action to dynamic trigger is not a good idea, because it will lead to handle corruption stack.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top