Load subcells and default subcell index from mod.yaml

This commit is contained in:
atlimit8
2014-07-31 18:20:52 -05:00
parent 4b7537bb13
commit 9b30c21f93
9 changed files with 95 additions and 36 deletions

View File

@@ -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: -512 ... 512, 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,35 @@ 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);
// Read subcell information
// sub-cell index 0 is the full cell
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);
foreach (var i in SubCellOffsets)
if (i.X < -512 || i.X > 512 || i.Y < -512 || i.Y > 512 || i.Z < 0)
throw new InvalidDataException("Subcell offsets must be in bounds (X & Y: -512 ... 512, Z > 0)");
}
// Read default subcell index used when creating actors that share cells without SubCellInit
if (subcells.ContainsKey("DefaultIndex"))
SubCellDefaultIndex = FieldLoader.GetValue<int>("DefaultIndex", subcells ["DefaultIndex"].Value);
// Otherwise set the default subcell index to the middle subcell entry
else
SubCellDefaultIndex = SubCellOffsets.Length / 2; // default is the middle subcell entry
}
// 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);

View File

@@ -78,16 +78,8 @@ namespace OpenRA
public readonly TileShape TileShape; public readonly TileShape TileShape;
[FieldLoader.Ignore] [FieldLoader.Ignore]
public readonly WVec[] SubCellOffsets = public readonly WVec[] SubCellOffsets;
{ public readonly int SubCellDefaultIndex;
new WVec(0, 0, 0),
new WVec(-299, -256, 0),
new WVec(256, -256, 0),
new WVec(0, 0, 0),
new WVec(-299, 256, 0),
new WVec(256, 256, 0),
};
public readonly int SubCellsDefaultIndex = 3;
[FieldLoader.LoadUsing("LoadOptions")] [FieldLoader.LoadUsing("LoadOptions")]
public MapOptions Options; public MapOptions Options;
@@ -257,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.

View File

@@ -33,8 +33,6 @@ namespace OpenRA.Traits
public Actor Actor; public Actor Actor;
} }
static readonly int[] SubCells = { 1, 2, 3, 4, 5 };
readonly ActorMapInfo info; readonly ActorMapInfo info;
readonly Map map; readonly Map map;
readonly CellLayer<InfluenceNode> influence; readonly CellLayer<InfluenceNode> influence;
@@ -87,18 +85,18 @@ namespace OpenRA.Traits
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 int? 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)

View File

@@ -238,7 +238,7 @@ namespace OpenRA.Mods.RA.Move
this.self = init.self; this.self = init.self;
this.Info = info; this.Info = info;
toSubCell = fromSubCell = info.SharesCell ? init.world.Map.SubCellsDefaultIndex : 0; toSubCell = fromSubCell = info.SharesCell ? init.world.Map.SubCellDefaultIndex : 0;
if (init.Contains<SubCellInit>()) if (init.Contains<SubCellInit>())
{ {
this.fromSubCell = this.toSubCell = init.Get<SubCellInit, int>(); this.fromSubCell = this.toSubCell = init.Get<SubCellInit, int>();
@@ -417,13 +417,7 @@ namespace OpenRA.Mods.RA.Move
} }
} }
public int GetDesiredSubcell(CPos a, Actor ignoreActor) bool IsDesiredSubcellNotBlocked(CPos a, int b, Actor ignoreActor)
{
if (!Info.SharesCell)
return 0;
// Prioritise the current subcell
return new[]{ fromSubCell, 1, 2, 3, 4, 5}.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())
@@ -437,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)

View File

@@ -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 : 0; var subCell = mi.SharesCell ? w.ActorMap.FreeSubCell(cell) : 0;
w.CreateActor(s.ToLowerInvariant(), new TypeDictionary w.CreateActor(s.ToLowerInvariant(), new TypeDictionary
{ {

View File

@@ -126,6 +126,10 @@ TileSets:
mods/cnc/tilesets/temperat.yaml mods/cnc/tilesets/temperat.yaml
mods/cnc/tilesets/jungle.yaml mods/cnc/tilesets/jungle.yaml
SubCells:
Offsets: 0,0,0, -299,-256,0, 256,-256,0, 0,0,0, -299,256,0, 256,256,0
DefaultIndex: 3
LoadScreen: CncLoadScreen LoadScreen: CncLoadScreen
Image: mods/cnc/uibits/chrome.png Image: mods/cnc/uibits/chrome.png
Text: Loading Text: Loading

View File

@@ -100,6 +100,10 @@ Notifications:
TileSets: TileSets:
mods/d2k/tilesets/arrakis.yaml mods/d2k/tilesets/arrakis.yaml
SubCells:
Offsets: 0,0,0, -299,-256,0, 256,-256,0, 0,0,0, -299,256,0, 256,256,0
DefaultIndex: 3
TileSize: 32,32 TileSize: 32,32
Music: Music:

View File

@@ -117,6 +117,10 @@ TileSets:
mods/ra/tilesets/temperat.yaml mods/ra/tilesets/temperat.yaml
mods/ra/tilesets/desert.yaml mods/ra/tilesets/desert.yaml
SubCells:
Offsets: 0,0,0, -299,-256,0, 256,-256,0, 0,0,0, -299,256,0, 256,256,0
DefaultIndex: 3
Music: Music:
mods/ra/music.yaml mods/ra/music.yaml

View File

@@ -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