diff --git a/OpenRa.Game/GameRules/UnitInfo.cs b/OpenRa.Game/GameRules/UnitInfo.cs index 03d7cb66ef..420ca1811f 100755 --- a/OpenRa.Game/GameRules/UnitInfo.cs +++ b/OpenRa.Game/GameRules/UnitInfo.cs @@ -38,7 +38,7 @@ namespace OpenRa.Game.GameRules public readonly string[] Prerequisite = { }; public readonly string Primary = null; public readonly string Secondary = null; - public readonly int ROT = 0; + public readonly int ROT = 255; public readonly int Reload = 0; public readonly bool SelfHealing = false; public readonly bool Sensors = false; // no idea what this does @@ -67,6 +67,7 @@ namespace OpenRa.Game.GameRules public readonly bool FraidyCat = false; public readonly bool Infiltrate = false; public readonly bool IsCanine = false; + public readonly int SquadSize = 1; public InfantryInfo(string name) : base(name) { } } diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 850c205523..34349e70fc 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -129,6 +129,7 @@ + diff --git a/OpenRa.Game/Traits/InfantrySquad.cs b/OpenRa.Game/Traits/InfantrySquad.cs new file mode 100644 index 0000000000..6f04a50d9f --- /dev/null +++ b/OpenRa.Game/Traits/InfantrySquad.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using OpenRa.Game.Graphics; +using IjwFramework.Types; +using OpenRa.Game.GameRules; + +namespace OpenRa.Game.Traits +{ + class InfantrySquad : ITick, IRender + { + readonly List elements = new List(); + + readonly int2[][] elementOffsets = new [] + { + new int2[] {}, + new [] { new int2(0,0) }, + new [] { new int2(-5,-5), new int2(5,5) }, + new [] { new int2(-6,5), new int2(0, -5), new int2(6,4) }, /* todo: move squad arrangements ! */ + }; + + public InfantrySquad(Actor self) + { + var ii = (UnitInfo.InfantryInfo)self.unitInfo; + for (int i = 0; i < ii.SquadSize; i++) + elements.Add(new Soldier(self.unitInfo.Name, + self.CenterLocation.ToInt2() + elementOffsets[ii.SquadSize][i])); + } + + public void Tick(Actor self) + { + for (int i = 0; i < elements.Count; i++) + elements[i].Tick( + self.CenterLocation.ToInt2() + elementOffsets[elements.Count][i]); + } + + public IEnumerable> Render(Actor self) + { + return elements.Select( + e => Util.Centered(e.anim.Image, e.location)) + .OrderBy( a => a.Second.Y ); /* important to y-order elements of a squad! */ + } + } + + class Soldier + { + public Animation anim; + public float2 location; + string name; + int facing = 128; + + string currentSequence; + + void PlaySequence(string seq, bool isFacing) + { + if (currentSequence == seq) return; + currentSequence = seq; + + if (isFacing) + anim.PlayFetchIndex(seq, () => facing / (256 / anim.CurrentSequence.Length)); + else + anim.PlayRepeating(seq); + } + + public Soldier(string type, int2 initialLocation) + { + name = type; + anim = new Animation(type); + anim.PlayFetchIndex("stand", + () => facing / (256 / anim.CurrentSequence.Length) ); + location = initialLocation; + } + + public void Tick( int2 desiredLocation ) + { + anim.Tick(); + var d = (desiredLocation - location); + var speed = ((UnitInfo.InfantryInfo)Rules.UnitInfo[name]).Speed / 2; + + facing = Util.GetFacing(d, facing); + + if (float2.WithinEpsilon(d, float2.Zero, .1f)) + PlaySequence("stand", true); + else + PlaySequence("run-" + (facing / 32), false); + + if (d.Length > speed) + d = (d.Length / speed) * d; + + location += d; + } + } +} diff --git a/OpenRa.Game/Traits/Mobile.cs b/OpenRa.Game/Traits/Mobile.cs index 900c614191..fa15ebcf74 100644 --- a/OpenRa.Game/Traits/Mobile.cs +++ b/OpenRa.Game/Traits/Mobile.cs @@ -74,7 +74,7 @@ namespace OpenRa.Game.Traits public UnitMovementType GetMovementType() { - var vi = self.unitInfo as UnitInfo.VehicleInfo; + var vi = self.unitInfo as UnitInfo.VehicleInfo; if (vi == null) return UnitMovementType.Foot; if (vi.WaterBound) return UnitMovementType.Float; return vi.Tracked ? UnitMovementType.Track : UnitMovementType.Wheel; diff --git a/OpenRa.Game/Traits/RenderUnit.cs b/OpenRa.Game/Traits/RenderUnit.cs index 43f3430aae..a20cb6d793 100644 --- a/OpenRa.Game/Traits/RenderUnit.cs +++ b/OpenRa.Game/Traits/RenderUnit.cs @@ -17,15 +17,9 @@ namespace OpenRa.Game.Traits / (256/anim.CurrentSequence.Length)); } - protected static Pair Centered(Sprite s, float2 location) - { - var loc = location - 0.5f * s.size; - return Pair.New(s, loc.Round()); - } - public override IEnumerable> Render(Actor self) { - yield return Centered( anim.Image, self.CenterLocation ); + yield return Util.Centered(anim.Image, self.CenterLocation); } } } diff --git a/OpenRa.Game/Traits/RenderUnitTurreted.cs b/OpenRa.Game/Traits/RenderUnitTurreted.cs index fea38cb4d5..88691f5ad7 100644 --- a/OpenRa.Game/Traits/RenderUnitTurreted.cs +++ b/OpenRa.Game/Traits/RenderUnitTurreted.cs @@ -23,11 +23,11 @@ namespace OpenRa.Game.Traits { var mobile = self.traits.Get(); - yield return Centered(anim.Image, self.CenterLocation); - yield return Centered(turretAnim.Image, self.CenterLocation + yield return Util.Centered(anim.Image, self.CenterLocation); + yield return Util.Centered(turretAnim.Image, self.CenterLocation + Util.GetTurretPosition(self, self.unitInfo.PrimaryOffset, primaryRecoil)); if (self.unitInfo.SecondaryOffset != null) - yield return Centered(turretAnim.Image, self.CenterLocation + yield return Util.Centered(turretAnim.Image, self.CenterLocation + Util.GetTurretPosition(self, self.unitInfo.SecondaryOffset, secondaryRecoil)); } diff --git a/OpenRa.Game/Traits/Util.cs b/OpenRa.Game/Traits/Util.cs index 34fe637be9..dca26daaa9 100755 --- a/OpenRa.Game/Traits/Util.cs +++ b/OpenRa.Game/Traits/Util.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using IjwFramework.Types; +using OpenRa.Game.Graphics; namespace OpenRa.Game.Traits { @@ -88,5 +90,11 @@ namespace OpenRa.Game.Traits return (RotateVectorByFacing(new float2(offset[0], offset[1]), quantizedFacing, .7f) + GetRecoil(self, recoil)); } + public static Pair Centered(Sprite s, float2 location) + { + var loc = location - 0.5f * s.size; + return Pair.New(s, loc.Round()); + } + } } diff --git a/units.ini b/units.ini index 6033e558f0..117c9a1450 100755 --- a/units.ini +++ b/units.ini @@ -372,14 +372,19 @@ Description=Attack Dog BuiltAt=KENN [E1] Description=Rifle Infantry +Traits=InfantrySquad,Mobile +SquadSize=3 [E2] Description=Grenadier [E3] Description=Rocket Soldier +Traits=InfantrySquad,Mobile +SquadSize=2 [E4] Description=Flamethrower [E6] Description=Engineer +Traits=InfantrySquad,Mobile [SPY] Description=Spy [THF]