Merge pull request #2917 from pchote/turret-cleanup

Remove Turret and PVecFloat cruft.
This commit is contained in:
Chris Forbes
2013-04-01 23:06:15 -07:00
41 changed files with 238 additions and 359 deletions

View File

@@ -34,6 +34,28 @@ namespace OpenRA
public static bool operator ==(WPos me, WPos other) { return (me.X == other.X && me.Y == other.Y && me.Z == other.Z); }
public static bool operator !=(WPos me, WPos other) { return !(me == other); }
public static WPos Average(params WPos[] list)
{
if (list == null || list.Length == 0)
return WPos.Zero;
var x = 0;
var y = 0;
var z = 0;
foreach(var pos in list)
{
x += pos.X;
y += pos.Y;
z += pos.Z;
}
x /= list.Length;
y /= list.Length;
z /= list.Length;
return new WPos(x,y,z);
}
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode(); }
public override bool Equals(object obj)

View File

@@ -26,8 +26,11 @@ namespace OpenRA
public static readonly WVec Zero = new WVec(0, 0, 0);
public static WVec operator +(WVec a, WVec b) { return new WVec(a.X + b.X, a.Y + b.Y, a.Z + b.Z); }
public static WVec operator -(WVec a, WVec b) { return new WVec(a.X - b.X, a.Y - b.Y, a.Y - b.Y); }
public static WVec operator -(WVec a, WVec b) { return new WVec(a.X - b.X, a.Y - b.Y, a.Z - b.Z); }
public static WVec operator -(WVec a) { return new WVec(-a.X, -a.Y, -a.Z); }
public static WVec operator /(WVec a, int b) { return new WVec(a.X / b, a.Y / b, a.Z / b); }
public static WVec operator *(int a, WVec b) { return new WVec(a * b.X, a * b.Y, a * b.Z); }
public static WVec operator *(WVec a, int b) { return b*a; }
public static bool operator ==(WVec me, WVec other) { return (me.X == other.X && me.Y == other.Y && me.Z == other.Z); }
public static bool operator !=(WVec me, WVec other) { return !(me == other); }
@@ -48,6 +51,8 @@ namespace OpenRA
(int)((lx * mtx[2] + ly*mtx[6] + lz*mtx[10]) / mtx[15]));
}
public static WVec Lerp(WVec a, WVec b, int mul, int div) { return a + (b - a) * mul / div; }
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode(); }
public override bool Equals(object obj)

View File

@@ -21,6 +21,7 @@ namespace OpenRA
public readonly int X, Y;
public CPos(int x, int y) { X = x; Y = y; }
public CPos(WPos a) { X = a.X / 1024; Y = a.Y / 1024; }
public static readonly CPos Zero = new CPos(0, 0);

View File

@@ -16,7 +16,7 @@ namespace OpenRA.Graphics
public class AnimationWithOffset
{
public Animation Animation;
public Func<float2> OffsetFunc;
public Func<WorldRenderer, float2> OffsetFunc;
public Func<bool> DisableFunc;
public int ZOffset;
@@ -25,18 +25,18 @@ namespace OpenRA.Graphics
{
}
public AnimationWithOffset(Animation a, Func<float2> o, Func<bool> d)
public AnimationWithOffset(Animation a, Func<WorldRenderer, float2> o, Func<bool> d)
{
this.Animation = a;
this.OffsetFunc = o;
this.DisableFunc = d;
}
public Renderable Image(Actor self, PaletteReference pal)
public Renderable Image(Actor self, WorldRenderer wr, PaletteReference pal)
{
var p = self.CenterLocation;
var loc = p.ToFloat2() - 0.5f * Animation.Image.size
+ (OffsetFunc != null ? OffsetFunc() : float2.Zero);
+ (OffsetFunc != null ? OffsetFunc(wr) : float2.Zero);
var r = new Renderable(Animation.Image, loc, pal, p.Y);
return ZOffset != 0 ? r.WithZOffset(ZOffset) : r;

View File

@@ -165,7 +165,7 @@ namespace OpenRA.Graphics
var avgPos = actors
.Select(a => (PVecInt)a.CenterLocation)
.Aggregate((a, b) => a + b) / actors.Count();
scrollPosition = NormalizeScrollPosition(((PVecFloat)avgPos - (PVecFloat)(1f / (2 * Zoom) * screenSize.ToFloat2())).ToInt2());
scrollPosition = NormalizeScrollPosition((avgPos.ToFloat2() - (1f / (2 * Zoom) * screenSize.ToFloat2())).ToInt2());
}
// Rectangle (in viewport coords) that contains things to be drawn

View File

@@ -221,11 +221,15 @@ namespace OpenRA.Graphics
public int2 ScreenPxPosition(WPos pos)
{
var c = Game.CellSize/1024f;
return new int2((int)(c*pos.X), (int)(c*(pos.Y - pos.Z)));
return new int2(Game.CellSize*pos.X/1024, Game.CellSize*(pos.Y - pos.Z)/1024);
}
public float ScreenZOffset(WPos pos) { return pos.Z*Game.CellSize/1024f; }
public int2 ScreenPxOffset(WVec vec)
{
return new int2(Game.CellSize*vec.X/1024, Game.CellSize*(vec.Y - vec.Z)/1024);
}
public float[] ScreenOffset(WVec vec)
{
var c = Game.CellSize/1024f;

1
OpenRA.Game/OpenRA.Game.csproj Executable file → Normal file
View File

@@ -84,7 +84,6 @@
<Compile Include="PSubVec.cs" />
<Compile Include="PSubPos.cs" />
<Compile Include="PVecInt.cs" />
<Compile Include="PVecFloat.cs" />
<Compile Include="PPos.cs" />
<Compile Include="Download.cs" />
<Compile Include="Effects\DelayedAction.cs" />

View File

@@ -39,7 +39,6 @@ namespace OpenRA
public static explicit operator PPos(int2 a) { return new PPos(a.X, a.Y); }
public static explicit operator PVecInt(PPos a) { return new PVecInt(a.X, a.Y); }
public static explicit operator PVecFloat(PPos a) { return new PVecFloat(a.X, a.Y); }
public static PPos operator +(PPos a, PVecInt b) { return new PPos(a.X + b.X, a.Y + b.Y); }
public static PVecInt operator -(PPos a, PPos b) { return new PVecInt(a.X - b.X, a.Y - b.Y); }

View File

@@ -29,7 +29,6 @@ namespace OpenRA
public static explicit operator PSubPos(int2 a) { return new PSubPos(a.X, a.Y); }
public static explicit operator PSubVec(PSubPos a) { return new PSubVec(a.X, a.Y); }
public static explicit operator PVecFloat(PSubPos a) { return new PVecFloat(a.X, a.Y); }
public static PSubPos operator +(PSubPos a, PSubVec b) { return new PSubPos(a.X + b.X, a.Y + b.Y); }
public static PSubVec operator -(PSubPos a, PSubPos b) { return new PSubVec(a.X - b.X, a.Y - b.Y); }

View File

@@ -94,10 +94,5 @@ namespace OpenRA
{
return new PSubVec((vec.X * PSubPos.PerPx), (vec.Y * PSubPos.PerPx));
}
public static PSubVec ToPSubVec(this PVecFloat vec)
{
return new PSubVec((int)(vec.X * PSubPos.PerPx), (int)(vec.Y * PSubPos.PerPx));
}
}
}

View File

@@ -1,97 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 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 System;
using System.Drawing;
namespace OpenRA
{
/// <summary>
/// Pixel coordinate vector (fine; float)
/// </summary>
public struct PVecFloat
{
public readonly float X, Y;
public PVecFloat(float x, float y) { X = x; Y = y; }
public PVecFloat(Size p) { X = p.Width; Y = p.Height; }
public static readonly PVecFloat Zero = new PVecFloat(0, 0);
public static explicit operator PVecInt(PVecFloat a) { return new PVecInt((int)a.X, (int)a.Y); }
public static explicit operator PVecFloat(float2 a) { return new PVecFloat(a.X, a.Y); }
public static PVecFloat operator +(PVecFloat a, PVecFloat b) { return new PVecFloat(a.X + b.X, a.Y + b.Y); }
public static PVecFloat operator -(PVecFloat a, PVecFloat b) { return new PVecFloat(a.X - b.X, a.Y - b.Y); }
public static PVecFloat operator *(float a, PVecFloat b) { return new PVecFloat(a * b.X, a * b.Y); }
public static PVecFloat operator *(PVecFloat b, float a) { return new PVecFloat(a * b.X, a * b.Y); }
public static PVecFloat operator /(PVecFloat a, float b) { return new PVecFloat(a.X / b, a.Y / b); }
public static PVecFloat operator -(PVecFloat a) { return new PVecFloat(-a.X, -a.Y); }
public static bool operator ==(PVecFloat me, PVecFloat other) { return (me.X == other.X && me.Y == other.Y); }
public static bool operator !=(PVecFloat me, PVecFloat other) { return !(me == other); }
public static PVecFloat Max(PVecFloat a, PVecFloat b) { return new PVecFloat(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); }
public static PVecFloat Min(PVecFloat a, PVecFloat b) { return new PVecFloat(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
public static float Dot(PVecFloat a, PVecFloat b) { return a.X * b.X + a.Y * b.Y; }
public static PVecFloat FromAngle(float a) { return new PVecFloat((float)Math.Sin(a), (float)Math.Cos(a)); }
public static PVecFloat Lerp(PVecFloat a, PVecFloat b, float t)
{
return new PVecFloat(
float2.Lerp(a.X, b.X, t),
float2.Lerp(a.Y, b.Y, t)
);
}
public static PVecFloat Lerp(PVecFloat a, PVecFloat b, PVecFloat t)
{
return new PVecFloat(
float2.Lerp(a.X, b.X, t.X),
float2.Lerp(a.Y, b.Y, t.Y)
);
}
public PVecFloat Sign() { return new PVecFloat(Math.Sign(X), Math.Sign(Y)); }
public PVecFloat Abs() { return new PVecFloat(Math.Abs(X), Math.Abs(Y)); }
public PVecFloat Round() { return new PVecFloat((float)Math.Round(X), (float)Math.Round(Y)); }
public float LengthSquared { get { return X * X + Y * Y; } }
public float Length { get { return (float)Math.Sqrt(LengthSquared); } }
public float2 ToFloat2() { return new float2(X, Y); }
public int2 ToInt2() { return new int2((int)X, (int)Y); }
static float Constrain(float x, float a, float b) { return x < a ? a : x > b ? b : x; }
public PVecFloat Constrain(PVecFloat min, PVecFloat max)
{
return new PVecFloat(
Constrain(X, min.X, max.X),
Constrain(Y, min.Y, max.Y)
);
}
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); }
public override bool Equals(object obj)
{
if (obj == null)
return false;
PVecFloat o = (PVecFloat)obj;
return o == this;
}
public override string ToString() { return "({0},{1})".F(X, Y); }
}
}

View File

@@ -26,7 +26,6 @@ namespace OpenRA
public static readonly PVecInt Zero = new PVecInt(0, 0);
public static PVecInt OneCell { get { return new PVecInt(Game.CellSize, Game.CellSize); } }
public static implicit operator PVecFloat(PVecInt a) { return new PVecFloat((float)a.X, (float)a.Y); }
public static explicit operator PVecInt(int2 a) { return new PVecInt(a.X, a.Y); }
public static PVecInt FromRadius(int r) { return new PVecInt(r, r); }

View File

@@ -16,7 +16,7 @@ using OpenRA.FileFormats;
namespace OpenRA.Traits
{
public class RenderSimpleInfo : ITraitInfo
public class RenderSimpleInfo : ITraitInfo, LocalCoordinatesModelInfo
{
[Desc("Defaults to the actor name.")]
public readonly string Image = null;
@@ -108,7 +108,7 @@ namespace OpenRA.Traits
foreach (var a in anims.Values)
if (a.DisableFunc == null || !a.DisableFunc())
{
Renderable ret = a.Image(self, palette);
Renderable ret = a.Image(self, wr, palette);
if (Info.Scale != 1f)
ret = ret.WithScale(Info.Scale).WithPos(ret.Pos + 0.5f * ret.Sprite.size * (1 - Info.Scale));
yield return ret;

View File

@@ -216,6 +216,7 @@ namespace OpenRA.Traits
WVec LocalToWorld(WVec vec);
WRot QuantizeOrientation(Actor self, WRot orientation);
}
public interface LocalCoordinatesModelInfo {}
public interface ITargetable
{

View File

@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Cnc
: 0);
var offset = new float2(-32,-21);
anims.Add("lights", new AnimationWithOffset( lights, () => offset, () => !buildComplete )
anims.Add("lights", new AnimationWithOffset( lights, wr => offset, () => !buildComplete )
{ ZOffset = 24 });
}

View File

@@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA.Render
var wake = new Animation(anim.Name);
wake.Play("left-wake");
Func<float2> offset = () => new float2(((anims["wake"].Animation.CurrentSequence.Name == "left-wake") ? 1 : -1),2);
Func<WorldRenderer, float2> offset = wr => new float2(((anims["wake"].Animation.CurrentSequence.Name == "left-wake") ? 1 : -1),2);
anims.Add( "wake", new AnimationWithOffset( wake, offset, () => false ) { ZOffset = -2 } );
}

View File

@@ -25,7 +25,7 @@ namespace OpenRA.Mods.Cnc
var rs = self.Trait<RenderSimple>();
var roof = new Animation(rs.GetImage(self));
roof.PlayThen("fire-start", () => roof.PlayRepeating("fire-loop"));
rs.anims.Add( "fire", new AnimationWithOffset( roof, () => new float2(7,-15), null ) { ZOffset = 24 } );
rs.anims.Add( "fire", new AnimationWithOffset( roof, wr => new float2(7,-15), null ) { ZOffset = 24 } );
}
}
}

View File

@@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA
var anim = new Animation("fire", () => 0);
anim.PlayRepeating(Info.Anim);
rs.anims.Add("fire",
new AnimationWithOffset(anim, () => new float2(0, -3), null));
new AnimationWithOffset(anim, wr => new float2(0, -3), null));
}
public void Tick(Actor self)

View File

@@ -128,7 +128,10 @@ namespace OpenRA.Mods.RA.Effects
}
if (Trail != null)
Trail.Tick((PPos)highPos.ToInt2());
{
var alt = (Info.High || Info.Angle > 0) ? GetAltitude() : 0;
Trail.Tick(new PPos((int)pos.X, (int)pos.Y).ToWPos((int)alt));
}
}
if (!Info.High) // check for hitting a wall
@@ -175,7 +178,7 @@ namespace OpenRA.Mods.RA.Effects
}
if (Trail != null)
Trail.Render(Args.firedBy);
Trail.Render(wr, Args.firedBy);
}
void Explode( World world )

View File

@@ -16,9 +16,10 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
class ContrailInfo : ITraitInfo
class ContrailInfo : ITraitInfo, Requires<LocalCoordinatesModelInfo>
{
public readonly int[] ContrailOffset = {0, 0};
[Desc("Position relative to body")]
public readonly WVec Offset = WVec.Zero;
public readonly int TrailLength = 25;
public readonly Color Color = Color.White;
@@ -29,31 +30,31 @@ namespace OpenRA.Mods.RA
class Contrail : ITick, IPostRender
{
Turret contrailTurret = null;
ContrailInfo info;
ContrailHistory history;
IFacing facing;
IMove move;
ILocalCoordinatesModel coords;
public Contrail(Actor self, ContrailInfo info)
{
contrailTurret = new Turret(info.ContrailOffset);
this.info = info;
history = new ContrailHistory(info.TrailLength,
info.UsePlayerColor ? ContrailHistory.ChooseColor(self) : info.Color);
facing = self.Trait<IFacing>();
move = self.Trait<IMove>();
coords = self.Trait<ILocalCoordinatesModel>();
}
public void Tick(Actor self)
{
history.Tick(self.CenterLocation - new PVecInt(0, move.Altitude) - (PVecInt)contrailTurret.PxPosition(self, facing).ToInt2());
var local = info.Offset.Rotate(coords.QuantizeOrientation(self, self.Orientation));
history.Tick(self.CenterPosition + coords.LocalToWorld(local));
}
public void RenderAfterWorld(WorldRenderer wr, Actor self) { history.Render(self); }
public void RenderAfterWorld(WorldRenderer wr, Actor self) { history.Render(wr, self); }
}
class ContrailHistory
{
List<PPos> positions = new List<PPos>();
List<WPos> positions = new List<WPos>();
readonly int TrailLength;
readonly Color Color;
readonly int StartSkip;
@@ -74,27 +75,28 @@ namespace OpenRA.Mods.RA
this.StartSkip = startSkip;
}
public void Tick(PPos currentPos)
public void Tick(WPos currentPos)
{
positions.Add(currentPos);
if (positions.Count >= TrailLength)
positions.RemoveAt(0);
}
public void Render(Actor self)
public void Render(WorldRenderer wr, Actor self)
{
Color trailStart = Color;
Color trailEnd = Color.FromArgb(trailStart.A - 255 / TrailLength, trailStart.R, trailStart.G, trailStart.B);
for (int i = positions.Count - 1 - StartSkip; i >= 4; --i)
{
var conPos = PPos.Average(positions[i], positions[i-1], positions[i-2], positions[i-3]);
var nextPos = PPos.Average(positions[i-1], positions[i-2], positions[i-3], positions[i-4]);
// World positions
var conPos = WPos.Average(positions[i], positions[i-1], positions[i-2], positions[i-3]);
var nextPos = WPos.Average(positions[i-1], positions[i-2], positions[i-3], positions[i-4]);
if (self.World.RenderedShroud.IsVisible(conPos.ToCPos()) ||
self.World.RenderedShroud.IsVisible(nextPos.ToCPos()))
if (self.World.RenderedShroud.IsVisible(new CPos(conPos)) ||
self.World.RenderedShroud.IsVisible(new CPos(nextPos)))
{
Game.Renderer.WorldLineRenderer.DrawLine(conPos.ToFloat2(), nextPos.ToFloat2(), trailStart, trailEnd);
Game.Renderer.WorldLineRenderer.DrawLine(wr.ScreenPosition(conPos), wr.ScreenPosition(nextPos), trailStart, trailEnd);
trailStart = trailEnd;
trailEnd = Color.FromArgb(trailStart.A - 255 / positions.Count, trailStart.R, trailStart.G, trailStart.B);

View File

@@ -145,7 +145,7 @@ namespace OpenRA.Mods.RA.Effects
}
if (Trail != null)
Trail.Tick(PxPosition - new PVecInt(0, Altitude));
Trail.Tick(PxPosition.ToWPos(Altitude));
}
void Explode(World world)
@@ -163,7 +163,7 @@ namespace OpenRA.Mods.RA.Effects
wr.Palette(Args.weapon.Underwater ? "shadow" : "effect"), PxPosition.Y);
if (Trail != null)
Trail.Render(Args.firedBy);
Trail.Render(wr, Args.firedBy);
}
}
}

View File

@@ -317,7 +317,6 @@
<Compile Include="Render\RenderSpy.cs" />
<Compile Include="Render\RenderUnit.cs" />
<Compile Include="Render\RenderUnitReload.cs" />
<Compile Include="Render\RenderUnitSpinner.cs" />
<Compile Include="Render\RenderUnitTurreted.cs" />
<Compile Include="Render\WithBuildingExplosion.cs" />
<Compile Include="Render\WithMuzzleFlash.cs" />
@@ -423,6 +422,7 @@
<Compile Include="Armament.cs" />
<Compile Include="DebugMuzzlePositions.cs" />
<Compile Include="Buildings\BaseProvider.cs" />
<Compile Include="Render\WithSpinner.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">

View File

@@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA.Render
anim.Play("turret");
anims.Add("turret_{0}".F(i++), new AnimationWithOffset(anim,
() => PPos.FromWPosHackZ(WPos.Zero + t.Position(self)).ToFloat2(), null));
wr => wr.ScreenPxOffset(t.Position(self)), null));
}
}
}

View File

@@ -1,41 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 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.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Render
{
class RenderUnitSpinnerInfo : RenderUnitInfo
{
public readonly int[] Offset = { 0, 0 };
public override object Create(ActorInitializer init) { return new RenderUnitSpinner(init.self); }
}
class RenderUnitSpinner : RenderUnit
{
public RenderUnitSpinner(Actor self)
: base(self)
{
var info = self.Info.Traits.Get<RenderUnitSpinnerInfo>();
var spinnerAnim = new Animation(GetImage(self));
var facing = self.Trait<IFacing>();
spinnerAnim.PlayRepeating("spinner");
var turret = new Turret(info.Offset);
anims.Add("spinner", new AnimationWithOffset(
spinnerAnim,
() => turret.PxPosition(self, facing).ToFloat2(),
null ) { ZOffset = 1 } );
}
}
}

View File

@@ -37,11 +37,11 @@ namespace OpenRA.Mods.RA.Render
anim.Play("turret");
anims.Add("turret_{0}".F(i++), new AnimationWithOffset(anim,
() => TurretPosition(self, turret, facing), null));
wr => TurretPosition(self, wr, turret, facing), null));
}
}
float2 TurretPosition(Actor self, Turreted t, IFacing facing)
float2 TurretPosition(Actor self, WorldRenderer wr, Turreted t, IFacing facing)
{
var recoil = self.TraitsImplementing<Armament>()
.Where(w => w.Info.Turret == t.Name)
@@ -50,9 +50,9 @@ namespace OpenRA.Mods.RA.Render
var localOffset = new WVec(-recoil, WRange.Zero, WRange.Zero);
var bodyOrientation = QuantizeOrientation(self, self.Orientation);
var turretOrientation = QuantizeOrientation(self, t.LocalOrientation(self));
var worldPos = WPos.Zero + t.Position(self) + LocalToWorld(localOffset.Rotate(turretOrientation).Rotate(bodyOrientation));
var worldPos = t.Position(self) + LocalToWorld(localOffset.Rotate(turretOrientation).Rotate(bodyOrientation));
return PPos.FromWPosHackZ(worldPos).ToFloat2();
return wr.ScreenPxOffset(worldPos);
}
}
}

View File

@@ -47,7 +47,7 @@ namespace OpenRA.Mods.RA.Render
muzzleFlashes.Add("muzzle{0}".F(muzzleFlashes.Count), new AnimationWithOffset(
muzzleFlash,
() => PPos.FromWPosHackZ(WPos.Zero + a.MuzzleOffset(self, barrel)).ToFloat2(),
wr => wr.ScreenPxOffset(a.MuzzleOffset(self, barrel)),
() => !isShowing));
}
}
@@ -63,7 +63,7 @@ namespace OpenRA.Mods.RA.Render
{
foreach (var a in muzzleFlashes.Values)
if (a.DisableFunc == null || !a.DisableFunc())
yield return a.Image(self, wr.Palette("effect"));
yield return a.Image(self, wr, wr.Palette("effect"));
}
public void Tick(Actor self)

View File

@@ -8,6 +8,7 @@
*/
#endregion
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Traits;
@@ -15,8 +16,10 @@ namespace OpenRA.Mods.RA.Render
{
public class WithRotorInfo : ITraitInfo, Requires<RenderSimpleInfo>
{
[Desc("Position relative to body")]
public readonly WVec Offset = WVec.Zero;
public readonly string Id = "rotor";
public readonly int[] Offset = { 0, 0 };
public object Create(ActorInitializer init) { return new WithRotor(init.self, this); }
}
@@ -26,14 +29,12 @@ namespace OpenRA.Mods.RA.Render
public WithRotor(Actor self, WithRotorInfo info)
{
var rs = self.Trait<RenderSimple>();
var facing = self.Trait<IFacing>();
rotorAnim = new Animation(rs.GetImage(self));
rotorAnim.PlayRepeating("rotor");
var turret = new Turret(info.Offset);
rs.anims.Add(info.Id, new AnimationWithOffset(
rotorAnim,
() => turret.PxPosition(self, facing).ToFloat2(),
wr => wr.ScreenPxOffset(rs.LocalToWorld(info.Offset.Rotate(rs.QuantizeOrientation(self, self.Orientation)))),
null ) { ZOffset = 1 } );
}

View File

@@ -0,0 +1,39 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 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.FileFormats;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Render
{
class WithSpinnerInfo : ITraitInfo, Requires<RenderSimpleInfo>
{
public readonly string Name = "spinner";
[Desc("Position relative to body")]
public readonly WVec Offset = WVec.Zero;
public object Create(ActorInitializer init) { return new WithSpinner(init.self, this); }
}
class WithSpinner
{
public WithSpinner(Actor self, WithSpinnerInfo info)
{
var rs = self.Trait<RenderSimple>();
var spinner = new Animation(rs.GetImage(self));
spinner.PlayRepeating("spinner");
rs.anims.Add(info.Name, new AnimationWithOffset(
spinner,
wr => wr.ScreenPxOffset(rs.LocalToWorld(info.Offset.Rotate(rs.QuantizeOrientation(self, self.Orientation)))),
null ) { ZOffset = 1 } );
}
}
}

View File

@@ -8,14 +8,16 @@
*/
#endregion
using OpenRA.FileFormats;
using OpenRA.Mods.RA.Effects;
using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
class SmokeTrailWhenDamagedInfo : ITraitInfo
class SmokeTrailWhenDamagedInfo : ITraitInfo, Requires<LocalCoordinatesModelInfo>
{
public readonly int[] Offset = { 0, 0 };
[Desc("Position relative to body")]
public readonly WVec Offset = WVec.Zero;
public readonly int Interval = 3;
public object Create(ActorInitializer init) { return new SmokeTrailWhenDamaged(init.self, this); }
@@ -23,34 +25,30 @@ namespace OpenRA.Mods.RA
class SmokeTrailWhenDamaged : ITick
{
Turret smokeTurret;
PPos position;
int interval;
ILocalCoordinatesModel coords;
SmokeTrailWhenDamagedInfo info;
int ticks;
public SmokeTrailWhenDamaged(Actor self, SmokeTrailWhenDamagedInfo info)
{
smokeTurret = new Turret(info.Offset);
interval = info.Interval;
this.info = info;
coords = self.Trait<ILocalCoordinatesModel>();
}
public void Tick(Actor self)
{
if (--ticks <= 0)
{
var move = self.Trait<IMove>();
if (move.Altitude > 0 && self.GetDamageState() >= DamageState.Heavy)
var position = self.CenterPosition;
if (position.Z > 0 && self.GetDamageState() >= DamageState.Heavy &&
self.World.RenderedShroud.IsVisible(new CPos(position)))
{
var facing = self.Trait<IFacing>();
var altitude = new PVecInt(0, move.Altitude);
position = (self.CenterLocation - (PVecInt)smokeTurret.PxPosition(self, facing).ToInt2());
if (self.World.RenderedShroud.IsVisible(position.ToCPos()))
self.World.AddFrameEndTask(
w => w.Add(new Smoke(w, position - altitude, "smokey")));
var offset = info.Offset.Rotate(coords.QuantizeOrientation(self, self.Orientation));
var pos = PPos.FromWPosHackZ(position + coords.LocalToWorld(offset));
self.World.AddFrameEndTask(w => w.Add(new Smoke(w, pos, "smokey")));
}
ticks = interval;
ticks = info.Interval;
}
}
}

View File

@@ -8,19 +8,30 @@
*/
#endregion
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Mods.RA.Render;
using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
class ThrowsParticleInfo : ITraitInfo, Requires<RenderUnitInfo>
class ThrowsParticleInfo : ITraitInfo, Requires<RenderSimpleInfo>
{
public readonly string Anim = null;
public readonly int[] Offset = new[] { 0, 0, 0, 0 };
public readonly int[] Spread = new[] { 0, 0 };
public readonly float Speed = 20;
public readonly string AnimKey = null;
[Desc("Initial position relative to body")]
public readonly WVec Offset = WVec.Zero;
[Desc("Maximum distance to throw the particle")]
public readonly WRange ThrowRange = new WRange(768);
[Desc("Maximum height to throw the particle")]
public readonly WRange ThrowHeight = new WRange(256);
[Desc("Number of ticks to animate")]
public readonly int Length = 15;
[Desc("Maximum rotation rate")]
public readonly float ROT = 15;
public object Create(ActorInitializer init) { return new ThrowsParticle(init, this); }
@@ -28,51 +39,56 @@ namespace OpenRA.Mods.RA
class ThrowsParticle : ITick
{
float2 pos;
float alt;
ThrowsParticleInfo info;
WVec pos;
WVec initialPos;
WVec finalPos;
int tick = 0;
float2 v;
float va;
float facing;
float dfacing;
const float gravity = 1.3f;
float rotation;
public ThrowsParticle(ActorInitializer init, ThrowsParticleInfo info)
{
this.info = info;
var self = init.self;
var ifacing = self.Trait<IFacing>();
var ru = self.Trait<RenderUnit>();
var rs = self.Trait<RenderSimple>();
alt = 0;
facing = Turreted.GetInitialTurretFacing( init, 0 );
pos = new Turret(info.Offset).PxPosition(self, ifacing).ToFloat2();
// TODO: Carry orientation over from the parent instead of just facing
var bodyFacing = init.Contains<FacingInit>() ? init.Get<FacingInit,int>() : 0;
facing = Turreted.GetInitialTurretFacing(init, 0);
v = Game.CosmeticRandom.Gauss2D(1) * info.Spread.RelOffset();
dfacing = Game.CosmeticRandom.Gauss1D(2) * info.ROT;
va = info.Speed;
// Calculate final position
var throwRotation = WRot.FromFacing(Game.CosmeticRandom.Next(1024));
var throwOffset = new WVec((int)(Game.CosmeticRandom.Gauss1D(1)*info.ThrowRange.Range), 0, 0).Rotate(throwRotation);
var anim = new Animation(ru.GetImage(self), () => (int)facing);
initialPos = pos = info.Offset.Rotate(rs.QuantizeOrientation(self, WRot.FromFacing(bodyFacing)));
finalPos = initialPos + throwOffset;
// Facing rotation
rotation = Game.CosmeticRandom.Gauss1D(2) * info.ROT;
var anim = new Animation(rs.GetImage(self), () => (int)facing);
anim.PlayRepeating(info.Anim);
ru.anims.Add(info.AnimKey, new AnimationWithOffset(
anim, () => pos - new float2(0, alt), null));
rs.anims.Add(info.Anim, new AnimationWithOffset(anim, wr => wr.ScreenPxOffset(pos), null));
}
public void Tick(Actor self)
{
va -= gravity;
alt += va;
if (tick == info.Length)
return;
tick++;
if (alt < 0) alt = 0;
else
{
pos += v;
v = .9f * v;
// Lerp position horizontally and height along a sinusoid using a cubic ease
var t = (tick*tick*tick / (info.Length*info.Length) - 3*tick*tick / info.Length + 3*tick);
var tp = WVec.Lerp(initialPos, finalPos, t, info.Length);
var th = new WAngle(512*(info.Length - t) / info.Length).Sin()*info.ThrowHeight.Range / 1024;
pos = new WVec(tp.X, tp.Y, th);
facing += dfacing;
dfacing *= .9f;
}
// Spin the particle
facing += rotation;
rotation *= .9f;
}
}
}

View File

@@ -95,31 +95,4 @@ namespace OpenRA.Mods.RA
return WRot.FromYaw(WAngle.FromFacing(turretFacing) - self.Orientation.Yaw);
}
}
// TODO: Remove this
public class Turret
{
public PVecInt UnitSpacePosition; // where, in the unit's local space.
public PVecInt ScreenSpacePosition; // screen-space hack to make things line up good.
public Turret(int[] offset)
{
ScreenSpacePosition = (PVecInt) offset.AbsOffset().ToInt2();
UnitSpacePosition = (PVecInt) offset.RelOffset().ToInt2();
}
public PVecFloat PxPosition(Actor self, IFacing facing)
{
// Things that don't have a rotating base don't need the turrets repositioned
if (facing == null) return ScreenSpacePosition;
var ru = self.TraitOrDefault<RenderUnit>();
var numDirs = (ru != null) ? ru.anim.CurrentSequence.Facings : 8;
var bodyFacing = facing.Facing;
var quantizedFacing = Util.QuantizeFacing(bodyFacing, numDirs) * (256 / numDirs);
return (PVecFloat)Util.RotateVectorByFacing(UnitSpacePosition.ToFloat2(), quantizedFacing, .7f)
+ (PVecFloat)ScreenSpacePosition.ToFloat2();
}
}
}

View File

@@ -28,10 +28,10 @@ TRAN:
Range: 8
RenderUnit:
WithRotor@PRIMARY:
Offset: 0,14,0,-4
Offset: -597,0,171
WithRotor@SECONDARY:
Id: rotor_2
Offset: 0,-14,0,-2
Offset: 597,0,85
WithShadow:
Cargo:
Types: Infantry
@@ -84,7 +84,7 @@ HELI:
Period: 200
RenderUnit:
WithRotor:
Offset: 0,0,0,-2
Offset: 0,0,85
WithMuzzleFlash:
WithShadow:
FallsToEarth:

View File

@@ -73,9 +73,6 @@ LTNK.Husk:
Image: ltnk
ThrowsParticle@turret:
Anim: turret
Spread: 3,3
Speed: 6
AnimKey: turret
MTNK.Husk:
Inherits: ^Husk
@@ -86,9 +83,6 @@ MTNK.Husk:
Image: mtnk
ThrowsParticle@turret:
Anim: turret
Spread: 3,3
Speed: 6
AnimKey: turret
HTNK.Husk:
Inherits: ^Husk
@@ -99,9 +93,6 @@ HTNK.Husk:
Image: htnk
ThrowsParticle@turret:
Anim: turret
Spread: 3,3
Speed: 6
AnimKey: turret
MSAM.Husk:
Inherits: ^Husk
@@ -112,9 +103,6 @@ MSAM.Husk:
Image: msam
ThrowsParticle@turret:
Anim: turret
Spread: 3,3
Speed: 6
AnimKey: turret
MLRS.Husk:
Inherits: ^Husk
@@ -125,9 +113,6 @@ MLRS.Husk:
Image: mlrs
ThrowsParticle@turret:
Anim: turret
Spread: 3,3
Speed: 6
AnimKey: turret
STNK.Husk:
Inherits: ^Husk

View File

@@ -564,8 +564,9 @@ MHQ:
Speed: 6
RevealsShroud:
Range: 6
RenderUnitSpinner:
Offset: 0,6
RenderUnit:
WithSpinner:
Offset: -256,0,256
AttackMove:
JustMove: yes
Explodes:

View File

@@ -21,10 +21,10 @@
RearmBuildings: starporta,starporto,starporth
MinimalLandAltitude: 25
SmokeTrailWhenDamaged@0:
Offset: 15, -12
Offset: -512,640,0
Interval: 3
SmokeTrailWhenDamaged@1:
Offset: -15, -12
Offset: -512,-640,0
Interval: 3
RenderUnit:
RenderCargo:
@@ -103,7 +103,7 @@ ORNI:
Moves: yes
Explosion: UnitExplodeScale
SmokeTrailWhenDamaged:
Offset: 0,-10
Offset: -427,0,0
ORNI.bomber:
CarpetBomb:
@@ -133,7 +133,7 @@ ORNI.bomber:
Moves: yes
Explosion: UnitExplodeScale
SmokeTrailWhenDamaged:
Offset: 0,-10
Offset: -427,0,0
CARRYALL.infantry:
ParaDrop:
@@ -149,10 +149,10 @@ CARRYALL.infantry:
RepairBuildings: repair
RearmBuildings: starporta,starporto,starporth
SmokeTrailWhenDamaged@0:
Offset: 15, -12
Offset: -512,540,0
Interval: 3
SmokeTrailWhenDamaged@1:
Offset: -15, -12
Offset: -512,-640,0
Interval: 3
RenderUnit:
Image: carryall

View File

@@ -498,9 +498,6 @@ GUNTOWER.Husk:
Image: GUNTOWER
ThrowsParticle@turret:
Anim: turret
Spread: 4,4
Speed: 6
AnimKey: turret
ROCKETTOWER:
Inherits: ^Building
@@ -559,9 +556,6 @@ ROCKETTOWER.Husk:
Image: ROCKETTOWER
ThrowsParticle@turret:
Anim: turret
Spread: 4,4
Speed: 6
AnimKey: turret
REPAIR:
Inherits: ^Building

View File

@@ -242,9 +242,6 @@ QUAD.starport:
HP: 100
ThrowsParticle@turret:
Anim: turret
Spread: 3,3
Speed: 6
AnimKey: turret
SIEGETANK:
Inherits: ^Tank
@@ -299,9 +296,6 @@ SIEGETANK.Husk:
Icon: siegetankicon
ThrowsParticle@turret:
Anim: turret
Spread: 3,3
Speed: 6
AnimKey: turret
RenderUnit:
Image: SIEGETANK

View File

@@ -187,10 +187,10 @@ TRAN:
LandableTerrainTypes: Clear,Rough,Road,Ore,Beach
RenderUnit:
WithRotor@PRIMARY:
Offset: 0,14,0,-8
Offset: -597,0,341
WithRotor@SECONDARY:
Id: rotor_2
Offset: 0,-14,0,-5
Offset: 597,0,213
WithShadow:
Cargo:
Types: Infantry
@@ -232,7 +232,7 @@ HELI:
Speed: 16
RenderUnit:
WithRotor:
Offset: 0,0,0,-2
Offset: 0,0,85
WithShadow:
LimitedAmmo:
Ammo: 6

View File

@@ -2602,9 +2602,6 @@ Rules:
Image: 4TNK
ThrowsParticle@turret:
Anim: turret
Spread: 3,3
Speed: 6
AnimKey: turret
Health:
HP: 2000
SILO:

View File

@@ -20,18 +20,18 @@ BADR:
Tooltip:
Name: Badger
Contrail@1:
ContrailOffset: 11, -11
Offset: -469,469,0
Contrail@2:
ContrailOffset: -11, -11
Offset: -469,-469,0
FallsToEarth:
Spins: no
Moves: yes
Explosion: UnitExplode
SmokeTrailWhenDamaged@0:
Offset: 11, -11
Offset: -469,469,0
Interval: 2
SmokeTrailWhenDamaged@1:
Offset: -11, -11
Offset: -469,-469,0
Interval: 2
-EjectOnDeath:
-GpsDot:
@@ -59,18 +59,18 @@ BADR.bomber:
Tooltip:
Name: Badger
Contrail@1:
ContrailOffset: 11, -11
Offset: 469,469,0
Contrail@2:
ContrailOffset: -11, -11
Offset: 469,-469,0
FallsToEarth:
Spins: no
Moves: yes
Explosion: UnitExplode
SmokeTrailWhenDamaged@0:
Offset: 11, -11
Offset: -469,469,0
Interval: 2
SmokeTrailWhenDamaged@1:
Offset: -11, -11
Offset: -469,-469,0
Interval: 2
-EjectOnDeath:
-GpsDot:
@@ -107,6 +107,7 @@ MIG:
Speed: 20
RearmBuildings: afld
RenderUnit:
CameraPitch: 99
WithShadow:
LimitedAmmo:
Ammo: 8
@@ -115,15 +116,15 @@ MIG:
Selectable:
Bounds: 44,40,0,0
Contrail@1:
ContrailOffset: 16,-14
Offset: -598,-683,0
Contrail@2:
ContrailOffset: -16,-14
Offset: -598,683,0
FallsToEarth:
Spins: no
Moves: yes
Explosion: UnitExplode
SmokeTrailWhenDamaged:
Offset: 0,-20,0,-4
Offset: -853,0,171
Interval: 2
YAK:
@@ -160,6 +161,7 @@ YAK:
ROT: 5
Speed: 16
RenderUnit:
CameraPitch: 99
WithShadow:
LimitedAmmo:
Ammo: 18
@@ -169,13 +171,13 @@ YAK:
ReturnOnIdle:
WithMuzzleFlash:
Contrail:
ContrailOffset: 0, -20
Offset: -853,0,0
FallsToEarth:
Spins: no
Moves: yes
Explosion: UnitExplode
SmokeTrailWhenDamaged:
Offset: 0, -20
Offset: -853,0,0
Interval: 2
@@ -207,10 +209,10 @@ TRAN:
LandableTerrainTypes: Clear,Rough,Road,Ore,Beach
RenderUnit:
WithRotor@PRIMARY:
Offset: 0,14,0,-8
Offset: -597,0,341
WithRotor@SECONDARY:
Id: rotor_2
Offset: 0,-14,0,-5
Offset: 597,0,213
WithShadow:
Cargo:
Types: Infantry
@@ -270,7 +272,7 @@ HELI:
Speed: 16
RenderUnit:
WithRotor:
Offset: 0,0,0,-2
Offset: 0,0,85
WithShadow:
LimitedAmmo:
Ammo: 8
@@ -278,7 +280,7 @@ HELI:
FallsToEarth:
Explosion: UnitExplode
SmokeTrailWhenDamaged:
Offset: 0,-10
Offset: -427,0,0
HIND:
Inherits: ^Helicopter
@@ -328,7 +330,7 @@ HIND:
FallsToEarth:
Explosion: UnitExplode
SmokeTrailWhenDamaged:
Offset: 0,-10
Offset: -427,0,0
U2:
Inherits: ^Plane
@@ -345,13 +347,13 @@ U2:
-Selectable:
-GainsExperience:
Contrail@1:
ContrailOffset: 16, -17
Offset: -725,683,0
Contrail@2:
ContrailOffset: -16, -17
Offset: -725,-683,0
FallsToEarth:
Spins: no
Moves: yes
Explosion: UnitExplode
SmokeTrailWhenDamaged:
Offset: 0,-25
Offset: -1c43,0,0
Interval: 2

View File

@@ -501,8 +501,9 @@ MGG:
Speed: 6
RevealsShroud:
Range: 6
RenderUnitSpinner:
Offset: 0,6
RenderUnit:
WithSpinner:
Offset: -299,0,171
AttackMove:
JustMove: yes
CreatesShroud:
@@ -522,10 +523,7 @@ MGG.Husk:
Image: mgg
ThrowsParticle@spinner:
Anim: spinner-idle
Spread: 3,3
Speed: 6
AnimKey: spinner-idle
Offset: 0,6
Offset: -299,0,171
MRJ:
Inherits: ^Vehicle
@@ -546,8 +544,9 @@ MRJ:
Speed: 6
RevealsShroud:
Range: 6
RenderUnitSpinner:
Offset: 0,6
RenderUnit:
WithSpinner:
Offset: -256,0,256
AttackMove:
JustMove: yes
Explodes:
@@ -562,9 +561,6 @@ MRJ:
Image: 1tnk
ThrowsParticle@turret:
Anim: turret
Spread: 3,3
Speed: 6
AnimKey: turret
2TNK.Husk:
Inherits: ^Husk
@@ -574,9 +570,6 @@ MRJ:
Image: 2tnk
ThrowsParticle@turret:
Anim: turret
Spread: 3,3
Speed: 6
AnimKey: turret
3TNK.Husk:
Inherits: ^Husk
@@ -586,9 +579,6 @@ MRJ:
Image: 3tnk
ThrowsParticle@turret:
Anim: turret
Spread: 3,3
Speed: 6
AnimKey: turret
4TNK.Husk:
Inherits: ^Husk
@@ -598,9 +588,6 @@ MRJ:
Image: 4tnk
ThrowsParticle@turret:
Anim: turret
Spread: 3,3
Speed: 6
AnimKey: turret
HARV.FullHusk:
Inherits: ^Husk
@@ -649,7 +636,8 @@ TTNK:
Weapon: TTankZap
LocalOffset: 0,0,213
AttackFrontal:
RenderUnitSpinner:
RenderUnit:
WithSpinner:
Selectable:
Bounds: 28,28,0,0
AutoTarget: