StarCraft has no "a button was pressed" condition. So you make the button change something that is guaranteed to change, and read that instead. The thing you read is the unit production queue.
- 1Put a unit-production button in a free slot of the unit's button set. Copying the Barracks' Marine button and changing only the unit is the easy way.
- 2Scope the requirement to that unit - "Current unit is... Jim Raynor". Do not set it to always allowed.
- 3Every cycle, read the selected unit's queue, and run the skill if something is in it.
- 4Put the queue back, whether or not you read anything.
You do not need a unit loop. A production button can only be pressed on the unit you clicked, and selecting several units hides the button entirely - so the only thing to check is the one unit each player has selected.
foreach(player : EUDLoopPlayer("Human")) {
// 0x6284E8 + 48 * p 에 선택한 유닛의 구조오프셋이 들어 있습니다.
const ptr, epd = dwepdread_epd(EPD(0x6284E8) + 12 * player);
if (ptr > 0) {
if (MemoryEPD(epd + 0x64 / 4, Exactly, $U("Jim Raynor (Marine)"))) {
if (MemoryEPD(epd + 0x98 / 4, Exactly, $U("Terran Civilian") * 65536)) {
// 버튼이 눌렸습니다. 스킬은 여기에.
}
// 인식 여부와 상관없이 매번 되돌립니다.
dwwrite_epd(epd + 0x98 / 4, 0 + 228 * 65536);
dwwrite_epd(epd + 0x9C / 4, 228 + 228 * 65536);
}
}
}| +0x64 | The unit's own id - check you are holding the right unit first. |
|---|---|
| +0x98 | Queue slots 0 and 1, two bytes each. |
| +0x9C | Slots 2 and 3. |
| +0xA0 | Slot 4 - and the other two bytes are the unit's mana. Do not overwrite this one wholesale. |
| 228 | An empty slot. Not 0 - 228. |
Never empty the queue completely. Setting every slot to 228 is the same as cancelling production: the unit goes invisible and immobile, or the game crashes. So slot 0 always holds a Marine (0) and the press is detected in slot 1 - which is why the code above writes 0 + 228*65536 to 0x98.
The reset sitting outside the detection branch is deliberate too: the detection only matches when slot 0 already holds a Marine, so the reset has to have run at least once for anything to be detectable.
Do not do this on a building that can really produce. Real production happens when the advanced info has Building checked and Zerg unchecked (bar the Infested Command Center), or on a Reaver or Carrier and their heroes. Detect a queue on a Barracks and an invisible unit really is created; it eats a unit index, clearing the queue does not remove it, and eventually you get "cannot" errors. This is item #28 on the crash list.
- If the unit can really produce, use an upgrade button and detect the upgrade instead.
- If you must use the queue anyway, the reset has to kill that unit too - with KillUnit, not KillUnitAt.
