Skip to content

Commit

Permalink
Introduce WarheadArgs
Browse files Browse the repository at this point in the history
- Passes additional arguments to warheads on impact
- Uses that to reduce parameter count of DoImpact by 1
  • Loading branch information
reaperrr authored and teinarss committed Jan 21, 2020
1 parent fdc0a6e commit 6220d7e
Show file tree
Hide file tree
Showing 31 changed files with 127 additions and 44 deletions.
12 changes: 5 additions & 7 deletions OpenRA.Game/Effects/DelayedImpact.cs
Expand Up @@ -10,6 +10,7 @@
#endregion

using System.Collections.Generic;
using OpenRA.GameRules;
using OpenRA.Graphics;
using OpenRA.Traits;

Expand All @@ -18,26 +19,23 @@ namespace OpenRA.Effects
public class DelayedImpact : IEffect
{
readonly Target target;
readonly Actor firedBy;
readonly IEnumerable<int> damageModifiers;
readonly IWarhead wh;
readonly WarheadArgs args;

int delay;

public DelayedImpact(int delay, IWarhead wh, Target target, Actor firedBy, IEnumerable<int> damageModifiers)
public DelayedImpact(int delay, IWarhead wh, Target target, WarheadArgs args)
{
this.wh = wh;
this.delay = delay;

this.target = target;
this.firedBy = firedBy;
this.damageModifiers = damageModifiers;
this.args = args;
}

public void Tick(World world)
{
if (--delay <= 0)
world.AddFrameEndTask(w => { w.Remove(this); wh.DoImpact(target, firedBy, damageModifiers); });
world.AddFrameEndTask(w => { w.Remove(this); wh.DoImpact(target, args); });
}

public IEnumerable<IRenderable> Render(WorldRenderer wr) { yield break; }
Expand Down
43 changes: 40 additions & 3 deletions OpenRA.Game/GameRules/WeaponInfo.cs
Expand Up @@ -33,6 +33,27 @@ public class ProjectileArgs
public Target GuidedTarget;
}

public class WarheadArgs
{
public WeaponInfo Weapon;
public int[] DamageModifiers = { };
public WPos Source;
public Actor SourceActor;
public Target WeaponTarget;

public WarheadArgs(ProjectileArgs args)
{
Weapon = args.Weapon;
DamageModifiers = args.DamageModifiers;
Source = args.Source;
SourceActor = args.SourceActor;
WeaponTarget = args.GuidedTarget;
}

// Default empty constructor for callers that want to initialize fields themselves
public WarheadArgs() { }
}

public interface IProjectile : IEffect { }
public interface IProjectileInfo { IProjectile Create(ProjectileArgs args); }

Expand Down Expand Up @@ -177,17 +198,33 @@ public bool IsValidAgainst(FrozenActor victim, Actor firedBy)
}

/// <summary>Applies all the weapon's warheads to the target.</summary>
public void Impact(Target target, Actor firedBy, IEnumerable<int> damageModifiers)
public void Impact(Target target, WarheadArgs args)
{
var world = args.SourceActor.World;
foreach (var warhead in Warheads)
{
var wh = warhead; // force the closure to bind to the current warhead

if (wh.Delay > 0)
firedBy.World.AddFrameEndTask(w => w.Add(new DelayedImpact(wh.Delay, wh, target, firedBy, damageModifiers)));
world.AddFrameEndTask(w => w.Add(new DelayedImpact(wh.Delay, wh, target, args)));
else
wh.DoImpact(target, firedBy, damageModifiers);
wh.DoImpact(target, args);
}
}

/// <summary>Applies all the weapon's warheads to the target. Only use for projectile-less, special-case impacts.</summary>
public void Impact(Target target, Actor firedBy)
{
// The impact will happen immediately at target.CenterPosition.
var args = new WarheadArgs
{
Weapon = this,
Source = firedBy.CenterPosition,
SourceActor = firedBy,
WeaponTarget = target
};

Impact(target, args);
}
}
}
3 changes: 2 additions & 1 deletion OpenRA.Game/Traits/TraitsInterfaces.cs
Expand Up @@ -14,6 +14,7 @@
using System.Diagnostics.CodeAnalysis;
using OpenRA.Activities;
using OpenRA.FileSystem;
using OpenRA.GameRules;
using OpenRA.Graphics;
using OpenRA.Network;
using OpenRA.Primitives;
Expand Down Expand Up @@ -490,7 +491,7 @@ public interface IWarhead
int Delay { get; }
bool IsValidAgainst(Actor victim, Actor firedBy);
bool IsValidAgainst(FrozenActor victim, Actor firedBy);
void DoImpact(Target target, Actor firedBy, IEnumerable<int> damageModifiers);
void DoImpact(Target target, WarheadArgs args);
}

public interface IRulesetLoaded<TInfo> { void RulesetLoaded(Ruleset rules, TInfo info); }
Expand Down
11 changes: 10 additions & 1 deletion OpenRA.Mods.Cnc/Projectiles/IonCannon.cs
Expand Up @@ -45,9 +45,18 @@ public IonCannon(Player firedBy, WeaponInfo weapon, World world, WPos launchPos,
public void Tick(World world)
{
anim.Tick();

if (!impacted && weaponDelay-- <= 0)
{
weapon.Impact(target, firedBy.PlayerActor, Enumerable.Empty<int>());
var warheadArgs = new WarheadArgs
{
Weapon = weapon,
Source = target.CenterPosition,
SourceActor = firedBy.PlayerActor,
WeaponTarget = target
};

weapon.Impact(target, warheadArgs);
impacted = true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Cnc/Projectiles/TeslaZap.cs
Expand Up @@ -72,7 +72,7 @@ public void Tick(World world)
target = args.Weapon.TargetActorCenter ? args.GuidedTarget.CenterPosition : args.GuidedTarget.Positions.PositionClosestTo(args.Source);

if (damageDuration-- > 0)
args.Weapon.Impact(Target.FromPos(target), args.SourceActor, args.DamageModifiers);
args.Weapon.Impact(Target.FromPos(target), new WarheadArgs(args));
}

public IEnumerable<IRenderable> Render(WorldRenderer wr)
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Cnc/Traits/EnergyWall.cs
Expand Up @@ -90,7 +90,7 @@ void ITick.Tick(Actor self)
{
var blockers = self.World.ActorMap.GetActorsAt(loc).Where(a => !a.IsDead && a != self);
foreach (var blocker in blockers)
info.WeaponInfo.Impact(Target.FromActor(blocker), self, Enumerable.Empty<int>());
info.WeaponInfo.Impact(Target.FromActor(blocker), self);
}
}

Expand Down
4 changes: 2 additions & 2 deletions OpenRA.Mods.Cnc/Traits/MadTank.cs
Expand Up @@ -217,7 +217,7 @@ public override bool Tick(Actor self)
if (mad.info.ThumpDamageWeapon != null)
{
// Use .FromPos since this weapon needs to affect more than just the MadTank actor
mad.info.ThumpDamageWeaponInfo.Impact(Target.FromPos(self.CenterPosition), self, Enumerable.Empty<int>());
mad.info.ThumpDamageWeaponInfo.Impact(Target.FromPos(self.CenterPosition), self);
}

screenShaker.AddEffect(mad.info.ThumpShakeTime, self.CenterPosition, mad.info.ThumpShakeIntensity, mad.info.ThumpShakeMultiplier);
Expand All @@ -241,7 +241,7 @@ protected override void OnLastRun(Actor self)
if (mad.info.DetonationWeapon != null)
{
// Use .FromPos since this actor is killed. Cannot use Target.FromActor
mad.info.DetonationWeaponInfo.Impact(Target.FromPos(self.CenterPosition), self, Enumerable.Empty<int>());
mad.info.DetonationWeaponInfo.Impact(Target.FromPos(self.CenterPosition), self);
}
self.Kill(self, mad.info.DamageTypes);
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Activities/Air/FallToEarth.cs
Expand Up @@ -41,7 +41,7 @@ public override bool Tick(Actor self)
if (info.ExplosionWeapon != null)
{
// Use .FromPos since this actor is killed. Cannot use Target.FromActor
info.ExplosionWeapon.Impact(Target.FromPos(self.CenterPosition), self, Enumerable.Empty<int>());
info.ExplosionWeapon.Impact(Target.FromPos(self.CenterPosition), self);
}

self.Kill(self);
Expand Down
9 changes: 8 additions & 1 deletion OpenRA.Mods.Common/Projectiles/AreaBeam.cs
Expand Up @@ -11,6 +11,7 @@

using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.GameRules;
using OpenRA.Graphics;
using OpenRA.Mods.Common.Graphics;
Expand Down Expand Up @@ -231,7 +232,13 @@ public void Tick(World world)
foreach (var a in actors)
{
var adjustedModifiers = args.DamageModifiers.Append(GetFalloff((args.Source - a.CenterPosition).Length));
args.Weapon.Impact(Target.FromActor(a), args.SourceActor, adjustedModifiers);

var warheadArgs = new WarheadArgs(args)
{
DamageModifiers = adjustedModifiers.ToArray(),
};

args.Weapon.Impact(Target.FromActor(a), warheadArgs);
}
}

Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Projectiles/Bullet.cs
Expand Up @@ -280,7 +280,7 @@ void Explode(World world)

world.AddFrameEndTask(w => w.Remove(this));

args.Weapon.Impact(Target.FromPos(pos), args.SourceActor, args.DamageModifiers);
args.Weapon.Impact(Target.FromPos(pos), new WarheadArgs(args));
}

bool AnyValidTargetsInRadius(World world, WPos pos, WDist radius, Actor firedBy, bool checkTargetType)
Expand Down
3 changes: 2 additions & 1 deletion OpenRA.Mods.Common/Projectiles/GravityBomb.cs
Expand Up @@ -89,7 +89,8 @@ public void Tick(World world)
{
pos += new WVec(0, 0, args.PassiveTarget.Z - pos.Z);
world.AddFrameEndTask(w => w.Remove(this));
args.Weapon.Impact(Target.FromPos(pos), args.SourceActor, args.DamageModifiers);

args.Weapon.Impact(Target.FromPos(pos), new WarheadArgs(args));
}

if (anim != null)
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Projectiles/InstantHit.cs
Expand Up @@ -78,7 +78,7 @@ public void Tick(World world)
target = Target.FromPos(blockedPos);
}

args.Weapon.Impact(target, args.SourceActor, args.DamageModifiers);
args.Weapon.Impact(target, new WarheadArgs(args));
world.AddFrameEndTask(w => w.Remove(this));
}

Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Projectiles/LaserZap.cs
Expand Up @@ -165,7 +165,7 @@ public void Tick(World world)

if (ticks < info.DamageDuration && --interval <= 0)
{
args.Weapon.Impact(Target.FromPos(target), args.SourceActor, args.DamageModifiers);
args.Weapon.Impact(Target.FromPos(target), new WarheadArgs(args));
interval = info.DamageInterval;
}

Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Projectiles/Missile.cs
Expand Up @@ -891,7 +891,7 @@ void Explode(World world)
if (ticks <= info.Arm)
return;

args.Weapon.Impact(Target.FromPos(pos), args.SourceActor, args.DamageModifiers);
args.Weapon.Impact(Target.FromPos(pos), new WarheadArgs(args));
}

public IEnumerable<IRenderable> Render(WorldRenderer wr)
Expand Down
12 changes: 11 additions & 1 deletion OpenRA.Mods.Common/Projectiles/NukeLaunch.cs
Expand Up @@ -140,7 +140,17 @@ void Explode(World world, bool removeProjectile)
if (detonated)
return;

weapon.Impact(Target.FromPos(pos), firedBy.PlayerActor, Enumerable.Empty<int>());
var target = Target.FromPos(pos);
var warheadArgs = new WarheadArgs
{
Weapon = weapon,
Source = target.CenterPosition,
SourceActor = firedBy.PlayerActor,
WeaponTarget = target
};

weapon.Impact(target, warheadArgs);

world.WorldActor.Trait<ScreenShaker>().AddEffect(20, pos, 5);

foreach (var flash in world.WorldActor.TraitsImplementing<FlashPaletteEffect>())
Expand Down
4 changes: 2 additions & 2 deletions OpenRA.Mods.Common/Projectiles/Railgun.cs
Expand Up @@ -188,12 +188,12 @@ public void Tick(World world)
animationComplete = true;

if (!info.DamageActorsInLine)
args.Weapon.Impact(Target.FromPos(target), args.SourceActor, args.DamageModifiers);
args.Weapon.Impact(Target.FromPos(target), new WarheadArgs(args));
else
{
var actors = world.FindActorsOnLine(args.Source, target, info.BeamWidth);
foreach (var a in actors)
args.Weapon.Impact(Target.FromActor(a), args.SourceActor, args.DamageModifiers);
args.Weapon.Impact(Target.FromActor(a), new WarheadArgs(args));
}
}

Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Traits/Buildings/Bridge.cs
Expand Up @@ -376,7 +376,7 @@ public void Demolish(Actor saboteur, int direction)
self.World.AddFrameEndTask(w =>
{
// Use .FromPos since this actor is killed. Cannot use Target.FromActor
info.DemolishWeaponInfo.Impact(Target.FromPos(self.CenterPosition), saboteur, Enumerable.Empty<int>());
info.DemolishWeaponInfo.Impact(Target.FromPos(self.CenterPosition), saboteur);
self.Kill(saboteur);
});
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Traits/Buildings/GroundLevelBridge.cs
Expand Up @@ -116,7 +116,7 @@ void IBridgeSegment.Demolish(Actor saboteur)
return;
// Use .FromPos since this actor is dead. Cannot use Target.FromActor
Info.DemolishWeaponInfo.Impact(Target.FromPos(self.CenterPosition), saboteur, Enumerable.Empty<int>());
Info.DemolishWeaponInfo.Impact(Target.FromPos(self.CenterPosition), saboteur);
self.Kill(saboteur);
});
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Traits/Crates/ExplodeCrateAction.cs
Expand Up @@ -38,7 +38,7 @@ public ExplodeCrateAction(Actor self, ExplodeCrateActionInfo info)
public override void Activate(Actor collector)
{
var weapon = collector.World.Map.Rules.Weapons[info.Weapon.ToLowerInvariant()];
weapon.Impact(Target.FromPos(collector.CenterPosition), collector, Enumerable.Empty<int>());
weapon.Impact(Target.FromPos(collector.CenterPosition), collector);

base.Activate(collector);
}
Expand Down
4 changes: 2 additions & 2 deletions OpenRA.Mods.Common/Traits/Explodes.cs
Expand Up @@ -120,13 +120,13 @@ void INotifyKilled.Killed(Actor self, AttackInfo e)
{
var cells = buildingInfo.OccupiedTiles(self.Location);
foreach (var c in cells)
weapon.Impact(Target.FromPos(self.World.Map.CenterOfCell(c)), source, Enumerable.Empty<int>());
weapon.Impact(Target.FromPos(self.World.Map.CenterOfCell(c)), source);

return;
}

// Use .FromPos since this actor is killed. Cannot use Target.FromActor
weapon.Impact(Target.FromPos(self.CenterPosition), source, Enumerable.Empty<int>());
weapon.Impact(Target.FromPos(self.CenterPosition), source);
}

WeaponInfo ChooseWeaponForExplosion(Actor self)
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Traits/ExplosionOnDamageTransition.cs
Expand Up @@ -71,7 +71,7 @@ void INotifyDamageStateChanged.DamageStateChanged(Actor self, AttackInfo e)
triggered = true;

// Use .FromPos since the actor might have been killed, don't use Target.FromActor
info.WeaponInfo.Impact(Target.FromPos(self.CenterPosition), e.Attacker, Enumerable.Empty<int>());
info.WeaponInfo.Impact(Target.FromPos(self.CenterPosition), e.Attacker);
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion OpenRA.Mods.Common/Warheads/ChangeOwnerWarhead.cs
Expand Up @@ -10,6 +10,7 @@
#endregion

using System.Collections.Generic;
using OpenRA.GameRules;
using OpenRA.Mods.Common.Traits;
using OpenRA.Traits;

Expand All @@ -23,8 +24,9 @@ public class ChangeOwnerWarhead : Warhead

public readonly WDist Range = WDist.FromCells(1);

public override void DoImpact(Target target, Actor firedBy, IEnumerable<int> damageModifiers)
public override void DoImpact(Target target, WarheadArgs args)
{
var firedBy = args.SourceActor;
var actors = target.Type == TargetType.Actor ? new[] { target.Actor } :
firedBy.World.FindActorsInCircle(target.CenterPosition, Range);

Expand Down
4 changes: 3 additions & 1 deletion OpenRA.Mods.Common/Warheads/CreateEffectWarhead.cs
Expand Up @@ -11,6 +11,7 @@

using System.Collections.Generic;
using System.Linq;
using OpenRA.GameRules;
using OpenRA.Mods.Common.Effects;
using OpenRA.Mods.Common.Traits;
using OpenRA.Primitives;
Expand Down Expand Up @@ -103,8 +104,9 @@ public ImpactTargetType GetDirectHitTargetType(World world, CPos cell, WPos pos,
return invalidHit ? ImpactTargetType.InvalidActor : ImpactTargetType.NoActor;
}

public override void DoImpact(Target target, Actor firedBy, IEnumerable<int> damageModifiers)
public override void DoImpact(Target target, WarheadArgs args)
{
var firedBy = args.SourceActor;
if (!target.IsValidFor(firedBy))
return;

Expand Down

0 comments on commit 6220d7e

Please sign in to comment.