As you know, upgrades have a maximum level, which can be set on a per-player basis. The memory locations that hold these maximums happen to be very close to the deaths table, and I was wondering if killing units for sufficiently high player numbers could affect this. It turns out that it's close enough for this to work, sort of. Only certain upgrades can be effected, and no Brood War upgrades can be effected. You need to preplace a bunch of Vespene Tank (Terran Type 2) units (which I'll call VTs for short); this is an extended power-up that happens to be the unit with the highest ID. (Technically other units work, but there's no reason to use them instead, and with this one you can get the largest range of upgrades.) You can use them to increase the maximum upgrade level; to do so, they will need to be given to an extended player, then killed by a unit. The player that owns the VT determines the upgrade, but before I explain this, I need to explain a bit how the memory in question is laid out.
There are 552 bytes in the region in question. The first 46 are for P1 upgrades, the second 46 are for P2 upgrades, etc. Within each group of 46, the first byte is upgrade 0 (Terran Infantry Armor), the second byte is upgrade 1 (Terran Ship Plating), etc. You can look up which upgrade ID corresponds to which actual upgrade in DatEdit or something. Now, because we're doing weird overflow shenanigans, when determining the player ID to use for the VT, we need to know where the upgrade in question is in memory, not in some abstract array thinger. To compute the offset we need, take the upgrade ID and add 12 times the ID of the player we want to affect. So, for P1's Terran Infantry Armor, the offset would just be 0. For P4's upgrade 16 (which happens to be U-238 Shells), the offset would be 52. (Because computers count from 0, the ID of P1 is 0, and the ID of P4 is 3, etc.)
Now, we need to convert this offset into a player ID for the VT. First, divide the offset by 4. This is because each entry in the deaths table is 4 bytes, so adding 1 to the VT's player ID moves its DC location up by 4. (If you end up with a number that isn't an integer, give up; we can only deal with offsets divisible by 4.) If that worked, then add 166, and that's the player ID you should give your VT.
Now, this is rather abstract, so I'll give a concrete example here. Let's say that you don't want P1 to be able to research Zerg Flyer Attacks until he has defeated a certain boss. You'd set P1's Zerg Flyer Attacks maximum level to 0 in the upgrade settings window, and place one or more VTs. Next, you'd look in DatEdit and find the ID of Zerg Flyer Attacks, which happens to be 4. P1's player ID is 0, and (0*12 + 4)/4 is 3. This is an integer, so you're good to go. You'd make the VTs belong to P169, and have some unit attack then once P1 defeats the boss. (Note that VTs have 800 HP and Independent armor; you'll need to set their HP to 1, and even then it'll take anything other than a Zealot or Firebat two hits to explode it.)
When is this useful? Not often. Really, the only case I can see for it being useful is if you want an upgrade's availability to depend on some ingame event, and can't spare a resource. For example, Jack's Black Hat RPG had some enemies give Vespene gas when killed, which was used to upgrade armor. If you want something similar, but are using both minerals and gas, then this can be used. (Incidentally, there's a similar trick for techs, but I'm too sleepy to math right now. I've also found a method for removing technology under /very/ specific circumstances, which I'll be posting here once I do some more research into it.)
Post has been edited 5 time(s), last time on Aug 12 2012, 4:50 pm by Biophysicist.
None.