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

Respawn System Problems

Status
Not open for further replies.
Level 7
Joined
Feb 23, 2020
Messages
253
Hello, i followed this tutorial on how to make something mui with waits, but this respawn system that i made apparently does not work properly. Did i do it wrong or is this just the wrong way of doing it?

Source: MUI Triggers with Waits

  • A Hero Dies
    • Events
      • Unit - A unit Dies
    • Conditions
      • ((Triggering unit) is A Hero) Equal to True
    • Actions
      • Set VariableSet DyingHeroIndex = (DyingHeroIndex + 1)
      • Set VariableSet DyingHero[DyingHeroIndex] = (Triggering unit)
      • Set VariableSet DyingHero_ItemPoint = (Position of DyingHero[DyingHeroIndex])
      • Set VariableSet DyingHero_Point = (Position of DyingHero[DyingHeroIndex])
      • Item - Create Resurrection Flag at DyingHero_ItemPoint
      • Custom script: call RemoveLocation(udg_DyingHero_ItemPoint)
  • Resurrect Dead hero
    • Events
      • Unit - A unit Acquires an item
    • Conditions
      • (Item-type of (Item being manipulated)) Equal to Resurrection Flag
    • Actions
      • Item - Remove (Item being manipulated)
      • Set VariableSet ReviveWriteIndex = (ReviveWriteIndex + 1)
      • Set VariableSet ReviveUnit[ReviveWriteIndex] = (Triggering unit)
      • Unit - Pause ReviveUnit[ReviveWriteIndex]
      • Wait 5.00 seconds
      • Set VariableSet ReviveReadIndex = (ReviveReadIndex + 1)
      • Unit - Unpause ReviveUnit[ReviveReadIndex]
      • Hero - Instantly revive DyingHero[DyingHeroIndex] at DyingHero_Point, Show revival graphics
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ReviveReadIndex Equal to ReviveWriteIndex
        • Then - Actions
          • Set VariableSet ReviveWriteIndex = 0
          • Set VariableSet ReviveReadIndex = 0
        • Else - Actions
      • Custom script: call RemoveLocation(udg_DyingHero_Point)
  • Self Resurrection
    • Events
      • Unit - A unit Dies
    • Conditions
      • ((Triggering unit) is A Hero) Equal to True
    • Actions
      • Set VariableSet DyingHero_SelfPoint = (Position of DyingHero[DyingHeroIndex])
      • Set VariableSet SelfResurrectionWriteIndex = (SelfResurrectionWriteIndex + 1)
      • Set VariableSet SelfResurrectionUnit[SelfResurrectionWriteIndex] = (Triggering unit)
      • Wait 40.00 seconds
      • Set VariableSet SelfResurrectionReadIndex = (SelfResurrectionReadIndex + 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (SelfResurrectionUnit[SelfResurrectionReadIndex] is dead) Equal to True
          • SelfResurrectionReadIndex Equal to SelfResurrectionWriteIndex
        • Then - Actions
          • Hero - Instantly revive SelfResurrectionUnit[SelfResurrectionReadIndex] at DyingHero_SelfPoint, Show revival graphics
          • Set VariableSet SelfResurrectionReadIndex = 0
          • Set VariableSet SelfResurrectionWriteIndex = 0
        • Else - Actions
      • Custom script: call RemoveLocation(udg_DyingHero_SelfPoint)
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,535
You need to split your If Then Else into two separate functions. Also, move DyingHero_SelfPoint to after the Wait 40.00 seconds. And it should use an Array as well, DyingHero_SelfPoint[index].

1) If (SelfResurrectionUnit[SelfResurrectionReadIndex] is dead) Equal to True then Instantly revive SelfResurrectionUnit[SelfResurrectionReadIndex] at DyingHero_SelfPoint[index]

2) If SelfResurrectionReadIndex Equal to SelfResurrectionWriteIndex then Set VariableSet SelfResurrectionReadIndex = 0 and Set VariableSet SelfResurrectionWriteIndex = 0
 
Last edited:
Level 13
Joined
May 10, 2009
Messages
868
I don't think this MUI approach really works for the resurrect hero via item pick up. As Magtheridon stated on his post, all data that is stored in a buffer is read in the same order (first in, first out).
I can write data to a buffer,
then read it in the same order that I wrote it.
That being said, think about what would happen if two heroes die, and then a third one comes up and picks up the item that should revive the second one. The first one's gonna be resurrected because that hero was the first one to be stored in the "buffer".

You need to store the dropped item and its hero into a list, then, later, iterate over it and find which hero is related to the item and then revive them.
 
Level 7
Joined
Feb 23, 2020
Messages
253
I don't think this MUI approach really works for the resurrect hero via item pick up. As Magtheridon stated on his post, all data that is stored in a buffer is read in the same order (first in, first out).

That being said, think about what would happen if two heroes die, and then a third one comes up and picks up the item that should revive the second one. The first one's gonna be resurrected because that hero was the first one to be stored in the "buffer".

You need to store the dropped item and its hero into a list, then, later, iterate over it and find which hero is related to the item and then revive them.
Yeah this is pretty much the problem i have, it always overwrites another player.


You need to split your If Then Else into two separate functions. Also, move DyingHero_SelfPoint to after the Wait 40.00 seconds. And it should use an Array as well, DyingHero_SelfPoint[index].

1) If (SelfResurrectionUnit[SelfResurrectionReadIndex] is dead) Equal to True then Instantly revive SelfResurrectionUnit[SelfResurrectionReadIndex] at DyingHero_SelfPoint[index]

2) If SelfResurrectionReadIndex Equal to SelfResurrectionWriteIndex then Set VariableSet SelfResurrectionReadIndex = 0 and Set VariableSet SelfResurrectionWriteIndex = 0

I will try this out and see if it works!
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,535
oh alright i see.
Here's a small system I threw together using a Unit Indexer. I link the Units together using their Custom Values, as well as the Custom Value of the Resurrection Flag.

Note that I changed your original design, so instead of pausing the "Reviver" for 5 seconds, I instead order it to cast a Hidden channeling ability. If it manages to finish channeling this ability then the dead ally will be revived. If not, then the Item respawns and the players can attempt to revive their dead ally again.

I did it like this because i'm not a fan of using Pauses so I try to avoid them whenever possible. They have unwanted side effects like freezing buffs, preventing them from expiring during the pause. Keep in mind, there's potential for issue with my system. For example, if the Hero becomes silenced while reviving, the Hidden channeling ability will be cancelled. If this is unwanted I could show you how to trigger the whole thing without using an ability or pauses.

  • Hero Dies
    • Events
      • Unit - A unit Dies
    • Conditions
      • ((Triggering unit) is A Hero) Equal to True
    • Actions
      • Set VariableSet DH_CV = (Custom value of (Triggering unit))
      • -------- --------
      • Set VariableSet DyingHero_Dead[DH_CV] = (Triggering unit)
      • Set VariableSet DyingHero_Point = (Position of (Triggering unit))
      • -------- --------
      • Item - Create Revive Flag at DyingHero_Point
      • Item - Set the custom value of (Last created item) to DH_CV
      • Item - Make (Last created item) Invulnerable
      • Set VariableSet DyingHero_Item[DH_CV] = (Last created item)
      • Custom script: call RemoveLocation(udg_DyingHero_Point)
      • -------- --------
      • Wait 40.00 seconds
      • -------- --------
      • Set VariableSet DH_CV = (Custom value of (Triggering unit))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Triggering unit) is alive) Equal to False
        • Then - Actions
          • Item - Remove DyingHero_Item[DH_CV]
          • Set VariableSet DyingHero_Point = (Position of (Triggering unit))
          • Hero - Instantly revive (Triggering unit) at DyingHero_Point, Show revival graphics
          • Custom script: call RemoveLocation(udg_DyingHero_Point)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • DyingHero_IsChanneling[(Custom value of DyingHero_Reviver[DH_CV])] Equal to True
            • Then - Actions
              • Unit - Order DyingHero_Reviver[DH_CV] to Stop.
            • Else - Actions
        • Else - Actions
  • Hero Revive Item
    • Events
      • Unit - A unit Acquires an item
    • Conditions
      • (Item-type of (Item being manipulated)) Equal to Revive Flag
    • Actions
      • Set VariableSet DH_CV = (Custom value of (Triggering unit))
      • -------- --------
      • Set VariableSet DyingHero_Reviver[DH_CV] = DyingHero_Dead[(Custom value of (Item being manipulated))]
      • Set VariableSet DyingHero_Reviver[(Custom value of (Item being manipulated))] = (Triggering unit)
      • Set VariableSet DyingHero_IsChanneling[DH_CV] = True
      • -------- --------
      • Item - Remove (Item being manipulated)
      • Unit - Add Resurrect Channel to (Triggering unit)
      • Unit - Order (Triggering unit) to Undead Gargoyle - Gargoyle Form.
  • Hero Finished Reviving
    • Events
      • Unit - A unit Finishes casting an ability
    • Conditions
      • (Ability being cast) Equal to Resurrect Channel
    • Actions
      • Set VariableSet DH_CV = (Custom value of (Triggering unit))
      • -------- --------
      • Set VariableSet DyingHero_Point = (Position of DyingHero_Reviver[DH_CV])
      • Set VariableSet DyingHero_IsChanneling[DH_CV] = False
      • -------- --------
      • Hero - Instantly revive DyingHero_Reviver[DH_CV] at DyingHero_Point, Show revival graphics
      • Custom script: call RemoveLocation(udg_DyingHero_Point)
  • Hero Failed Reviving
    • Events
      • Unit - A unit Stops casting an ability
    • Conditions
      • (Ability being cast) Equal to Resurrect Channel
    • Actions
      • Set VariableSet DH_CV = (Custom value of (Triggering unit))
      • -------- --------
      • Set VariableSet DyingHero_IsChanneling[DH_CV] = False
      • -------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (DyingHero_Reviver[DH_CV] is alive) Equal to False
        • Then - Actions
          • Set VariableSet DyingHero_Point = (Position of DyingHero_Reviver[DH_CV])
          • Item - Create Revive Flag at DyingHero_Point
          • Set VariableSet DyingHero_Item[(Custom value of DyingHero_Reviver[DH_CV])] = (Last created item)
          • Item - Set the custom value of (Last created item) to (Custom value of DyingHero_Reviver[DH_CV])
          • Item - Make (Last created item) Invulnerable
          • Custom script: call RemoveLocation(udg_DyingHero_Point)
        • Else - Actions
      • Unit - Remove Resurrect Channel from (Triggering unit)

Unit Indexer explained:
A Unit Indexer allows you to save data to units. It does so by assigning each unit a unique Custom Value, which is a single Integer that can be stored to a unit which you can set/get freely as long as you have access to the unit. This is useful because we can then use a unit's Custom Value as the Index for our Array variables, and since each unit has it's own UNIQUE custom value there will never be any conflicts.

So for example, say you created 3 Footman.

1st footman is assigned a Custom Value of 1 by the system.
2nd footman is assigned a Custom Value of 2 by the system.
3rd footman is assigned a Custom Value of 3 by the system.

Now you can use the custom value of these unit's as the Index [] in your Arrays.
  • Example
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Killing unit)) Equal to Footman
    • Actions
      • Set Variable FootmanKills[Custom value of (Killing unit)] = FootmanKills[Custom value of (Killing unit)] + 1
      • Game - Display to (All players) for 30.00 seconds the text: (String(FootmanKills[Custom value of (Killing unit)]))
With the above trigger I'm able to keep track of each of my individual Footman's kills.
 

Attachments

  • Resurrect Example.w3m
    23.7 KB · Views: 28
Last edited:
Level 7
Joined
Feb 23, 2020
Messages
253
Here's a small system I threw together using a Unit Indexer. I link the Units together using their Custom Values, as well as the Custom Value of the Resurrection Flag.

Note that I changed your original design, so instead of pausing the "Reviver" for 5 seconds, I instead order it to cast a Hidden channeling ability. If it manages to finish channeling this ability then the dead ally will be revived. If not, then the Item respawns and the players can attempt to revive their dead ally again.

I did it like this because i'm not a fan of using Pauses so I try to avoid them whenever possible. They have unwanted side effects like freezing buffs, preventing them from expiring during the pause. Keep in mind, there's potential for issue with my system. For example, if the Hero becomes silenced while reviving, the Hidden channeling ability will be cancelled. If this is unwanted I could show you how to trigger the whole thing without using an ability or pauses.

  • Hero Dies
    • Events
      • Unit - A unit Dies
    • Conditions
      • ((Triggering unit) is A Hero) Equal to True
    • Actions
      • Set VariableSet DH_CV = (Custom value of (Triggering unit))
      • -------- --------
      • Set VariableSet DyingHero_Dead[DH_CV] = (Triggering unit)
      • Set VariableSet DyingHero_Point = (Position of (Triggering unit))
      • -------- --------
      • Item - Create Revive Flag at DyingHero_Point
      • Item - Set the custom value of (Last created item) to DH_CV
      • Item - Make (Last created item) Invulnerable
      • Set VariableSet DyingHero_Item[DH_CV] = (Last created item)
      • Custom script: call RemoveLocation(udg_DyingHero_Point)
      • -------- --------
      • Wait 40.00 seconds
      • -------- --------
      • Set VariableSet DH_CV = (Custom value of (Triggering unit))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Triggering unit) is alive) Equal to False
        • Then - Actions
          • Item - Remove DyingHero_Item[DH_CV]
          • Set VariableSet DyingHero_Point = (Position of (Triggering unit))
          • Hero - Instantly revive (Triggering unit) at DyingHero_Point, Show revival graphics
          • Custom script: call RemoveLocation(udg_DyingHero_Point)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • DyingHero_IsChanneling[(Custom value of DyingHero_Reviver[DH_CV])] Equal to True
            • Then - Actions
              • Unit - Order DyingHero_Reviver[DH_CV] to Stop.
            • Else - Actions
        • Else - Actions
  • Hero Revive Item
    • Events
      • Unit - A unit Acquires an item
    • Conditions
      • (Item-type of (Item being manipulated)) Equal to Revive Flag
    • Actions
      • Set VariableSet DH_CV = (Custom value of (Triggering unit))
      • -------- --------
      • Set VariableSet DyingHero_Reviver[DH_CV] = DyingHero_Dead[(Custom value of (Item being manipulated))]
      • Set VariableSet DyingHero_Reviver[(Custom value of (Item being manipulated))] = (Triggering unit)
      • Set VariableSet DyingHero_IsChanneling[DH_CV] = True
      • -------- --------
      • Item - Remove (Item being manipulated)
      • Unit - Add Resurrect Channel to (Triggering unit)
      • Unit - Order (Triggering unit) to Undead Gargoyle - Gargoyle Form.
  • Hero Finished Reviving
    • Events
      • Unit - A unit Finishes casting an ability
    • Conditions
      • (Ability being cast) Equal to Resurrect Channel
    • Actions
      • Set VariableSet DH_CV = (Custom value of (Triggering unit))
      • -------- --------
      • Set VariableSet DyingHero_Point = (Position of DyingHero_Reviver[DH_CV])
      • Set VariableSet DyingHero_IsChanneling[DH_CV] = False
      • -------- --------
      • Hero - Instantly revive DyingHero_Reviver[DH_CV] at DyingHero_Point, Show revival graphics
      • Custom script: call RemoveLocation(udg_DyingHero_Point)
  • Hero Failed Reviving
    • Events
      • Unit - A unit Stops casting an ability
    • Conditions
      • (Ability being cast) Equal to Resurrect Channel
    • Actions
      • Set VariableSet DH_CV = (Custom value of (Triggering unit))
      • -------- --------
      • Set VariableSet DyingHero_IsChanneling[DH_CV] = False
      • -------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (DyingHero_Reviver[DH_CV] is alive) Equal to False
        • Then - Actions
          • Set VariableSet DyingHero_Point = (Position of DyingHero_Reviver[DH_CV])
          • Item - Create Revive Flag at DyingHero_Point
          • Set VariableSet DyingHero_Item[(Custom value of DyingHero_Reviver[DH_CV])] = (Last created item)
          • Item - Set the custom value of (Last created item) to (Custom value of DyingHero_Reviver[DH_CV])
          • Item - Make (Last created item) Invulnerable
          • Custom script: call RemoveLocation(udg_DyingHero_Point)
        • Else - Actions
      • Unit - Remove Resurrect Channel from (Triggering unit)

Unit Indexer explained:
A Unit Indexer allows you to save data to units. It does so by assigning each unit a unique Custom Value, which is a single Integer that can be stored to a unit which you can set/get freely as long as you have access to the unit. This is useful because we can then use a unit's Custom Value as the Index for our Array variables, and since each unit has it's own UNIQUE custom value there will never be any conflicts.

So for example, say you created 3 Footman.

1st footman is assigned a Custom Value of 1 by the system.
2nd footman is assigned a Custom Value of 2 by the system.
3rd footman is assigned a Custom Value of 3 by the system.

Now you can use the custom value of these unit's as the Index [] in your Arrays.
  • Example
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Killing unit)) Equal to Footman
    • Actions
      • Set Variable FootmanKills[Custom value of (Killing unit)] = FootmanKills[Custom value of (Killing unit)] + 1
      • Game - Display to (All players) for 30.00 seconds the text: (String(FootmanKills[Custom value of (Killing unit)]))
With the above trigger I'm able to keep track of each of my individual Footman's kills.

Wow, thank you very much Uncle! This really looks like an even better version of mine.
 
Status
Not open for further replies.
Top