| 11-24-2009, 11:06 AM | #2 |
Well, I'd make a struct to represent my spawn point, each struct would have a stack of spawngroups, which would be another struct that would contain an array of unit types to spawn. At the start of the game, each spawnpoint would pick a random spawngroup from it's stack, spawn those units, add them to the spawnpoint's unitgroup and attach the spawnpoint to the units; then, whenever a unit dies, find the spawnpoint it is linked to, remove the dying unit from that spawnpoint's unitgroup, when the unitgroup is empty start a timer with the spawnpoint attached to it, when the timer expires spawn another random spawngroup for the attached spawnpoint. |
| 11-24-2009, 12:59 PM | #3 |
Im very new to structs and all, sounds like id have to make a struct inside of a struct. And id just have no idea on how to structure the second part of your post. At init each spawn point picks a group, then a delay then they spawn, and when they die they get removed from the spawnpoints group but why? Attached spawnpoint? |
| 11-24-2009, 02:44 PM | #4 |
This would be a rough framework of the data structures needed finished spawn system: JASS:library SpawnSystem requires AutoIndex, TimerUtils globals private constant integer MAX_UNITS_PER_GROUP = 5 private constant integer MAX_GROUPS_PER_POINT = 5 endglobals struct spawnGroup private integer array spawnedUnitType[MAX_UNITS_PER_GROUP] private integer spawnedUnitCount=0 method addUnitType takes integer utype returns boolean if this.spawnedUnitCount >= MAX_UNITS_PER_GROUP then return false endif set this.spawnedUnitType[this.spawnedUnitCount] = utype set this.spawnedUnitCount = this.spawnedUnitCount + 1 return true endmethod method spawnUnits takes real x, real y, group g returns nothing local integer i = 0 loop exitwhen i>=this.spawnedUnitCount call GroupAddUnit(g, CreateUnit( Player(12), this.spawnedUnitType[i], x,y,0.0 )) set i=i+1 endloop endmethod endstruct struct spawnPoint private spawnGroup array spawnGroupType[MAX_GROUPS_PER_POINT] private integer spawnGroupCount=0 private real x private real y private group g public real respawnDelay = 0.0 // This is used by the spawnUnits method to link the spawned units // to the spawnPoint that spawned them. private static spawnPoint temp private static spawnPoint array unitLink private static method linkUnitEnum takes nothing returns nothing set spawnPoint.unitLink[GetUnitId(GetEnumUnit())]=spawnPoint.temp endmethod // When this method is called, the spawnPoint will pick one of // it's spawn groups at random and tell it to spawn the units. method spawnUnits takes nothing returns nothing local integer i = GetRandomInt(0,this.spawnGroupCount-1) call this.spawnGroupType[i].spawnUnits(this.x, this.y, this.g) set spawnPoint.temp = this call ForGroup(this.g, function spawnPoint.linkUnitEnum) endmethod // With this method, we add spawnGroups to our spawnPoint. method addSpawnGroup takes spawnGroup g returns boolean if this.spawnGroupCount >= MAX_UNITS_PER_GROUP then return false endif set this.spawnGroupType[this.spawnGroupCount] = g set this.spawnGroupCount = this.spawnGroupCount + 1 return true endmethod // Custom create method that already initializes some properties of the spawnPoint struct. static method create takes real x, real y returns spawnPoint local spawnPoint this = spawnPoint.allocate() set this.x = x set this.y = y if this.g==null then set this.g=CreateGroup() else // If this struct index was already used once, reuse the old group: call GroupClear(this.g) endif return this endmethod private static boolean groupEmpty private static method unitDeathEnum takes nothing returns nothing set spawnPoint.groupEmpty=false endmethod private static method respawn takes nothing returns nothing local spawnPoint this = spawnPoint(GetTimerData(GetExpiredTimer())) call this.spawnUnits() call ReleaseTimer(GetExpiredTimer()) endmethod private static method unitDeath takes nothing returns boolean local integer i = GetUnitId( GetDyingUnit() ) local spawnPoint this = spawnPoint.unitLink[i] local timer t if this != 0 then call GroupRemoveUnit(this.g, GetDyingUnit() ) set spawnPoint.unitLink[i] = 0 set spawnPoint.groupEmpty = true call ForGroup( this.g, function spawnPoint.unitDeathEnum ) if spawnPoint.groupEmpty then set t=NewTimer() call SetTimerData(t, integer(this)) call TimerStart(t, respawnDelay, false, function spawnPoint.respawn) endif endif return false endmethod private static method onInit takes nothing returns nothing local trigger t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_DEATH ) call TriggerAddCondition( t, Condition( function spawnPoint.unitDeath ) ) endmethod endstruct endlibrary Edit: Now this uses AutoIndex to attach spawnPoints to units and then retrieve them when units die. Also uses TimerUtils to allow units to be respawned with a delay which can be set for each spawn point individually. |
| 11-24-2009, 05:07 PM | #5 |
Im looking into autoindex but where do I input the unitgroups in your framework? |
| 11-24-2009, 08:21 PM | #6 |
Okay, I added the respawning code to the example above, the new sections of the code are highlighted. Once all the units linked to a spawnPoint are killed, the spawnPoint will spawn a new group of units. |
| 11-25-2009, 11:04 AM | #7 |
Thanks and where do I create my creep groups? say SpawnGroup[1] = 'hpea' , 'hpea', 'hpea' etc. |
| 11-25-2009, 01:02 PM | #8 |
Well, you'd need an init scope, something like this (I didn't feel like looking up the rawcodes of the various creeps, so I just put 'hpea' everywhere, you'll need to replace that): JASS:library SpawnInit initializer Init requires SpawnSystem globals private spawnPoint array SP endglobals private function Init takes nothing returns nothing local spawnGroup trollsEasy = spawnGroup.create() local spawnGroup spidersEasy = spawnGroup.create() //...declare all the spawn groups you'll be using. call trollsEasy.addUnitType( 'hpea' ) // Ice troll call trollsEasy.addUnitType( 'hpea' ) // Ice troll call trollsEasy.addUnitType( 'hpea' ) // Ice troll priest call spidersEasy.addUnitType( 'hpea' ) // Spiderling call spidersEasy.addUnitType( 'hpea' ) // Spiderling call spidersEasy.addUnitType( 'hpea' ) // Spiderling call spidersEasy.addUnitType( 'hpea' ) // Spiderling //...setup all the spawn groups. set SP[1] = spawnPoint.create( 500.0, 2000.0 ) // Spider lair spawnpoint: this only spawns spiders call SP[1].addSpawnGroup( spidersEasy ) call SP[1].spawnUnits() set SP[1].respawnDelay = 30.0 set SP[2] = spawnPoint.create( 800.0, -1000.0 ) // Random spawnpoint: this spawns either trolls or spiders call SP[2].addSpawnGroup( spidersEasy ) call SP[2].addSpawnGroup( trollsEasy ) call SP[2].spawnUnits() set SP[2].respawnDelay = 60.0 //...create and setup all the spawn points. endfunction endlibrary |
| 11-28-2009, 08:38 AM | #9 |
Im puzzled again, both of the creep groups have the posibility to be spawned at the same spawn point but in the library I have to set them as different points? Ok i figured this out, I just add the spawn group to the points. Im getting a constructor requires no arguements error in the Spawn init library, on the " set SP[1] = spawnGroup.create( 500.0, 2000.0 ) // Spider lair spawnpoint" line. Ive added this event response so that it only checks on neutral hostile deaths. JASS:call TriggerRegisterPlayerUnitEvent(t, Player(PLAYER_NEUTRAL_AGGRESSIVE), EVENT_PLAYER_UNIT_DEATH , null) |
| 11-28-2009, 08:59 AM | #10 |
Your trigger wont run on random time. It will calculate random number once (on trigger init) and use same number all time. You shoud use timer expiration event with timer reset on every expiration. |
| 11-28-2009, 09:36 AM | #11 |
Im planning on using anitarfs libraries, unless these are the triggers that you are refering to |
| 11-28-2009, 11:39 AM | #12 |
Right, that was a typo, it was supposed to be spawnPoint, not spawnGroup there. So, to fix: set SP[1] = spawnPoint.create( 500.0, 2000.0 ) // Spider lair spawnpoint Same for SP[2] and onward, obviously. I've also edited the previous post to fix the example. |
| 11-28-2009, 12:11 PM | #13 |
Another error, SP[1] is not of a type that allows . syntax . ? |
| 11-28-2009, 01:17 PM | #14 |
Another typo, when the SP array is declared, it should say private spawnPoint array SP, not private spawnPont array SP. |
| 11-28-2009, 02:44 PM | #15 |
Do the creeps have to be preplaced? |
