working missile trails

This commit is contained in:
Chris Forbes
2011-04-09 19:37:11 +12:00
parent 5fd3cc7977
commit 79079ebe07
4 changed files with 91 additions and 51 deletions

View File

@@ -14,6 +14,7 @@ using OpenRA.Effects;
using OpenRA.GameRules; using OpenRA.GameRules;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Traits; using OpenRA.Traits;
using System.Drawing;
namespace OpenRA.Mods.RA.Effects namespace OpenRA.Mods.RA.Effects
{ {
@@ -30,6 +31,9 @@ namespace OpenRA.Mods.RA.Effects
public readonly bool Proximity = false; public readonly bool Proximity = false;
public readonly float Angle = 0; public readonly float Angle = 0;
public readonly int TrailInterval = 2; public readonly int TrailInterval = 2;
public readonly int ContrailLength = 0;
public readonly bool ContrailUsePlayerColor = false;
public readonly int ContrailDelay = 1;
public IEffect Create(ProjectileArgs args) { return new Bullet( this, args ); } public IEffect Create(ProjectileArgs args) { return new Bullet( this, args ); }
} }
@@ -43,6 +47,7 @@ namespace OpenRA.Mods.RA.Effects
Animation anim; Animation anim;
const int BaseBulletSpeed = 100; /* pixels / 40ms frame */ const int BaseBulletSpeed = 100; /* pixels / 40ms frame */
ContrailHistory Trail;
public Bullet(BulletInfo info, ProjectileArgs args) public Bullet(BulletInfo info, ProjectileArgs args)
{ {
@@ -60,6 +65,13 @@ namespace OpenRA.Mods.RA.Effects
anim = new Animation(Info.Image, GetEffectiveFacing); anim = new Animation(Info.Image, GetEffectiveFacing);
anim.PlayRepeating("idle"); anim.PlayRepeating("idle");
} }
if (Info.ContrailLength > 0)
{
Trail = new ContrailHistory(Info.ContrailLength,
Info.ContrailUsePlayerColor ? ContrailHistory.ChooseColor(args.firedBy) : Color.White,
Info.ContrailDelay);
}
} }
int TotalTime() { return (Args.dest - Args.src).Length * BaseBulletSpeed / Info.Speed; } int TotalTime() { return (Args.dest - Args.src).Length * BaseBulletSpeed / Info.Speed; }
@@ -94,7 +106,6 @@ namespace OpenRA.Mods.RA.Effects
if (t > TotalTime()) Explode( world ); if (t > TotalTime()) Explode( world );
if (Info.Trail != null)
{ {
var at = (float)t / TotalTime(); var at = (float)t / TotalTime();
var altitude = float2.Lerp(Args.srcAltitude, Args.destAltitude, at); var altitude = float2.Lerp(Args.srcAltitude, Args.destAltitude, at);
@@ -104,12 +115,15 @@ namespace OpenRA.Mods.RA.Effects
? (pos - new float2(0, GetAltitude())) ? (pos - new float2(0, GetAltitude()))
: pos; : pos;
if (--ticksToNextSmoke < 0) if (Info.Trail != null && --ticksToNextSmoke < 0)
{ {
world.AddFrameEndTask(w => w.Add( world.AddFrameEndTask(w => w.Add(
new Smoke(w, highPos.ToInt2(), Info.Trail))); new Smoke(w, highPos.ToInt2(), Info.Trail)));
ticksToNextSmoke = Info.TrailInterval; ticksToNextSmoke = Info.TrailInterval;
} }
if (Trail != null)
Trail.Tick(highPos);
} }
if (!Info.High) // check for hitting a wall if (!Info.High) // check for hitting a wall
@@ -129,29 +143,35 @@ namespace OpenRA.Mods.RA.Effects
const float height = .1f; const float height = .1f;
public IEnumerable<Renderable> Render() public IEnumerable<Renderable> Render()
{ {
if (anim != null) if (anim != null)
{ {
var at = (float)t / TotalTime(); var at = (float)t / TotalTime();
var altitude = float2.Lerp(Args.srcAltitude, Args.destAltitude, at); var altitude = float2.Lerp(Args.srcAltitude, Args.destAltitude, at);
var pos = float2.Lerp(Args.src, Args.dest, at) - new float2(0, altitude); var pos = float2.Lerp(Args.src, Args.dest, at) - new float2(0, altitude);
if (Info.High || Info.Angle > 0) if (Args.firedBy.World.LocalShroud.IsVisible(OpenRA.Traits.Util.CellContaining(pos)))
{ {
if (Info.Shadow) if (Info.High || Info.Angle > 0)
yield return new Renderable(anim.Image, pos - .5f * anim.Image.size, "shadow", (int)pos.Y); {
if (Info.Shadow)
yield return new Renderable(anim.Image, pos - .5f * anim.Image.size, "shadow", (int)pos.Y);
var highPos = pos - new float2(0, GetAltitude()); var highPos = pos - new float2(0, GetAltitude());
yield return new Renderable(anim.Image, highPos - .5f * anim.Image.size, Args.firedBy.Owner.Palette, (int)pos.Y); yield return new Renderable(anim.Image, highPos - .5f * anim.Image.size, Args.firedBy.Owner.Palette, (int)pos.Y);
} }
else else
yield return new Renderable(anim.Image, pos - .5f * anim.Image.size, yield return new Renderable(anim.Image, pos - .5f * anim.Image.size,
Args.weapon.Underwater ? "shadow" : Args.firedBy.Owner.Palette, (int)pos.Y); Args.weapon.Underwater ? "shadow" : Args.firedBy.Owner.Palette, (int)pos.Y);
} }
} }
if (Trail != null)
Trail.Render(Args.firedBy);
}
void Explode( World world ) void Explode( World world )
{ {

View File

@@ -58,6 +58,7 @@ namespace OpenRA.Mods.RA
List<float2> positions = new List<float2>(); List<float2> positions = new List<float2>();
readonly int TrailLength; readonly int TrailLength;
readonly Color Color; readonly Color Color;
readonly int StartSkip;
public static Color ChooseColor(Actor self) public static Color ChooseColor(Actor self)
{ {
@@ -66,9 +67,13 @@ namespace OpenRA.Mods.RA
} }
public ContrailHistory(int trailLength, Color color) public ContrailHistory(int trailLength, Color color)
: this(trailLength, color, 0) { }
public ContrailHistory(int trailLength, Color color, int startSkip)
{ {
this.TrailLength = trailLength; this.TrailLength = trailLength;
this.Color = color; this.Color = color;
this.StartSkip = startSkip;
} }
public void Tick(float2 currentPos) public void Tick(float2 currentPos)
@@ -84,7 +89,7 @@ namespace OpenRA.Mods.RA
Color trailEnd = Color.FromArgb(trailStart.A - 255 / TrailLength, trailStart.R, Color trailEnd = Color.FromArgb(trailStart.A - 255 / TrailLength, trailStart.R,
trailStart.G, trailStart.B); trailStart.G, trailStart.B);
for (int i = positions.Count - 1; i >= 1; --i) for (int i = positions.Count - 1 - StartSkip; i >= 1; --i)
{ {
var conPos = positions[i]; var conPos = positions[i];
var nextPos = positions[i - 1]; var nextPos = positions[i - 1];

View File

@@ -34,7 +34,8 @@ namespace OpenRA.Mods.RA.Effects
public readonly bool TurboBoost = false; public readonly bool TurboBoost = false;
public readonly int TrailInterval = 2; public readonly int TrailInterval = 2;
public readonly int ContrailLength = 0; public readonly int ContrailLength = 0;
public readonly bool ContrailUsePlayerColor = true; public readonly bool ContrailUsePlayerColor = false;
public readonly int ContrailDelay = 1;
public IEffect Create(ProjectileArgs args) { return new Missile( this, args ); } public IEffect Create(ProjectileArgs args) { return new Missile( this, args ); }
} }
@@ -54,28 +55,31 @@ namespace OpenRA.Mods.RA.Effects
int Altitude; int Altitude;
ContrailHistory Trail; ContrailHistory Trail;
public Missile(MissileInfo info, ProjectileArgs args) public Missile(MissileInfo info, ProjectileArgs args)
{ {
Info = info; Info = info;
Args = args; Args = args;
SubPxPosition = 1024*Args.src; SubPxPosition = 1024 * Args.src;
Altitude = Args.srcAltitude; Altitude = Args.srcAltitude;
Facing = Args.facing; Facing = Args.facing;
if (info.Inaccuracy > 0) if (info.Inaccuracy > 0)
offset = (info.Inaccuracy * args.firedBy.World.SharedRandom.Gauss2D(2)).ToInt2(); offset = (info.Inaccuracy * args.firedBy.World.SharedRandom.Gauss2D(2)).ToInt2();
if (Info.Image != null) if (Info.Image != null)
{ {
anim = new Animation(Info.Image, () => Facing); anim = new Animation(Info.Image, () => Facing);
anim.PlayRepeating("idle"); anim.PlayRepeating("idle");
} }
if (Info.ContrailLength > 0) if (Info.ContrailLength > 0)
Trail = new ContrailHistory(Info.ContrailLength, {
Info.ContrailUsePlayerColor ? ContrailHistory.ChooseColor(args.firedBy) : Color.White); Trail = new ContrailHistory(Info.ContrailLength,
} Info.ContrailUsePlayerColor ? ContrailHistory.ChooseColor(args.firedBy) : Color.White,
Info.ContrailDelay);
}
}
// In pixels // In pixels
const int MissileCloseEnough = 7; const int MissileCloseEnough = 7;
@@ -149,8 +153,9 @@ namespace OpenRA.Mods.RA.Effects
public IEnumerable<Renderable> Render() public IEnumerable<Renderable> Render()
{ {
yield return new Renderable(anim.Image,PxPosition.ToFloat2() - 0.5f * anim.Image.size - new float2(0, Altitude), if (Args.firedBy.World.LocalShroud.IsVisible(OpenRA.Traits.Util.CellContaining(PxPosition.ToFloat2())))
Args.weapon.Underwater ? "shadow" : "effect", PxPosition.Y); yield return new Renderable(anim.Image,PxPosition.ToFloat2() - 0.5f * anim.Image.size - new float2(0, Altitude),
Args.weapon.Underwater ? "shadow" : "effect", PxPosition.Y);
if (Trail != null) if (Trail != null)
Trail.Render(Args.firedBy); Trail.Render(Args.firedBy);

View File

@@ -119,7 +119,8 @@ Maverick:
High: true High: true
Shadow: false Shadow: false
Proximity: true Proximity: true
Trail: smokey # Trail: smokey
ContrailLength: 10
Inaccuracy: 12 Inaccuracy: 12
Image: DRAGON Image: DRAGON
ROT: 5 ROT: 5
@@ -266,6 +267,7 @@ Dragon:
Shadow: false Shadow: false
Proximity: true Proximity: true
Trail: smokey Trail: smokey
ContrailLength: 10
Inaccuracy: 3 Inaccuracy: 3
Image: DRAGON Image: DRAGON
ROT: 5 ROT: 5
@@ -295,7 +297,8 @@ Hellfire:
High: true High: true
Shadow: false Shadow: false
Proximity: true Proximity: true
Trail: smokey # Trail: smokey
ContrailLength: 10
Inaccuracy: 3 Inaccuracy: 3
Image: DRAGON Image: DRAGON
ROT: 5 ROT: 5
@@ -452,7 +455,8 @@ MammothTusk:
High: true High: true
Shadow: false Shadow: false
Proximity: true Proximity: true
Trail: smokey # Trail: smokey
ContrailLength: 10
Inaccuracy: 3 Inaccuracy: 3
Image: DRAGON Image: DRAGON
ROT: 5 ROT: 5
@@ -481,6 +485,7 @@ MammothTusk:
Angle: .1 Angle: .1
Inaccuracy: 40 Inaccuracy: 40
Image: 120MM Image: 120MM
ContrailLength: 30
Warhead: Warhead:
Spread: 10 Spread: 10
Versus: Versus:
@@ -616,7 +621,8 @@ Nike:
High: true High: true
Shadow: false Shadow: false
Proximity: true Proximity: true
Trail: smokey # Trail: smokey
ContrailLength: 10
Image: MISSILE Image: MISSILE
ROT: 25 ROT: 25
RangeLimit: 50 RangeLimit: 50
@@ -644,7 +650,8 @@ RedEye:
High: true High: true
Shadow: false Shadow: false
Proximity: true Proximity: true
Trail: smokey # Trail: smokey
ContrailLength: 10
Image: MISSILE Image: MISSILE
ROT: 20 ROT: 20
RangeLimit: 30 RangeLimit: 30
@@ -673,6 +680,7 @@ RedEye:
Angle: .1 Angle: .1
Inaccuracy: 120 Inaccuracy: 120
Image: 120MM Image: 120MM
ContrailLength: 30
Warhead: Warhead:
Spread: 3 Spread: 3
Versus: Versus:
@@ -701,6 +709,7 @@ SubMissile:
Inaccuracy: 70 Inaccuracy: 70
Image: MISSILE Image: MISSILE
Trail: smokey Trail: smokey
ContrailLength: 30
Warhead: Warhead:
Spread: 10 Spread: 10
Versus: Versus:
@@ -727,7 +736,8 @@ Stinger:
High: true High: true
Shadow: false Shadow: false
Proximity: true Proximity: true
Trail: smokey # Trail: smokey
ContrailLength: 10
Image: DRAGON Image: DRAGON
ROT: 20 ROT: 20
RangeLimit: 50 RangeLimit: 50
@@ -753,11 +763,11 @@ TorpTube:
ValidTargets: Water, Underwater ValidTargets: Water, Underwater
Underwater: yes Underwater: yes
Burst: 2 Burst: 2
BurstDelay: 1 BurstDelay: 20
Projectile: Missile Projectile: Missile
Image: MISSILE Image: MISSILE
Arm: 3 Arm: 3
Speed: 6 Speed: 10
Trail: bubbles Trail: bubbles
ROT: 1 ROT: 1
RangeLimit: 160 RangeLimit: 160
@@ -771,7 +781,7 @@ TorpTube:
WaterExplosion: large_splash WaterExplosion: large_splash
InfDeath: 3 InfDeath: 3
SmudgeType: Crater SmudgeType: Crater
Damage: 90 Damage: 180
2Inch: 2Inch:
ROF: 60 ROF: 60