Fix various map generator bounds and size related issues
- If generating a RectangularIsometric map via lobby, make the height twice the width so that the map is approximately world-square. - Use equal top and bottom cordons for RectangularIsometric maps. - Change some map bounds checking. - Check that actors are at least partially inside map.Contains before placing. (To avoid frozen actor crashes.) - Fix editor generated map blitting for RectangularIsometric.
This commit is contained in:
committed by
Gustas Kažukauskas
parent
915ad36ddc
commit
91ddfd6fc1
@@ -176,7 +176,7 @@ namespace OpenRA.Mods.Common.MapGenerator
|
||||
{
|
||||
var maxTerrainHeight = Map.Grid.MaximumTerrainHeight;
|
||||
var tl = new PPos(1, 1 + maxTerrainHeight);
|
||||
var br = new PPos(Map.MapSize.Width - 2, Map.MapSize.Height + maxTerrainHeight - 2);
|
||||
var br = new PPos(Map.MapSize.Width - 2, Map.MapSize.Height - maxTerrainHeight - 2);
|
||||
Map.SetBounds(tl, br);
|
||||
Map.Title = MapGenerationArgs.Title;
|
||||
Map.Author = MapGenerationArgs.Author;
|
||||
@@ -185,12 +185,26 @@ namespace OpenRA.Mods.Common.MapGenerator
|
||||
|
||||
/// <summary>
|
||||
/// Commits draft data to the map, such as player and actor definitions.
|
||||
/// This may trigger some initialization of map data structures that could become invalid
|
||||
/// if further edits to the map are made.
|
||||
/// </summary>
|
||||
public void BakeMap()
|
||||
{
|
||||
var playerCount = ActorsOfType("mpspawn").Count();
|
||||
Map.PlayerDefinitions = new MapPlayers(Map.Rules, playerCount).ToMiniYaml();
|
||||
|
||||
// Return true iff any of the actors projected footprint satisfies Map.Contains(PPos).
|
||||
// Note that this is not the same as Map.Tiles.Contains or Map.Bounds.Contains.
|
||||
// Note that calling this initializes cell projections.
|
||||
bool HasProjectedFootprintInMap(ActorPlan plan)
|
||||
{
|
||||
return plan.Footprint()
|
||||
.SelectMany(f => Map.ProjectedCellsCovering(f.Key.ToMPos(Map)))
|
||||
.Any(Map.Contains);
|
||||
}
|
||||
|
||||
Map.ActorDefinitions = ActorPlans
|
||||
.Where(HasProjectedFootprintInMap)
|
||||
.Select((plan, i) => new MiniYamlNode($"Actor{i}", plan.Reference.Save()))
|
||||
.ToImmutableArray();
|
||||
}
|
||||
@@ -261,10 +275,13 @@ namespace OpenRA.Mods.Common.MapGenerator
|
||||
zoneable[mpos] = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Zone based on Map.Bounds.Contains. This is stricter than Map.Contains, ignoring height.
|
||||
/// </summary>
|
||||
public void ZoneFromOutOfBounds<T>(CellLayer<T> zoneable, T value)
|
||||
{
|
||||
foreach (var mpos in Map.AllCells.MapCoords)
|
||||
if (!Map.Contains(mpos))
|
||||
if (!Map.Bounds.Contains(mpos.U, mpos.V))
|
||||
zoneable[mpos] = value;
|
||||
}
|
||||
|
||||
@@ -1687,10 +1704,10 @@ namespace OpenRA.Mods.Common.MapGenerator
|
||||
throw new ArgumentException("fillSide was not In or Out");
|
||||
|
||||
var notFillSide = fillSide == Side.In ? Side.Out : Side.In;
|
||||
var fillSeeds = CellLayerUtils.Create(Map, (MPos mpos) =>
|
||||
var fillSeeds = CellLayerUtils.Create(Map, mpos =>
|
||||
sides[mpos] == fillSide &&
|
||||
!mask[mpos] &&
|
||||
Map.Contains(mpos));
|
||||
Map.Bounds.Contains(mpos.U, mpos.V));
|
||||
fillSeeds = ImproveSymmetry(fillSeeds, false, (a, b) => a || b);
|
||||
var fillable = CellLayerUtils.Map(sides, side => side != notFillSide);
|
||||
CellLayerUtils.SimpleFloodFill(
|
||||
|
||||
@@ -747,7 +747,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
var replace = PlayableToReplaceable();
|
||||
foreach (var mpos in map.AllCells.MapCoords)
|
||||
if (playable[mpos] || !map.Contains(mpos))
|
||||
if (playable[mpos] || !map.Bounds.Contains(mpos.U, mpos.V))
|
||||
replace[mpos] = MultiBrush.Replaceability.None;
|
||||
|
||||
terraformer.PaintArea(debrisTilingRandom, replace, param.UnplayableObstacles);
|
||||
|
||||
@@ -261,8 +261,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
var map = world.Map;
|
||||
var terrainInfo = modData.DefaultTerrainInfo[map.Tileset];
|
||||
var size = new Size(map.Bounds.Width + 2, map.Bounds.Height + 2);
|
||||
var args = settings.Compile(terrainInfo, size);
|
||||
var args = settings.Compile(terrainInfo, map.MapSize);
|
||||
|
||||
// Run main generator logic. May throw.
|
||||
var generateStopwatch = Stopwatch.StartNew();
|
||||
@@ -301,12 +300,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
previews.Add(kv.Key, preview);
|
||||
}
|
||||
|
||||
var offset = map.CellContaining(map.ProjectedTopLeft) - generatedMap.CellContaining(generatedMap.ProjectedTopLeft);
|
||||
var blitSource = new EditorBlitSource(generatedMap.AllCells, previews, tiles);
|
||||
var cellBounds = CellLayerUtils.CellBounds(map);
|
||||
var topLeft = new CPos(cellBounds.TopLeft.X, cellBounds.TopLeft.Y);
|
||||
var bottomRight = new CPos(cellBounds.BottomRight.X, cellBounds.BottomRight.Y);
|
||||
var cellRegion = new CellRegion(map.Grid.Type, topLeft, bottomRight);
|
||||
var blitSource = new EditorBlitSource(cellRegion, previews, tiles);
|
||||
var editorBlit = new EditorBlit(
|
||||
MapBlitFilters.All,
|
||||
resourceLayer,
|
||||
new CPos(offset.X, offset.Y),
|
||||
topLeft,
|
||||
map,
|
||||
blitSource,
|
||||
editorActorLayer,
|
||||
|
||||
@@ -234,9 +234,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
|
||||
void RandomizeSize()
|
||||
{
|
||||
var mapGrid = modData.Manifest.Get<MapGrid>();
|
||||
var sizeRange = MapSizes[selectedSize];
|
||||
var width = Game.CosmeticRandom.Next(sizeRange.X, sizeRange.Y);
|
||||
size = new Size(width + 2, width + 2);
|
||||
var height =
|
||||
mapGrid.Type == MapGridType.RectangularIsometric
|
||||
? width * 2
|
||||
: width;
|
||||
|
||||
size = new Size(width + 2, height + mapGrid.MaximumTerrainHeight * 2 + 2);
|
||||
}
|
||||
|
||||
void RefreshSettings()
|
||||
|
||||
Reference in New Issue
Block a user