Skip to content

Commit

Permalink
Merge pull request #159 from dnqbob/Fix-supcrash
Browse files Browse the repository at this point in the history
SupportPower: Check Level before using Level and get crashed
  • Loading branch information
MustaphaTR authored Jun 19, 2024
2 parents bc4e000 + 470001d commit f284646
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 33 deletions.
6 changes: 5 additions & 1 deletion OpenRA.Mods.AS/Effects/AirstrikePowerASEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ public class AirstrikePowerASEffect : IEffect

public AirstrikePowerASEffect(World world, Player p, WPos pos, IEnumerable<Actor> planes, AirstrikePowerAS power, AirstrikePowerASInfo info)
{
var level = power.GetLevel();
if (level == 0)
return;

this.info = info;
this.world = world;
owner = p;
Expand All @@ -49,7 +53,7 @@ public AirstrikePowerASEffect(World world, Player p, WPos pos, IEnumerable<Actor
info.BeaconPaletteIsPlayerPalette,
info.BeaconPalette,
info.BeaconImage,
info.BeaconPosters.First(bp => bp.Key == power.GetLevel()).Value,
info.BeaconPosters.First(bp => bp.Key == level).Value,
info.BeaconPosterPalette,
info.BeaconSequence,
info.ArrowSequence,
Expand Down
12 changes: 8 additions & 4 deletions OpenRA.Mods.AS/Traits/SupportPowers/AirstrikePowerRV.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,15 @@ public override void Activate(Actor self, Order order, SupportPowerManager manag

public Actor[] SendAirstrike(Actor self, WPos target, WAngle? facing = null)
{
var level = GetLevel();
if (level == 0)
return Array.Empty<Actor>();

var aircraft = new List<Actor>();
if (!facing.HasValue)
facing = new WAngle(1024 * self.World.SharedRandom.Next(info.QuantizedFacings) / info.QuantizedFacings);

var altitude = self.World.Map.Rules.Actors[info.UnitTypes.First(ut => ut.Key == GetLevel()).Value].TraitInfo<AircraftInfo>().CruiseAltitude.Length;
var altitude = self.World.Map.Rules.Actors[info.UnitTypes.First(ut => ut.Key == level).Value].TraitInfo<AircraftInfo>().CruiseAltitude.Length;
var attackRotation = WRot.FromYaw(facing.Value);
var delta = new WVec(0, -1024, 0).Rotate(attackRotation);
target += new WVec(0, 0, altitude);
Expand Down Expand Up @@ -139,7 +143,7 @@ void OnRemovedFromWorld(Actor a)
}

// Create the actors immediately so they can be returned
var squadSize = info.SquadSizes.First(ss => ss.Key == GetLevel()).Value;
var squadSize = info.SquadSizes.First(ss => ss.Key == level).Value;
for (var i = -squadSize / 2; i <= squadSize / 2; i++)
{
// Even-sized squads skip the lead plane
Expand All @@ -150,7 +154,7 @@ void OnRemovedFromWorld(Actor a)
var so = info.SquadOffset;
var spawnOffset = new WVec(i * so.Y, -Math.Abs(i) * so.X, 0).Rotate(attackRotation);
var targetOffset = new WVec(i * so.Y, 0, 0).Rotate(attackRotation);
var a = self.World.CreateActor(false, info.UnitTypes.First(ut => ut.Key == GetLevel()).Value, new TypeDictionary
var a = self.World.CreateActor(false, info.UnitTypes.First(ut => ut.Key == level).Value, new TypeDictionary
{
new CenterPositionInit(startEdge + spawnOffset),
new OwnerInit(self.Owner),
Expand All @@ -171,7 +175,7 @@ void OnRemovedFromWorld(Actor a)
{
PlayLaunchSounds();
var effect = new AirstrikePowerRVEffect(self.World, self.Owner, target, startEdge, finishEdge, attackRotation, altitude, GetLevel(), aircraft.ToArray(), this, info);
var effect = new AirstrikePowerRVEffect(self.World, self.Owner, target, startEdge, finishEdge, attackRotation, altitude, level, aircraft.ToArray(), this, info);
self.World.Add(effect);
});

Expand Down
16 changes: 12 additions & 4 deletions OpenRA.Mods.AS/Traits/SupportPowers/DetonateWeaponPower.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ public DetonateWeaponPower(Actor self, DetonateWeaponPowerInfo info)

public override void Activate(Actor self, Order order, SupportPowerManager manager)
{
var level = GetLevel();
if (level == 0)
return;

base.Activate(self, order, manager);
PlayLaunchSounds();

Expand All @@ -114,7 +118,7 @@ public override void Activate(Actor self, Order order, SupportPowerManager manag
}

var targetPosition = order.Target.CenterPosition + new WVec(WDist.Zero, WDist.Zero, Info.AirburstAltitude);
var weapon = Info.WeaponInfos.First(wi => wi.Key == GetLevel()).Value;
var weapon = Info.WeaponInfos.First(wi => wi.Key == level).Value;
self.World.AddFrameEndTask(w => w.Add(new DelayedAction(Info.ActivationDelay, () => self.World.AddFrameEndTask(w => weapon.Impact(Target.FromPos(targetPosition), self)))));

if (Info.CameraRange != WDist.Zero)
Expand All @@ -135,7 +139,7 @@ public override void Activate(Actor self, Order order, SupportPowerManager manag
Info.BeaconPaletteIsPlayerPalette,
Info.BeaconPalette,
Info.BeaconImage,
Info.BeaconPosters.First(bp => bp.Key == GetLevel()).Value,
Info.BeaconPosters.First(bp => bp.Key == level).Value,
Info.BeaconPosterPalette,
Info.BeaconSequence,
Info.ArrowSequence,
Expand Down Expand Up @@ -206,17 +210,21 @@ protected override void Tick(World world)

protected override IEnumerable<IRenderable> RenderAnnotations(WorldRenderer wr, World world)
{
var level = power.GetLevel();
if (level == 0)
yield break;

var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos);

if (power.Info.TargetCircleRanges == null || power.Info.TargetCircleRanges.Count <= 0 || power.GetLevel() == 0)
if (power.Info.TargetCircleRanges == null || power.Info.TargetCircleRanges.Count <= 0 || level == 0)
{
yield break;

Check failure on line 221 in OpenRA.Mods.AS/Traits/SupportPowers/DetonateWeaponPower.cs

View workflow job for this annotation

GitHub Actions / Windows (.NET 6.0)

Remove redundant statement. (http://pihrt.net/roslynator/analyzer?id=RCS1134)

Check failure on line 221 in OpenRA.Mods.AS/Traits/SupportPowers/DetonateWeaponPower.cs

View workflow job for this annotation

GitHub Actions / Windows (.NET 6.0)

Remove redundant statement. (http://pihrt.net/roslynator/analyzer?id=RCS1134)

Check failure on line 221 in OpenRA.Mods.AS/Traits/SupportPowers/DetonateWeaponPower.cs

View workflow job for this annotation

GitHub Actions / Linux (.NET 6.0)

Remove redundant statement. (http://pihrt.net/roslynator/analyzer?id=RCS1134)

Check failure on line 221 in OpenRA.Mods.AS/Traits/SupportPowers/DetonateWeaponPower.cs

View workflow job for this annotation

GitHub Actions / Linux (.NET 6.0)

Remove redundant statement. (http://pihrt.net/roslynator/analyzer?id=RCS1134)
}
else
{
yield return new RangeCircleAnnotationRenderable(
world.Map.CenterOfCell(xy),
power.Info.TargetCircleRanges[power.GetLevel()],
power.Info.TargetCircleRanges[level],
0,
power.Info.TargetCircleUsePlayerColor ? power.Self.Owner.Color : power.Info.TargetCircleColor,
power.Info.TargetCircleWidth,
Expand Down
6 changes: 5 additions & 1 deletion OpenRA.Mods.AS/Traits/SupportPowers/FireArmamentPower.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,17 @@ void Activation(Actor self, Order order)

if (FireArmamentPowerInfo.DisplayBeacon)
{
var level = GetLevel();
if (level == 0)
return;

var beacon = new Beacon(
order.Player,
target.CenterPosition,
FireArmamentPowerInfo.BeaconPaletteIsPlayerPalette,
FireArmamentPowerInfo.BeaconPalette,
FireArmamentPowerInfo.BeaconImage,
FireArmamentPowerInfo.BeaconPosters.First(bp => bp.Key == GetLevel()).Value,
FireArmamentPowerInfo.BeaconPosters.First(bp => bp.Key == level).Value,
FireArmamentPowerInfo.BeaconPosterPalette,
FireArmamentPowerInfo.BeaconSequence,
FireArmamentPowerInfo.ArrowSequence,
Expand Down
34 changes: 28 additions & 6 deletions OpenRA.Mods.AS/Traits/SupportPowers/RA2ChronoshiftPower.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ public override void SelectTarget(Actor self, string order, SupportPowerManager

public override void Activate(Actor self, Order order, SupportPowerManager manager)
{
var level = GetLevel();
if (level == 0)
return;

base.Activate(self, order, manager);

var info = (RA2ChronoshiftPowerInfo)Info;
Expand Down Expand Up @@ -161,7 +165,6 @@ public override void Activate(Actor self, Order order, SupportPowerManager manag

var targetDelta = self.World.Map.CellContaining(order.Target.CenterPosition) - order.ExtraLocation;

var level = GetLevel();
var teleportCells = CellsMatching(self.World.Map.CellContaining(order.Target.CenterPosition), footprints.First(f => f.Key == level).Value, dimensions.First(d => d.Key == level).Value).ToList();

foreach (var target in UnitsInRange(order.ExtraLocation))
Expand All @@ -179,9 +182,13 @@ public override void Activate(Actor self, Order order, SupportPowerManager manag

public IEnumerable<Actor> UnitsInRange(CPos xy)
{
var units = new HashSet<Actor>();
var level = GetLevel();
if (level == 0)
return units;

var tiles = CellsMatching(xy, footprints.First(f => f.Key == level).Value, dimensions.First(d => d.Key == level).Value);
var units = new HashSet<Actor>();

foreach (var t in tiles)
units.UnionWith(Self.World.ActorMap.GetActorsAt(t));

Expand All @@ -190,10 +197,13 @@ public IEnumerable<Actor> UnitsInRange(CPos xy)

public bool SimilarTerrain(CPos xy, CPos sourceLocation)
{
var level = GetLevel();
if (level == 0)
return false;

if (!Self.Owner.Shroud.IsExplored(xy))
return false;

var level = GetLevel();
var footprint = footprints.First(f => f.Key == level).Value;
var dimension = dimensions.First(f => f.Key == level).Value;
var sourceTiles = CellsMatching(xy, footprint, dimension);
Expand Down Expand Up @@ -285,8 +295,12 @@ protected override IEnumerable<IRenderable> RenderAnnotations(WorldRenderer wr,

protected override IEnumerable<IRenderable> Render(WorldRenderer wr, World world)
{
var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
var level = power.GetLevel();
if (level == 0)
yield break;

var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos);

var tiles = power.CellsMatching(xy, footprints.First(f => f.Key == level).Value, dimensions.First(d => d.Key == level).Value);
var palette = wr.Palette(((RA2ChronoshiftPowerInfo)power.Info).TargetOverlayPalette);
foreach (var t in tiles)
Expand Down Expand Up @@ -398,12 +412,16 @@ protected override void Tick(World world)

protected override IEnumerable<IRenderable> RenderAboveShroud(WorldRenderer wr, World world)
{
var level = power.GetLevel();
if (level == 0)
yield break;

var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
var palette = wr.Palette(power.Info.IconPalette);

// Destination tiles
var delta = xy - sourceLocation;
var level = power.GetLevel();

foreach (var t in power.CellsMatching(sourceLocation, footprints.First(f => f.Key == level).Value, dimensions.First(d => d.Key == level).Value))
{
var isValid = manager.Self.Owner.Shroud.IsExplored(t + delta);
Expand Down Expand Up @@ -450,6 +468,10 @@ protected override IEnumerable<IRenderable> RenderAnnotations(WorldRenderer wr,

protected override IEnumerable<IRenderable> Render(WorldRenderer wr, World world)
{
var level = power.GetLevel();
if (level == 0)
yield break;

if (overlay != null)
{
var powerInfo = (RA2ChronoshiftPowerInfo)power.Info;
Expand All @@ -459,7 +481,7 @@ protected override IEnumerable<IRenderable> Render(WorldRenderer wr, World world

// Source tiles
var palette = wr.Palette(power.Info.IconPalette);
var level = power.GetLevel();

foreach (var t in power.CellsMatching(sourceLocation, footprints.First(f => f.Key == level).Value, dimensions.First(d => d.Key == level).Value))
yield return new SpriteRenderable(sourceTile, wr.World.Map.CenterOfCell(t), WVec.Zero, -511, palette, 1f, sourceAlpha, float3.Ones, TintModifiers.IgnoreWorldTint, true);
}
Expand Down
12 changes: 8 additions & 4 deletions OpenRA.Mods.Common/Traits/SupportPowers/AirstrikePower.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,15 @@ public override void Activate(Actor self, Order order, SupportPowerManager manag

public Actor[] SendAirstrike(Actor self, WPos target, WAngle? facing = null)
{
var level = GetLevel();
if (level == 0)
return Array.Empty<Actor>();

var aircraft = new List<Actor>();
if (!facing.HasValue)
facing = new WAngle(1024 * self.World.SharedRandom.Next(info.QuantizedFacings) / info.QuantizedFacings);

var altitude = self.World.Map.Rules.Actors[info.UnitTypes.First(ut => ut.Key == GetLevel()).Value].TraitInfo<AircraftInfo>().CruiseAltitude.Length;
var altitude = self.World.Map.Rules.Actors[info.UnitTypes.First(ut => ut.Key == level).Value].TraitInfo<AircraftInfo>().CruiseAltitude.Length;
var attackRotation = WRot.FromYaw(facing.Value);
var delta = new WVec(0, -1024, 0).Rotate(attackRotation);
target += new WVec(0, 0, altitude);
Expand Down Expand Up @@ -124,7 +128,7 @@ void OnRemovedFromWorld(Actor a)
}

// Create the actors immediately so they can be returned
var squadSize = info.SquadSizes.First(ss => ss.Key == GetLevel()).Value;
var squadSize = info.SquadSizes.First(ss => ss.Key == level).Value;
for (var i = -squadSize / 2; i <= squadSize / 2; i++)
{
// Even-sized squads skip the lead plane
Expand All @@ -135,7 +139,7 @@ void OnRemovedFromWorld(Actor a)
var so = info.SquadOffset;
var spawnOffset = new WVec(i * so.Y, -Math.Abs(i) * so.X, 0).Rotate(attackRotation);
var targetOffset = new WVec(i * so.Y, 0, 0).Rotate(attackRotation);
var a = self.World.CreateActor(false, info.UnitTypes.First(ut => ut.Key == GetLevel()).Value, new TypeDictionary
var a = self.World.CreateActor(false, info.UnitTypes.First(ut => ut.Key == level).Value, new TypeDictionary
{
new CenterPositionInit(startEdge + spawnOffset),
new OwnerInit(self.Owner),
Expand Down Expand Up @@ -187,7 +191,7 @@ void OnRemovedFromWorld(Actor a)
Info.BeaconPaletteIsPlayerPalette,
Info.BeaconPalette,
Info.BeaconImage,
Info.BeaconPosters.First(bp => bp.Key == GetLevel()).Value,
Info.BeaconPosters.First(bp => bp.Key == level).Value,
Info.BeaconPosterPalette,
Info.BeaconSequence,
Info.ArrowSequence,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ public override void SelectTarget(Actor self, string order, SupportPowerManager

public override void Activate(Actor self, Order order, SupportPowerManager manager)
{
var level = GetLevel();
if (level == 0)
return;

base.Activate(self, order, manager);
PlayLaunchSounds();

Expand All @@ -100,15 +104,18 @@ public override void Activate(Actor self, Order order, SupportPowerManager manag

foreach (var a in UnitsInRange(self.World.Map.CellContaining(position)))
a.TraitsImplementing<ExternalCondition>()
.FirstOrDefault(t => t.Info.Condition == info.Conditions.First(c => c.Key == GetLevel()).Value && t.CanGrantCondition(self))
?.GrantCondition(a, self, info.Durations.First(d => d.Key == GetLevel()).Value);
.FirstOrDefault(t => t.Info.Condition == info.Conditions.First(c => c.Key == level).Value && t.CanGrantCondition(self))
?.GrantCondition(a, self, info.Durations.First(d => d.Key == level).Value);
}

public IEnumerable<Actor> UnitsInRange(CPos xy)
{
var units = new HashSet<Actor>();
var level = GetLevel();
if (level == 0)
return units;

var tiles = CellsMatching(xy, footprints.First(f => f.Key == level).Value, info.Dimensions.First(d => d.Key == level).Value);
var units = new HashSet<Actor>();
foreach (var t in tiles)
foreach (var a in Self.World.ActorMap.GetActorsAt(t))
units.Add(a);
Expand Down Expand Up @@ -183,10 +190,13 @@ protected override IEnumerable<IRenderable> RenderAnnotations(WorldRenderer wr,

protected override IEnumerable<IRenderable> Render(WorldRenderer wr, World world)
{
var level = power.GetLevel();
if (level == 0)
yield break;

var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
var pal = wr.Palette(TileSet.TerrainPaletteInternalName);

var level = power.GetLevel();
foreach (var t in power.CellsMatching(xy, footprints.First(f => f.Key == level).Value, dimensions.First(d => d.Key == level).Value))
yield return new SpriteRenderable(tile, wr.World.Map.CenterOfCell(t), WVec.Zero, -511, pal, 1f, alpha, float3.Ones, TintModifiers.IgnoreWorldTint, true);
}
Expand Down
8 changes: 6 additions & 2 deletions OpenRA.Mods.Common/Traits/SupportPowers/NukePower.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,15 @@ public override void Activate(Actor self, Order order, SupportPowerManager manag

public void Activate(Actor self, WPos targetPosition)
{
var level = GetLevel();
if (level == 0)
return;

var palette = Info.IsPlayerPalette ? Info.MissilePalette + self.Owner.InternalName : Info.MissilePalette;
var skipAscent = Info.SkipAscent || body == null;
var launchPos = skipAscent ? WPos.Zero : self.CenterPosition + body.LocalToWorld(Info.SpawnOffset);

var weaponInfo = Info.WeaponInfos.First(wi => wi.Key == GetLevel()).Value;
var weaponInfo = Info.WeaponInfos.First(wi => wi.Key == level).Value;
var missile = new NukeLaunch(self.Owner, Info.MissileImage, weaponInfo, palette, Info.MissileUp, Info.MissileDown,
launchPos,
targetPosition, Info.DetonationAltitude, Info.RemoveMissileOnDetonation,
Expand All @@ -203,7 +207,7 @@ public void Activate(Actor self, WPos targetPosition)
Info.BeaconPaletteIsPlayerPalette,
Info.BeaconPalette,
Info.BeaconImage,
Info.BeaconPosters.First(bp => bp.Key == GetLevel()).Value,
Info.BeaconPosters.First(bp => bp.Key == level).Value,
Info.BeaconPosterPalette,
Info.BeaconSequence,
Info.ArrowSequence,
Expand Down
12 changes: 8 additions & 4 deletions OpenRA.Mods.Common/Traits/SupportPowers/ParatroopersPower.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,14 @@ public override void Activate(Actor self, Order order, SupportPowerManager manag
var aircraft = new List<Actor>();
var units = new List<Actor>();

var level = GetLevel();
if (level == 0)
return (aircraft.ToArray(), units.ToArray());

if (!facing.HasValue)
facing = new WAngle(1024 * self.World.SharedRandom.Next(info.QuantizedFacings) / info.QuantizedFacings);

var utLower = info.UnitTypes.First(ut => ut.Key == GetLevel()).Value.ToLowerInvariant();
var utLower = info.UnitTypes.First(ut => ut.Key == level).Value.ToLowerInvariant();
if (!self.World.Map.Rules.Actors.TryGetValue(utLower, out var unitType))
throw new YamlException($"Actors ruleset does not include the entry '{utLower}'");

Expand Down Expand Up @@ -156,7 +160,7 @@ void OnRemovedFromWorld(Actor a)
}

// Create the actors immediately so they can be returned
var squadSize = info.SquadSizes.First(ss => ss.Key == GetLevel()).Value;
var squadSize = info.SquadSizes.First(ss => ss.Key == level).Value;
for (var i = -squadSize / 2; i <= squadSize / 2; i++)
{
// Even-sized squads skip the lead plane
Expand All @@ -175,7 +179,7 @@ void OnRemovedFromWorld(Actor a)
}));
}

var dropItems = info.DropItems.First(di => di.Key == GetLevel()).Value;
var dropItems = info.DropItems.First(di => di.Key == level).Value;
foreach (var p in dropItems)
{
units.Add(self.World.CreateActor(false, p.ToLowerInvariant(), new TypeDictionary
Expand Down Expand Up @@ -240,7 +244,7 @@ void OnRemovedFromWorld(Actor a)
Info.BeaconPaletteIsPlayerPalette,
Info.BeaconPalette,
Info.BeaconImage,
Info.BeaconPosters.First(bp => bp.Key == GetLevel()).Value,
Info.BeaconPosters.First(bp => bp.Key == level).Value,
Info.BeaconPosterPalette,
Info.BeaconSequence,
Info.ArrowSequence,
Expand Down
Loading

0 comments on commit f284646

Please sign in to comment.