You can prevent attacking allies using orders:
When a player orders a unit to do something targeting another
object -> unit, destructable, item, it triggers this Event:
-
Events:
-
Unit - A unit Is issued an order targeting an object
You can then check to see which order it was. In your case you're looking for the attack order:
-
Conditions:
-
(Issued order) Equal to "attack"
Simply add a condition to check if the (Target of issued order) belongs to an ally of the (Ordered unit) if you want this to only work when attacking allies:
-
((Target unit of Issued order) belongs to an ally of (Owner of (Ordered unit)) Equal to True
Now it gets a little weird here. In order to interrupt an order you often have to use some strange workarounds:
-
Actions:
-
Set Variable TempPoint1 = Position of (Triggering unit)
-
Set Variable TempPoint2 = TempPoint1 offset by 0.0, 0.0
-
Unit - Order (Triggering unit) to Move to TempPoint2
-
Custom script: call RemoveLocation (udg_TempPoint1)
-
Custom script: call RemoveLocation (udg_TempPoint2)
The above trigger SHOULD interrupt the unit's order by telling it to move to it's own position. If that doesn't work then try adding a very slight offset like 0.01 to either the X/Y coordinates. I found that you can't just issue a "stop" order here for some reason. I don't think Pause/Stop/Unpause works either.
If you're ever confused about the names of these orders you can always Display a text message of the (Issued order). I recommend doing this in order to get a better understanding of how orders in Warcraft 3 work.