Add ImpactOrientation to WarheadArgs

Allows to pass the horizontal facing/yaw
and vertical angle/pitch of the carrier
projectile to warheads for further use.

Add ImpactPosition to WarheadArgs

InflictDamage doesn't pass the impact pos
directly, and the very point of WarheadArgs
is to avoid adding more and more arguments
to the warhead methods.
This commit is contained in:
reaperrr
2019-09-26 17:14:11 +02:00
committed by teinarss
parent bf7fecff10
commit 8513a83331
9 changed files with 80 additions and 10 deletions

View File

@@ -38,6 +38,8 @@ namespace OpenRA.GameRules
public WeaponInfo Weapon; public WeaponInfo Weapon;
public int[] DamageModifiers = { }; public int[] DamageModifiers = { };
public WPos? Source; public WPos? Source;
public WRot ImpactOrientation;
public WPos ImpactPosition;
public Actor SourceActor; public Actor SourceActor;
public Target WeaponTarget; public Target WeaponTarget;
@@ -45,6 +47,7 @@ namespace OpenRA.GameRules
{ {
Weapon = args.Weapon; Weapon = args.Weapon;
DamageModifiers = args.DamageModifiers; DamageModifiers = args.DamageModifiers;
ImpactPosition = args.PassiveTarget;
Source = args.Source; Source = args.Source;
SourceActor = args.SourceActor; SourceActor = args.SourceActor;
WeaponTarget = args.GuidedTarget; WeaponTarget = args.GuidedTarget;

View File

@@ -237,6 +237,12 @@ namespace OpenRA.Mods.Common.Projectiles
var warheadArgs = new WarheadArgs(args) var warheadArgs = new WarheadArgs(args)
{ {
ImpactOrientation = new WRot(WAngle.Zero, Util.GetVerticalAngle(args.Source, target), args.CurrentMuzzleFacing()),
// Calculating an impact position is bogus for line damage.
// FindActorsOnLine guarantees that the beam touches the target's HitShape,
// so we just assume a center hit to avoid bogus warhead recalculations.
ImpactPosition = a.CenterPosition,
DamageModifiers = adjustedModifiers.ToArray(), DamageModifiers = adjustedModifiers.ToArray(),
}; };

View File

@@ -122,7 +122,7 @@ namespace OpenRA.Mods.Common.Projectiles
ContrailRenderable contrail; ContrailRenderable contrail;
[Sync] [Sync]
WPos pos, target, source; WPos pos, lastPos, target, source;
int length; int length;
int ticks, smokeTicks; int ticks, smokeTicks;
@@ -200,7 +200,7 @@ namespace OpenRA.Mods.Common.Projectiles
if (anim != null) if (anim != null)
anim.Tick(); anim.Tick();
var lastPos = pos; lastPos = pos;
pos = WPos.LerpQuadratic(source, target, angle, ticks, length); pos = WPos.LerpQuadratic(source, target, angle, ticks, length);
// Check for walls or other blocking obstacles // Check for walls or other blocking obstacles
@@ -287,7 +287,13 @@ namespace OpenRA.Mods.Common.Projectiles
world.AddFrameEndTask(w => w.Remove(this)); world.AddFrameEndTask(w => w.Remove(this));
args.Weapon.Impact(Target.FromPos(pos), new WarheadArgs(args)); var warheadArgs = new WarheadArgs(args)
{
ImpactOrientation = new WRot(WAngle.Zero, Util.GetVerticalAngle(lastPos, pos), args.Facing),
ImpactPosition = pos,
};
args.Weapon.Impact(Target.FromPos(pos), warheadArgs);
} }
bool AnyValidTargetsInRadius(World world, WPos pos, WDist radius, Actor firedBy, bool checkTargetType) bool AnyValidTargetsInRadius(World world, WPos pos, WDist radius, Actor firedBy, bool checkTargetType)

View File

@@ -12,6 +12,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using OpenRA.GameRules; using OpenRA.GameRules;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Projectiles namespace OpenRA.Mods.Common.Projectiles
@@ -58,7 +59,7 @@ namespace OpenRA.Mods.Common.Projectiles
WVec velocity; WVec velocity;
[Sync] [Sync]
WPos pos; WPos pos, lastPos;
public GravityBomb(GravityBombInfo info, ProjectileArgs args) public GravityBomb(GravityBombInfo info, ProjectileArgs args)
{ {
@@ -82,6 +83,7 @@ namespace OpenRA.Mods.Common.Projectiles
public void Tick(World world) public void Tick(World world)
{ {
lastPos = pos;
pos += velocity; pos += velocity;
velocity += acceleration; velocity += acceleration;
@@ -90,7 +92,13 @@ namespace OpenRA.Mods.Common.Projectiles
pos += new WVec(0, 0, args.PassiveTarget.Z - pos.Z); pos += new WVec(0, 0, args.PassiveTarget.Z - pos.Z);
world.AddFrameEndTask(w => w.Remove(this)); world.AddFrameEndTask(w => w.Remove(this));
args.Weapon.Impact(Target.FromPos(pos), new WarheadArgs(args)); var warheadArgs = new WarheadArgs(args)
{
ImpactOrientation = new WRot(WAngle.Zero, Util.GetVerticalAngle(lastPos, pos), args.Facing),
ImpactPosition = pos,
};
args.Weapon.Impact(Target.FromPos(pos), warheadArgs);
} }
if (anim != null) if (anim != null)

View File

@@ -81,7 +81,13 @@ namespace OpenRA.Mods.Common.Projectiles
target = Target.FromPos(blockedPos); target = Target.FromPos(blockedPos);
} }
args.Weapon.Impact(target, new WarheadArgs(args)); var warheadArgs = new WarheadArgs(args)
{
ImpactOrientation = new WRot(WAngle.Zero, Util.GetVerticalAngle(args.Source, target.CenterPosition), args.Facing),
ImpactPosition = target.CenterPosition,
};
args.Weapon.Impact(target, warheadArgs);
world.AddFrameEndTask(w => w.Remove(this)); world.AddFrameEndTask(w => w.Remove(this));
} }

View File

@@ -168,7 +168,13 @@ namespace OpenRA.Mods.Common.Projectiles
if (ticks < info.DamageDuration && --interval <= 0) if (ticks < info.DamageDuration && --interval <= 0)
{ {
args.Weapon.Impact(Target.FromPos(target), new WarheadArgs(args)); var warheadArgs = new WarheadArgs(args)
{
ImpactOrientation = new WRot(WAngle.Zero, Util.GetVerticalAngle(source, target), args.CurrentMuzzleFacing()),
ImpactPosition = target,
};
args.Weapon.Impact(Target.FromPos(target), warheadArgs);
interval = info.DamageInterval; interval = info.DamageInterval;
} }

View File

@@ -895,7 +895,13 @@ namespace OpenRA.Mods.Common.Projectiles
if (ticks <= info.Arm) if (ticks <= info.Arm)
return; return;
args.Weapon.Impact(Target.FromPos(pos), new WarheadArgs(args)); var warheadArgs = new WarheadArgs(args)
{
ImpactOrientation = new WRot(WAngle.Zero, WAngle.FromFacing(vFacing), WAngle.FromFacing(hFacing)),
ImpactPosition = pos,
};
args.Weapon.Impact(Target.FromPos(pos), warheadArgs);
} }
public IEnumerable<IRenderable> Render(WorldRenderer wr) public IEnumerable<IRenderable> Render(WorldRenderer wr)

View File

@@ -199,12 +199,32 @@ namespace OpenRA.Mods.Common.Projectiles
animationComplete = true; animationComplete = true;
if (!info.DamageActorsInLine) if (!info.DamageActorsInLine)
args.Weapon.Impact(Target.FromPos(target), new WarheadArgs(args)); {
var warheadArgs = new WarheadArgs(args)
{
ImpactOrientation = new WRot(WAngle.Zero, Util.GetVerticalAngle(args.Source, target), args.Facing),
ImpactPosition = target,
};
args.Weapon.Impact(Target.FromPos(target), warheadArgs);
}
else else
{ {
var actors = world.FindActorsOnLine(args.Source, target, info.BeamWidth); var actors = world.FindActorsOnLine(args.Source, target, info.BeamWidth);
foreach (var a in actors) foreach (var a in actors)
args.Weapon.Impact(Target.FromActor(a), new WarheadArgs(args)); {
var warheadArgs = new WarheadArgs(args)
{
ImpactOrientation = new WRot(WAngle.Zero, Util.GetVerticalAngle(args.Source, target), args.Facing),
// Calculating an impact position is bogus for line damage.
// FindActorsOnLine guarantees that the beam touches the target's HitShape,
// so we just assume a center hit to avoid bogus warhead recalculations.
ImpactPosition = a.CenterPosition,
};
args.Weapon.Impact(Target.FromActor(a), warheadArgs);
}
} }
} }

View File

@@ -108,6 +108,15 @@ namespace OpenRA.Mods.Common
return WPos.Lerp(fromPos, toPos, 1, 2); return WPos.Lerp(fromPos, toPos, 1, 2);
} }
public static WAngle GetVerticalAngle(WPos source, WPos target)
{
var delta = target - source;
var horizontalDelta = delta.HorizontalLength;
var verticalVector = new WVec(-delta.Z, -horizontalDelta, 0);
return verticalVector.Yaw;
}
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> ts, MersenneTwister random) public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> ts, MersenneTwister random)
{ {
// Fisher-Yates // Fisher-Yates