@@ -37,6 +37,20 @@ namespace OpenRA
|
|||||||
public readonly Size TileSize = new Size(24, 24);
|
public readonly Size TileSize = new Size(24, 24);
|
||||||
public readonly TileShape TileShape = TileShape.Rectangle;
|
public readonly TileShape TileShape = TileShape.Rectangle;
|
||||||
|
|
||||||
|
[Desc("(x,y,z) offset of the full cell and each sub-cell", "X & Y should be between -512 ... 512 and Z >= 0")]
|
||||||
|
public readonly WVec[] SubCellOffsets =
|
||||||
|
{
|
||||||
|
new WVec(0, 0, 0), // full cell - index 0
|
||||||
|
new WVec(-299, -256, 0), // top left - index 1
|
||||||
|
new WVec(256, -256, 0), // top right - index 2
|
||||||
|
new WVec(0, 0, 0), // center - index 3
|
||||||
|
new WVec(-299, 256, 0), // bottom left - index 4
|
||||||
|
new WVec(256, 256, 0), // bottom right - index 5
|
||||||
|
};
|
||||||
|
|
||||||
|
[Desc("Default subcell index used if SubCellInit is absent", "0 - full cell, 1 - first sub-cell")]
|
||||||
|
public readonly int SubCellDefaultIndex = 3;
|
||||||
|
|
||||||
public Manifest(string mod)
|
public Manifest(string mod)
|
||||||
{
|
{
|
||||||
var path = new[] { "mods", mod, "mod.yaml" }.Aggregate(Path.Combine);
|
var path = new[] { "mods", mod, "mod.yaml" }.Aggregate(Path.Combine);
|
||||||
@@ -87,6 +101,24 @@ namespace OpenRA
|
|||||||
if (yaml.ContainsKey("TileShape"))
|
if (yaml.ContainsKey("TileShape"))
|
||||||
TileShape = FieldLoader.GetValue<TileShape>("TileShape", yaml["TileShape"].Value);
|
TileShape = FieldLoader.GetValue<TileShape>("TileShape", yaml["TileShape"].Value);
|
||||||
|
|
||||||
|
if (yaml.ContainsKey("SubCells"))
|
||||||
|
{
|
||||||
|
var subcells = yaml["SubCells"].ToDictionary();
|
||||||
|
|
||||||
|
// Read (x,y,z) offset (relative to cell center) pairs for positioning subcells
|
||||||
|
if (subcells.ContainsKey("Offsets"))
|
||||||
|
SubCellOffsets = FieldLoader.GetValue<WVec[]>("Offsets", subcells["Offsets"].Value);
|
||||||
|
|
||||||
|
if (subcells.ContainsKey("DefaultIndex"))
|
||||||
|
SubCellDefaultIndex = FieldLoader.GetValue<int>("DefaultIndex", subcells["DefaultIndex"].Value);
|
||||||
|
else // Otherwise set the default subcell index to the middle subcell entry
|
||||||
|
SubCellDefaultIndex = SubCellOffsets.Length / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate default index - 0 for no subcells, otherwise > 1 & <= subcell count (offset triples count - 1)
|
||||||
|
if (SubCellDefaultIndex < (SubCellOffsets.Length > 1 ? 1 : 0) || SubCellDefaultIndex >= SubCellOffsets.Length)
|
||||||
|
throw new InvalidDataException("Subcell default index must be a valid index into the offset triples and must be greater than 0 for mods with subcells");
|
||||||
|
|
||||||
// Allow inherited mods to import parent maps.
|
// Allow inherited mods to import parent maps.
|
||||||
var compat = new List<string>();
|
var compat = new List<string>();
|
||||||
compat.Add(mod);
|
compat.Add(mod);
|
||||||
|
|||||||
@@ -63,13 +63,12 @@ namespace OpenRA
|
|||||||
public CPos Value(World world) { return value; }
|
public CPos Value(World world) { return value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SubCellInit : IActorInit<SubCell>
|
public class SubCellInit : IActorInit<int>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey] public readonly int value = 0;
|
[FieldFromYamlKey] public readonly int value = 0;
|
||||||
public SubCellInit() { }
|
public SubCellInit() { }
|
||||||
public SubCellInit(int init) { value = init; }
|
public SubCellInit(int init) { value = init; }
|
||||||
public SubCellInit(SubCell init) { value = (int)init; }
|
public int Value(World world) { return value; }
|
||||||
public SubCell Value(World world) { return (SubCell)value; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CenterPositionInit : IActorInit<WPos>
|
public class CenterPositionInit : IActorInit<WPos>
|
||||||
|
|||||||
@@ -77,6 +77,9 @@ namespace OpenRA
|
|||||||
public Bitmap CustomPreview;
|
public Bitmap CustomPreview;
|
||||||
|
|
||||||
public readonly TileShape TileShape;
|
public readonly TileShape TileShape;
|
||||||
|
[FieldLoader.Ignore]
|
||||||
|
public readonly WVec[] SubCellOffsets;
|
||||||
|
public readonly int SubCellDefaultIndex;
|
||||||
|
|
||||||
[FieldLoader.LoadUsing("LoadOptions")]
|
[FieldLoader.LoadUsing("LoadOptions")]
|
||||||
public MapOptions Options;
|
public MapOptions Options;
|
||||||
@@ -246,6 +249,8 @@ namespace OpenRA
|
|||||||
MapTiles = Exts.Lazy(() => LoadMapTiles());
|
MapTiles = Exts.Lazy(() => LoadMapTiles());
|
||||||
MapResources = Exts.Lazy(() => LoadResourceTiles());
|
MapResources = Exts.Lazy(() => LoadResourceTiles());
|
||||||
TileShape = Game.modData.Manifest.TileShape;
|
TileShape = Game.modData.Manifest.TileShape;
|
||||||
|
SubCellOffsets = Game.modData.Manifest.SubCellOffsets;
|
||||||
|
SubCellDefaultIndex = Game.modData.Manifest.SubCellDefaultIndex;
|
||||||
|
|
||||||
// The Uid is calculated from the data on-disk, so
|
// The Uid is calculated from the data on-disk, so
|
||||||
// format changes must be flushed to disk.
|
// format changes must be flushed to disk.
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ namespace OpenRA.Traits
|
|||||||
{
|
{
|
||||||
WPos CenterPosition { get; }
|
WPos CenterPosition { get; }
|
||||||
CPos TopLeft { get; }
|
CPos TopLeft { get; }
|
||||||
IEnumerable<Pair<CPos, SubCell>> OccupiedCells();
|
IEnumerable<Pair<CPos, int>> OccupiedCells();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class IOccupySpaceExts
|
public static class IOccupySpaceExts
|
||||||
|
|||||||
@@ -29,16 +29,10 @@ namespace OpenRA.Traits
|
|||||||
class InfluenceNode
|
class InfluenceNode
|
||||||
{
|
{
|
||||||
public InfluenceNode Next;
|
public InfluenceNode Next;
|
||||||
public SubCell SubCell;
|
public int SubCell;
|
||||||
public Actor Actor;
|
public Actor Actor;
|
||||||
}
|
}
|
||||||
|
|
||||||
static readonly SubCell[] SubCells =
|
|
||||||
{
|
|
||||||
SubCell.TopLeft, SubCell.TopRight, SubCell.Center,
|
|
||||||
SubCell.BottomLeft, SubCell.BottomRight
|
|
||||||
};
|
|
||||||
|
|
||||||
readonly ActorMapInfo info;
|
readonly ActorMapInfo info;
|
||||||
readonly Map map;
|
readonly Map map;
|
||||||
readonly CellLayer<InfluenceNode> influence;
|
readonly CellLayer<InfluenceNode> influence;
|
||||||
@@ -79,30 +73,30 @@ namespace OpenRA.Traits
|
|||||||
yield return i.Actor;
|
yield return i.Actor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Actor> GetUnitsAt(CPos a, SubCell sub)
|
public IEnumerable<Actor> GetUnitsAt(CPos a, int sub)
|
||||||
{
|
{
|
||||||
if (!map.Contains(a))
|
if (!map.Contains(a))
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
for (var i = influence[a]; i != null; i = i.Next)
|
for (var i = influence[a]; i != null; i = i.Next)
|
||||||
if (!i.Actor.Destroyed && (i.SubCell == sub || i.SubCell == SubCell.FullCell))
|
if (!i.Actor.Destroyed && (i.SubCell == sub || i.SubCell == 0))
|
||||||
yield return i.Actor;
|
yield return i.Actor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasFreeSubCell(CPos a)
|
public bool HasFreeSubCell(CPos a)
|
||||||
{
|
{
|
||||||
if (!AnyUnitsAt(a))
|
return FreeSubCell(a) >= 0;
|
||||||
return true;
|
|
||||||
|
|
||||||
return SubCells.Any(b => !AnyUnitsAt(a, b));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubCell? FreeSubCell(CPos a)
|
public int FreeSubCell(CPos a)
|
||||||
{
|
{
|
||||||
if (!HasFreeSubCell(a))
|
if (!AnyUnitsAt(a))
|
||||||
return null;
|
return map.SubCellDefaultIndex;
|
||||||
|
|
||||||
return SubCells.First(b => !AnyUnitsAt(a, b));
|
for (var i = 1; i < map.SubCellOffsets.Length; i++)
|
||||||
|
if (!AnyUnitsAt(a, i))
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AnyUnitsAt(CPos a)
|
public bool AnyUnitsAt(CPos a)
|
||||||
@@ -110,10 +104,10 @@ namespace OpenRA.Traits
|
|||||||
return influence[a] != null;
|
return influence[a] != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AnyUnitsAt(CPos a, SubCell sub)
|
public bool AnyUnitsAt(CPos a, int sub)
|
||||||
{
|
{
|
||||||
for (var i = influence[a]; i != null; i = i.Next)
|
for (var i = influence[a]; i != null; i = i.Next)
|
||||||
if (i.SubCell == sub || i.SubCell == SubCell.FullCell)
|
if (i.SubCell == sub || i.SubCell == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace OpenRA.Mods.RA.Activities
|
|||||||
mobile.IsMoving = true;
|
mobile.IsMoving = true;
|
||||||
|
|
||||||
from = self.CenterPosition;
|
from = self.CenterPosition;
|
||||||
to = self.World.Map.CenterOfCell(targetMobile.fromCell) + MobileInfo.SubCellOffsets[targetMobile.fromSubCell];
|
to = self.World.Map.CenterOfCell(targetMobile.fromCell) + self.World.Map.SubCellOffsets[targetMobile.fromSubCell];
|
||||||
length = Math.Max((to - from).Length / speed.Range, 1);
|
length = Math.Max((to - from).Length / speed.Range, 1);
|
||||||
|
|
||||||
self.Trait<RenderInfantry>().Attacking(self, Target.FromActor(target));
|
self.Trait<RenderInfantry>().Attacking(self, Target.FromActor(target));
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ namespace OpenRA.Mods.RA.Activities
|
|||||||
var exitCell = ChooseExitCell(actor);
|
var exitCell = ChooseExitCell(actor);
|
||||||
if (exitCell == null)
|
if (exitCell == null)
|
||||||
{
|
{
|
||||||
foreach (var blocker in BlockedExitCells(actor).SelectMany(self.World.ActorMap.GetUnitsAt))
|
foreach (var blocker in BlockedExitCells(actor).SelectMany(p => self.World.ActorMap.GetUnitsAt(p)))
|
||||||
{
|
{
|
||||||
foreach (var nbm in blocker.TraitsImplementing<INotifyBlockingMove>())
|
foreach (var nbm in blocker.TraitsImplementing<INotifyBlockingMove>())
|
||||||
nbm.OnNotifyBlockingMove(blocker, self);
|
nbm.OnNotifyBlockingMove(blocker, self);
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ namespace OpenRA.Mods.RA.Air
|
|||||||
|
|
||||||
public class Aircraft : IFacing, IPositionable, ISync, INotifyKilled, IIssueOrder, IOrderVoice, INotifyAddedToWorld, INotifyRemovedFromWorld
|
public class Aircraft : IFacing, IPositionable, ISync, INotifyKilled, IIssueOrder, IOrderVoice, INotifyAddedToWorld, INotifyRemovedFromWorld
|
||||||
{
|
{
|
||||||
static readonly Pair<CPos, SubCell>[] NoCells = { };
|
static readonly Pair<CPos, int>[] NoCells = { };
|
||||||
|
|
||||||
readonly AircraftInfo info;
|
readonly AircraftInfo info;
|
||||||
readonly Actor self;
|
readonly Actor self;
|
||||||
@@ -210,7 +210,7 @@ namespace OpenRA.Mods.RA.Air
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { return NoCells; }
|
public IEnumerable<Pair<CPos, int>> OccupiedCells() { return NoCells; }
|
||||||
|
|
||||||
public WVec FlyStep(int facing)
|
public WVec FlyStep(int facing)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -133,14 +133,14 @@ namespace OpenRA.Mods.RA.Buildings
|
|||||||
this.Info = info;
|
this.Info = info;
|
||||||
|
|
||||||
occupiedCells = FootprintUtils.UnpathableTiles( self.Info.Name, Info, TopLeft )
|
occupiedCells = FootprintUtils.UnpathableTiles( self.Info.Name, Info, TopLeft )
|
||||||
.Select(c => Pair.New(c, SubCell.FullCell)).ToArray();
|
.Select(c => Pair.New(c, 0)).ToArray();
|
||||||
|
|
||||||
CenterPosition = init.world.Map.CenterOfCell(topLeft) + FootprintUtils.CenterOffset(init.world, Info);
|
CenterPosition = init.world.Map.CenterOfCell(topLeft) + FootprintUtils.CenterOffset(init.world, Info);
|
||||||
SkipMakeAnimation = init.Contains<SkipMakeAnimsInit>();
|
SkipMakeAnimation = init.Contains<SkipMakeAnimsInit>();
|
||||||
}
|
}
|
||||||
|
|
||||||
Pair<CPos, SubCell>[] occupiedCells;
|
Pair<CPos, int>[] occupiedCells;
|
||||||
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { return occupiedCells; }
|
public IEnumerable<Pair<CPos, int>> OccupiedCells() { return occupiedCells; }
|
||||||
|
|
||||||
public void Created(Actor self)
|
public void Created(Actor self)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ namespace OpenRA.Mods.RA
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CPos TopLeft { get { return Location; } }
|
public CPos TopLeft { get { return Location; } }
|
||||||
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { yield return Pair.New(Location, SubCell.FullCell); }
|
public IEnumerable<Pair<CPos, int>> OccupiedCells() { yield return Pair.New(Location, 0); }
|
||||||
|
|
||||||
public WPos CenterPosition { get; private set; }
|
public WPos CenterPosition { get; private set; }
|
||||||
public void SetPosition(Actor self, WPos pos) { SetPosition(self, self.World.Map.CellContaining(pos)); }
|
public void SetPosition(Actor self, WPos pos) { SetPosition(self, self.World.Map.CellContaining(pos)); }
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ namespace OpenRA.Mods.RA
|
|||||||
self.QueueActivity(new Drag(CenterPosition, finalPos, distance / speed));
|
self.QueueActivity(new Drag(CenterPosition, finalPos, distance / speed));
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { yield return Pair.New(TopLeft, SubCell.FullCell); }
|
public IEnumerable<Pair<CPos, int>> OccupiedCells() { yield return Pair.New(TopLeft, 0); }
|
||||||
public bool CanEnterCell(CPos cell, Actor ignoreActor, bool checkTransientActors)
|
public bool CanEnterCell(CPos cell, Actor ignoreActor, bool checkTransientActors)
|
||||||
{
|
{
|
||||||
if (!self.World.Map.Contains(cell))
|
if (!self.World.Map.Contains(cell))
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace OpenRA.Mods.RA
|
|||||||
{
|
{
|
||||||
[Sync] readonly CPos location;
|
[Sync] readonly CPos location;
|
||||||
[Sync] readonly WPos position;
|
[Sync] readonly WPos position;
|
||||||
readonly IEnumerable<Pair<CPos, SubCell>> occupied;
|
readonly IEnumerable<Pair<CPos, int>> occupied;
|
||||||
|
|
||||||
public Immobile(ActorInitializer init, ImmobileInfo info)
|
public Immobile(ActorInitializer init, ImmobileInfo info)
|
||||||
{
|
{
|
||||||
@@ -32,14 +32,14 @@ namespace OpenRA.Mods.RA
|
|||||||
position = init.world.Map.CenterOfCell(location);
|
position = init.world.Map.CenterOfCell(location);
|
||||||
|
|
||||||
if (info.OccupiesSpace)
|
if (info.OccupiesSpace)
|
||||||
occupied = new [] { Pair.New(TopLeft, SubCell.FullCell) };
|
occupied = new [] { Pair.New(TopLeft, 0) };
|
||||||
else
|
else
|
||||||
occupied = new Pair<CPos, SubCell>[0];
|
occupied = new Pair<CPos, int>[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public CPos TopLeft { get { return location; } }
|
public CPos TopLeft { get { return location; } }
|
||||||
public WPos CenterPosition { get { return position; } }
|
public WPos CenterPosition { get { return position; } }
|
||||||
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { return occupied; }
|
public IEnumerable<Pair<CPos, int>> OccupiedCells() { return occupied; }
|
||||||
|
|
||||||
public void AddedToWorld(Actor self)
|
public void AddedToWorld(Actor self)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -133,16 +133,6 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
return TilesetMovementClass[tileset];
|
return TilesetMovementClass[tileset];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly Dictionary<SubCell, WVec> SubCellOffsets = new Dictionary<SubCell, WVec>()
|
|
||||||
{
|
|
||||||
{SubCell.TopLeft, new WVec(-299, -256, 0)},
|
|
||||||
{SubCell.TopRight, new WVec(256, -256, 0)},
|
|
||||||
{SubCell.Center, new WVec(0, 0, 0)},
|
|
||||||
{SubCell.BottomLeft, new WVec(-299, 256, 0)},
|
|
||||||
{SubCell.BottomRight, new WVec(256, 256, 0)},
|
|
||||||
{SubCell.FullCell, new WVec(0, 0, 0)},
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool IsMovingInMyDirection(Actor self, Actor other)
|
static bool IsMovingInMyDirection(Actor self, Actor other)
|
||||||
{
|
{
|
||||||
if (!other.IsMoving()) return false;
|
if (!other.IsMoving()) return false;
|
||||||
@@ -208,7 +198,7 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
|
|
||||||
int __facing;
|
int __facing;
|
||||||
CPos __fromCell, __toCell;
|
CPos __fromCell, __toCell;
|
||||||
public SubCell fromSubCell, toSubCell;
|
public int fromSubCell, toSubCell;
|
||||||
|
|
||||||
//int __altitude;
|
//int __altitude;
|
||||||
|
|
||||||
@@ -226,7 +216,7 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
|
|
||||||
[Sync] public int PathHash; // written by Move.EvalPath, to temporarily debug this crap.
|
[Sync] public int PathHash; // written by Move.EvalPath, to temporarily debug this crap.
|
||||||
|
|
||||||
public void SetLocation(CPos from, SubCell fromSub, CPos to, SubCell toSub)
|
public void SetLocation(CPos from, int fromSub, CPos to, int toSub)
|
||||||
{
|
{
|
||||||
if (fromCell == from && toCell == to && fromSubCell == fromSub && toSubCell == toSub)
|
if (fromCell == from && toCell == to && fromSubCell == fromSub && toSubCell == toSub)
|
||||||
return;
|
return;
|
||||||
@@ -248,16 +238,16 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
this.self = init.self;
|
this.self = init.self;
|
||||||
this.Info = info;
|
this.Info = info;
|
||||||
|
|
||||||
toSubCell = fromSubCell = info.SharesCell ? SubCell.Center : SubCell.FullCell;
|
toSubCell = fromSubCell = info.SharesCell ? init.world.Map.SubCellDefaultIndex : 0;
|
||||||
if (init.Contains<SubCellInit>())
|
if (init.Contains<SubCellInit>())
|
||||||
{
|
{
|
||||||
this.fromSubCell = this.toSubCell = init.Get<SubCellInit, SubCell>();
|
this.fromSubCell = this.toSubCell = init.Get<SubCellInit, int>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (init.Contains<LocationInit>())
|
if (init.Contains<LocationInit>())
|
||||||
{
|
{
|
||||||
this.__fromCell = this.__toCell = init.Get<LocationInit, CPos>();
|
this.__fromCell = this.__toCell = init.Get<LocationInit, CPos>();
|
||||||
SetVisualPosition(self, init.world.Map.CenterOfCell(fromCell) + MobileInfo.SubCellOffsets[fromSubCell]);
|
SetVisualPosition(self, init.world.Map.CenterOfCell(fromCell) + self.World.Map.SubCellOffsets[fromSubCell]);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Facing = init.Contains<FacingInit>() ? init.Get<FacingInit, int>() : info.InitialFacing;
|
this.Facing = init.Contains<FacingInit>() ? init.Get<FacingInit, int>() : info.InitialFacing;
|
||||||
@@ -271,7 +261,7 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
public void SetPosition(Actor self, CPos cell)
|
public void SetPosition(Actor self, CPos cell)
|
||||||
{
|
{
|
||||||
SetLocation(cell, fromSubCell, cell, fromSubCell);
|
SetLocation(cell, fromSubCell, cell, fromSubCell);
|
||||||
SetVisualPosition(self, self.World.Map.CenterOfCell(fromCell) + MobileInfo.SubCellOffsets[fromSubCell]);
|
SetVisualPosition(self, self.World.Map.CenterOfCell(fromCell) + self.World.Map.SubCellOffsets[fromSubCell]);
|
||||||
FinishedMoving(self);
|
FinishedMoving(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,7 +404,7 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
|
|
||||||
public CPos TopLeft { get { return toCell; } }
|
public CPos TopLeft { get { return toCell; } }
|
||||||
|
|
||||||
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells()
|
public IEnumerable<Pair<CPos, int>> OccupiedCells()
|
||||||
{
|
{
|
||||||
if (fromCell == toCell)
|
if (fromCell == toCell)
|
||||||
yield return Pair.New(fromCell, fromSubCell);
|
yield return Pair.New(fromCell, fromSubCell);
|
||||||
@@ -427,14 +417,7 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubCell GetDesiredSubcell(CPos a, Actor ignoreActor)
|
bool IsDesiredSubcellNotBlocked(CPos a, int b, Actor ignoreActor)
|
||||||
{
|
|
||||||
if (!Info.SharesCell)
|
|
||||||
return SubCell.FullCell;
|
|
||||||
|
|
||||||
// Prioritise the current subcell
|
|
||||||
return new[]{ fromSubCell, SubCell.TopLeft, SubCell.TopRight, SubCell.Center,
|
|
||||||
SubCell.BottomLeft, SubCell.BottomRight}.First(b =>
|
|
||||||
{
|
{
|
||||||
var blockingActors = self.World.ActorMap.GetUnitsAt(a, b).Where(c => c != ignoreActor);
|
var blockingActors = self.World.ActorMap.GetUnitsAt(a, b).Where(c => c != ignoreActor);
|
||||||
if (blockingActors.Any())
|
if (blockingActors.Any())
|
||||||
@@ -448,7 +431,22 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
public int GetDesiredSubcell(CPos a, Actor ignoreActor)
|
||||||
|
{
|
||||||
|
if (!Info.SharesCell)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Prioritise the current subcell
|
||||||
|
if (IsDesiredSubcellNotBlocked(a, fromSubCell, ignoreActor))
|
||||||
|
return fromSubCell;
|
||||||
|
|
||||||
|
for (var i = 1; i < self.World.Map.SubCellOffsets.Length; i++)
|
||||||
|
if (IsDesiredSubcellNotBlocked(a, i, ignoreActor))
|
||||||
|
return i;
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanEnterCell(CPos p)
|
public bool CanEnterCell(CPos p)
|
||||||
|
|||||||
@@ -150,8 +150,8 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
mobile.SetLocation(mobile.fromCell, mobile.fromSubCell, nextCell.Value.First, nextCell.Value.Second);
|
mobile.SetLocation(mobile.fromCell, mobile.fromSubCell, nextCell.Value.First, nextCell.Value.Second);
|
||||||
var move = new MoveFirstHalf(
|
var move = new MoveFirstHalf(
|
||||||
this,
|
this,
|
||||||
self.World.Map.CenterOfCell(mobile.fromCell) + MobileInfo.SubCellOffsets[mobile.fromSubCell],
|
self.World.Map.CenterOfCell(mobile.fromCell) + self.World.Map.SubCellOffsets[mobile.fromSubCell],
|
||||||
Util.BetweenCells(self.World, mobile.fromCell, mobile.toCell) + (MobileInfo.SubCellOffsets[mobile.fromSubCell] + MobileInfo.SubCellOffsets[mobile.toSubCell]) / 2,
|
Util.BetweenCells(self.World, mobile.fromCell, mobile.toCell) + (self.World.Map.SubCellOffsets[mobile.fromSubCell] + self.World.Map.SubCellOffsets[mobile.toSubCell]) / 2,
|
||||||
mobile.Facing,
|
mobile.Facing,
|
||||||
mobile.Facing,
|
mobile.Facing,
|
||||||
0);
|
0);
|
||||||
@@ -180,7 +180,7 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Pair<CPos, SubCell>? PopPath(Actor self, Mobile mobile)
|
Pair<CPos, int>? PopPath(Actor self, Mobile mobile)
|
||||||
{
|
{
|
||||||
if (path.Count == 0)
|
if (path.Count == 0)
|
||||||
return null;
|
return null;
|
||||||
@@ -347,15 +347,15 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
|
|
||||||
protected override MovePart OnComplete(Actor self, Mobile mobile, Move parent)
|
protected override MovePart OnComplete(Actor self, Mobile mobile, Move parent)
|
||||||
{
|
{
|
||||||
var fromSubcellOffset = MobileInfo.SubCellOffsets[mobile.fromSubCell];
|
var fromSubcellOffset = self.World.Map.SubCellOffsets[mobile.fromSubCell];
|
||||||
var toSubcellOffset = MobileInfo.SubCellOffsets[mobile.toSubCell];
|
var toSubcellOffset = self.World.Map.SubCellOffsets[mobile.toSubCell];
|
||||||
|
|
||||||
var nextCell = parent.PopPath(self, mobile);
|
var nextCell = parent.PopPath(self, mobile);
|
||||||
if (nextCell != null)
|
if (nextCell != null)
|
||||||
{
|
{
|
||||||
if (IsTurn(mobile, nextCell.Value.First))
|
if (IsTurn(mobile, nextCell.Value.First))
|
||||||
{
|
{
|
||||||
var nextSubcellOffset = MobileInfo.SubCellOffsets[nextCell.Value.Second];
|
var nextSubcellOffset = self.World.Map.SubCellOffsets[nextCell.Value.Second];
|
||||||
var ret = new MoveFirstHalf(
|
var ret = new MoveFirstHalf(
|
||||||
move,
|
move,
|
||||||
Util.BetweenCells(self.World, mobile.fromCell, mobile.toCell) + (fromSubcellOffset + toSubcellOffset) / 2,
|
Util.BetweenCells(self.World, mobile.fromCell, mobile.toCell) + (fromSubcellOffset + toSubcellOffset) / 2,
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<CPos> FindUnitPathToRange(CPos src, SubCell srcSub, WPos target, WRange range, Actor self)
|
public List<CPos> FindUnitPathToRange(CPos src, int srcSub, WPos target, WRange range, Actor self)
|
||||||
{
|
{
|
||||||
using (new PerfSample("Pathfinder"))
|
using (new PerfSample("Pathfinder"))
|
||||||
{
|
{
|
||||||
@@ -89,7 +89,7 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
var rangeSquared = range.Range*range.Range;
|
var rangeSquared = range.Range*range.Range;
|
||||||
|
|
||||||
// Correct for SubCell offset
|
// Correct for SubCell offset
|
||||||
target -= MobileInfo.SubCellOffsets[srcSub];
|
target -= self.World.Map.SubCellOffsets[srcSub];
|
||||||
|
|
||||||
// Select only the tiles that are within range from the requested SubCell
|
// Select only the tiles that are within range from the requested SubCell
|
||||||
// This assumes that the SubCell does not change during the path traversal
|
// This assumes that the SubCell does not change during the path traversal
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ namespace OpenRA.Mods.RA
|
|||||||
throw new InvalidOperationException("No cells available to spawn starting unit {0}".F(s));
|
throw new InvalidOperationException("No cells available to spawn starting unit {0}".F(s));
|
||||||
|
|
||||||
var cell = validCells.Random(w.SharedRandom);
|
var cell = validCells.Random(w.SharedRandom);
|
||||||
var subCell = mi.SharesCell ? w.ActorMap.FreeSubCell(cell).Value : SubCell.FullCell;
|
var subCell = mi.SharesCell ? w.ActorMap.FreeSubCell(cell) : 0;
|
||||||
|
|
||||||
w.CreateActor(s.ToLowerInvariant(), new TypeDictionary
|
w.CreateActor(s.ToLowerInvariant(), new TypeDictionary
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -145,6 +145,9 @@ TileSets:
|
|||||||
|
|
||||||
TileSize: 48,24
|
TileSize: 48,24
|
||||||
TileShape: Diamond
|
TileShape: Diamond
|
||||||
|
SubCells:
|
||||||
|
Offsets: 0,0,0, -256,128,0, 0,-128,0, 256,128,0
|
||||||
|
DefaultIndex: 2
|
||||||
|
|
||||||
Music:
|
Music:
|
||||||
mods/ts/music.yaml
|
mods/ts/music.yaml
|
||||||
|
|||||||
Reference in New Issue
Block a user