diff --git a/OpenRA.Mods.Common/Effects/AreaBeam.cs b/OpenRA.Mods.Common/Effects/AreaBeam.cs index 98d974da6d..ec0ddfcadb 100644 --- a/OpenRA.Mods.Common/Effects/AreaBeam.cs +++ b/OpenRA.Mods.Common/Effects/AreaBeam.cs @@ -35,6 +35,9 @@ namespace OpenRA.Mods.Common.Effects [Desc("The width of the beam.")] public readonly WDist Width = new WDist(512); + [Desc("The shape of the beam. Accepts values Cylindrical or Flat.")] + public readonly BeamRenderableShape Shape = BeamRenderableShape.Cylindrical; + [Desc("How far beyond the target the projectile keeps on travelling.")] public readonly WDist BeyondTargetRange = new WDist(0); @@ -190,9 +193,7 @@ namespace OpenRA.Mods.Common.Effects { if (!IsBeamComplete && info.RenderBeam && !(wr.World.FogObscures(tailPos) && wr.World.FogObscures(headPos))) { - float width, y, z; - wr.ScreenVectorComponents(new WVec(info.Width, WDist.Zero, WDist.Zero), out width, out y, out z); - var beamRender = new BeamRenderable(headPos, 0, tailPos - headPos, width, color); + var beamRender = new BeamRenderable(headPos, 0, tailPos - headPos, info.Shape, info.Width, color); return new[] { (IRenderable)beamRender }; } diff --git a/OpenRA.Mods.Common/Effects/LaserZap.cs b/OpenRA.Mods.Common/Effects/LaserZap.cs index f59be66867..11d949be35 100644 --- a/OpenRA.Mods.Common/Effects/LaserZap.cs +++ b/OpenRA.Mods.Common/Effects/LaserZap.cs @@ -21,7 +21,11 @@ namespace OpenRA.Mods.Common.Effects [Desc("Not a sprite, but an engine effect.")] class LaserZapInfo : IProjectileInfo { - public readonly int BeamWidth = 2; + [Desc("The width of the zap.")] + public readonly WDist Width = new WDist(86); + + [Desc("The shape of the beam. Accepts values Cylindrical or Flat.")] + public readonly BeamRenderableShape Shape = BeamRenderableShape.Cylindrical; public readonly int BeamDuration = 10; @@ -98,7 +102,7 @@ namespace OpenRA.Mods.Common.Effects if (ticks < info.BeamDuration) { var rc = Color.FromArgb((info.BeamDuration - ticks) * 255 / info.BeamDuration, color); - yield return new BeamRenderable(args.Source, 0, target - args.Source, info.BeamWidth, rc); + yield return new BeamRenderable(args.Source, 0, target - args.Source, info.Shape, info.Width, rc); } if (hitanim != null) diff --git a/OpenRA.Mods.Common/Graphics/BeamRenderable.cs b/OpenRA.Mods.Common/Graphics/BeamRenderable.cs index faeb2a24d3..118119ab54 100644 --- a/OpenRA.Mods.Common/Graphics/BeamRenderable.cs +++ b/OpenRA.Mods.Common/Graphics/BeamRenderable.cs @@ -13,21 +13,24 @@ using OpenRA.Graphics; namespace OpenRA.Mods.Common.Graphics { + public enum BeamRenderableShape { Cylindrical, Flat } public struct BeamRenderable : IRenderable, IFinalizedRenderable { readonly WPos pos; readonly int zOffset; readonly WVec length; + readonly BeamRenderableShape shape; + readonly WDist width; readonly Color color; - readonly float width; - public BeamRenderable(WPos pos, int zOffset, WVec length, float width, Color color) + public BeamRenderable(WPos pos, int zOffset, WVec length, BeamRenderableShape shape, WDist width, Color color) { this.pos = pos; this.zOffset = zOffset; this.length = length; - this.color = color; + this.shape = shape; this.width = width; + this.color = color; } public WPos Pos { get { return pos; } } @@ -35,22 +38,35 @@ namespace OpenRA.Mods.Common.Graphics public int ZOffset { get { return zOffset; } } public bool IsDecoration { get { return true; } } - public IRenderable WithPalette(PaletteReference newPalette) { return new BeamRenderable(pos, zOffset, length, width, color); } - public IRenderable WithZOffset(int newOffset) { return new BeamRenderable(pos, zOffset, length, width, color); } - public IRenderable OffsetBy(WVec vec) { return new BeamRenderable(pos + vec, zOffset, length, width, color); } + public IRenderable WithPalette(PaletteReference newPalette) { return new BeamRenderable(pos, zOffset, length, shape, width, color); } + public IRenderable WithZOffset(int newOffset) { return new BeamRenderable(pos, zOffset, length, shape, width, color); } + public IRenderable OffsetBy(WVec vec) { return new BeamRenderable(pos + vec, zOffset, length, shape, width, color); } public IRenderable AsDecoration() { return this; } public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return this; } public void Render(WorldRenderer wr) { - var wlr = Game.Renderer.WorldLineRenderer; - var src = wr.ScreenPosition(pos); - var dest = wr.ScreenPosition(pos + length); + var vecLength = length.Length; + if (vecLength == 0) + return; - var oldWidth = wlr.LineWidth; - wlr.LineWidth = wr.Viewport.Zoom * width; - wlr.DrawLine(src, dest, color); - wlr.LineWidth = oldWidth; + if (shape == BeamRenderableShape.Flat) + { + var delta = length * width.Length / (2 * vecLength); + var corner = new WVec(-delta.Y, delta.X, delta.Z); + var a = wr.ScreenPosition(pos - corner); + var b = wr.ScreenPosition(pos + corner); + var c = wr.ScreenPosition(pos + corner + length); + var d = wr.ScreenPosition(pos - corner + length); + Game.Renderer.WorldRgbaColorRenderer.FillRect(a, b, c, d, color); + } + else + { + var start = wr.ScreenPosition(pos); + var end = wr.ScreenPosition(pos + length); + var screenWidth = wr.ScreenVector(new WVec(width, WDist.Zero, WDist.Zero))[0]; + Game.Renderer.WorldRgbaColorRenderer.DrawLine(start, end, screenWidth, color); + } } public void RenderDebugGeometry(WorldRenderer wr) { } diff --git a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs index 2fe4617c25..f89b879feb 100644 --- a/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs +++ b/OpenRA.Mods.Common/UtilityCommands/UpgradeRules.cs @@ -3178,6 +3178,15 @@ namespace OpenRA.Mods.Common.UtilityCommands TryUpdateColor(ref node.Value.Value); } + if (engineVersion < 20151129) + { + if (node.Key == "BeamWidth" && parent.Value.Value == "LaserZap") + { + node.Key = "Width"; + ConvertPxToRange(ref node.Value.Value); + } + } + UpgradeWeaponRules(engineVersion, ref node.Value.Nodes, node, depth + 1); } } diff --git a/mods/cnc/weapons/other.yaml b/mods/cnc/weapons/other.yaml index 864d51311e..4476e9a170 100644 --- a/mods/cnc/weapons/other.yaml +++ b/mods/cnc/weapons/other.yaml @@ -123,7 +123,7 @@ Laser: Charges: true Report: OBELRAY1.AUD Projectile: LaserZap - BeamWidth: 2 + Width: 85 HitAnim: laserfire Warhead@1Dam: SpreadDamage Spread: 42 diff --git a/mods/d2k/weapons.yaml b/mods/d2k/weapons.yaml index 0c6bdcb0fc..b3a4edb9d9 100644 --- a/mods/d2k/weapons.yaml +++ b/mods/d2k/weapons.yaml @@ -535,6 +535,7 @@ Sound: Duration: 4 # Has a length of 0c512 DamageInterval: 3 # Travels 0c384 between impacts, will hit a target roughly three times Width: 0c512 + Shape: Flat Falloff: 100, 100, 50 Range: 0, 6c0, 11c0 BeyondTargetRange: 1c0 diff --git a/mods/ts/weapons/energyweapons.yaml b/mods/ts/weapons/energyweapons.yaml index 494974e11d..dfba483513 100644 --- a/mods/ts/weapons/energyweapons.yaml +++ b/mods/ts/weapons/energyweapons.yaml @@ -74,6 +74,7 @@ SonicZap: Duration: 90 DamageInterval: 5 # Roughly 18 impacts. Width: 0c384 + Shape: Flat BeyondTargetRange: 0c256 Blockable: true Color: 00FFFFC8 @@ -174,7 +175,7 @@ ObeliskLaserFire: Charges: true Report: OBELRAY1.AUD Projectile: LaserZap - BeamWidth: 4 + Width: 170 Warhead@1Dam: SpreadDamage Spread: 42 Damage: 250 @@ -185,7 +186,7 @@ TurretLaserFire: Range: 5c512 Report: LASTUR1.AUD Projectile: LaserZap - BeamWidth: 2 + Width: 85 BeamDuration: 5 Warhead@1Dam: SpreadDamage Spread: 42