• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[Trigger] How to add offset?

Status
Not open for further replies.
Level 22
Joined
Jul 25, 2009
Messages
3,091
  • Order Squad Leader
    • Events
      • Unit - A unit Is issued an order with no target
      • Unit - A unit Is issued an order targeting an object
      • Unit - A unit Is issued an order targeting a point
    • Conditions
      • ((Ordered unit) is A structure) Equal to False
      • GLeader[(Custom value of (Ordered unit))] Equal to (Ordered unit)
      • (Custom value of (Ordered unit)) Not equal to 0
    • Actions
      • Trigger - Turn off (This trigger)
      • Set GGroup[1] = (Units in (Playable map area) matching (((Custom value of (Matching unit)) Equal to (Custom value of (Ordered unit))) and (((Matching unit) is A structure) Equal to False)))
      • Custom script: call GroupImmediateOrder( udg_GGroup[1], OrderId2String(GetIssuedOrderId()) )
      • Custom script: call GroupTargetOrder( udg_GGroup[1], OrderId2String(GetIssuedOrderId()), GetOrderTargetUnit() )
      • Custom script: call GroupTargetOrder( udg_GGroup[1], OrderId2String(GetIssuedOrderId()), GetOrderTargetDestructable() )
      • Custom script: call GroupTargetOrder( udg_GGroup[1], OrderId2String(GetIssuedOrderId()), GetOrderTargetItem() )
      • Set GPoint[1] = (Target point of issued order)
      • Custom script: call GroupPointOrderLoc( udg_GGroup[1], OrderId2String(GetIssuedOrderId()), udg_GPoint[1] )
      • Custom script: call RemoveLocation(udg_GPoint[1])
      • Custom script: call DestroyGroup(udg_GGroup[1])
      • Trigger - Turn on (This trigger)
I want to add an offset to the location each individual unit is ordered to so that they don't clump at a single location. Because they are locust units they do not use formations built into wc3's engine.

Is this possible to do while still being lightweight ie not causing lag.
 
From what I know locus units are not considered in (Units in (Playable map area) and (Units in Range).
But (Units Owned by player) does consider them. It's still like you said they do not care about formation, so you have to calc it yourself and order unit for unit.
You should think about using constant squad groups. It will be alot faster then recalcing the squads for every order with Units owned/ by in Rect/ in Range which can take alot of performance with many units on your map and players spamming orders.

Now to the actual formation trigger.

define rowsize and distance between units
calc the angle between old SquadCenterPostion and new SquadCenter.
old squad center is the sum of x/y divided by the unit count​
calc the row angle its angle +90°
Now Enum the units and positionate them around the target point.

This Trigger will not generate formations the same way as warcraft 3 formation, but still quite an acceptable row formation, but it is bad if the group exceeds an large amount of units (and the units are not locust).
(Some optimazions would be to refill the group in opposite order, if the group is ordered to do a over 90° turn)
  • Order Squad rows
    • Events
      • Unit - Paladin 0013 <gen> Is issued an order targeting a point
    • Conditions
    • Actions
      • -------- In this trigger, group is an constant group contanting the squad. --------
      • Set TargetLoc = (Target point of issued order)
      • -------- The amont of units in one row. --------
      • Set Formation_RowSize = 4
      • -------- Distance between units --------
      • Set FormationOffset_PerUnit = 128.00
      • -------- ---- --------
      • -------- automatic calced start offset --------
      • -------- ---- --------
      • Set FormationOffset_Start = (FormationOffset_PerUnit x (Real((Formation_RowSize / 2))))
      • Set FormationOffset_Start = (0.00 - FormationOffset_Start)
      • -------- ---- --------
      • -------- calc old Center --------
      • -------- Sum up x/y then divide it by the amount of units thats the center --------
      • -------- ---- --------
      • Set X = 0.00
      • Set Y = 0.00
      • Set UnitCount = 0
      • Unit Group - Pick every unit in Group and do (Actions)
        • Loop - Actions
          • Set Loc = (Position of (Picked unit))
          • Set X = (X + (X of Loc))
          • Set Y = (Y + (Y of Loc))
          • Set UnitCount = (UnitCount + 1)
          • Custom script: call RemoveLocation(udg_Loc)
      • Set X = (X / (Real(UnitCount)))
      • Set Y = (Y / (Real(UnitCount)))
      • Set OldLoc = (Point(X, Y))
      • Set AngleOrder = (Angle from OldLoc to TargetLoc)
      • Custom script: call RemoveLocation(udg_OldLoc)
      • -------- ---- --------
      • -------- Defines the Normal of the angle ordered --------
      • -------- ---- --------
      • Set AngleOrder_Right = (AngleOrder + 90.00)
      • -------- Now order the units to proper positions --------
      • Set Count = 0
      • Set FormationOffset_Current = FormationOffset_Start
      • Unit Group - Pick every unit in Group and do (Actions)
        • Loop - Actions
          • Set Loc = (TargetLoc offset by FormationOffset_Current towards AngleOrder_Right degrees)
          • Unit - Order (Picked unit) to Move To Loc
          • Custom script: call RemoveLocation(udg_Loc)
          • Set Count = (Count + 1)
          • -------- Repos RowCenter --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Count Equal to Formation_RowSize
            • Then - Actions
              • -------- Next row bill be placed behind the current one. --------
              • Set Loc = (TargetLoc offset by (0.00 - FormationOffset_PerUnit) towards AngleOrder degrees)
              • Set FormationOffset_Current = FormationOffset_Start
              • Custom script: call RemoveLocation(udg_TargetLoc)
              • Set TargetLoc = Loc
              • Set Count = 0
            • Else - Actions
              • Set FormationOffset_Current = (FormationOffset_Current + FormationOffset_PerUnit)
        • Custom script: call RemoveLocation(udg_TargetLoc)
Some other approach would be to precalc offsets and member indexes, but that would requier a better datastructur for the members of a squad, which you don't use.
for such one checkout: Group Control
 

Attachments

  • Formation.w3x
    24.9 KB · Views: 59
Level 22
Joined
Jul 25, 2009
Messages
3,091
I'd prefer to keep my current system, I do have a data structure for members of the squad somewhat, but the calculation is somewhat simple without precalculating. You have a 360 degree radius divided by the number of units in a squad to find your symmetrical angles (assuming all I want is a circle around the leader) out of 6 members it would be 72 degrees. 360/#ofUnitsinGroup.

My question was more along the lines of how to do I this all using roughly the same custom script I'm already using because I need formations to work for smart orders.

Edit: I can also add constant groups related to each squad pretty easily ie GGroup[TempInt] to reference the exact group instead of using the temp group I am now, I was just lazy.
 
Status
Not open for further replies.
Top