HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Creep Respawn Help

02-10-2006, 07:32 PM#1
Morkeliph
I know this is a redundant question, but I'm a beginner. I'm creating a map that includes a large number of creeps that I need to respawn. They pnly need to respawn once but they actually respawn into a different creep. For example, when a centaur drudge dies, it is replaced with a polar furbolg. That part is easy enough, but the catch is that I don't want them to respawn for a considerable amount of time (around 240 seconds). I've tried a few different things but I'm worried about memory leaks and just using too much memory at once (for instance, when you've got 200 creeps that are all counting down to response, the game gets slow and may even crash, especially when there are multiple user or AI players in the game). Does anyone have any suggestions on how I can do this effectively? I'm not very JASS knowledgable, but I'm definitely trying to learn. Thanks!
02-10-2006, 08:24 PM#2
johnfn
Well the thing that depends here is where you want it to respawn. If you want to respawn where it died, its easy.

Variables: newUnit, type: unit type and locOfDyingUnit, type : point.
Trigger:
Collapse Events
Generic Unit Event - A Unit Dies
Conditions
Collapse Actions
set locOfDyingUnit = Location of (Dying Unit)
set newUnit = (No unit)
Collapse If (Dying unit) Equal to (Centaur Drudge)
Collapse Then (Conditions)
Set newUnit = Polar Furblog
Else (Conditions)
Collapse If (Dying unit) Equal to (Some other type of monster)
Collapse Then (Conditions)
Set newUnit = something
Else (Conditions)
Wait 240.0 seconds
Create 1 newUnit at (locOfDyingUnit) Facing Default Building Facing degress
------- This means that if newUnit was never set because that unit isn't supposed to respawn, no units will be created --------

Anyways, obviously thats not the most efficient but I thought you might want to start out easy :D

If you want it to respawn where it originally started, thats a little harder though, so you might wanna do that a little later.


By the way, to clear up a few misconceptions: Waits wont cause lag. They let other triggers do their thing, then bring the focus back to the current trigger once the wait is up.

Memory leaks are only caused by variables such as Points, Unit Groups and Player Groups but I'm pretty sure that if you store them soley in global variables you wont have any temporary points hanging around and therefore no memory leaks.

So something like this

Trigger:
Move (Some unit) to Position of (blahblahblah)

That actually leaks because the position of blahblahblah answers back a point, and that point isn't saved to anything and therefore leaks. (really, its a little more complex then this, it is saved to a variable, but the variable isn't set to null and IT leaks) Just like:


Trigger:
Pick all units in (Units in (Playable Map Area))

leaks, because that answers back (returns) a unit group, but it isn't caught by any variables or saved to anything and leaks.

Check out Cubasis's memory leak tutorial, he knows a lot more then I do.
02-10-2006, 08:46 PM#3
Morkeliph
Hey, that helps a bit. Thanks!

I think I've found something that might work close enough to how I want it to, but I am terrible at memory leak and JASS. Here's a picture of what I've got, and the memory leak custom scripting I've begun (but obviously need help with). Any tips on how to minimize memory leak in this sort of a situation would be most appreciated! Thanks!

Zoom (requires log in)
Zoom (requires log in)

That for Player Red is a mistake, it should be Neutral Hostile.
Attached Images
File type: jpgtrigger.JPG (44.1 KB)
File type: jpgtrigger2.JPG (22.9 KB)
02-11-2006, 12:11 AM#4
Morkeliph
Okay, I think I've gotten some triggers that work fairly well, and I've tested them out a few times as well. Is there anyone here who can check this for memory leaks? I have a program written by Im_on_56k, and it came out negative, but I swear there's got to be leaks in here that I need to fix.
Thanks!

Trigger:
Respawn
Collapse Events
Unit - A unit owned by Neutral Hostile Dies
Conditions
Collapse Actions
Set DeathPoint[(Custom value of (Dying unit))] = (Position of (Dying unit))
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
Temp_Type[(Custom value of (Dying unit))] Equal to Centaur Drudge
Collapse Then - Actions
Wait until (((Units within 1536.00 of DeathPoint[(Custom value of (Dying unit))] matching ((((Matching unit) belongs to an enemy of Neutral Hostile) Equal to True) and (((Matching unit) is alive) Equal to True))) is empty) Equal to True), checking every 20.00 seconds
Unit - Create 1 Polar Furbolg for Neutral Hostile at Temp_Point[(Custom value of (Dying unit))] facing Default building facing degrees
Else - Actions
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
Temp_Type[(Custom value of (Dying unit))] Equal to Centaur Archer
Collapse Then - Actions
Wait until (((Units within 1536.00 of DeathPoint[(Custom value of (Dying unit))] matching ((((Matching unit) belongs to an enemy of Neutral Hostile) Equal to True) and (((Matching unit) is alive) Equal to True))) is empty) Equal to True), checking every 20.00 seconds
Unit - Create 1 Polar Furbolg Shaman for Neutral Hostile at Temp_Point[(Custom value of (Dying unit))] facing Default building facing degrees
Else - Actions
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
Temp_Type[(Custom value of (Dying unit))] Equal to Centaur Firecaller
Collapse Then - Actions
Wait until (((Units within 1536.00 of DeathPoint[(Custom value of (Dying unit))] matching ((((Matching unit) belongs to an enemy of Neutral Hostile) Equal to True) and (((Matching unit) is alive) Equal to True))) is empty) Equal to True), checking every 20.00 seconds
Unit - Create 1 Polar Furbolg Tracker for Neutral Hostile at Temp_Point[(Custom value of (Dying unit))] facing Default building facing degrees
Else - Actions
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
Temp_Type[(Custom value of (Dying unit))] Equal to Centaur Outrunner
Collapse Then - Actions
Wait until (((Units within 1536.00 of DeathPoint[(Custom value of (Dying unit))] matching ((((Matching unit) belongs to an enemy of Neutral Hostile) Equal to True) and (((Matching unit) is alive) Equal to True))) is empty) Equal to True), checking every 20.00 seconds
Unit - Create 1 Polar Furbolg Champion for Neutral Hostile at Temp_Point[(Custom value of (Dying unit))] facing Default building facing degrees
Else - Actions
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
Temp_Type[(Custom value of (Dying unit))] Equal to Centaur Sorcerer
Collapse Then - Actions
Wait until (((Units within 1536.00 of DeathPoint[(Custom value of (Dying unit))] matching ((((Matching unit) belongs to an enemy of Neutral Hostile) Equal to True) and (((Matching unit) is alive) Equal to True))) is empty) Equal to True), checking every 20.00 seconds
Unit - Create 1 Polar Furbolg Elder Shaman for Neutral Hostile at Temp_Point[(Custom value of (Dying unit))] facing Default building facing degrees
Unit - Create 1 Polar Furbolg Ursa Warrior for Neutral Hostile at Temp_Point[(Custom value of (Dying unit))] facing Default building facing degrees
Else - Actions
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
Temp_Type[(Custom value of (Dying unit))] Equal to Ogre Warrior
Collapse Then - Actions
Wait until (((Units within 1536.00 of DeathPoint[(Custom value of (Dying unit))] matching ((((Matching unit) belongs to an enemy of Neutral Hostile) Equal to True) and (((Matching unit) is alive) Equal to True))) is empty) Equal to True), checking every 20.00 seconds
Unit - Create 1 Succubus for Neutral Hostile at Temp_Point[(Custom value of (Dying unit))] facing Default building facing degrees
Else - Actions
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
Temp_Type[(Custom value of (Dying unit))] Equal to Ogre Magi
Collapse Then - Actions
Wait until (((Units within 1536.00 of DeathPoint[(Custom value of (Dying unit))] matching ((((Matching unit) belongs to an enemy of Neutral Hostile) Equal to True) and (((Matching unit) is alive) Equal to True))) is empty) Equal to True), checking every 20.00 seconds
Unit - Create 1 Vile Tormentor for Neutral Hostile at Temp_Point[(Custom value of (Dying unit))] facing Default building facing degrees
Else - Actions
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
Temp_Type[(Custom value of (Dying unit))] Equal to Ogre Mauler
Collapse Then - Actions
Wait until (((Units within 1536.00 of DeathPoint[(Custom value of (Dying unit))] matching ((((Matching unit) belongs to an enemy of Neutral Hostile) Equal to True) and (((Matching unit) is alive) Equal to True))) is empty) Equal to True), checking every 20.00 seconds
Unit - Create 1 Vile Temptress for Neutral Hostile at Temp_Point[(Custom value of (Dying unit))] facing Default building facing degrees
Else - Actions
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
Temp_Type[(Custom value of (Dying unit))] Equal to Ogre Lord
Collapse Then - Actions
Wait until (((Units within 1536.00 of DeathPoint[(Custom value of (Dying unit))] matching ((((Matching unit) belongs to an enemy of Neutral Hostile) Equal to True) and (((Matching unit) is alive) Equal to True))) is empty) Equal to True), checking every 20.00 seconds
Unit - Create 1 Maiden of Pain for Neutral Hostile at Temp_Point[(Custom value of (Dying unit))] facing Default building facing degrees
Unit - Create 1 Queen of Suffering for Neutral Hostile at Temp_Point[(Custom value of (Dying unit))] facing Default building facing degrees
Else - Actions
02-11-2006, 12:24 AM#5
Vexorian
Yes, it is plagged by group leaks. Tons of them actually.
02-14-2006, 07:27 PM#6
Morkeliph
Okay, I see them now. I'll be working on it, but I need helo with one thing. What custom script do I make to destroy particular array variables? For instance, if I want to destroy Temp_Type[Custom value of Dying Unit], what would that look like for a custom script?

Thanks!
02-14-2006, 09:14 PM#7
Captain Griffen
Think outside the box once in a while.

When the first unit dies, make it spawn a 240 second long spawn with locus ability, no model, etc., and give that an ability to spawn the required creep when it dies.

This requires the creation of one unit, two abilities, and has no triggers. Elegent.
02-14-2006, 10:08 PM#8
Anitarf
A great suggestion. If you don't know where to find the ability, it's the one used by the hydra creep to spawn 2 lesser hydras when dying.

As for the group leaks in your trigger, they are difficlut to fix, because when waiting for condition, you need to dynamically create the unit group, because if you use the same group all the time the condition will never be true. However, by dynamically creating the group, you leak, because you can't destroy it inside the "wait for condition" function which is the one creating the groups when it calls "units in range of location matching condition".
02-15-2006, 02:49 PM#9
Morkeliph
Quote:
Originally Posted by Captain Griffen
Think outside the box once in a while.

When the first unit dies, make it spawn a 240 second long spawn with locus ability, no model, etc., and give that an ability to spawn the required creep when it dies.

This requires the creation of one unit, two abilities, and has no triggers. Elegent.
I think I'd run into the same problem I was having before. The 240-second spawn is analogous to giving a 240-second wait command in the triggers. WHen you've got 200 creeps all waiting to respawn, that's 200 different "timers" ticking down, which takes considerable memory and slows doen the game or makes it crash. Believe me, I've tried it. Hence the reason I'm abandoning the 240-second-interval and trying to get them to spawn under a different method. Any suggestions are welcome, though I am trying to figure it out for myself.

Thanks.
02-15-2006, 06:01 PM#10
Captain Griffen
I think that it runs a lot faster when done via an ability and a unit, because it is then (correct me if I'm wrong), running using the game engine, rather than a script, which is a lot faster.
02-15-2006, 07:21 PM#11
Guest
It might get slightly complicated, but i would use locals with custom script.
It may seem slightly ok now, but you need alot of varibles, and lots of integer to keep track of each varible array.
If you use locals for each dying unit, it will respawn when it needs in no time.
I could make you a function if you really need it bad.

The main problem is varibles like UnitLocAfterDeath[UnitNumber]...
You need to set UnitNumber up 1 after each death, and thats just 1 varible.
if you use locals it would be something like this

Code:
local unit u = GetDyingUnit()
local location l = GetUnitLoc(u)
call TriggerSleepAction(240)
call CreateNUnitsAtLoc( 1, GetUnitTypeId(GroupPickRandomUnit(GetUnitsInRectAll(GetPlayableMapRect()))), Player(PLAYER_NEUTRAL_AGGRESSIVE), GetUnitLoc(u), GetUnitFacing(u) )

This would work fine, but after a long time, all the units would be the same. Unless you made a seprate trigger which removes a random unit and replaces it with a specific unit every, lets say, 140 secs, but only if its not im combat.

Hope this is of good help to you :)
02-15-2006, 08:10 PM#12
Anitarf
Having 200 units with their life timers ticking down is hardly any worse than having 200 units without that, and since you would only create a dummy countdown unit whenever one of the original units died, I really don't see a problem why that wouldn't work.
02-17-2006, 01:26 AM#13
Morkeliph
Okay, after having tried several different things and having limited success, I've actually abandoned the whole original idea in favor of another one that I like. Tell me if you think this idea sucks, how it could be improved, and if you think it'll even work or just be a pain in the butt.

So, I've got groups of creeps scattered around that you fight through as you make your hero levels up and you hunt out your opponents. Instead of having creeps respawn like you typically see, there will be a few wandering neutral flyers that resurrect groups they happen to come across. Corpses will never disappear because they are permanent, so there's no worry about that. The benefit I see here is that it introduces a bit more variability to the game, you never know exactly what's going to happen because the flyers wander and ressurrect aimlessly. Additionally, if you can take them out (there'll be a few of them) you can stop creep respawning altogether and they'll drop useful items as well. What do you think?
02-17-2006, 01:30 AM#14
Linera
sounds like a good idea.

not good if you're making a RPG though.
02-17-2006, 01:56 AM#15
Morkeliph
It's not an RPG, it's PvP elimination, with some RPG elements to it. I think it'll be fun, or at least different.

Additionally, this is the error message I was getting in the past. I only get it occasionally now. Does nayone know what it means or what I can do about it?
Zoom (requires log in)
Attached Images
File type: jpgerror.JPG (20.8 KB)