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 int[] DamageModifiers = { };
public WPos? Source;
public WRot ImpactOrientation;
public WPos ImpactPosition;
public Actor SourceActor;
public Target WeaponTarget;
@@ -45,6 +47,7 @@ namespace OpenRA.GameRules
{
Weapon = args.Weapon;
DamageModifiers = args.DamageModifiers;
ImpactPosition = args.PassiveTarget;
Source = args.Source;
SourceActor = args.SourceActor;
WeaponTarget = args.GuidedTarget;

View File

@@ -237,6 +237,12 @@ namespace OpenRA.Mods.Common.Projectiles
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(),
};

View File

@@ -122,7 +122,7 @@ namespace OpenRA.Mods.Common.Projectiles
ContrailRenderable contrail;
[Sync]
WPos pos, target, source;
WPos pos, lastPos, target, source;
int length;
int ticks, smokeTicks;
@@ -200,7 +200,7 @@ namespace OpenRA.Mods.Common.Projectiles
if (anim != null)
anim.Tick();
var lastPos = pos;
lastPos = pos;
pos = WPos.LerpQuadratic(source, target, angle, ticks, length);
// Check for walls or other blocking obstacles
@@ -287,7 +287,13 @@ namespace OpenRA.Mods.Common.Projectiles
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)

View File

@@ -12,6 +12,7 @@
using System.Collections.Generic;
using OpenRA.GameRules;
using OpenRA.Graphics;
using OpenRA.Primitives;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Projectiles
@@ -58,7 +59,7 @@ namespace OpenRA.Mods.Common.Projectiles
WVec velocity;
[Sync]
WPos pos;
WPos pos, lastPos;
public GravityBomb(GravityBombInfo info, ProjectileArgs args)
{
@@ -82,6 +83,7 @@ namespace OpenRA.Mods.Common.Projectiles
public void Tick(World world)
{
lastPos = pos;
pos += velocity;
velocity += acceleration;
@@ -90,7 +92,13 @@ namespace OpenRA.Mods.Common.Projectiles
pos += new WVec(0, 0, args.PassiveTarget.Z - pos.Z);
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)

View File

@@ -81,7 +81,13 @@ namespace OpenRA.Mods.Common.Projectiles
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));
}

View File

@@ -168,7 +168,13 @@ namespace OpenRA.Mods.Common.Projectiles
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;
}

View File

@@ -895,7 +895,13 @@ namespace OpenRA.Mods.Common.Projectiles
if (ticks <= info.Arm)
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)

View File

@@ -199,12 +199,32 @@ namespace OpenRA.Mods.Common.Projectiles
animationComplete = true;
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
{
var actors = world.FindActorsOnLine(args.Source, target, info.BeamWidth);
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);
}
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)
{
// Fisher-Yates