- To limit the total number of units on the hill, I want to have a shared source of supply for each player/computer team
- I need to determine the supply cost (or supplies given for overloards and command centers) for the given tribute
- I need to modify the players supply to reflect the supply of the computer and ensure the player cannot get more than 200 supply worth of units
- I need to remove the supply cost (or supply given) of units which are killed
My first attempt was to look for a setting in the player setup which will allow such an alliance, but that was unsuccessful. However, I did find out how to modify the supplies that a player has with triggers. The trouble is, I could not figure out how to determine the supply cost of a unit. I was hoping it was located with the resources (minerals, gas, supply?), but no luck there either.
Then I found an incredible function: Catalog Field Value Get as Integer.
This allows one to look up any entry in the catalog and return the value associated with it. Other triggers exist to modify these values, but are not necessary for this map. Next, how do I find the supplies used by a unit? Unfortunately, with this task of sharing supplies, nothing came easily.
Catalog Field Value Get as Integer is a command that allows you to query the catalog and return any value associated with any unit. The trick is getting to know how to navigate the selection window in the trigger editor. First is to select the Catalog to get data from. I am looking to find out how many supplies a unit uses, so I'll be looking at the Units catalog. The unit in question is the unit type of triggering unit, and the catalog entry I am looking for is supplies.
There is no supplies entry. . .Back to hunting.
It turns out, at least in this case, that the name given in the table view of the catalog editor (or detailed view) is not the name the triggers use. To get that name, we get to dig through the XML view of the catalog. After scrolling around and looking for a unit that impacts the supply count, I came across Drone. In the list for the Drone, there is an entry: <Food value="-1"/>.
FOOD! Not supplies.
Now to find Food in the list of attributes for the unit type of triggering unit. Success! For testing purposes, I made a variable in the give tribute trigger and set it up like this:
supply = (Value of Units (Unit type of (Triggering unit)) Food for player Any Player as an integer) <Integer>
Catalog Field Value Get as Integer is a command that allows you to query the catalog and return any value associated with any unit. The trick is getting to know how to navigate the selection window in the trigger editor. First is to select the Catalog to get data from. I am looking to find out how many supplies a unit uses, so I'll be looking at the Units catalog. The unit in question is the unit type of triggering unit, and the catalog entry I am looking for is supplies.
There is no supplies entry. . .Back to hunting.
It turns out, at least in this case, that the name given in the table view of the catalog editor (or detailed view) is not the name the triggers use. To get that name, we get to dig through the XML view of the catalog. After scrolling around and looking for a unit that impacts the supply count, I came across Drone. In the list for the Drone, there is an entry: <Food value="-1"/>.
FOOD! Not supplies.
Now to find Food in the list of attributes for the unit type of triggering unit. Success! For testing purposes, I made a variable in the give tribute trigger and set it up like this:
supply = (Value of Units (Unit type of (Triggering unit)) Food for player Any Player as an integer) <Integer>
Then I took this value and subtracted (negative value) it to the players used supply when they have a unit enter the computer control region. I also added this value when a unit dies while under control of the respective computer. This got me started, but it did not work for units who gave supply (such as overlords). While that is fixable with more code, the place it failed massively was in the case of partial supply units, namely zerglings. Because it returned the value as an integer, zerglings became free. How is that for a scary thought?
To solve this, I looked through the catalog field value functions again. No getting a real number, but one can get a string. BINGO. This string preserves the fractional portion (it's just a string after all, it doesn't know any better). Now to convert the string to a real number, and BAM, we have our fractional values! Now my variable looks more like this:
supply = (Real((Value of Units (Unit type of (Triggering unit)) Food for player Any Player))) <Real>
Now to mess with the players supplies properly. I first tried my previous approach of subtracting the supply value from the supplies used (making it bigger, as supplies is negative), but the supplies used is once again taken as an integer, and loses the partial contribution from those pesky zerglings. More hunting for a solution. Getting a sense of why this task was so difficult for me (and why there are months between posts...)?
OK, after much trial and even more error (don't attempt to keep track of every units supply everywhere, it is not pretty), I settled on generating an array which I called supplies. It is in real number format and there is an entry for every player (I leave the 0th entry unused, so player 1 is in index 1). The basic idea is to keep track of the number of supplies I've given as a fractional value, and to only change the players supplies when the value moves from one integer to another. It looks something like this:
Player - Modify player owner Supplies Used: Add {(Integer({supplies[owner]-supply}))-(Integer(supplies[owner]))}
Variable - Modify supplies[owner]: - supply
The second line tells you how the first is calculated. The modification to the owners supply count is done by adding difference between the integer value of the supplies[owner] - suppy (unit) and supplies[owner]. The second value is always bigger than the first because the value of supply is negative. Once this is done, I update the array for the next iteration of units transferring or dying. When a unit dies, I do the opposite:
Player - Modify player owner Supplies Used: Add {(Integer({supplies[owner]+supply}))-(Integer(supplies[owner]))}
Variable - Modify supplies[owner]: + supply
To ensure supply is never negative, I nest this within a conditional statement. This also allows me to handle the case where the supply is positive (overloards and CC's). Finally, here is what the two functions look like:
Give Tribute
Events
Unit - Any Unit Enters (Region named "ComputerControl")
Local Variables
supply = (Real((Value of Units (Unit type of (Triggering unit)) Food for player Any Player))) <Real>
owner = (Owner of (Triggering unit)) <Integer>
Conditions
Actions
General - If (Conditions) then do (Actions) else do (Actions)
If
((Triggering unit) is under construction) == True
Then
Unit - Set progress of (Triggering unit) slot 1 to 100%
Else
Variable - Modify Tribute Army Value[owner]: + (Sum - Minerals, Vespene cost of (Unit type of (Triggering unit)))
Leaderboard - Set Leaderboard item text at column 2 and row owner to (Text(Tribute Army Value[owner]))
Leaderboard - Sort Leaderboard by column 2, in Descending order, with priority 1
Unit - Change ownership of (Triggering unit) to player {owner+8} and Retain Color
Unit - Share Vision of (Triggering unit) with Player owner
AI - Add (Triggering unit) to the next attack wave for player {owner+8}
AI - Set the target for player {owner+8} attack (or defense) waves to be the region Hill with replace behavior Replace Never.
AI - Send the attack wave from player {owner+8} to attack in 0 seconds and Don't Wait
General - If (Conditions) then do (Actions) else do (Actions)
If
supply <= 0
Then
Player - Modify player owner Supplies Used: Add {(Integer({supplies[owner]-supply}))-(Integer(supplies[owner]))}
Variable - Modify supplies[owner]: - supply
Else
Player - Modify player owner Supplies Made: Add (Integer(supply))
Tribute Dies
Events
Unit - Any Unit dies
Local Variables
supply = (Real((Value of Units (Unit type of (Triggering unit)) Food for player Any Player))) <Real>
owner = 0 <Integer>
Conditions
(Owner of (Triggering unit)) >= 9
Actions
Variable - Set owner = {(Owner of (Triggering unit))-8}
Variable - Modify Tribute Army Value[owner]: - (Sum - Minerals, Vespene cost of (Unit type of (Triggering unit)))
Leaderboard - Set Leaderboard item text at column 2 and row owner to (Text(Tribute Army Value[owner]))
General - If (Conditions) then do (Actions) else do (Actions)
If
supply <= 0
Then
Player - Modify player owner Supplies Used: Add {(Integer({supplies[owner]+supply}))-(Integer(supplies[owner]))}
Variable - Modify supplies[owner]: + supply
Else
Player - Modify player owner Supplies Made: Subtract (Integer(supply))
The final bit is the supplies array. To try and make it as representable as possible, I started the supply value at -0.1. This way the first zergling would be free, and the second would add to the supply. This means that the first zergling to die will remove 1 supply, allowing the player to get 200.5 supply instead of just 200 supply, but hopefully that will play little role in the game. Here is the supplies array initialization:
supplies = -0.1 <Real[9]>
And we have shared supplies! At least mostly shared supplies between a player and a non-producing computer...but shared supplies none-the-less!


