changes facing (and desireFacing) on Mobile and on Turreted. range is now 0..255

This commit is contained in:
Bob
2009-10-19 23:45:14 +13:00
parent 451fdc1615
commit a7ce0f97d1
14 changed files with 162 additions and 150 deletions

View File

@@ -25,7 +25,9 @@ namespace OpenRa.Game
if (leftMouseButton) return; if (leftMouseButton) return;
if (game.LocalPlayer == Unit.Owner) if (game.LocalPlayer == Unit.Owner)
game.PlaySound("ackno.r00", false); game.PlaySound("ackno.r00", false);
Unit.traits.Get<Traits.Mobile>().destination = Destination; var mobile = Unit.traits.Get<Traits.Mobile>();
mobile.destination = Destination;
mobile.desiredFacing = null;
} }
} }

View File

@@ -140,6 +140,7 @@
<Compile Include="Traits\TraitsInterfaces.cs" /> <Compile Include="Traits\TraitsInterfaces.cs" />
<Compile Include="Traits\Tree.cs" /> <Compile Include="Traits\Tree.cs" />
<Compile Include="Traits\Turreted.cs" /> <Compile Include="Traits\Turreted.cs" />
<Compile Include="Traits\Util.cs" />
<Compile Include="UiOverlay.cs" /> <Compile Include="UiOverlay.cs" />
<Compile Include="Graphics\UnitSheetBuilder.cs" /> <Compile Include="Graphics\UnitSheetBuilder.cs" />
<Compile Include="Graphics\Util.cs" /> <Compile Include="Graphics\Util.cs" />

View File

@@ -30,7 +30,7 @@ namespace OpenRa.Game.Traits
var mobile = self.traits.Get<Mobile>(); var mobile = self.traits.Get<Mobile>();
var turreted = self.traits.Get<Turreted>(); var turreted = self.traits.Get<Turreted>();
turreted.desiredFacing = mobile.GetFacing( target.Location - self.Location ); turreted.desiredFacing = Util.GetFacing( target.CenterLocation - self.CenterLocation, turreted.turretFacing );
if( turreted.desiredFacing != turreted.turretFacing ) if( turreted.desiredFacing != turreted.turretFacing )
return; return;

View File

@@ -15,6 +15,7 @@ namespace OpenRa.Game.Traits
public Order Order(Actor self, Game game, int2 xy) public Order Order(Actor self, Game game, int2 xy)
{ {
DeployLocation = null;
// TODO: check that there's enough space at the destination. // TODO: check that there's enough space at the destination.
if( xy == self.Location ) if( xy == self.Location )
return new DeployMcvOrder( self, xy ); return new DeployMcvOrder( self, xy );
@@ -24,18 +25,15 @@ namespace OpenRa.Game.Traits
public void Tick(Actor self, Game game, int dt) public void Tick(Actor self, Game game, int dt)
{ {
var mobile = self.traits.Get<Mobile>(); if( self.Location != DeployLocation )
return;
var mobile = self.traits.Get<Mobile>();
mobile.desiredFacing = 96;
if( mobile.moveFraction < mobile.moveFractionTotal ) if( mobile.moveFraction < mobile.moveFractionTotal )
return; return;
if( self.Location != DeployLocation ) if( mobile.facing != mobile.desiredFacing )
{
DeployLocation = null;
return;
}
if (mobile.Turn(12))
return; return;
game.world.AddFrameEndTask(_ => game.world.AddFrameEndTask(_ =>

View File

@@ -15,6 +15,7 @@ namespace OpenRa.Game.Traits
public int2 toCell { get { return self.Location; } } public int2 toCell { get { return self.Location; } }
public int moveFraction, moveFractionTotal; public int moveFraction, moveFractionTotal;
public int facing; public int facing;
public int? desiredFacing;
public Mobile(Actor self) public Mobile(Actor self)
{ {
@@ -22,41 +23,6 @@ namespace OpenRa.Game.Traits
fromCell = destination = self.Location; fromCell = destination = self.Location;
} }
public bool Turn(int desiredFacing)
{
if (facing == desiredFacing)
return false;
int df = (desiredFacing - facing + 32) % 32;
facing = (facing + (df > 16 ? 31 : 1)) % 32;
return true;
}
static float2[] fvecs = Util.MakeArray<float2>(32,
i => -float2.FromAngle(i / 16.0f * (float)Math.PI) * new float2(1f, 1.3f));
// TODO: move this somewhere more appropriate, now that AttackTurreted uses it.
public int GetFacing(float2 d)
{
if (float2.WithinEpsilon(d, float2.Zero, 0.001f))
return facing;
int highest = -1;
float highestDot = -1.0f;
for (int i = 0; i < fvecs.Length; i++)
{
float dot = float2.Dot(fvecs[i], d);
if (dot > highestDot)
{
highestDot = dot;
highest = i;
}
}
return highest;
}
void UpdateCenterLocation() void UpdateCenterLocation()
{ {
float fraction = (moveFraction > 0) ? (float)moveFraction / moveFractionTotal : 0f; float fraction = (moveFraction > 0) ? (float)moveFraction / moveFractionTotal : 0f;
@@ -71,13 +37,19 @@ namespace OpenRa.Game.Traits
void Move(Actor self, Game game, int dt) void Move(Actor self, Game game, int dt)
{ {
if (fromCell != toCell) if( fromCell != toCell )
{ desiredFacing = Util.GetFacing( toCell - fromCell, facing );
if (Turn(GetFacing(toCell - fromCell)))
return;
moveFraction += dt * ((UnitInfo.MobileInfo)self.unitInfo).Speed; if( desiredFacing != null && desiredFacing != facing )
{
Util.TickFacing( ref facing, desiredFacing.Value, self.unitInfo.ROT );
return;
} }
desiredFacing = null;
if( fromCell != toCell )
moveFraction += dt * ((UnitInfo.MobileInfo)self.unitInfo).Speed;
if (moveFraction < moveFractionTotal) if (moveFraction < moveFractionTotal)
return; return;

View File

@@ -10,8 +10,8 @@ namespace OpenRa.Game.Traits
public RenderBuildingTurreted(Actor self) public RenderBuildingTurreted(Actor self)
: base(self) : base(self)
{ {
anim.PlayThen("make", () => anim.PlayFetchIndex("idle", anim.PlayThen( "make", () => anim.PlayFetchIndex( "idle",
() => self.traits.Get<Turreted>().turretFacing)); () => self.traits.Get<Turreted>().turretFacing / 8 ) );
} }
} }
} }

View File

@@ -12,7 +12,7 @@ namespace OpenRa.Game.Traits
public RenderUnit(Actor self) public RenderUnit(Actor self)
: base(self) : base(self)
{ {
anim.PlayFetchIndex("idle", () => self.traits.Get<Mobile>().facing); anim.PlayFetchIndex("idle", () => self.traits.Get<Mobile>().facing / 8);
} }
protected static Pair<Sprite, float2> Centered(Sprite s, float2 location) protected static Pair<Sprite, float2> Centered(Sprite s, float2 location)

View File

@@ -15,7 +15,7 @@ namespace OpenRa.Game.Traits
: base(self) : base(self)
{ {
turretAnim = new Animation(self.unitInfo.Name); turretAnim = new Animation(self.unitInfo.Name);
turretAnim.PlayFetchIndex("turret", () => self.traits.Get<Turreted>().turretFacing); turretAnim.PlayFetchIndex("turret", () => self.traits.Get<Turreted>().turretFacing / 8);
} }
public override IEnumerable<Pair<Sprite, float2>> Render(Actor self) public override IEnumerable<Pair<Sprite, float2>> Render(Actor self)

View File

@@ -14,21 +14,13 @@ namespace OpenRa.Game.Traits
{ {
} }
public void Tick(Actor self, Game game, int dt) public void Tick( Actor self, Game game, int dt )
{ {
// TODO: desiredFacing should follow the base unit's facing only when not in combat. // TODO: desiredFacing should follow the base unit's facing only when not in combat.
// also, we want to be able to use this for GUN; avoid referencing Mobile. // also, we want to be able to use this for GUN; avoid referencing Mobile.
var df = desiredFacing ?? self.traits.Get<Mobile>().facing; var df = desiredFacing ?? self.traits.Get<Mobile>().facing;
if( turretFacing != desiredFacing ) Util.TickFacing( ref turretFacing, df, self.unitInfo.ROT );
{
var leftTurn = ( 32 + turretFacing - desiredFacing ) % 32;
var rightTurn = ( 32 + desiredFacing - turretFacing ) % 32;
if( leftTurn > rightTurn )
turretFacing = ( turretFacing + 1 ) % 32;
else
turretFacing = ( turretFacing + 31 ) % 32;
}
} }
} }
} }

47
OpenRa.Game/Traits/Util.cs Executable file
View File

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace OpenRa.Game.Traits
{
static class Util
{
public static void TickFacing( ref int facing, int desiredFacing, int rot )
{
var leftTurn = ( facing - desiredFacing ) & 0xFF;
var rightTurn = ( desiredFacing - facing ) & 0xFF;
if( Math.Min( leftTurn, rightTurn ) < rot )
facing = desiredFacing;
else if( rightTurn < leftTurn )
facing = ( facing + rot ) & 0xFF;
else
facing = ( facing - rot ) & 0xFF;
}
static float2[] fvecs = Graphics.Util.MakeArray<float2>( 32,
i => -float2.FromAngle( i / 16.0f * (float)Math.PI ) * new float2( 1f, 1.3f ) );
public static int GetFacing( float2 d, int currentFacing )
{
if( float2.WithinEpsilon( d, float2.Zero, 0.001f ) )
return currentFacing;
int highest = -1;
float highestDot = -1.0f;
for( int i = 0 ; i < fvecs.Length ; i++ )
{
float dot = float2.Dot( fvecs[ i ], d );
if( dot > highestDot )
{
highestDot = dot;
highest = i;
}
}
return highest * 8;
}
}
}