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

Unit Respawn

Status
Not open for further replies.
Level 3
Joined
Jul 18, 2010
Messages
35
What's a trigger to make sure "certain" types of units respawn after a certain amount of time?

Scenario: forest full of bandits, all the little wimpy bandits respawn but the big boss at the end won't.

I know I can use variables to specifically save unit after unit, but I figured I'd ask if there was any better way to do this (since that method takes a ridiculous amount of time and variables)
 
Level 11
Joined
Nov 15, 2007
Messages
781
The easiest thing to do would just be make your bosses heroes, and have NPC-heroes not respawn with a unit classification check (boolean) condition.
 
Level 17
Joined
Feb 11, 2011
Messages
1,860
  • Unit Dies
    • Events
      • Unit - A unit owned by Neutral Hostile Dies
    • Conditions
      • ((Triggering unit) is A Hero) Equal to False
    • Actions
      • Wait 10.00 seconds
      • Set Temp_Point = someLocation
      • Unit - Create 1 (Unit-type of (Triggering unit)) for Neutral Hostile at Temp_Point facing (Random angle) degrees
      • Custom script: call RemoveLocation(udg_Temp_Point)
This considers that the Bandits are owned by neutral hostile and that bosses are heroes.

The only tricky part is setting the location to respawn. A solution could be that you add certain Bandits to a unit-group. Then you check if the dying unit is in that unit-group. If it is, you set the location to where that specific group spawns.
 
Level 3
Joined
Jul 18, 2010
Messages
35
I want the unit to respawn in the same location it was before it was ever attacked

EDIT: My focus isn't on the big hero at the end, I know how to make sure he won't respawn - thats easy. All I REALLY need is a way for units to respawn to their ORIGINAL location after dying
 
Last edited:
JASS:
struct CreepRespawn extends array

    private static hashtable CreepHash = InitHashtable()
    private static real TIMER = 120 //interval

    //This will save units position on map initialization (make sure all your units are placed on the ground)
    private static method CreepSetup takes nothing returns nothing
        local unit u
        call GroupEnumUnitsInRect(bj_lastCreatedGroup, bj_mapInitialPlayableArea, null)
        loop
            set u = FirstOfGroup(bj_lastCreatedGroup)
            exitwhen u == null
            call SaveReal(CreepHash, GetHandleId(u), 0, GetUnitX(u))
            call SaveReal(CreepHash, GetHandleId(u), 1, GetUnitY(u))
            call GroupRemoveUnit(bj_lastCreatedGroup, u)
        endloop
    endmethod
    
    //This will simply respawn unit after some time at it's location set above
    private static method CreepRespawn takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local integer index = GetHandleId(u)
        local integer id = GetUnitTypeId(u)
        local player p = GetOwningPlayer(u)  
        local real x = LoadReal(CreepHash, index, 0)
        local real y = LoadReal(CreepHash, index, 1)
     
        call FlushChildHashtable(CreepHash, index)   
        
        call TriggerSleepAction( TIMER )
        
        set u = CreateUnit(p, id, x, y, GetRandomReal(-0.03, 0.03))
        set index = GetHandleId(u)
        call SaveReal(CreepHash, index, 0, x)
        call SaveReal(CreepHash, index, 1, y)
        call SetUnitCreepGuard( u , false )
        call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl", x, y))
        
        set u = null
        set p = null
    endmethod
    

    private static method onInit takes nothing returns nothing
        local trigger t = CreateTrigger()
        call CreepSetup()
        call TriggerRegisterPlayerUnitEvent( t, Player(0), EVENT_PLAYER_UNIT_DEATH , null ) //Player red
        call TriggerRegisterPlayerUnitEvent( t, Player(1), EVENT_PLAYER_UNIT_DEATH , null ) //Player blue
        call TriggerRegisterPlayerUnitEvent( t, Player(2), EVENT_PLAYER_UNIT_DEATH , null ) //Player teal
        call TriggerAddAction( t, function thistype.CreepRespawn )
        set t = null
    endmethod

endstruct
I didn't tested it but it should work ^_^
 
Last edited:
Level 3
Joined
Jul 18, 2010
Messages
35
Looks complicated, but I'll do what I can to copy it down and try it lol.

RE-EDIT: Alright so what am I supposed to do with that long list of text? Copy paste it or what?
 
Last edited:
Level 33
Joined
Mar 27, 2008
Messages
8,035
Uses of wait also can solve the problem and as long the unit is (Triggering unit), the trigger is MUI of course.

Mr Bean trigger works well just change your location to:
  • Actions
    • Set Temp_Point = (Position of (Triggering unit))
    • Wait YourOwnDuration seconds
    • Unit - Create 1 (Unit-type of (Triggering unit)) for (Triggering player) at Temp_Point facing Default building facing degrees
    • Custom script: call RemoveLocation(udg_Temp_Point)
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
why make things so complicated to put in unit groups while you can just put a
condition for a unit type that dies?...

  • Unit Dies
  • Events
    • Unit - A unit owned by Neutral Hostile Dies
  • Conditions
    • Unit - Unittype equals to bandit
  • Actions
    • Wait - 10 seconds
    • Custom script: call CreateUnit(GetTriggerPlayer(), GetUnitTpeId(GetTriggerUnit()), GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), 0)
EDIT:
- Temp_Point is a global variable, it will bug after the wait, the wait above the TEmp_Point is fine...
- Never use local groups, use bj_lastCreatedGroup instead...
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
What's a trigger to make sure "certain" types of units respawn after a certain amount of time?

Scenario: forest full of bandits, all the little wimpy bandits respawn but the big boss at the end won't.

I know I can use variables to specifically save unit after unit, but I figured I'd ask if there was any better way to do this (since that method takes a ridiculous amount of time and variables)

easiest thing if u use point value for this, example set forest troll point value to 10 and boss point value to 50 and when unit die check his point value and wait same amount than dying/triggering unit point value :)
for this u dont need variable array and set the respawn time at begining of game, just u must set in object editor what take a bit more time but u must do only 1x and map dont need to store useless data and load useless things in map init, so could be faster a bit
 
Level 2
Joined
Mar 20, 2012
Messages
18
At the most below of your actions, add this;

  • Special Effect - Create a special effect at Temp_Point using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
  • Special Effect - Destroy (Last created special effect)

Thanks for your reply.

But it didn't work. Should I create variable "Temp_Point" first? Cuz, I don't have that variable. I have "Creep_Point" and "Temp_Integer" variables.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
Thanks for your reply.

But it didn't work. Should I create variable "Temp_Point" first? Cuz, I don't have that variable. I have "Creep_Point" and "Temp_Integer" variables.

see, i made a demo map for u

  • Respawn
    • Events
      • Unit - A unit owned by Neutral Hostile Dies
    • Conditions
    • Actions
      • Custom script: local unit u = GetDyingUnit()
      • Custom script: local integer id = GetUnitTypeId(u)
      • Custom script: local integer lv = GetHeroLevel(u)
      • Custom script: local integer cv = GetUnitUserData(u)
      • Game - Display to (All players) the text: ((This is for test: + dying unit is |cffffff00) + ((Name of (Triggering unit)) + (|r and his respawn time (what is same than point value): + (String((Point-value of (Triggering unit)))))))
      • Wait (Real((Point-value of (Triggering unit)))) seconds
      • Custom script: call RemoveUnit( u )
      • Set RespawnEffect = (Art path of Raise Dead Effect Art (index 0))
      • Custom script: call DestroyEffect(AddSpecialEffect (udg_RespawnEffect,udg_CreepX[cv],udg_CreepY[cv]))
      • Custom script: set u = CreateUnit(GetTriggerPlayer(),id,udg_CreepX[cv],udg_CreepY[cv],udg_CreepAng[cv])
      • Custom script: if lv > 1 then
      • Custom script: call SetHeroLevel(u,lv,false)
      • Custom script: endif
      • Custom script: set u = null
this leakless and i guess enough fast too, configurable the effect (RespawnEffect is string, u can choose art path of abilities in gui)
 

Attachments

  • respawn.w3x
    22.5 KB · Views: 66
Status
Not open for further replies.
Top