| 01-18-2007, 04:48 AM | #1 |
I have a dillema. On my map-in-development, I have a nice and unorganized nest of triggers that I have yet to optimize. My system of spawning units is nearly completed, save for a small (but extremely huge) problem. Domination, my map, is a capture-the-points type map, where you must select your races and heroes, then use your army and hold dominance over the four points against 3 other teams. When the game starts, you get a small amount of army points that you must spend on eight categories of units: Light Melee, Light Ranged, Medium/Mounted, Artillery, Flying, Spellcaster, Tanker, and Elite. As the game progresses and your team accumulates kills, you will get more army points to spend at your lesiure. Right now, the race and hero selection, initilization and start features, events, statistics, victory/scoring conditions, and all other normal game elements are all fine and working acceptably. Except for one element, though. That element would be the system that actually randomly selects the units that must be made. It sounds like a simple system, right? WRONG. It must factor in several factors: 1. The units must be of levels that are affordable from all the points you allocated. Otherwise, you might not spawn anything! 2. The allocated points for each category must be divided absolutely evenly between all of the unit-levels of that category. This is very important for unit categories that span five levels; you may not have a level 6, 7, 8, 9, and 10 elite unit, so the system would have to divide those points among the levels that you have, not the ones you don't have. 3. It has to know if you allocated enough points for everything. For example, you allocated 7 points towards light melee units. A level 1 light melee unit costs 2 points, a level 2 light melee unit costs 4 points, and a level 3 light melee unit costs 7 points. The level 3 possibility would have to be omitted because 7*3 and 7*2 are 21 and 14, which is above your price range, UNLESS you ONLY have a level 3 light melee unit, then 7*1 would be simply 7, which you CAN afford. Repeat that process for the other levels. I am at a loss of how to implement this system. I tried brute-forcing it the time consuming way, but the editor just spit errors at me for having too many IF THEN ELSE functions nested inside eachother. If anyone can help me with this, I would be eternally grateful. |
| 01-19-2007, 03:35 AM | #2 |
hmm... I'll give it a shot... Assuming that you have a global integer for SpawnInterval, an array of integers stored in the globals PlayerLightMeleePoints[1-12], PlayerLightRangedPoints[1-12], etc., an integer array for PlayerLightMeleeLevel[1-12], etc., and an integer array for PointCostForLevel[1-Number of Levels], a global integer for NumberOfUnitsSpawned[1-12] (We'll do this in case you want to handicap a player), and a global srting array MeleeUnitTypes_StringValue[1-NumberofTypes], RangedUnitTypes, etc., then perhaps: JASS:function TimerSpawnUnits takes nothing returns nothing local timer time=CreateTimer() call TimerStart(time, udg_SpawnInterval, true,function SpawnUnits) endfunction function SpawnUnits takes nothing returns nothing local integer a=1 local integer b local integer c loop exitwhen a==13 //this will loop 12 times, once per player. We do this to avoid the playergroup leak that the ForPlayerGroup creates set b=udg_NumberOfUnitsSpawned[a] loop exitwhen b==0 if ( not (udg_PlayerLightMeleePoints[a] < b*(PointCostPerLevel[PlayerLightMeleeLevel[a]]) ) ) then set c=udg_NumberOfUnitsSpawned[a] loop exitwhen c==0 call CreateNUnitsAtLoc(1, S2I(LightMeleeUnitTypes[GetRandomInt(1,6)]) set c=c-1 //we do this to avoid the CreateNUnitsAtLoc leak, which creates a unit group that cannot be destroyed endloop else set b=b-1 endloop set b=udg_NumberOfUnitsSpawned[a] loop exitwhen b==0 if ( not (udg_PlayerLightRangedPoints[a] < b*(PointCostPerLevel[PlayerLightRangedLevel[a]) ) ) then set c=udg_NumberOfUnitsSpawned[a] loop exitwhen c==0 call CreateNUnitsAtLoc(1, S2I(LightRangedUnitTypes[GetRandomInt(1,6)]) set c=c-1 //we do this to avoid the CreateNUnitsAtLoc leak, which creates a unit group that cannot be destroyed endloop else set b=b-1 endloop //... //replace the globals for all the different catagories and I beleive this will work. If not, then I have no idea how to do this. set a=a+1 endloop endfunction //=========================================================================== function InitTrig_SpawnTheUnits takes nothing returns nothing set gg_trg_SpawnTheUnits = CreateTrigger( ) call TriggerAddAction( gg_trg_SpawnTheUnits, function TimerSpawnUnits ) endfunction Although I'm almost positive that this wouldn't work if you just copied and pasted it into your trigger, I hope this gives you an idea of how to figure this out. |
| 01-19-2007, 04:53 AM | #3 |
I seem to have made a huge discovery that would make it somewhat easier: I don't have a variable for the point costs per unit. That would make it a hell of a lot easier for me, but I never thought of it until you mentioned it. My variables are slightly different, one being a huge array of 960. I'l try it again tomorrow, and see if it works. |
| 01-21-2007, 04:22 AM | #4 |
Uh, crap. My trigger sort of works, but it sometimes spawns the wrong type of unit, or doesn't spawn enough units. With small numbers of some types of units, this problem does not exist, but once the number of units goes into the threes and higher for each category, I get these anomalies, even in single player. |
| 01-21-2007, 04:31 AM | #5 |
Check the unit type for GUI and Rawcodes for JASS. Also check how much it creates as well. -Av3n |
| 01-21-2007, 07:10 AM | #6 |
Don't put SpawnUnits after TimerSpawnUnits. JASS:if ( not (udg_PlayerLightMeleePoints[a] < b*(PointCostPerLevel[PlayerLightMeleeLevel[a]]) ) ) then Should be Boolean comparaison. JASS:call CreateNUnitsAtLoc(1, S2I(LightMeleeUnitTypes[GetRandomInt(1,6)]) //... call CreateNUnitsAtLoc(1, S2I(LightRangedUnitTypes[GetRandomInt(1,6)]) Missing 2 parameters. You are playing weirdly with loops, aren't you? |
