Refactor UnitInfluence trait -> world.ActorMap
This commit is contained in:
@@ -13,15 +13,21 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Traits
|
||||
namespace OpenRA
|
||||
{
|
||||
public class UnitInfluenceInfo : ITraitInfo
|
||||
public enum SubCell
|
||||
{
|
||||
public object Create( ActorInitializer init ) { return new UnitInfluence( init.world ); }
|
||||
FullCell,
|
||||
TopLeft,
|
||||
TopRight,
|
||||
Center,
|
||||
BottomLeft,
|
||||
BottomRight
|
||||
}
|
||||
|
||||
public class UnitInfluence
|
||||
public class ActorMap
|
||||
{
|
||||
class InfluenceNode
|
||||
{
|
||||
@@ -33,7 +39,7 @@ namespace OpenRA.Traits
|
||||
InfluenceNode[,] influence;
|
||||
Map map;
|
||||
|
||||
public UnitInfluence( World world )
|
||||
public ActorMap( World world )
|
||||
{
|
||||
map = world.Map;
|
||||
influence = new InfluenceNode[world.Map.MapSize.X, world.Map.MapSize.Y];
|
||||
@@ -136,7 +136,6 @@
|
||||
<Compile Include="Traits\Selectable.cs" />
|
||||
<Compile Include="Traits\Render\RenderSimple.cs" />
|
||||
<Compile Include="Traits\TraitsInterfaces.cs" />
|
||||
<Compile Include="Traits\World\UnitInfluence.cs" />
|
||||
<Compile Include="Network\UnitOrders.cs" />
|
||||
<Compile Include="Traits\Util.cs" />
|
||||
<Compile Include="UiOverlay.cs" />
|
||||
@@ -185,6 +184,7 @@
|
||||
<Compile Include="Widgets\ScrollItem.cs" />
|
||||
<Compile Include="Widgets\DropDownButtonWidget.cs" />
|
||||
<Compile Include="Download.cs" />
|
||||
<Compile Include="ActorMap.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
|
||||
|
||||
@@ -84,13 +84,12 @@ namespace OpenRA.Orders
|
||||
|
||||
if( mi.Button == MouseButton.Right )
|
||||
{
|
||||
var uim = self.World.WorldActor.Trait<UnitInfluence>();
|
||||
foreach( var o in self.TraitsImplementing<IIssueOrder>()
|
||||
.SelectMany( trait => trait.Orders
|
||||
.Select( x => new { Trait = trait, Order = x } ) )
|
||||
.OrderByDescending( x => x.Order.OrderPriority ) )
|
||||
{
|
||||
var actorsAt = uim.GetUnitsAt( xy ).ToList();
|
||||
var actorsAt = self.World.ActorMap.GetUnitsAt( xy ).ToList();
|
||||
|
||||
string cursor = null;
|
||||
if( underCursor != null )
|
||||
|
||||
@@ -85,16 +85,6 @@ namespace OpenRA.Traits
|
||||
public interface IRadarColorModifier { Color RadarColorOverride(Actor self); }
|
||||
public interface IHasLocation { int2 PxPosition { get; } }
|
||||
|
||||
public enum SubCell
|
||||
{
|
||||
FullCell,
|
||||
TopLeft,
|
||||
TopRight,
|
||||
Center,
|
||||
BottomLeft,
|
||||
BottomRight
|
||||
}
|
||||
|
||||
public interface IOccupySpace : IHasLocation
|
||||
{
|
||||
int2 TopLeft { get; }
|
||||
|
||||
@@ -15,7 +15,7 @@ using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA.Traits
|
||||
{
|
||||
public class ResourceLayerInfo : TraitInfo<ResourceLayer>, Requires<UnitInfluenceInfo> { }
|
||||
public class ResourceLayerInfo : TraitInfo<ResourceLayer> { }
|
||||
|
||||
public class ResourceLayer: IRenderOverlay, IWorldLoaded
|
||||
{
|
||||
@@ -84,7 +84,7 @@ namespace OpenRA.Traits
|
||||
{
|
||||
if (!world.Map.IsInMap(a.X, a.Y)) return false;
|
||||
if (!rt.info.AllowedTerrainTypes.Contains(world.GetTerrainInfo(a).Type)) return false;
|
||||
if (!rt.info.AllowUnderActors && world.WorldActor.Trait<UnitInfluence>().AnyUnitsAt(a)) return false;
|
||||
if (!rt.info.AllowUnderActors && world.ActorMap.AnyUnitsAt(a)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ namespace OpenRA
|
||||
public readonly Actor WorldActor;
|
||||
public readonly Map Map;
|
||||
public readonly TileSet TileSet;
|
||||
public readonly ActorMap ActorMap;
|
||||
|
||||
public void IssueOrder( Order o ) { orderManager.IssueOrder( o ); } /* avoid exposing the OM to mod code */
|
||||
|
||||
@@ -100,6 +101,7 @@ namespace OpenRA
|
||||
|
||||
WorldActor = CreateActor( "World", new TypeDictionary() );
|
||||
LocalShroud = WorldActor.Trait<Shroud>();
|
||||
ActorMap = new ActorMap(this);
|
||||
|
||||
// Add players
|
||||
foreach (var cmp in WorldActor.TraitsImplementing<ICreatePlayers>())
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
bool ShouldLayMine(Actor self, int2 p)
|
||||
{
|
||||
// if there is no unit (other than me) here, we want to place a mine here
|
||||
return !self.World.WorldActor.Trait<UnitInfluence>()
|
||||
return !self.World.ActorMap
|
||||
.GetUnitsAt(p).Any(a => a != self);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
int2? ChooseExitTile(Actor self, Actor cargo)
|
||||
{
|
||||
// is anyone still hogging this tile?
|
||||
if (self.World.WorldActor.Trait<UnitInfluence>().GetUnitsAt(self.Location).Count() > 1)
|
||||
if (self.World.ActorMap.GetUnitsAt(self.Location).Count() > 1)
|
||||
return null;
|
||||
|
||||
var mobile = cargo.Trait<Mobile>();
|
||||
|
||||
@@ -170,7 +170,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
if (!self.World.Map.IsInMap(cell))
|
||||
return false;
|
||||
|
||||
if (self.World.WorldActor.Trait<UnitInfluence>().AnyUnitsAt(cell))
|
||||
if (self.World.ActorMap.AnyUnitsAt(cell))
|
||||
return false;
|
||||
|
||||
var type = self.World.GetTerrainType(cell);
|
||||
|
||||
@@ -144,10 +144,8 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
void KillUnitsOnBridge()
|
||||
{
|
||||
var uim = self.World.WorldActor.Trait<UnitInfluence>();
|
||||
|
||||
foreach (var c in TileSprites[currentTemplate].Keys)
|
||||
foreach (var a in uim.GetUnitsAt(c))
|
||||
foreach (var a in self.World.ActorMap.GetUnitsAt(c))
|
||||
if (a.HasTrait<IMove>() && !a.Trait<IMove>().CanEnterCell(c))
|
||||
a.Kill(self);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
public static bool IsCellBuildable(this World world, int2 a, bool waterBound, Actor toIgnore)
|
||||
{
|
||||
if (world.WorldActor.Trait<BuildingInfluence>().GetBuildingAt(a) != null) return false;
|
||||
if (world.WorldActor.Trait<UnitInfluence>().GetUnitsAt(a).Any(b => b != toIgnore)) return false;
|
||||
if (world.ActorMap.GetUnitsAt(a).Any(b => b != toIgnore)) return false;
|
||||
|
||||
if (waterBound)
|
||||
return world.Map.IsInMap(a.X,a.Y) && world.GetTerrainInfo(a).IsWater;
|
||||
|
||||
@@ -100,17 +100,15 @@ namespace OpenRA.Mods.RA
|
||||
return false;
|
||||
|
||||
if (self.World.WorldActor.Trait<BuildingInfluence>().GetBuildingAt(cell) != null) return false;
|
||||
if (self.World.WorldActor.Trait<UnitInfluence>().GetUnitsAt(cell).Any()) return false;
|
||||
if (self.World.ActorMap.GetUnitsAt(cell).Any()) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetPosition(Actor self, int2 cell)
|
||||
{
|
||||
var uim = self.World.WorldActor.Trait<UnitInfluence>();
|
||||
|
||||
if( self.IsInWorld )
|
||||
uim.Remove(self, this);
|
||||
self.World.ActorMap.Remove(self, this);
|
||||
|
||||
Location = cell;
|
||||
PxPosition = Util.CenterOfCell(cell);
|
||||
@@ -121,7 +119,7 @@ namespace OpenRA.Mods.RA
|
||||
rs.anim.PlayRepeating(seq);
|
||||
|
||||
if( self.IsInWorld )
|
||||
uim.Add(self, this);
|
||||
self.World.ActorMap.Add(self, this);
|
||||
}
|
||||
|
||||
public IEnumerable<string> CrushClasses { get { yield return "crate"; } }
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
// Don't drop on any actors
|
||||
if (self.World.WorldActor.Trait<BuildingInfluence>().GetBuildingAt(p) != null) continue;
|
||||
if (self.World.WorldActor.Trait<UnitInfluence>().GetUnitsAt(p).Any()) continue;
|
||||
if (self.World.ActorMap.GetUnitsAt(p).Any()) continue;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
// Don't spawn on any actors
|
||||
if (self.World.WorldActor.Trait<BuildingInfluence>().GetBuildingAt(p) != null) continue;
|
||||
if (self.World.WorldActor.Trait<UnitInfluence>().GetUnitsAt(p).Any()) continue;
|
||||
if (self.World.ActorMap.GetUnitsAt(p).Any()) continue;
|
||||
|
||||
self.World.AddFrameEndTask(
|
||||
w => crates.Add(w.CreateActor("crate", new TypeDictionary
|
||||
|
||||
@@ -133,7 +133,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
var pos = float2.Lerp(Args.src, Args.dest, at);
|
||||
var cell = Traits.Util.CellContaining(pos);
|
||||
|
||||
if (world.WorldActor.Trait<UnitInfluence>().GetUnitsAt(cell).Any(
|
||||
if (world.ActorMap.GetUnitsAt(cell).Any(
|
||||
a => a.HasTrait<IBlocksBullets>()))
|
||||
{
|
||||
Args.dest = pos.ToInt2();
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
if (!Info.High) // check for hitting a wall
|
||||
{
|
||||
var cell = Traits.Util.CellContaining(PxPosition);
|
||||
if (world.WorldActor.Trait<UnitInfluence>().GetUnitsAt(cell).Any(
|
||||
if (world.ActorMap.GetUnitsAt(cell).Any(
|
||||
a => a.HasTrait<IBlocksBullets>()))
|
||||
Explode(world);
|
||||
}
|
||||
|
||||
@@ -83,15 +83,15 @@ namespace OpenRA.Mods.RA.Move
|
||||
{SubCell.FullCell, new int2(0,0)},
|
||||
};
|
||||
|
||||
public bool CanEnterCell(World world, UnitInfluence uim, int2 cell, Actor ignoreActor, bool checkTransientActors)
|
||||
public bool CanEnterCell(World world, int2 cell, Actor ignoreActor, bool checkTransientActors)
|
||||
{
|
||||
if (MovementCostForCell(world, cell) == int.MaxValue)
|
||||
return false;
|
||||
|
||||
if (SharesCell && uim.HasFreeSubCell(cell))
|
||||
if (SharesCell && world.ActorMap.HasFreeSubCell(cell))
|
||||
return true;
|
||||
|
||||
var blockingActors = uim.GetUnitsAt(cell).Where(x => x != ignoreActor).ToList();
|
||||
var blockingActors = world.ActorMap.GetUnitsAt(cell).Where(x => x != ignoreActor).ToList();
|
||||
if (checkTransientActors && blockingActors.Count > 0)
|
||||
{
|
||||
// Non-sharable unit can enter a cell with shareable units only if it can crush all of them
|
||||
@@ -105,12 +105,6 @@ namespace OpenRA.Mods.RA.Move
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CanEnterCell(World world, int2 cell, Actor ignoreActor, bool checkTransientActors)
|
||||
{
|
||||
var uim = world.WorldActor.Trait<UnitInfluence>();
|
||||
return CanEnterCell(world, uim, cell, ignoreActor, checkTransientActors);
|
||||
}
|
||||
}
|
||||
|
||||
public class Mobile : IIssueOrder, IResolveOrder, IOrderVoice, IOccupySpace, IMove, IFacing, INudge, ISync
|
||||
@@ -163,8 +157,6 @@ namespace OpenRA.Mods.RA.Move
|
||||
AddInfluence();
|
||||
}
|
||||
|
||||
UnitInfluence uim;
|
||||
|
||||
const int avgTicksBeforePathing = 5;
|
||||
const int spreadTicksBeforePathing = 5;
|
||||
internal int ticksBeforePathing = 0;
|
||||
@@ -174,7 +166,6 @@ namespace OpenRA.Mods.RA.Move
|
||||
this.self = init.self;
|
||||
this.Info = info;
|
||||
|
||||
uim = self.World.WorldActor.Trait<UnitInfluence>();
|
||||
__toSubCell = __fromSubCell = info.SharesCell ? SubCell.Center : SubCell.FullCell;
|
||||
if (init.Contains<SubCellInit>())
|
||||
{
|
||||
@@ -321,7 +312,7 @@ namespace OpenRA.Mods.RA.Move
|
||||
return new[]{ __fromSubCell, SubCell.TopLeft, SubCell.TopRight, SubCell.Center,
|
||||
SubCell.BottomLeft, SubCell.BottomRight}.First(b =>
|
||||
{
|
||||
var blockingActors = uim.GetUnitsAt(a,b).Where(c => c != ignoreActor);
|
||||
var blockingActors = self.World.ActorMap.GetUnitsAt(a,b).Where(c => c != ignoreActor);
|
||||
if (blockingActors.Count() > 0)
|
||||
{
|
||||
// Non-sharable unit can enter a cell with shareable units only if it can crush all of them
|
||||
@@ -343,13 +334,12 @@ namespace OpenRA.Mods.RA.Move
|
||||
|
||||
public bool CanEnterCell(int2 cell, Actor ignoreActor, bool checkTransientActors)
|
||||
{
|
||||
var uim = self.World.WorldActor.Trait<UnitInfluence>();
|
||||
return Info.CanEnterCell(self.World, uim, cell, ignoreActor, checkTransientActors);
|
||||
return Info.CanEnterCell(self.World, cell, ignoreActor, checkTransientActors);
|
||||
}
|
||||
|
||||
public void FinishedMoving(Actor self)
|
||||
{
|
||||
var crushable = uim.GetUnitsAt(toCell).Where(a => a != self && a.HasTrait<ICrushable>());
|
||||
var crushable = self.World.ActorMap.GetUnitsAt(toCell).Where(a => a != self && a.HasTrait<ICrushable>());
|
||||
foreach (var a in crushable)
|
||||
{
|
||||
var crushActions = a.TraitsImplementing<ICrushable>().Where(b => b.CrushClasses.Intersect(Info.Crushes).Any());
|
||||
@@ -374,13 +364,13 @@ namespace OpenRA.Mods.RA.Move
|
||||
public void AddInfluence()
|
||||
{
|
||||
if (self.IsInWorld)
|
||||
uim.Add(self, this);
|
||||
self.World.ActorMap.Add(self, this);
|
||||
}
|
||||
|
||||
public void RemoveInfluence()
|
||||
{
|
||||
if (self.IsInWorld)
|
||||
uim.Remove(self, this);
|
||||
self.World.ActorMap.Remove(self, this);
|
||||
}
|
||||
|
||||
public void OnNudge(Actor self, Actor nudger)
|
||||
|
||||
@@ -162,7 +162,7 @@ namespace OpenRA.Mods.RA.Move
|
||||
|
||||
void NudgeBlocker(Actor self, int2 nextCell)
|
||||
{
|
||||
var blocker = self.World.WorldActor.Trait<UnitInfluence>().GetUnitsAt(nextCell).FirstOrDefault();
|
||||
var blocker = self.World.ActorMap.GetUnitsAt(nextCell).FirstOrDefault();
|
||||
if (blocker == null) return;
|
||||
|
||||
Log.Write("debug", "NudgeBlocker #{0} nudges #{1} at {2} from {3}",
|
||||
|
||||
@@ -27,12 +27,10 @@ namespace OpenRA.Mods.RA.Move
|
||||
public bool inReverse;
|
||||
|
||||
MobileInfo mobileInfo;
|
||||
UnitInfluence uim;
|
||||
|
||||
public PathSearch(World world, MobileInfo mobileInfo)
|
||||
{
|
||||
this.world = world;
|
||||
uim = world.WorldActor.Trait<UnitInfluence>();
|
||||
cellInfo = InitCellInfo();
|
||||
this.mobileInfo = mobileInfo;
|
||||
queue = new PriorityQueue<PathDistance>();
|
||||
@@ -105,7 +103,7 @@ namespace OpenRA.Mods.RA.Move
|
||||
if (costHere == int.MaxValue)
|
||||
continue;
|
||||
|
||||
if (!mobileInfo.CanEnterCell(world, uim, newHere, ignoreBuilding, checkForBlocked))
|
||||
if (!mobileInfo.CanEnterCell(world, newHere, ignoreBuilding, checkForBlocked))
|
||||
continue;
|
||||
|
||||
if (customBlock != null && customBlock(newHere))
|
||||
|
||||
@@ -121,11 +121,10 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
static bool CanUseExit(Actor self, ActorInfo producee, ExitInfo s)
|
||||
{
|
||||
var uim = self.World.WorldActor.Trait<UnitInfluence>();
|
||||
var mobileInfo = producee.Traits.GetOrDefault<MobileInfo>();
|
||||
|
||||
return mobileInfo == null ||
|
||||
mobileInfo.CanEnterCell(self.World, uim, self.Location + s.ExitCell, self, true);
|
||||
mobileInfo.CanEnterCell(self.World, self.Location + s.ExitCell, self, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,8 +66,8 @@ namespace OpenRA.Mods.RA.Render
|
||||
public override void Tick(Actor self)
|
||||
{
|
||||
base.Tick(self);
|
||||
if (isOpen && !self.World.WorldActor.Trait<UnitInfluence>()
|
||||
.GetUnitsAt(openExit).Any( a => a != self ))
|
||||
if (isOpen && !self.World.ActorMap.GetUnitsAt(openExit)
|
||||
.Any( a => a != self ))
|
||||
{
|
||||
isOpen = false;
|
||||
roof.PlayBackwardsThen(NormalizeSequence(self, "build-top"), () => roof.Play(NormalizeSequence(self, "idle-top")));
|
||||
|
||||
@@ -62,11 +62,10 @@ namespace OpenRA.Mods.RA
|
||||
public IEnumerable<Actor> UnitsInRange(int2 xy)
|
||||
{
|
||||
int range = (Info as ChronoshiftPowerInfo).Range;
|
||||
var uim = self.World.WorldActor.Trait<UnitInfluence>();
|
||||
var tiles = self.World.FindTilesInCircle(xy, range);
|
||||
var units = new List<Actor>();
|
||||
foreach (var t in tiles)
|
||||
units.AddRange(uim.GetUnitsAt(t));
|
||||
units.AddRange(self.World.ActorMap.GetUnitsAt(t));
|
||||
|
||||
return units.Distinct().Where(a => a.HasTrait<Chronoshiftable>());
|
||||
}
|
||||
|
||||
@@ -48,11 +48,10 @@ namespace OpenRA.Mods.RA
|
||||
public IEnumerable<Actor> UnitsInRange(int2 xy)
|
||||
{
|
||||
int range = (Info as IronCurtainPowerInfo).Range;
|
||||
var uim = self.World.WorldActor.Trait<UnitInfluence>();
|
||||
var tiles = self.World.FindTilesInCircle(xy, range);
|
||||
var units = new List<Actor>();
|
||||
foreach (var t in tiles)
|
||||
units.AddRange(uim.GetUnitsAt(t));
|
||||
units.AddRange(self.World.ActorMap.GetUnitsAt(t));
|
||||
|
||||
return units.Distinct().Where(a => a.HasTrait<IronCurtainable>());
|
||||
}
|
||||
|
||||
@@ -53,7 +53,6 @@ World:
|
||||
NukePaletteEffect:
|
||||
CncWaterPaletteRotation:
|
||||
BuildingInfluence:
|
||||
UnitInfluence:
|
||||
BridgeLayer:
|
||||
Bridges: bridge1, bridge2, bridge3, bridge4
|
||||
PaletteFromCurrentTileset@terrain:
|
||||
|
||||
@@ -107,7 +107,6 @@ World:
|
||||
NukePaletteEffect:
|
||||
LightPaletteRotator:
|
||||
BuildingInfluence:
|
||||
UnitInfluence:
|
||||
ChooseBuildTabOnSelect:
|
||||
BridgeLayer:
|
||||
Bridges: bridge1, bridge2, br1, br2, br3
|
||||
|
||||
Reference in New Issue
Block a user