• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Need help about triggers

Status
Not open for further replies.
Level 3
Joined
Sep 7, 2013
Messages
47
Hi, I am making a trigger wherein if a unit is attacked or has been hit by a spell, an ability will have to be removed. Then after 10 seconds (without being hit by physical attacks or spells) the ability will return. I tried using waits first but if the event occurs again (if the unit has been attacked again) the first event will still be activated, thus, returning back the ability (even though the unit has been attacked recently).

I clearly understand the problem (about the trigger event) but I can't think of an alternative. I am confident to have basic knowledge of JASS but I'd like to avoid heavy triggering as possible (I can't have my brain bleed any more).

Thanks in advance
 
Level 12
Joined
Mar 24, 2011
Messages
1,082
If you use a timer instead of wait and start it each time the event happens you will be fine.

You will have a trigger which detects given event and starts the timer and takes the ability away.
A trigger which detects when the timer expires and gives back the ability


Nitpicking: Maybe explain what are you trying to achieve.
What event exactly do you need ? As it has been said many times in a lot of places Unit is attacked != Unit is hit
If you want to detect any damage taken or only the first you may need a DDS (Damage Detection System).
If you want to detect any damage taken to a specific unit maybe
  • Unit - Unit <gen> Takes damage
or
  • Trigger - Add to (SomeTrigger) the event (Unit - SomeUnit Takes damage)
may help
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
He wants to give units an ability when they are out of combat.

I did this not long ago by giving every unit a timer.
Save the timer in a hashtable under the key of the unit.
Then when a unit takes damage (or deals damage if you want that too) then start the timer from the hashtable with (duration) as how long the unit will have to not be damaged to get "out of combat".

You need either a Damage Detection System or an Alternative Damage System to check the damage events.

When a unit takes damage (a unit comes in combat), remove all the abilities that you dont want to have in combat.
When the timer expires, add all the abilities that you want to have out of combat.

To do this properly, you will have to use JASS.

This can be done a bit easier if you know how to make events.
Create a global real variable.
When you want to fire the event, you set the value to 1 and back to 0 immediately.
To use this "event" as event, you use "Game - Value of Real Variable : (MyRealVariable) becomes Equal to 0.00"
Then that trigger is ran when that variable is set to 1 and 0.


Go to your map and make the following variables:
TempTimer : timer
TempReal : real
OutOfCombat_Hashtable : hashtable
OutOfCombat_Unit : unit
OutOfCombat_Event : real
(make sure that you create the hashtable on initialization)

Then when a unit takes damage, you load a timer from the hashtable and start it.
  • Set OutOfCombat_Unit = (Damaged Unit)
  • Set TempTimer = (Load 0 of Key(OutOfCombat_Unit) in OutOfCombat_Hashtable)
  • Set TempReal = (time to get out of combat)
  • Custom script: call TimerStart(udg_TempTimer, udg_TempReal, false, function OutOfCombat)
  • Hashtable - Save Handle Of OutOfCombat_Unit as 0 of Key(TempTimer) in OutOfCombat_Hashtable
  • Hashtable - Save Handle Of TempTimer as 0 of Key(OutOfCombat_Unit) in OutOfCombat_Hashtable
Then go to the header file and make this function:
JASS:
function OutOfCombat takes nothing returns nothing
    local timer t = GetExpiredTimer()
    set udg_OutOfCombat_Unit = LoadUnitHandle(udg_OutOfCombat_Hashtable, GetHandleId(t), 0)
    
    set udg_OutOfCombat_Event = 1.
    set udg_OutOfCombat_Event = 0.
    
    set t = null
endfunction

Then you make another trigger:
Your OutOfComat_Unit is now the unit that comes out of combat.
  • Out of Combat
    • Events
      • Game - udg_OutOfCombat_Event becomes Equal to 0.00
    • Conditions
    • Actions
      • -------- Add out of combat abilities. --------
That is almost the best way to do it... I use a slightly different way but it gets really complicated very fast.
 
Level 3
Joined
Sep 7, 2013
Messages
47
Well I have this custom ability called Passive Mode (Tornado slow aura based targeted at self). Wandering neutral hostile units in my map have this (So, they would not be so aggressive and it really looks good on wandering units). And when they are attacked or takes damage (I will change it to "takes damage" as i just implemented DDS recently) that ability will be removed so they will appear to be aggressive again. But, for example I damaged the mobs and leave them, they will remain fast until the end of the game (or until they are killed) and that doesn't look good as they go rampant around fast.
That's why I want a trigger that returns the ability after "being out of combat"

Wietlol, about that trigger... If the unit takes damage, timer will start but if the unit takes damage again (with the timer not expiring yet) will the timer restart?

Thanks thanks. I am finally getting over with this
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
When you start an already running timer, you set the remaining duration to the new number.

I don't say that you remove the old timer and create a new one with the new values because it is still the old timer... with the old handle id.

It is like you have a unit and let it run from A to B and when he is half way there, you set him back to A... so mean.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Well... what do you want to have then?

You have to make a timer for each unit to make it out of combat after a delay. (Could be done by a wait action too.)
Then you got to stop that old timer (cannot be done by wait actions) and create a new one when you take damage.

You can create an event for each timer... but that would be stupid and massive memory consuming.
So you create one function that is called that fires an event to make it global.
That function must be given via JASS.

But if it is too complicated... what would you do then? I really wonder.
 
Status
Not open for further replies.
Top