From e6c0a0060497e3000c7a3af543146c9ce0a17af1 Mon Sep 17 00:00:00 2001 From: Chicken man Date: Fri, 4 Apr 2014 21:06:40 -0400 Subject: [PATCH] Closes #4463. Added Shrapnel, as well as variable velocity and arc for bullets --- OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj | 5 +- OpenRA.Mods.D2k/ThrowsShrapnel.cs | 79 ++++++++++++++++++++++++++ OpenRA.Mods.RA/Effects/Bullet.cs | 30 +++++++--- mods/d2k/rules/defaults.yaml | 4 ++ mods/d2k/rules/structures.yaml | 4 ++ mods/d2k/weapons.yaml | 25 +++++++- 6 files changed, 135 insertions(+), 12 deletions(-) create mode 100644 OpenRA.Mods.D2k/ThrowsShrapnel.cs diff --git a/OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj b/OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj index 8a730f4322..4a22d8c937 100644 --- a/OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj +++ b/OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj @@ -76,6 +76,7 @@ + @@ -120,7 +121,5 @@ cd "$(SolutionDir)" true - - - + \ No newline at end of file diff --git a/OpenRA.Mods.D2k/ThrowsShrapnel.cs b/OpenRA.Mods.D2k/ThrowsShrapnel.cs new file mode 100644 index 0000000000..62d6821133 --- /dev/null +++ b/OpenRA.Mods.D2k/ThrowsShrapnel.cs @@ -0,0 +1,79 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 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. For more information, + * see COPYING. + */ +#endregion + +using OpenRA.GameRules; +using OpenRA.FileFormats; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using OpenRA.Traits; + +namespace OpenRA.Mods.D2k +{ + public class ThrowsShrapnelInfo : ITraitInfo + { + [WeaponReference] + public string[] Weapons = { }; + public int[] Pieces = { 3, 10 }; + public WRange[] Range = { WRange.FromCells(2), WRange.FromCells(5) }; + public object Create(ActorInitializer actor) { return new ThrowsShrapnel(this); } + } + + class ThrowsShrapnel : INotifyKilled + { + readonly ThrowsShrapnelInfo info; + + public ThrowsShrapnel(ThrowsShrapnelInfo info) + { + this.info = info; + } + + public void Killed(Actor self, AttackInfo attack) + { + foreach (var name in info.Weapons) + { + var wep = Rules.Weapons[name]; + var pieces = self.World.SharedRandom.Next(info.Pieces[0], info.Pieces[1]); + var range = self.World.SharedRandom.Next(info.Range[0].Range, info.Range[1].Range); + + for (var i = 0; pieces > i; i++) + { + var rotation = WRot.FromFacing(self.World.SharedRandom.Next(1024)); + var args = new ProjectileArgs + { + Weapon = wep, + Facing = self.World.SharedRandom.Next(-1,255), + FirepowerModifier = self.TraitsImplementing() + .Select(a => a.GetFirepowerModifier()) + .Product(), + + Source = self.CenterPosition, + SourceActor = self, + PassiveTarget = self.CenterPosition + new WVec(range, 0, 0).Rotate(rotation) + }; + + self.World.AddFrameEndTask(x => + { + if (args.Weapon.Projectile != null) + { + var projectile = args.Weapon.Projectile.Create(args); + if (projectile != null) + self.World.Add(projectile); + + if (args.Weapon.Report != null && args.Weapon.Report.Any()) + Sound.Play(args.Weapon.Report.Random(self.World.SharedRandom), self.CenterPosition); + } + }); + } + } + } + } +} diff --git a/OpenRA.Mods.RA/Effects/Bullet.cs b/OpenRA.Mods.RA/Effects/Bullet.cs index 28ef4a1139..9c323ecd37 100755 --- a/OpenRA.Mods.RA/Effects/Bullet.cs +++ b/OpenRA.Mods.RA/Effects/Bullet.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2013 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2014 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. For more information, @@ -22,8 +22,8 @@ namespace OpenRA.Mods.RA.Effects { public class BulletInfo : IProjectileInfo { - [Desc("Projectile speed in WRange / tick")] - public readonly WRange Speed = new WRange(17); + [Desc("Projectile speed in WRange / tick, two values indicate variable velocity")] + public readonly WRange[] Speed = { new WRange(17) }; public readonly string Trail = null; [Desc("Maximum offset at the maximum range")] public readonly WRange Inaccuracy = WRange.Zero; @@ -31,7 +31,8 @@ namespace OpenRA.Mods.RA.Effects [Desc("Check for whether an actor with Wall: trait blocks fire")] public readonly bool High = false; public readonly bool Shadow = false; - public readonly WAngle Angle = WAngle.Zero; + [Desc("Arc in WAngles, two values indicate variable arc.")] + public readonly WAngle[] Angle = { WAngle.Zero }; public readonly int TrailInterval = 2; public readonly int TrailDelay = 1; public readonly int ContrailLength = 0; @@ -46,6 +47,8 @@ namespace OpenRA.Mods.RA.Effects { readonly BulletInfo info; readonly ProjectileArgs args; + [Sync] readonly WAngle angle; + [Sync] readonly WRange speed; ContrailRenderable trail; Animation anim; @@ -63,6 +66,17 @@ namespace OpenRA.Mods.RA.Effects this.args = args; this.pos = args.Source; + if (info.Angle.Length > 1 && info.Speed.Length > 1) + { + angle = new WAngle(args.SourceActor.World.SharedRandom.Next(info.Angle[0].Angle, info.Angle[1].Angle)); + speed = new WRange(args.SourceActor.World.SharedRandom.Next(info.Speed[0].Range, info.Speed[1].Range)); + } + else + { + angle = info.Angle[0]; + speed = info.Speed[0]; + } + target = args.PassiveTarget; if (info.Inaccuracy.Range > 0) { @@ -71,7 +85,7 @@ namespace OpenRA.Mods.RA.Effects } facing = Traits.Util.GetFacing(target - pos, 0); - length = Math.Max((target - pos).Length / info.Speed.Range, 1); + length = Math.Max((target - pos).Length / speed.Range, 1); if (info.Image != null) { @@ -91,7 +105,7 @@ namespace OpenRA.Mods.RA.Effects int GetEffectiveFacing() { var at = (float)ticks / (length - 1); - var attitude = info.Angle.Tan() * (1 - 2 * at) / (4 * 1024); + var attitude = angle.Tan() * (1 - 2 * at) / (4 * 1024); var u = (facing % 128) / 128f; var scale = 512 * u * (1 - u); @@ -106,11 +120,11 @@ namespace OpenRA.Mods.RA.Effects if (anim != null) anim.Tick(); - pos = WPos.LerpQuadratic(args.Source, target, info.Angle, ticks, length); + pos = WPos.LerpQuadratic(args.Source, target, angle, ticks, length); if (info.Trail != null && --smokeTicks < 0) { - var delayedPos = WPos.LerpQuadratic(args.Source, target, info.Angle, ticks - info.TrailDelay, length); + var delayedPos = WPos.LerpQuadratic(args.Source, target, angle, ticks - info.TrailDelay, length); world.AddFrameEndTask(w => w.Add(new Smoke(w, delayedPos, info.Trail))); smokeTicks = info.TrailInterval; } diff --git a/mods/d2k/rules/defaults.yaml b/mods/d2k/rules/defaults.yaml index f33eb7b2f2..55a17f8556 100644 --- a/mods/d2k/rules/defaults.yaml +++ b/mods/d2k/rules/defaults.yaml @@ -266,3 +266,7 @@ LuaScriptEvents: Demolishable: DamagedWithoutFoundation: + ThrowsShrapnel: + Weapons: shrapnel + Pieces: 3, 7 + Range: 2c0, 5c0 diff --git a/mods/d2k/rules/structures.yaml b/mods/d2k/rules/structures.yaml index 5e80875e68..d7228271e6 100644 --- a/mods/d2k/rules/structures.yaml +++ b/mods/d2k/rules/structures.yaml @@ -428,6 +428,10 @@ CONCRETEB: Sellable: Guardable: BodyOrientation: + ThrowsShrapnel: + Weapons: shrapnel + Pieces: 3, 7 + Range: 2c0, 5c0 WALL: Inherits: ^WALL diff --git a/mods/d2k/weapons.yaml b/mods/d2k/weapons.yaml index 848cfdb788..2ecbf5039a 100644 --- a/mods/d2k/weapons.yaml +++ b/mods/d2k/weapons.yaml @@ -624,4 +624,27 @@ Grenade: Weathering: ROF: 100 Warhead: - Damage: 5 \ No newline at end of file + Damage: 5 + +Shrapnel: + ROF: 60 + Range: 4c0 + Report: + Projectile: Bullet + Speed: 50, 125 + High: true + Angle: 91, 264 + Inaccuracy: 416 + Image: bombs + Warhead: + Spread: 192 + Versus: + None: 50% + Wood: 100% + Light: 25% + Heavy: 5% + Explosion: med_explosion + InfDeath: 3 + SmudgeType: SandCrater + Damage: 60 + ImpactSound: EXPLLG5.WAV \ No newline at end of file