working missile trails
This commit is contained in:
@@ -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 )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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];
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user