From 8513a83331a8cf9ff24b5bf51b870a927261f98f Mon Sep 17 00:00:00 2001 From: reaperrr Date: Thu, 26 Sep 2019 17:14:11 +0200 Subject: [PATCH] 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. --- OpenRA.Game/GameRules/WeaponInfo.cs | 3 +++ OpenRA.Mods.Common/Projectiles/AreaBeam.cs | 6 +++++ OpenRA.Mods.Common/Projectiles/Bullet.cs | 12 +++++++--- OpenRA.Mods.Common/Projectiles/GravityBomb.cs | 12 ++++++++-- OpenRA.Mods.Common/Projectiles/InstantHit.cs | 8 ++++++- OpenRA.Mods.Common/Projectiles/LaserZap.cs | 8 ++++++- OpenRA.Mods.Common/Projectiles/Missile.cs | 8 ++++++- OpenRA.Mods.Common/Projectiles/Railgun.cs | 24 +++++++++++++++++-- OpenRA.Mods.Common/Util.cs | 9 +++++++ 9 files changed, 80 insertions(+), 10 deletions(-) diff --git a/OpenRA.Game/GameRules/WeaponInfo.cs b/OpenRA.Game/GameRules/WeaponInfo.cs index 49ad380049..f2f67e79cc 100644 --- a/OpenRA.Game/GameRules/WeaponInfo.cs +++ b/OpenRA.Game/GameRules/WeaponInfo.cs @@ -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; diff --git a/OpenRA.Mods.Common/Projectiles/AreaBeam.cs b/OpenRA.Mods.Common/Projectiles/AreaBeam.cs index 1cb2084f2f..728286ffc5 100644 --- a/OpenRA.Mods.Common/Projectiles/AreaBeam.cs +++ b/OpenRA.Mods.Common/Projectiles/AreaBeam.cs @@ -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(), }; diff --git a/OpenRA.Mods.Common/Projectiles/Bullet.cs b/OpenRA.Mods.Common/Projectiles/Bullet.cs index 29fc755d7f..0470215d8e 100644 --- a/OpenRA.Mods.Common/Projectiles/Bullet.cs +++ b/OpenRA.Mods.Common/Projectiles/Bullet.cs @@ -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) diff --git a/OpenRA.Mods.Common/Projectiles/GravityBomb.cs b/OpenRA.Mods.Common/Projectiles/GravityBomb.cs index 9deb1b905f..d18a694e4e 100644 --- a/OpenRA.Mods.Common/Projectiles/GravityBomb.cs +++ b/OpenRA.Mods.Common/Projectiles/GravityBomb.cs @@ -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) diff --git a/OpenRA.Mods.Common/Projectiles/InstantHit.cs b/OpenRA.Mods.Common/Projectiles/InstantHit.cs index 7624ef6522..a9b9651c70 100644 --- a/OpenRA.Mods.Common/Projectiles/InstantHit.cs +++ b/OpenRA.Mods.Common/Projectiles/InstantHit.cs @@ -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)); } diff --git a/OpenRA.Mods.Common/Projectiles/LaserZap.cs b/OpenRA.Mods.Common/Projectiles/LaserZap.cs index 09c12589e1..f199ea215d 100644 --- a/OpenRA.Mods.Common/Projectiles/LaserZap.cs +++ b/OpenRA.Mods.Common/Projectiles/LaserZap.cs @@ -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; } diff --git a/OpenRA.Mods.Common/Projectiles/Missile.cs b/OpenRA.Mods.Common/Projectiles/Missile.cs index b7f2be2a8d..8346cedb25 100644 --- a/OpenRA.Mods.Common/Projectiles/Missile.cs +++ b/OpenRA.Mods.Common/Projectiles/Missile.cs @@ -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 Render(WorldRenderer wr) diff --git a/OpenRA.Mods.Common/Projectiles/Railgun.cs b/OpenRA.Mods.Common/Projectiles/Railgun.cs index f8bb6e8fa1..1c95e3615f 100644 --- a/OpenRA.Mods.Common/Projectiles/Railgun.cs +++ b/OpenRA.Mods.Common/Projectiles/Railgun.cs @@ -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); + } } } diff --git a/OpenRA.Mods.Common/Util.cs b/OpenRA.Mods.Common/Util.cs index 1acb1d2f9f..2a130fd589 100644 --- a/OpenRA.Mods.Common/Util.cs +++ b/OpenRA.Mods.Common/Util.cs @@ -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 Shuffle(this IEnumerable ts, MersenneTwister random) { // Fisher-Yates