Skip to content

Commit d406b5c

Browse files
committed
fix attackorderpower
1 parent 0cabedf commit d406b5c

1 file changed

Lines changed: 139 additions & 10 deletions

File tree

OpenRA.Mods.Cnc/Traits/SupportPowers/AttackOrderPower.cs

Lines changed: 139 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@ protected override void Created(Actor self)
7070

7171
void INotifyBurstComplete.FiredBurst(Actor self, in Target target, Armament a)
7272
{
73-
self.World.IssueOrder(new Order("Stop", self, false));
73+
if (attack != null)
74+
attack.OnStopOrder(self);
75+
else
76+
self.CancelActivity();
7477
}
7578
}
7679

@@ -99,12 +102,116 @@ public SelectAttackPowerTarget(Actor self, string order, SupportPowerManager man
99102
cursorBlocked = cursor + "-blocked";
100103
}
101104

105+
bool TryGetRanges(World world, AttackBase attackTrait, out WDist minRange, out WDist maxRange)
106+
{
107+
minRange = WDist.Zero;
108+
maxRange = WDist.Zero;
109+
110+
if (attackTrait == null)
111+
return false;
112+
113+
try
114+
{
115+
minRange = attackTrait.GetMinimumRange();
116+
maxRange = attackTrait.GetMaximumRange();
117+
return true;
118+
}
119+
catch
120+
{
121+
world.CancelInputMode();
122+
return false;
123+
}
124+
}
125+
126+
AttackBase ResolveAttack(World world)
127+
{
128+
if (attack != null && !attack.IsTraitDisabled)
129+
return attack;
130+
131+
if (instance == null)
132+
{
133+
world.CancelInputMode();
134+
return null;
135+
}
136+
137+
foreach (var power in instance.Instances)
138+
{
139+
var actor = power?.Self;
140+
if (actor == null || !actor.IsInWorld)
141+
continue;
142+
143+
var attackTrait = actor.TraitsImplementing<AttackBase>()
144+
.FirstOrDefault(a => a != null && !a.IsTraitDisabled);
145+
146+
if (attackTrait != null)
147+
return attackTrait;
148+
}
149+
150+
world.CancelInputMode();
151+
return null;
152+
}
153+
154+
bool TryGetActiveInstances(World world,
155+
out SupportPowerInstance powerInstance,
156+
out IReadOnlyCollection<Actor> activeActors)
157+
{
158+
powerInstance = instance;
159+
activeActors = null;
160+
if (powerInstance == null)
161+
{
162+
world.CancelInputMode();
163+
return false;
164+
}
165+
166+
var active = powerInstance.Instances?
167+
.Where(i => i != null
168+
&& !i.IsTraitPaused
169+
&& i.Self != null
170+
&& !i.Self.IsDead
171+
&& i.Self.IsInWorld
172+
&& i.Self.OccupiesSpace != null)
173+
.Select(i => i.Self)
174+
.ToList();
175+
if (active == null || active.Count == 0)
176+
return false;
177+
178+
activeActors = active;
179+
return true;
180+
}
181+
102182
bool IsValidTarget(World world, CPos cell)
103183
{
184+
var currentAttack = ResolveAttack(world);
185+
if (currentAttack == null)
186+
return false;
187+
188+
if (!TryGetRanges(world, currentAttack, out _, out var maxRange))
189+
return false;
190+
191+
if (!TryGetActiveInstances(world, out _, out var activeActors))
192+
return false;
193+
104194
var pos = world.Map.CenterOfCell(cell);
105-
var range = attack.GetMaximumRange().LengthSquared;
195+
var range = maxRange.LengthSquared;
196+
197+
if (!world.Map.Contains(cell))
198+
return false;
106199

107-
return world.Map.Contains(cell) && instance.Instances.Any(a => !a.IsTraitPaused && (a.Self.CenterPosition - pos).HorizontalLengthSquared < range);
200+
foreach (var a in activeActors)
201+
{
202+
if (a == null || a.World == null || !a.IsInWorld)
203+
continue;
204+
205+
var occupies = a.OccupiesSpace;
206+
if (occupies == null)
207+
continue;
208+
209+
var center = occupies.CenterPosition;
210+
if ((center - pos).HorizontalLengthSquared < range)
211+
return true;
212+
}
213+
214+
return false;
108215
}
109216

110217
protected override IEnumerable<Order> OrderInner(World world, CPos cell, int2 worldPixel, MouseInput mi)
@@ -120,7 +227,7 @@ protected override IEnumerable<Order> OrderInner(World world, CPos cell, int2 wo
120227
protected override void Tick(World world)
121228
{
122229
// Cancel the OG if we can't use the power
123-
if (!manager.Powers.TryGetValue(order, out var p) || !p.Active || !p.Ready)
230+
if (!manager.Powers.TryGetValue(order, out var p) || !p.Active || !p.Ready || instance == null)
124231
world.CancelInputMode();
125232
}
126233

@@ -129,21 +236,43 @@ protected override void Tick(World world)
129236

130237
protected override IEnumerable<IRenderable> RenderAnnotations(WorldRenderer wr, World world)
131238
{
132-
var info = instance.Info as AttackOrderPowerInfo;
133-
foreach (var a in instance.Instances.Where(i => !i.IsTraitPaused))
239+
var currentAttack = ResolveAttack(world);
240+
if (currentAttack == null)
241+
yield break;
242+
243+
if (!TryGetRanges(world, currentAttack, out var minRange, out var maxRange))
244+
yield break;
245+
246+
if (!TryGetActiveInstances(world, out var currentInstance, out var activeActors))
247+
yield break;
248+
249+
var info = currentInstance.Info as AttackOrderPowerInfo;
250+
if (info == null)
251+
yield break;
252+
253+
foreach (var actor in activeActors)
134254
{
255+
if (actor == null || !actor.IsInWorld || actor.World == null)
256+
continue;
257+
258+
var occupies = actor.OccupiesSpace;
259+
if (occupies == null)
260+
continue;
261+
262+
var center = occupies.CenterPosition;
263+
135264
yield return new RangeCircleAnnotationRenderable(
136-
a.Self.CenterPosition,
137-
attack.GetMinimumRange(),
265+
center,
266+
minRange,
138267
0,
139268
info.CircleColor,
140269
info.CircleWidth,
141270
info.CircleBorderColor,
142271
info.CircleBorderWidth);
143272

144273
yield return new RangeCircleAnnotationRenderable(
145-
a.Self.CenterPosition,
146-
attack.GetMaximumRange(),
274+
center,
275+
maxRange,
147276
0,
148277
info.CircleColor,
149278
info.CircleWidth,

0 commit comments

Comments
 (0)