From 090c015b27f81de9bdbf7e7df36dc8dccfed2474 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Fri, 27 Jan 2017 18:35:50 +0100 Subject: [PATCH 1/6] Pass InstantHit target directly if inaccuracy is zero This is required to make the TargetDamage warhead deal damage only to a specific target. --- OpenRA.Mods.Common/Projectiles/InstantHit.cs | 32 +++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/OpenRA.Mods.Common/Projectiles/InstantHit.cs b/OpenRA.Mods.Common/Projectiles/InstantHit.cs index ee4eb1ae15..23c8465372 100644 --- a/OpenRA.Mods.Common/Projectiles/InstantHit.cs +++ b/OpenRA.Mods.Common/Projectiles/InstantHit.cs @@ -40,41 +40,37 @@ namespace OpenRA.Mods.Common.Projectiles readonly ProjectileArgs args; readonly InstantHitInfo info; - bool doneDamage; - WPos target; + Target target; WPos source; public InstantHit(InstantHitInfo info, ProjectileArgs args) { this.args = args; this.info = info; - target = args.PassiveTarget; source = args.Source; + + if (info.Inaccuracy.Length > 0) + { + var inaccuracy = Util.ApplyPercentageModifiers(info.Inaccuracy.Length, args.InaccuracyModifiers); + var maxOffset = inaccuracy * (args.PassiveTarget - source).Length / args.Weapon.Range.Length; + target = Target.FromPos(args.PassiveTarget + WVec.FromPDF(args.SourceActor.World.SharedRandom, 2) * maxOffset / 1024); + } + else + target = args.GuidedTarget; } public void Tick(World world) { // Check for blocking actors WPos blockedPos; - if (info.Blockable && BlocksProjectiles.AnyBlockingActorsBetween(world, source, target, + if (info.Blockable && BlocksProjectiles.AnyBlockingActorsBetween(world, source, target.CenterPosition, info.Width, info.TargetExtraSearchRadius, out blockedPos)) { - target = blockedPos; + target = Target.FromPos(blockedPos); } - if (info.Inaccuracy.Length > 0) - { - var inaccuracy = OpenRA.Mods.Common.Util.ApplyPercentageModifiers(info.Inaccuracy.Length, args.InaccuracyModifiers); - var maxOffset = inaccuracy * (target - source).Length / args.Weapon.Range.Length; - target += WVec.FromPDF(args.SourceActor.World.SharedRandom, 2) * maxOffset / 1024; - } - - if (!doneDamage) - { - args.Weapon.Impact(Target.FromPos(target), args.SourceActor, args.DamageModifiers); - doneDamage = true; - world.AddFrameEndTask(w => w.Remove(this)); - } + args.Weapon.Impact(target, args.SourceActor, args.DamageModifiers); + world.AddFrameEndTask(w => w.Remove(this)); } public IEnumerable Render(WorldRenderer wr) From a8f7b0e2debf0118aabd69fd862da57dce2b8f8e Mon Sep 17 00:00:00 2001 From: reaperrr Date: Wed, 25 Jan 2017 18:46:35 +0100 Subject: [PATCH 2/6] Add TargetDamageWarhead Only deals damage to the actor that was targeted by the carrying projectile. Currently only supported by InstantHit projectile. --- OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 1 + .../Warheads/TargetDamageWarhead.cs | 62 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 OpenRA.Mods.Common/Warheads/TargetDamageWarhead.cs diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 770fd27890..6cac6b07e1 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -574,6 +574,7 @@ + diff --git a/OpenRA.Mods.Common/Warheads/TargetDamageWarhead.cs b/OpenRA.Mods.Common/Warheads/TargetDamageWarhead.cs new file mode 100644 index 0000000000..751a261b31 --- /dev/null +++ b/OpenRA.Mods.Common/Warheads/TargetDamageWarhead.cs @@ -0,0 +1,62 @@ +#region Copyright & License Information +/* + * Copyright 2007-2017 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using System.Collections.Generic; +using OpenRA.GameRules; +using OpenRA.Mods.Common.Traits; +using OpenRA.Traits; + +namespace OpenRA.Mods.Common.Warheads +{ + public class TargetDamageWarhead : DamageWarhead + { + public override void DoImpact(Target target, Actor firedBy, IEnumerable damageModifiers) + { + // Damages a single actor, rather than a position. Only support by InstantHit for now. + // TODO: Add support for 'area of damage' + if (target.Type == TargetType.Actor) + DoImpact(target.Actor, firedBy, damageModifiers); + } + + public override void DoImpact(WPos pos, Actor firedBy, IEnumerable damageModifiers) + { + // For now this only displays debug overlay + // TODO: Add support for 'area of effect' / multiple targets + var world = firedBy.World; + var debugOverlayRange = new[] { WDist.Zero, new WDist(128) }; + + if (world.LocalPlayer != null) + { + var devMode = world.LocalPlayer.PlayerActor.TraitOrDefault(); + if (devMode != null && devMode.ShowCombatGeometry) + world.WorldActor.Trait().AddImpact(pos, debugOverlayRange, DebugOverlayColor); + } + } + + public override void DoImpact(Actor victim, Actor firedBy, IEnumerable damageModifiers) + { + if (!IsValidAgainst(victim, firedBy)) + return; + + var damage = Util.ApplyPercentageModifiers(Damage, damageModifiers.Append(DamageVersus(victim))); + victim.InflictDamage(firedBy, new Damage(damage, DamageTypes)); + + var world = firedBy.World; + if (world.LocalPlayer != null) + { + var debugOverlayRange = new[] { WDist.Zero, new WDist(128) }; + var devMode = world.LocalPlayer.PlayerActor.TraitOrDefault(); + if (devMode != null && devMode.ShowCombatGeometry) + world.WorldActor.Trait().AddImpact(victim.CenterPosition, debugOverlayRange, DebugOverlayColor); + } + } + } +} From ce5c11d4f0c1147aac77293805a5302d30fbd7f5 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Fri, 27 Jan 2017 18:58:39 +0100 Subject: [PATCH 3/6] Use inheritance and TargetDamageWH for TS heal weapons --- mods/ts/weapons/healweapons.yaml | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/mods/ts/weapons/healweapons.yaml b/mods/ts/weapons/healweapons.yaml index 6e82fbdff3..a6c2057c54 100644 --- a/mods/ts/weapons/healweapons.yaml +++ b/mods/ts/weapons/healweapons.yaml @@ -1,25 +1,21 @@ -Heal: +^HealWeapon: ReloadDelay: 80 Range: 2c849 Report: healer1.aud ValidTargets: Infantry - Projectile: Bullet - Speed: 1c682 - Warhead@1Dam: SpreadDamage + Projectile: InstantHit + Warhead@1Dam: TargetDamage DebugOverlayColor: 00FF00 - Spread: 213 Damage: -50 ValidTargets: Infantry +Heal: + Inherits: ^HealWeapon + Repair: - ReloadDelay: 80 + Inherits: ^HealWeapon Range: 1c819 Report: repair11.aud ValidTargets: Repair - Projectile: Bullet - Speed: 1c682 - Warhead@1Dam: SpreadDamage - DebugOverlayColor: 00FF00 - Spread: 213 - Damage: -50 + Warhead@1Dam: TargetDamage ValidTargets: Repair From 416857c6ea727ce0f28c520b0af0a5fe5ac729a4 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Fri, 27 Jan 2017 21:44:28 +0100 Subject: [PATCH 4/6] Various misc TS weapon fixes - Falloff of FireballLauncher and Bomb now more like in TS - Spread of FireballLauncher now matches TS - Spread of Bomb is now closer to TS (behaviour not entirely identical, because Spread was cell-based and had a ceiling at ~1.5 cells away from impact cell). - Bomb now destroys Tiberium like in TS - Visceroid now uses TargetDamage warhead to damage target directly - Veins now use TargetDamage warhead to damage target directly --- mods/ts/weapons/otherweapons.yaml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/mods/ts/weapons/otherweapons.yaml b/mods/ts/weapons/otherweapons.yaml index ce92133034..205957c3e8 100644 --- a/mods/ts/weapons/otherweapons.yaml +++ b/mods/ts/weapons/otherweapons.yaml @@ -9,7 +9,8 @@ FireballLauncher: Burst: 5 BurstDelay: 5 Warhead@1Dam: SpreadDamage - Spread: 341 + Spread: 288 + Falloff: 100, 50, 25, 12, 6, 3, 0 Damage: 25 Versus: None: 600 @@ -33,7 +34,8 @@ Bomb: Shadow: true Palette: ra Warhead@1Dam: SpreadDamage - Spread: 298 + Spread: 512 + Falloff: 100, 50, 25, 12, 6, 3, 0 Damage: 160 Versus: None: 200 @@ -55,6 +57,8 @@ Bomb: Warhead@4Smu: LeaveSmudge SmudgeType: MediumCrater InvalidTargets: Vehicle, Building, Wall + Warhead@5Res: DestroyResource + Size: 1 FiendShard: ReloadDelay: 30 @@ -86,7 +90,7 @@ SlimeAttack: Range: 1c384 Report: vicer1.aud Projectile: InstantHit - Warhead@1Dam: SpreadDamage + Warhead@1Dam: TargetDamage Damage: 100 Versus: Light: 60 @@ -96,8 +100,7 @@ SlimeAttack: Veins: ReloadDelay: 16 - Warhead@Damage: SpreadDamage - Spread: 42 + Warhead@Damage: TargetDamage Damage: 5 DamageTypes: BulletDeath Warhead@Effect: CreateEffect From c057acba7a95e422c2d5446583e773b1c7ed8f1f Mon Sep 17 00:00:00 2001 From: reaperrr Date: Mon, 30 Jan 2017 21:18:34 +0100 Subject: [PATCH 5/6] Use TargetDamage for D2k WormJaw --- mods/d2k/weapons/other.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mods/d2k/weapons/other.yaml b/mods/d2k/weapons/other.yaml index 184bacea9a..59c324dcf4 100644 --- a/mods/d2k/weapons/other.yaml +++ b/mods/d2k/weapons/other.yaml @@ -60,10 +60,8 @@ WormJaw: ReloadDelay: 10 InvalidTargets: Structure, Infantry Range: 1c512 - Warhead@1Dam: SpreadDamage # HACK: The warhead is needed for targeting + Warhead@1Dam: TargetDamage # HACK: The warhead is needed for targeting InvalidTargets: Structure, Infantry - Spread: 0 - Falloff: 0,0 OrniBomb: ReloadDelay: 25 From e2b0c5bce401266af78a2719dca5063065f441bd Mon Sep 17 00:00:00 2001 From: reaperrr Date: Mon, 30 Jan 2017 21:14:49 +0100 Subject: [PATCH 6/6] Return empty Enumerable immediately in InstantHit ...rather than allocating a compiler generated enumerable via 'yield'. --- OpenRA.Mods.Common/Projectiles/InstantHit.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenRA.Mods.Common/Projectiles/InstantHit.cs b/OpenRA.Mods.Common/Projectiles/InstantHit.cs index 23c8465372..309201abd7 100644 --- a/OpenRA.Mods.Common/Projectiles/InstantHit.cs +++ b/OpenRA.Mods.Common/Projectiles/InstantHit.cs @@ -10,6 +10,7 @@ #endregion using System.Collections.Generic; +using System.Linq; using OpenRA.GameRules; using OpenRA.Graphics; using OpenRA.Mods.Common.Traits; @@ -75,7 +76,7 @@ namespace OpenRA.Mods.Common.Projectiles public IEnumerable Render(WorldRenderer wr) { - yield break; + return Enumerable.Empty(); } } }