Combine IHasLocation -> IOccupySpace, IMove -> ITeleportable.

This commit is contained in:
Paul Chote
2013-07-21 10:44:07 +12:00
parent 36a45d1a3f
commit ecc119cb29
31 changed files with 61 additions and 65 deletions

View File

@@ -26,8 +26,6 @@ namespace OpenRA
public readonly uint ActorID;
Lazy<IOccupySpace> occupySpace;
IHasLocation HasLocation;
Lazy<IMove> Move;
Lazy<IFacing> Facing;
public Cached<Rectangle> Bounds;
@@ -37,21 +35,13 @@ namespace OpenRA
public CPos Location { get { return occupySpace.Value.TopLeft; } }
public PPos CenterLocation
{
get
{
if (HasLocation == null)
HasLocation = Trait<IHasLocation>();
return HasLocation.PxPosition;
}
}
public PPos CenterLocation { get { return occupySpace.Value.PxPosition; } }
public WPos CenterPosition
{
get
{
var altitude = Move.Value != null ? Move.Value.Altitude : 0;
var altitude = occupySpace.Value != null ? occupySpace.Value.Altitude : 0;
return CenterLocation.ToWPos(altitude);
}
}
@@ -93,7 +83,6 @@ namespace OpenRA
AddTrait(trait.Create(init));
}
Move = Lazy.New(() => TraitOrDefault<IMove>());
Facing = Lazy.New(() => TraitOrDefault<IFacing>());
Size = Lazy.New(() =>
@@ -152,13 +141,13 @@ namespace OpenRA
loc += new PVecInt(si.Bounds[2], si.Bounds[3]);
}
var move = Move.Value;
if (move != null)
var ios = occupySpace.Value;
if (ios != null)
{
loc -= new PVecInt(0, move.Altitude);
loc -= new PVecInt(0, ios.Altitude);
if (useAltitude)
size = new PVecInt(size.X, size.Y + move.Altitude);
size = new PVecInt(size.X, size.Y + ios.Altitude);
}
return new Rectangle(loc.X, loc.Y, size.X, size.Y);

View File

@@ -96,12 +96,16 @@ namespace OpenRA.Traits
public interface IVisibilityModifier { bool IsVisible(Actor self, Player byPlayer); }
public interface IRadarColorModifier { Color RadarColorOverride(Actor self); }
public interface IHasLocation { PPos PxPosition { get; } }
public interface IOccupySpace : IHasLocation
public interface IOccupySpace
{
PPos PxPosition { get; }
CPos TopLeft { get; }
IEnumerable<Pair<CPos, SubCell>> OccupiedCells();
// TODO: We shouldn't expose the setter here
// This will be going away soon, so isn't a big deal
int Altitude { get; set; }
}
public static class IOccupySpaceExts
@@ -134,7 +138,7 @@ namespace OpenRA.Traits
public interface ITags { IEnumerable<TagType> GetTags(); }
public interface ISelectionBar { float GetValue(); Color GetColor(); }
public interface ITeleportable : IHasLocation /* crap name! */
public interface ITeleportable : IOccupySpace
{
bool CanEnterCell(CPos location);
void SetPosition(Actor self, CPos cell);
@@ -142,7 +146,6 @@ namespace OpenRA.Traits
void AdjustPxPosition(Actor self, PPos px); /* works like SetPxPosition, but visual only */
}
public interface IMove : ITeleportable { int Altitude { get; set; } }
public interface INotifyBlockingMove { void OnNotifyBlockingMove(Actor self, Actor blocking); }
public interface IFacing

View File

@@ -31,5 +31,6 @@ namespace OpenRA.Traits
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { yield break; }
public PPos PxPosition { get { return Util.CenterOfCell(location); } }
public int Altitude { get { return 0; } set { } }
}
}

View File

@@ -45,7 +45,7 @@ namespace OpenRA.Traits
for (var i = 0; i <= bins.GetUpperBound(0); i++)
bins[i, j].Clear();
foreach (var a in self.World.ActorsWithTrait<IHasLocation>())
foreach (var a in self.World.ActorsWithTrait<IOccupySpace>())
{
var bounds = a.Actor.ExtendedBounds.Value;

View File

@@ -205,7 +205,7 @@ namespace OpenRA.Mods.Cnc.Missions
{
if (b.Destroyed) return;
w2.Add(b);
b.TraitsImplementing<IMove>().FirstOrDefault().SetPosition(b, a.Location);
b.TraitsImplementing<ITeleportable>().FirstOrDefault().SetPosition(b, a.Location);
b.QueueActivity(mobile.MoveTo(unload, 2));
});
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2012 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2013 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,
@@ -135,7 +135,7 @@ namespace OpenRA.Mods.Cnc.Missions
IEnumerable<Actor> UnitsNearActor(Actor actor, int range)
{
return world.FindActorsInCircle(actor.CenterPosition, WRange.FromCells(range))
.Where(a => a.IsInWorld && a != world.WorldActor && !a.Destroyed && a.HasTrait<IMove>() && !a.Owner.NonCombatant);
.Where(a => a.IsInWorld && a != world.WorldActor && !a.Destroyed && a.HasTrait<ITeleportable>() && !a.Owner.NonCombatant);
}
void NODReinforceNthA()
@@ -198,4 +198,4 @@ namespace OpenRA.Mods.Cnc.Missions
Media.PlayFMVFullscreen(w, "nod1.vqa", afterFMV)));
}
}
}
}

View File

@@ -763,7 +763,7 @@ namespace OpenRA.Mods.RA.AI
if (!buildableThings.Any()) return null;
var myUnits = p.World
.ActorsWithTrait<IMove>()
.ActorsWithTrait<ITeleportable>()
.Where(a => a.Actor.Owner == p)
.Select(a => a.Actor.Info.Name).ToArray();
@@ -783,7 +783,7 @@ namespace OpenRA.Mods.RA.AI
int CountUnits(string unit, Player owner)
{
return world.ActorsWithTrait<IMove>().Where(a => a.Actor.Owner == owner && a.Actor.Info.Name == unit).Count();
return world.ActorsWithTrait<ITeleportable>().Where(a => a.Actor.Owner == owner && a.Actor.Info.Name == unit).Count();
}
int? CountBuildingByCommonName(string commonName, Player owner)
@@ -1145,7 +1145,7 @@ namespace OpenRA.Mods.RA.AI
void FindNewUnits(Actor self)
{
var newUnits = self.World.ActorsWithTrait<IMove>()
var newUnits = self.World.ActorsWithTrait<ITeleportable>()
.Where(a => a.Actor.Owner == p && !a.Actor.HasTrait<BaseBuilding>()
&& !activeUnits.Contains(a.Actor))
.Select(a => a.Actor).ToArray();

View File

@@ -36,7 +36,7 @@ namespace OpenRA.Mods.RA.Air
public int GetInitialFacing() { return InitialFacing; }
}
public class Aircraft : IMove, IFacing, IOccupySpace, ISync, INotifyKilled, IIssueOrder, IOrderVoice
public class Aircraft : IFacing, ITeleportable, ISync, INotifyKilled, IIssueOrder, IOrderVoice
{
public IDisposable reservation;
@@ -77,7 +77,7 @@ namespace OpenRA.Mods.RA.Air
public Actor GetActorBelow()
{
if (self.Trait<IMove>().Altitude != 0)
if (self.Trait<IOccupySpace>().Altitude != 0)
return null; // not on the ground.
return self.World.FindActorsInBox(self.CenterPosition, self.CenterPosition)

View File

@@ -30,7 +30,7 @@ namespace OpenRA.Mods.RA
var pilot = self.World.CreateActor(false, info.PilotActor.ToLowerInvariant(),
new TypeDictionary { new OwnerInit(self.Owner) });
var r = self.World.SharedRandom.Next(1, 100);
var aircraft = self.Trait<IMove>();
var aircraft = self.Trait<ITeleportable>();
if (IsSuitableCell(pilot, self.Location) && r > 100 - info.SuccessRate && aircraft.Altitude > 10
&& self.Owner.WinState != WinState.Lost)

View File

@@ -99,7 +99,7 @@ namespace OpenRA.Mods.RA
// Note: facing is only used by the legacy positioning code
// The world coordinate model uses Actor.Orientation
public void CheckFire(Actor self, AttackBase attack, IMove move, IFacing facing, Target target)
public void CheckFire(Actor self, AttackBase attack, IFacing facing, Target target)
{
if (FireDelay > 0) return;
@@ -120,7 +120,7 @@ namespace OpenRA.Mods.RA
return;
var barrel = Barrels[Burst % Barrels.Length];
var destMove = target.IsActor ? target.Actor.TraitOrDefault<IMove>() : null;
var destios = target.IsActor ? target.Actor.TraitOrDefault<IOccupySpace>() : null;
var muzzlePosition = self.CenterPosition + MuzzleOffset(self, barrel);
var legacyMuzzlePosition = PPos.FromWPos(muzzlePosition);
@@ -136,7 +136,7 @@ namespace OpenRA.Mods.RA
srcAltitude = legacyMuzzleAltitude,
dest = target.CenterLocation,
destAltitude = destMove != null ? destMove.Altitude : 0,
destAltitude = destios != null ? destios.Altitude : 0,
facing = legacyFacing,

View File

@@ -89,12 +89,12 @@ namespace OpenRA.Mods.RA
public virtual void DoAttack(Actor self, Target target)
{
if( !CanAttack( self, target ) ) return;
if (!CanAttack(self, target))
return;
var move = self.TraitOrDefault<IMove>();
var facing = self.TraitOrDefault<IFacing>();
foreach (var a in Armaments)
a.CheckFire(self, this, move, facing, target);
a.CheckFire(self, this, facing, target);
}
public IEnumerable<IOrderTargeter> Orders

View File

@@ -38,10 +38,9 @@ namespace OpenRA.Mods.RA
if (!target.IsInRange(self.CenterPosition, range))
return;
var move = self.TraitOrDefault<IMove>();
var facing = self.TraitOrDefault<IFacing>();
foreach (var a in Armaments)
a.CheckFire(self, this, move, facing, target);
a.CheckFire(self, this, facing, target);
if (target.Actor != null)
target.Actor.ChangeOwner(self.Owner);

View File

@@ -158,7 +158,7 @@ namespace OpenRA.Mods.RA
{
foreach (var c in TileSprites[currentTemplate].Keys)
foreach (var a in self.World.ActorMap.GetUnitsAt(c))
if (a.HasTrait<IMove>() && !a.Trait<IMove>().CanEnterCell(c))
if (a.HasTrait<ITeleportable>() && !a.Trait<ITeleportable>().CanEnterCell(c))
a.Kill(self);
}

View File

@@ -111,6 +111,7 @@ namespace OpenRA.Mods.RA.Buildings
public CPos TopLeft { get { return topLeft; } }
public PPos PxPosition { get { return pxPosition; } }
public int Altitude { get { return 0; } set { } }
public IEnumerable<string> ProvidesPrerequisites { get { yield return self.Info.Name; } }

View File

@@ -92,8 +92,8 @@ namespace OpenRA.Mods.RA
return false;
// Cannot unload mid-air
var move = self.TraitOrDefault<IMove>();
if (move != null && move.Altitude > info.minimalUnloadAltitude)
var ios = self.TraitOrDefault<IOccupySpace>();
if (ios != null && ios.Altitude > info.minimalUnloadAltitude)
return false;
// TODO: Check if there is a free tile to unload to
@@ -106,8 +106,8 @@ namespace OpenRA.Mods.RA
return false;
// Cannot load mid-air
var move = self.TraitOrDefault<IMove>();
return move == null || move.Altitude == info.minimalUnloadAltitude;
var ios = self.TraitOrDefault<IOccupySpace>();
return ios == null || ios.Altitude == info.minimalUnloadAltitude;
}
public string CursorForOrder(Actor self, Order order)

View File

@@ -58,7 +58,7 @@ namespace OpenRA.Mods.RA
var args = new ProjectileArgs
{
srcAltitude = self.Trait<IMove>().Altitude,
srcAltitude = self.Trait<IOccupySpace>().Altitude,
destAltitude = 0,
src = self.CenterLocation,
dest = self.CenterLocation,

View File

@@ -94,7 +94,7 @@ namespace OpenRA.Mods.RA
public bool CanJumpTo(CPos xy, bool ignoreVis)
{
var movement = self.TraitOrDefault<IMove>();
var movement = self.TraitOrDefault<ITeleportable>();
if (chargeTick <= 0 // Can jump
&& (self.Location - xy).Length <= Info.JumpDistance // Within jump range

View File

@@ -24,7 +24,7 @@ namespace OpenRA.Mods.RA
}
// ITeleportable is required for paradrop
class Crate : ITick, IOccupySpace, ITeleportable, ICrushable, ISync, INotifyParachuteLanded
class Crate : ITick, ITeleportable, ICrushable, ISync, INotifyParachuteLanded
{
readonly Actor self;
[Sync] int ticks;
@@ -86,6 +86,7 @@ namespace OpenRA.Mods.RA
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { yield return Pair.New( Location, SubCell.FullCell); }
public PPos PxPosition { get; private set; }
public int Altitude { get { return 0; } set { } }
public void SetPxPosition(Actor self, PPos px)
{

View File

@@ -98,8 +98,8 @@ namespace OpenRA.Mods.RA.Effects
var dist = Args.target.CenterLocation + offset - PxPosition;
var targetAltitude = 0;
if (Args.target.IsValid && Args.target.IsActor && Args.target.Actor.HasTrait<IMove>())
targetAltitude = Args.target.Actor.Trait<IMove>().Altitude;
if (Args.target.IsValid && Args.target.IsActor && Args.target.Actor.HasTrait<IOccupySpace>())
targetAltitude = Args.target.Actor.Trait<IOccupySpace>().Altitude;
var jammed = Info.Jammable && world.ActorsWithTrait<JamsMissiles>().Any(tp =>
(tp.Actor.CenterLocation - PxPosition).ToCVec().Length <= tp.Trait.Range

View File

@@ -27,6 +27,7 @@ namespace OpenRA.Mods.RA
[Sync] CPos location;
[Sync] public PPos PxPosition { get; set; }
public int Altitude { get { return 0; } set { } }
[Sync] public int Facing { get; set; }
public int ROT { get { return 0; } }

View File

@@ -62,6 +62,7 @@ namespace OpenRA.Mods.RA
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { yield return Pair.New(TopLeft, SubCell.FullCell); }
public PPos PxPosition { get { return Util.CenterOfCell( location ); } }
public int Altitude { get { return 0; } set { } }
}
/* tag trait for stuff that shouldnt trigger mines */

View File

@@ -60,7 +60,7 @@ namespace OpenRA.Mods.RA
if (order.OrderString == "PlaceMinefield")
{
var movement = self.Trait<IMove>();
var movement = self.Trait<ITeleportable>();
minefield = GetMinefieldCells(minefieldStart, order.TargetLocation,
self.Info.Traits.Get<MinelayerInfo>().MinefieldDepth)
@@ -130,7 +130,7 @@ namespace OpenRA.Mods.RA
if (!minelayer.IsInWorld)
return;
var movement = minelayer.Trait<IMove>();
var movement = minelayer.Trait<ITeleportable>();
var minefield = GetMinefieldCells(minefieldStart, lastMousePos,
minelayer.Info.Traits.Get<MinelayerInfo>().MinefieldDepth)
.Where(p => movement.CanEnterCell(p)).ToArray();

View File

@@ -170,7 +170,7 @@ namespace OpenRA.Mods.RA.Missions
if (yak == null || (yak != null && !yak.IsDead() && (yak.GetCurrentActivity() is FlyCircle || yak.IsIdle)))
{
var alliedUnitsNearYakPoint = world.FindAliveCombatantActorsInCircle(yakAttackPoint.CenterPosition, WRange.FromCells(10))
.Where(a => a.Owner != soviets && a.HasTrait<IMove>() && a != tanya && a != einstein && a != engineer);
.Where(a => a.Owner != soviets && a.HasTrait<ITeleportable>() && a != tanya && a != einstein && a != engineer);
if (alliedUnitsNearYakPoint.Any())
YakStrafe(alliedUnitsNearYakPoint);
}
@@ -384,7 +384,7 @@ namespace OpenRA.Mods.RA.Missions
bool AlliesNearTown()
{
return world.FindAliveCombatantActorsInCircle(townPoint.CenterPosition, WRange.FromCells(AlliedTownTransferRange))
.Any(a => a.Owner == allies1 && a.HasTrait<IMove>());
.Any(a => a.Owner == allies1 && a.HasTrait<ITeleportable>());
}
void TransferTownUnitsToAllies()
@@ -399,7 +399,7 @@ namespace OpenRA.Mods.RA.Missions
var sovietAttackUnits = world.FindAliveCombatantActorsInCircle(sovietTownAttackPoint1.CenterPosition, WRange.FromCells(SovietTownAttackGroupRange))
.Union(world.FindAliveCombatantActorsInCircle(sovietTownAttackPoint2.CenterPosition, WRange.FromCells(SovietTownAttackGroupRange)))
.Union(world.FindAliveCombatantActorsInCircle(townPoint.CenterPosition, WRange.FromCells(AlliedTownTransferRange)))
.Where(a => a.HasTrait<IMove>() && a.Owner == soviets);
.Where(a => a.HasTrait<ITeleportable>() && a.Owner == soviets);
foreach (var unit in sovietAttackUnits)
unit.QueueActivity(new AttackMove.AttackMoveActivity(unit, new Move.Move(townPoint.Location, SovietTownMoveNearEnough)));

View File

@@ -106,7 +106,7 @@ namespace OpenRA.Mods.RA.Missions
public static bool AreaSecuredWithUnits(World world, Player player, WPos location, WRange range)
{
var units = world.FindAliveCombatantActorsInCircle(location, range).Where(a => a.HasTrait<IMove>());
var units = world.FindAliveCombatantActorsInCircle(location, range).Where(a => a.HasTrait<ITeleportable>());
return units.Any() && units.All(a => a.Owner == player);
}

View File

@@ -185,7 +185,7 @@ namespace OpenRA.Mods.RA.Missions
var units = world.CreateActor((sovietInfantry).Random(world.SharedRandom), new TypeDictionary { new LocationInit(sovietinfantryentry1.Location), new OwnerInit(soviets) });
units.QueueActivity(new Move.Move(sovietinfantryrally1.Location, 3));
var unitsincircle = world.FindAliveCombatantActorsInCircle(sovietinfantryrally1.CenterPosition, WRange.FromCells(10))
.Where(a => a.Owner == soviets && a.IsIdle && a.HasTrait<IMove>());
.Where(a => a.Owner == soviets && a.IsIdle && a.HasTrait<ITeleportable>());
if (unitsincircle.Count() >= sovietInfantryGroupSize)
{
foreach (var scatteredunits in unitsincircle)

View File

@@ -299,7 +299,7 @@ namespace OpenRA.Mods.RA.Missions
void ManageSovietUnits()
{
var units = world.FindAliveCombatantActorsInCircle(sovietrally.CenterPosition, WRange.FromCells(3))
.Where(u => u.IsIdle && u.HasTrait<IMove>() && u.HasTrait<AttackBase>() && u.Owner == soviets);
.Where(u => u.IsIdle && u.HasTrait<ITeleportable>() && u.HasTrait<AttackBase>() && u.Owner == soviets);
if (units.Count() >= sovietAttackGroupSize)
{
foreach (var unit in units)

View File

@@ -145,7 +145,7 @@ namespace OpenRA.Mods.RA.Move
public int GetInitialFacing() { return InitialFacing; }
}
public class Mobile : IIssueOrder, IResolveOrder, IOrderVoice, IOccupySpace, IMove, IFacing, ISync
public class Mobile : IIssueOrder, IResolveOrder, IOrderVoice, ITeleportable, IFacing, ISync
{
public readonly Actor self;
public readonly MobileInfo Info;

View File

@@ -50,7 +50,7 @@ namespace OpenRA.Mods.RA.Orders
if (!world.LocalPlayer.Shroud.IsExplored(xy))
return "move-blocked";
var movement = self.TraitOrDefault<IMove>();
var movement = self.TraitOrDefault<ITeleportable>();
return (movement.CanEnterCell(xy)) ? "chrono-target" : "move-blocked";
}
}

View File

@@ -112,7 +112,7 @@ namespace OpenRA.Mods.RA
attackerStats.BuildingsKilled++;
defenderStats.BuildingsDead++;
}
else if (self.HasTrait<IMove>())
else if (self.HasTrait<ITeleportable>())
{
attackerStats.UnitsKilled++;
defenderStats.UnitsDead++;

View File

@@ -40,7 +40,7 @@ namespace OpenRA.Mods.RA.Render
public void Tick(Actor self)
{
var isFlying = self.Trait<IMove>().Altitude > 0 && !self.IsDead();
var isFlying = self.Trait<IOccupySpace>().Altitude > 0 && !self.IsDead();
if (isFlying ^ (rotorAnim.CurrentSequence.Name != "rotor"))
return;

View File

@@ -24,16 +24,16 @@ namespace OpenRA.Mods.RA.Render
{
public IEnumerable<IRenderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<IRenderable> r)
{
var move = self.Trait<IMove>();
var ios = self.Trait<IOccupySpace>();
/* rude hack */
var visualOffset = ((move is Helicopter || move is Mobile) && move.Altitude > 0)
var visualOffset = ((ios is Helicopter || ios is Mobile) && ios.Altitude > 0)
? (int)Math.Abs((self.ActorID + Game.LocalTick) / 5 % 4 - 1) - 1 : 0;
var shadowSprites = r.Select(a => a.WithPalette(wr.Palette("shadow"))
.WithPos(a.Pos - new WVec(0, 0, a.Pos.Z)).WithZOffset(a.ZOffset + a.Pos.Z));
var flyingSprites = (move.Altitude <= 0) ? r :
var flyingSprites = (ios.Altitude <= 0) ? r :
r.Select(a => a.WithPos(a.Pos - new WVec(0,0,43*visualOffset)));
return shadowSprites.Concat(flyingSprites);