SCRMaps
/
Sign in

Making one unit attack exactly that

Neither the trigger actions nor the AI scripts have “this unit attacks that unit”. Five struct fields do.

13 min read

A computer standing helpless in front of a wall-in is an old weakness, and the stock answer is Send All Units on Random Suicide Missions - they attack regardless of aggro. But it is every unit, map-wide, workers included, exactly as the name says. Fine for a handful of mobs; unusable for a computer with an economy.

After every attempt to scope it failed, what is left is the struct. The measured minimum is five fields.

The five fields a forced attack needs
0x4D order0x0A, Attack Unit.
0x4E orderState1.
0x58 orderTargetPosThe target's position.
0x5C orderTargetThe target's pointer.
0x7C autoTargetUnitThe target's pointer again.

Do not leave the last one out. 0x5C is the order and 0x7C is what the unit picked for itself, so writing only the first lets the unit's own acquisition replace it with whatever is nearest and wander off. And re-issue it every cycle for as long as you want the attack held.

u.order = 0x0A;  u.orderState = 1;
u.orderTargetPos = target.pos;
u.orderTarget    = target;
u.autoTargetUnit = target;
With CUnit no offset appears at all.

Do not run a full unit loop every frame to find them. That is the same source's conclusion - EUDLoopUnit every frame lags badly. Classify each unit once as it appears with EUDLoopNewUnit, into an array or a UnitGroup, and let the per-frame work loop only that list.

If your map uses triggers and AI scripts together there is one more thing. An AI script takes no arguments and returns no values, so maps that need both halves to talk build a protocol out of hero unit creations: the trigger side creates a particular hero to mean “the Factory is done”, the script watches for it, and each side removes the other's signal once it has read it.

It is crude and it is the only channel there is. Write down which unit means what - the map that did this kept the protocol as a separate document. One unremoved signal unit is a deadlock with no error message.

AI-script limits to know before planning around them
expandYou cannot say which worker takes the expansion, so a computer running two races may send the wrong one.
Add-onsAfter an expansion is taken, add-ons stop being buildable through build or player_need. Nobody has explained why.

Which is why that map placed buildings through the struct and used the AI script only for unit production, upgrades and research. It is not a choice between the two but a division of what each can actually do.

Before reaching for the struct, three things people build whole systems for and that are one field or one action each.

Three one-field answers
Hitting what is in front without chasingSet that unit type's AI Attack Unit order to 19, Tower: it engages what comes into range and does not follow when the target leaves. Order 100, Watch Target, is the near miss - it tracks and never attacks.
A computer fleeing an invincible unitYou cannot stop it. A computer unit flees anything it cannot counter-attack with its own weapon - invincible, cloaked, or out of its weapon's domain. Workers and buildings are the exceptions. Either drop the invincibility or re-issue the attack order the moment it flees.
Cancelling every targeted order at onceThe stock SetAllyStatus action does it - see below.

The last one is the interesting one. SetAllyStatus walks that player's units and cancels an order when the order matches that unit type's AI attack order and the order's target belongs to an ally. Which can be used like this:

  1. 1Write 1, allied, over the whole alliance table for that player.
  2. 2Set the unit type's AI attack order to the order you want cancelled.
  3. 3Set CurrentPlayer to that player and run SetAllyStatus.
  4. 4Restore the alliance table and the AI attack order.

It only works on orders that have a target. StarCraft assumes an attack order always has a target unit and reads it unconditionally, so pointing this at a targetless order crashes.

When a computer unit castsThree ways to read the struct wrongHolding on to many units
Sign in to track your progress