• 🏆 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!

Hashtable and Loop Change unit owner

Status
Not open for further replies.
Level 6
Joined
May 15, 2009
Messages
191
Can anyone help me as to what is wrong with my trigger?

I have this dungeon map, where the enemy player is Player 7, and the two heroes are controlled by Player 1, and Player 2.

I'm trying to create a Debuff (called Sirens Lure) which (unless dispelled) will cause control of the Target Hero to be changed over to Player 7.
I've tried using hashtables, and the buff lasts for 25 seconds. When there are only 10 seconds left of the buff, it should force the unit to come under control of Player 7, and it should change back once the buff duration ran out.

The trigger is in two parts:
Ability cast:

  • Siren Calling
    • Events
      • Unit - A unit owned by Player 7 (Green) Starts the effect of an ability
      • Unit - A unit owned by Player 1 (Red) Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Siren's Lure
    • Actions
      • Set Tempr1 = 25.10
      • Set TempU1 = (Target unit of ability being cast)
      • Unit Group - Add TempU1 to SirenLure_group
      • Hashtable - Save Tempr1 as 1 of (Key (Target unit of ability being cast)) in SirenLure_hash
  • Sirens Calling Loop
    • Events
      • Time - Every 0.30 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in SirenLure_group and do (Actions)
        • Loop - Actions
          • Set TempU1 = (Picked unit)
          • Game - Display to (All players) the text: ((Name of TempU1) + is now TempUnit Loop)
          • Set Tempr1 = (Load 1 of (Key (Picked unit)) from SirenLure_hash)
          • -------- If there is only 10 seconds left on the Debuff, the unit will be put under control of Player 7 (Green) --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Tempr1 Less than or equal to 10.00
              • Tempr1 Greater than 0.00
              • (TempU1 has buff Siren's Lure ) Equal to True
            • Then - Actions
              • Unit - Change ownership of TempU1 to Player 7 (Green) and Change color
              • Hashtable - Save (Tempr1 - 0.30) as 1 of (Key (Picked unit)) in SirenLure_hash
              • Game - Display to (All players) the text: (Name of TempU1)
            • Else - Actions
              • -------- Returns the Hero to the Original Player, based on the Unit-type --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Owner of TempU1) Equal to Player 7 (Green)
                  • (Unit-type of TempU1) Equal to Spirit of the Flame
                • Then - Actions
                  • Unit - Change ownership of TempU1 to Player 1 (Red) and Change color
                • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Owner of TempU1) Equal to Player 7 (Green)
                  • (Unit-type of TempU1) Equal to Spirit of the Sea
                • Then - Actions
                  • Unit - Change ownership of TempU1 to Player 2 (Blue) and Change color
                • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Owner of TempU1) Equal to Player 7 (Green)
                  • (Unit-type of TempU1) Equal to Spirit of the Sea
                • Then - Actions
                  • Unit - Change ownership of TempU1 to Player 2 (Blue) and Change color
                • Else - Actions
              • -------- Cleans up the Hashtable and Group --------
              • Unit Group - Remove TempU1 from SirenLure_group
              • Hashtable - Clear all child hashtables of child (Key (Picked unit)) in SirenLure_hash
Help is much appreciated.

-Battlehound/Woodenplank
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
It doesn't work, because your spell is supposed to use 3 intervals, while you code it using 2 intervals.

The intervals are (-∞ , 0>; (0, 10> and (10, 25.1>

Interval (10, 25.1> is time when the unit has the debuff, but nothing happens (players are supposed to dispel the debuff in this interval).
Interval (0, 10> is time when the unit is mind controlled.
Interval (-∞ , 0> is when the spell should end (duration ended).

What you do is check if the time is not in the second interval (0, 10> and if it ain't, you end the spell - so you don't take into account the first interval (10, 25.1>, hence it doesn't work, because when the loop runs the first time for that unit, the spell also ends for it, since the "THEN" part of the ITE is not true, it will go to the "ELSE" part, ending the spell.
 
You save a value (25) into hashtable. Then load this value. If loaded value is between 0 and 10 you decrease it, else you you "return hero to original player" and clean hashtable.

So in the first run it will be cleaned instantly, because values is 25 --> not between 0 and 10.

Decrease the value each loop without any condition. Then you make an ITE (IfThenElse) inside, to check if value equals 10. If true, you change owner.
(adapt the start value and decrease value so you ensure thevalue gets exactly 10, that you don't miss the condition... and you only want todo it once, so exact condition is helpful)

Then seperatly of first ITE you create an other one afterwerds. Here you check if value is smaller than 0, if yes you clean and so on.

And, is this neededed?
  • (Unit-type of TempU1) Equal to Spirit of the Sea
 
Level 6
Joined
May 15, 2009
Messages
191
Sorry, but you've really rather confused me. How is the trigger supposed to look? Like, step by step? Can the Editor use Intervals?

Sorry, I'm feeling rather blank right now...

Here's the trigger as of current, still not getting the intervals working, but I didn't understand your advice.

  • Sirens Calling Loop
    • Events
      • Time - Every 0.40 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in SirenLure_group and do (Actions)
        • Loop - Actions
          • Set TempU1 = (Picked unit)
          • Set Tempr1 = (Load 1 of (Key (Picked unit)) from SirenLure_hash)
          • Hashtable - Save (Tempr1 - 0.30) as 1 of (Key (Picked unit)) in SirenLure_hash
          • -------- If there is only 10 seconds left on the Debuff, the unit will be put under control of Player 7 (Green) --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Tempr1 Less than or equal to 10.00
              • Tempr1 Greater than 0.00
              • (TempU1 has buff Siren's Lure ) Equal to True
            • Then - Actions
              • Unit - Change ownership of TempU1 to Player 7 (Green) and Change color
              • Game - Display to (All players) the text: (Name of TempU1)
            • Else - Actions
          • -------- Returns the Hero to the Original Player, based on the Unit-type --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Owner of TempU1) Equal to Player 7 (Green)
              • (Unit-type of TempU1) Equal to Spirit of the Flame
              • Tempr1 Less than or equal to 0.00
            • Then - Actions
              • Unit - Change ownership of TempU1 to Player 1 (Red) and Change color
              • -------- Cleans up the Hashtable and Group --------
              • Unit Group - Remove TempU1 from SirenLure_group
              • Hashtable - Clear all child hashtables of child (Key (Picked unit)) in SirenLure_hash
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Owner of TempU1) Equal to Player 7 (Green)
              • (Unit-type of TempU1) Equal to Spirit of the Sea
              • Tempr1 Less than or equal to 0.00
            • Then - Actions
              • Unit - Change ownership of TempU1 to Player 2 (Blue) and Change color
              • -------- Cleans up the Hashtable and Group --------
              • Unit Group - Remove TempU1 from SirenLure_group
              • Hashtable - Clear all child hashtables of child (Key (Picked unit)) in SirenLure_hash
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Owner of TempU1) Equal to Player 7 (Green)
              • (Unit-type of TempU1) Equal to Spirit of the Sea
              • Tempr1 Less than or equal to 0.00
            • Then - Actions
              • Unit - Change ownership of TempU1 to Player 2 (Blue) and Change color
              • -------- Cleans up the Hashtable and Group --------
              • Unit Group - Remove TempU1 from SirenLure_group
              • Hashtable - Clear all child hashtables of child (Key (Picked unit)) in SirenLure_hash
            • Else - Actions
Thanks guys, but I'm still not seeing it.
 
Level 8
Joined
Feb 3, 2013
Messages
277
first 15 seconds of the spell does nothing
in the following 10 seconds unit's ownership is changed
at 0 second, units ownership is returned back to its original state?

btw for changing the units back to its original owner, you can save the Player to the hashtable and load it when your changing back the ownership instead of using 3 different if statements

god gui is so awful to read :<

I made an example
  • Spell
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Storm Bolt
    • Actions
      • Custom script: local unit tempUnit = GetSpellTargetUnit()
      • Custom script: local unit tempCast = GetTriggerUnit()
      • Custom script: local player tempP = GetOwningPlayer(tempCast)
      • Custom script: local player tempP2 = GetOwningPlayer(tempUnit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Target unit of ability being cast) is in AbilGroup) Equal to False
        • Then - Actions
          • Custom script: call SaveReal(udg_HASH, 0, GetHandleId(tempUnit), 20.0)
          • Custom script: call SavePlayerHandle(udg_HASH, 1, GetHandleId(tempUnit), tempP)
          • Custom script: call SavePlayerHandle(udg_HASH, 2, GetHandleId(tempUnit), tempP2)
          • Custom script: call GroupAddUnit(udg_AbilGroup, tempUnit)
        • Else - Actions
      • Custom script: set tempUnit = null
      • Custom script: set tempCast = null
      • Custom script: set tempP = null
      • Custom script: set tempP2 = null
  • Loop
    • Events
      • Time - Every 0.20 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in AbilGroup and do (Actions)
        • Loop - Actions
          • Custom script: local player op = LoadPlayerHandle(udg_HASH, 2, GetHandleId(GetEnumUnit()))
          • Custom script: local player ep = LoadPlayerHandle(udg_HASH, 1, GetHandleId(GetEnumUnit()))
          • Custom script: set udg_time = LoadReal(udg_HASH, 0, GetHandleId(GetEnumUnit())) - .2
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • time Less than or equal to 0.00
            • Then - Actions
              • Custom script: call SetUnitOwner(GetEnumUnit(), op, true)
              • Custom script: call GroupRemoveUnit(udg_AbilGroup, GetEnumUnit())
              • Custom script: call FlushChildHashtable(udg_HASH, GetHandleId(GetEnumUnit()))
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (time Less than or equal to 10.00) and (time Greater than 0.00)
                • Then - Actions
                  • Custom script: call SetUnitOwner(GetEnumUnit(), ep, true)
                • Else - Actions
          • Custom script: call SaveReal(udg_HASH, 0, GetHandleId(GetEnumUnit()), udg_time)
          • Custom script: set op = null
          • Custom script: set ep = null


now it's not the best, but it's an example and it works lol, i'm leaking a unit handle but that's about it
i probably should've jass'ed the whole thing, but meh
 

Attachments

  • OwnerShip Ability Change.w3x
    17.9 KB · Views: 29
Last edited:
You don't need so much If/Then/Else to check if the value is 0. You only need one.

And yo, you also could store player in hashatble, you could use key 2 for it, for example.

You use 0.4 as periodic event now, but substract only 0.3.

god gui is so awful to read :<
Yes, with many ITE the readability really sucks. :d
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
Code:
If (Conditions)
    Time is greater than 10
Then (Actions)
    Decrement time for that unit
Else (Actions)
    If (Conditions)
        Time is greater than 0 and less than or equal to 10
    Then (Actions)
        Change owner
        Decrement time
    Else (Actions)
        End spell for that unit
The first ITE checks if it's time between 10 and 25 seconds. If the time is indeed there, you just decrease time.
Second ITE checks if time is between 0 and 10. If it is there, you "mind control" the unit.
Now if time is not greater than 10 seconds and is also not in the interval (0, 10), then it is obvious that the time will be less than 0, in which case the last "ELSE" takes action and ends the spell.

Note how I nested one ITE inside the other ITE. This will prevent bug, where the spell ticks 2 times per one trigger run.

----

Edit:
It may be my choice of words that confuses you.
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • Tempr1 Less than or equal to 10.00
      • Tempr1 Greater than 0.00
    • Then - Actions
      • -------- MIND CONTROL --------
    • Else - Actions
      • -------- SOMETHING ELSE --------
This is part of the code you used.
What does this tell you? It tells you, that if the variable Tempr1 has value that is less than or equal to 10 and that is also greater than 0, then you Mind control, else you do something else.
This is exactly the interval.
If Tempr1 is in interval (0, 10>, then you Mind control, else you do something else.
Do you see what I meant by intervals?

----

Edit #2:
I use '>' or '<' to imply it is closed interval (= includes its endpoints), while '(' or ')' implies it is open interval (= does not include its endpoints). However english terminology uses '[' or ']' for closed interval, so the correct way to write it would probably be (0, 10]. Hope that cleared some things as well (or made it more complicated? :D )
 
Last edited:
Level 6
Joined
May 15, 2009
Messages
191
I've followed your advice Nichilus, and the trigger looks as follows. However, there is still no changing owner.

  • Sirens Calling Loop
    • Events
      • Time - Every 0.40 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in SirenLure_group and do (Actions)
        • Loop - Actions
          • Set TempU1 = (Picked unit)
          • Set Tempr1 = (Load 1 of (Key (Picked unit)) from SirenLure_hash)
          • -------- If there is only 10 seconds left on the Debuff, the unit will be put under control of Player 7 (Green) --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Tempr1 Greater than 10.00
            • Then - Actions
              • Hashtable - Save (Tempr1 - 0.40) as 1 of (Key (Picked unit)) in SirenLure_hash
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Tempr1 Less than or equal to 10.00
                  • Tempr1 Greater than 0.00
                  • (TempU1 has buff Siren's Lure ) Equal to True
                • Then - Actions
                  • Unit - Change ownership of TempU1 to Player 7 (Green) and Change color
                  • Hashtable - Save (Tempr1 - 0.40) as 1 of (Key (Picked unit)) in SirenLure_hash
                • Else - Actions
                  • Unit - Change ownership of TempU1 to Player 1 (Red) and Change color
                  • -------- Cleans up the Hashtable and Group --------
                  • Unit Group - Remove TempU1 from SirenLure_group
                  • Hashtable - Clear all child hashtables of child (Key (Picked unit)) in SirenLure_hash
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
uh, hard to say. You could use debug messages to check things out (e.g. the value of loaded tempr1, etc.).
I played a bit with the editor and coded such spell myself (though it may be a bit harder to understand). I can post it if you want.
 
You don't need to change owner each peridoc if your value gets lower 10. Choose an exact match, and then only change the owner once at exactly 10. (calculate before)

  • (Hashtable - Save (Tempr1 - 0.40) as 1 of (Key (Picked unit)) in SirenLure_hash
^This can be done each period, without any checks. Move it to the upper actions.

You maybe want to create a new ITW at top of loop, with only condition if unit still has the buff. If not you clear it and so on. (because atm you only check for buff if your value is between 0 and 10.

But slowly the trigger looks better:thumbs_up: ... and yo debugmsg might help. :)
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
I thought so as well, but he will never get exact time 10.00, because he starts with 25.10 and subtract it with 0.40 every trigger run. However it won't solve his problem, so I left that as it was.
As I remade the spell, I used integers representing number of iterations, which imo serve better.
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
Ok, here it is. The map is attached at the bottom of this post.

  • Map Ini
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set Hash = (Last created hashtable)
      • Visibility - Create an initially Enabled visibility modifier for Player 1 (Red) emitting Visibility across (Playable map area)
  • Sirens call
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Siren's call
    • Actions
      • Set u = (Target unit of ability being cast)
      • Custom script: set udg_id = GetHandleId(udg_u)
      • Hashtable - Save 100 as (Key Siren_Ticks) of id in Hash
      • Set pl = (Owner of (Triggering unit))
      • Hashtable - Save Handle Ofpl as (Key Siren_CasterOwner) of id in Hash
      • Unit Group - Add u to Siren_Group
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Sirens call Loop <gen> is on) Equal to False
        • Then - Actions
          • Trigger - Turn on Sirens call Loop <gen>
        • Else - Actions
  • Sirens call Loop
    • Events
      • Time - Every 0.25 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in Siren_Group and do (Actions)
        • Loop - Actions
          • Set u = (Picked unit)
          • Custom script: set udg_id = GetHandleId(udg_u)
          • Set int = (Load (Key Siren_Ticks) of id from Hash)
          • Set int = (int - 1)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • int Equal to 0
                  • (u is dead) Equal to True
                  • (u has buff Siren's call ) Equal to False
            • Then - Actions
              • Set pl = (Load (Key Siren_Player) of id in Hash)
              • Unit - Change ownership of u to pl and Change color
              • Hashtable - Clear all child hashtables of child id in Hash
              • Unit Group - Remove u from Siren_Group
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • int Equal to 40
                • Then - Actions
                  • Set pl = (Owner of u)
                  • Hashtable - Save Handle Ofpl as (Key Siren_Player) of id in Hash
                  • Set pl = (Load (Key Siren_CasterOwner) of id in Hash)
                  • Unit - Change ownership of u to pl and Change color
                  • Hashtable - Save int as (Key Siren_Ticks) of id in Hash
                  • Special Effect - Create a special effect attached to the origin of u using Abilities\Spells\Items\AIil\AIilTarget.mdl
                  • Special Effect - Destroy (Last created special effect)
                • Else - Actions
                  • Hashtable - Save int as (Key Siren_Ticks) of id in Hash
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Siren_Group is empty) Equal to True
        • Then - Actions
          • Trigger - Turn off (This trigger)
        • Else - Actions
Some additional info to clear things up:
All the variables used, except for the unit group variable (called Siren_group) are temporal variables - you don't have to create those as long as you substitute them with your own.


Do note:
If you use different integer and/or unit variable than the variable called 'id' and/or variable 'u', then you will need to change it in the custom script as well.
Change this line:
  • Custom script: set udg_id = GetHandleId(udg_u)
into this:
  • Custom script: set udg_NameOfYour_Integer_Variable = GetHandleId(udg_NameOfYour_Unit_Variable)

Also. This line:
  • Custom script: set udg_id = GetHandleId(udg_u)
is practically the same as this line:
  • Set id = (Key (Picked player))
but with the custom script you can get the handle id from variables - you are not limited to (Picked unit) or other similar function calls



Attached test map:
 

Attachments

  • Siren's call.w3x
    19.7 KB · Views: 33
Level 23
Joined
Apr 16, 2012
Messages
4,041
just a note: the custom script set udg_id = GetHandleId(udg_u) is particularly useful when you are using JNGP, since JNGP is based on 1.23b editor, there is the Handle Id of handle, but you cant pick anything, so you always have to use the custom script.
 
Level 6
Joined
May 15, 2009
Messages
191
Thx for the trigger, although I did notice that you distinguished between Siren_CasterOwner and Siren_Player, was that just a typo? Or did I miss something?

Also, will this be MUI? If not, then I assume that Bribes unit indexing system could be used, using the Custom Value of the TempUnit as an index?

In any case, thank you all, but it still doesn't quite work for me. There are two problems: 1, sometimes the ability seems to instantly "mind control" the targeted unit, is this because of MUI issues?
And 2, the unit doesn't seem to change back to the original owner, after the effect ends.
Here's the triggers as I've done them:

  • Sirens Lure
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Siren's Lure
    • Actions
      • Set TempU1 = (Target unit of ability being cast)
      • Hashtable - Save 100 as (Key Siren_Ticks) of SirensLure_id in SirenLure_hash
      • Set SirensLure_Player = (Owner of (Triggering unit))
      • Hashtable - Save Handle OfSirensLure_Player as (Key Sirens_CasterOwner) of SirensLure_id in SirenLure_hash
      • Unit Group - Add TempU1 to SirenLure_group
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Sirens Lure Loop <gen> is on) Equal to False
        • Then - Actions
          • Trigger - Turn on Sirens Lure Loop <gen>
        • Else - Actions
  • Sirens Lure Loop
    • Events
      • Time - Every 0.25 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in SirenLure_group and do (Actions)
        • Loop - Actions
          • Set TempU1 = (Picked unit)
          • Custom script: set udg_SirensLure_id = GetHandleId(udg_TempU1)
          • Set Tempi1 = (Load (Key Siren_Ticks) of SirensLure_id from SirenLure_hash)
          • Set Tempi1 = (Tempi1 - 1)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • Tempi1 Equal to 0
                  • (TempU1 is dead) Equal to True
                  • (TempU1 has buff Siren's Lure ) Equal to True
            • Then - Actions
              • Set SirensLure_Player = (Load (Key Sirens_CasterOwner) of SirensLure_id in SirenLure_hash)
              • Unit - Change ownership of TempU1 to SirensLure_Player and Change color
              • Hashtable - Clear all child hashtables of child (Key (Picked unit)) in SirenLure_hash
              • Unit Group - Remove TempU1 from SirenLure_group
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Tempi1 Equal to 40
                • Then - Actions
                  • Set SirensLure_Player = (Owner of TempU1)
                  • Hashtable - Save Handle OfSirensLure_Player as (Key Sirens_CasterOwner) of SirensLure_id in SirenLure_hash
                  • Set SirensLure_Player = (Load (Key Sirens_CasterOwner) of SirensLure_id in SirenLure_hash)
                  • Unit - Change ownership of TempU1 to SirensLure_Player and Change color
                  • Hashtable - Save Tempi1 as (Key Siren_Ticks) of SirensLure_id in SirenLure_hash
                  • Set Tempp1 = (Position of TempU1)
                  • Special Effect - Create a special effect at Tempp1 using Abilities\Spells\Other\Charm\CharmTarget.mdl
                  • Special Effect - Destroy (Last created special effect)
                  • Custom script: call RemoveLocation(udg_Tempp1)
                • Else - Actions
                  • Hashtable - Save Tempi1 as (Key Siren_Ticks) of SirensLure_id in SirenLure_hash
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (SirenLure_group is empty) Equal to True
        • Then - Actions
          • Trigger - Turn off (This trigger)
        • Else - Actions


Also, it seems that sometimes the buff runs out before the Owner change is made?
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
Siren_Player is the original owner of the target; Siren_CasterOwner is owner of the unit which cast the spell.

The spell I posted is MUI. There are more units in the map and if you cast it on more units, it will still work.

Your trigger most likely doesn't work, because you don't change the owner.

Let's say the owner of the casting unit is Player 2 (Blue), owner of the targeted unit is Player 1 (Red).
Cast Trigger -> You save handle of Player2 into hashtable as Sirens_CasterOwner.
Loop Trigger -> You save handle of Player1 into hashtable as Sirens_CasterOwner, effectively rewriting what was written there previously.
Next line in Loop Trigger -> You load what you saved into hashtable as Sirens_CasterOwner and in following line, you change owner of target to loaded player, which is by that time Player 1 (Red), hence you change ownership of unit from Player 1 (Red) to Player 1 (Red) :)
 
Level 6
Joined
May 15, 2009
Messages
191
I've changed the trigger now, and I think I followed your advice. But it only seems to work after the unit has been affected for a VERY long time, with multiple castings of the buff. And when that happens, the unit never changes back.

  • Sirens Lure Loop
    • Events
      • Time - Every 0.25 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in SirenLure_group and do (Actions)
        • Loop - Actions
          • Set TempU1 = (Picked unit)
          • Custom script: set udg_SirensLure_id = GetHandleId(udg_TempU1)
          • Set Tempi1 = (Load (Key Siren_Ticks) of SirensLure_id from SirenLure_hash)
          • Set Tempi1 = (Tempi1 - 1)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • Tempi1 Equal to 0
                  • (TempU1 is dead) Equal to True
                  • (TempU1 has buff Siren's Lure ) Equal to False
            • Then - Actions
              • -------- Changes the Unit back to its original owner. --------
              • Set SirensLure_Player = (Load (Key Sirens_Player) of SirensLure_id in SirenLure_hash)
              • Unit - Change ownership of TempU1 to SirensLure_Player and Change color
              • Hashtable - Clear all child hashtables of child (Key (Picked unit)) in SirenLure_hash
              • Unit Group - Remove TempU1 from SirenLure_group
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Tempi1 Equal to 40
                • Then - Actions
                  • -------- If the Unit is alive, has the buff and the duration is exactly 10 the unit is changed to the CasterOwner --------
                  • Set SirensLure_Player = (Owner of TempU1)
                  • Hashtable - Save Handle OfSirensLure_Player as (Key Sirens_Player) of SirensLure_id in SirenLure_hash
                  • Set SirensLure_Player = (Load (Key Sirens_CasterOwner) of SirensLure_id in SirenLure_hash)
                  • Unit - Change ownership of TempU1 to SirensLure_Player and Change color
                  • Hashtable - Save Tempi1 as (Key Siren_Ticks) of SirensLure_id in SirenLure_hash
                  • Set Tempp1 = (Position of TempU1)
                  • Special Effect - Create a special effect at Tempp1 using Abilities\Spells\Other\Charm\CharmTarget.mdl
                  • Special Effect - Destroy (Last created special effect)
                  • Custom script: call RemoveLocation(udg_Tempp1)
                • Else - Actions
                  • -------- If the value is not 10, another tick is simply saved --------
                  • Hashtable - Save Tempi1 as (Key Siren_Ticks) of SirensLure_id in SirenLure_hash
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (SirenLure_group is empty) Equal to True
        • Then - Actions
          • Trigger - Turn off (This trigger)
        • Else - Actions
Thanks for investing so much of your time in this, much appreciated.
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
The spell afflicts the unit for 25 seconds - first 15 seconds nothing happens, then unit is mind controlled for 10 seconds.
So if unit gets the debuff and lets say after 10 seconds (= the remaining time of the buff is 15 seconds) another unit casts on this afflicted unit Siren's call again, then the time resets back to 25 seconds.

However I do see the problem when unit is mindcontrolled (already change player) and some other player casts Mind Control on this unit... that way the trigger would save the current player (= the one who Mind Controls it) as the original owner of the unit, which may cause bugs.
This could be addressed by simple fix - when unit is mind controlled and someone else casts the spell on it, it will remove the mind control and return unit back to its original owner - this approach would make sense, because you "remove" the first buff to put there your own version of the buff.

The fix:
Add this as the third "action" in the cast trigger:
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • (u is in Siren_Group) Equal to True
    • Then - Actions
      • Set pl = (Load (Key Siren_Player) of id in Hash)
      • Unit - Change ownership of u to pl and Change color
    • Else - Actions
So the trigger looks like this:
  • Sirens call
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Siren's call
    • Actions
      • Set u = (Target unit of ability being cast)
      • Custom script: set udg_id = GetHandleId(udg_u)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (u is in Siren_Group) Equal to True
        • Then - Actions
          • Set pl = (Load (Key Siren_Player) of id in Hash)
          • Unit - Change ownership of u to pl and Change color
        • Else - Actions
      • Hashtable - Save 100 as (Key Siren_Ticks) of id in Hash
      • Set pl = (Owner of (Triggering unit))
      • Hashtable - Save Handle Ofpl as (Key Siren_CasterOwner) of id in Hash
      • Unit Group - Add u to Siren_Group
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Sirens call Loop <gen> is on) Equal to False
        • Then - Actions
          • Trigger - Turn on Sirens call Loop <gen>
        • Else - Actions
Don't forget - in the case of what I posted, Siren_Player is the original owner of the unit, so as I've written above, the fix will return unti to its original owner before everything is set up again.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
I think this should be MUI, yea.

I assume the spells work in so that you cast spell which has a 25 seconds buff duration, if it is not so, feel free to correct me:

The difference may be because the buff runs out before the 0.25 seconds passed, so lets say its only been 0.01 second from the last check, so the buff is not on the unit, but you will only change owner after 0.24 seconds later. You could lower this to like 0.1 or 0.05 seconds. The lowest minimum period for periodic timer that is recommended is 0.03 seconds. That represents a 33,3 FPS

edit: Well maybe Im wrong, it seems that there is more to the spell than just this
 
Level 6
Joined
May 15, 2009
Messages
191
Thanks for the fix and all the help Nichilus, I owe you (not that I could really help you I guess, but nevertheless) - it works flawlessly now, I just added a Remove Buff for when the unit is changed back to the original owner, seeing as it sometimes didn't dissapear along as the timer hit 0 (dunno, hero resistance something?)

Thanks again. It works a charm (-pun) now:)
 
Status
Not open for further replies.
Top