ImportGen2Map: Fix imports of malformed maps.

Fixes #21126
This commit is contained in:
Jakub Vesely
2023-10-23 19:32:13 +02:00
committed by Gustas
parent d1797a021f
commit 91802e6f10
3 changed files with 54 additions and 15 deletions

View File

@@ -776,19 +776,10 @@ namespace OpenRA
if (Grid.MaximumTerrainHeight > 0)
{
// The minimap is drawn in cell space, so we need to
// unproject the PPos bounds to find the MPos boundaries.
// This matches the calculation in RadarWidget that is used ingame
for (var x = Bounds.Left; x < Bounds.Right; x++)
{
var allTop = Unproject(new PPos(x, Bounds.Top));
var allBottom = Unproject(new PPos(x, Bounds.Bottom));
if (allTop.Count > 0)
top = Math.Min(top, allTop.MinBy(uv => uv.V).V);
(top, bottom) = GetCellSpaceBounds();
if (allBottom.Count > 0)
bottom = Math.Max(bottom, allBottom.MaxBy(uv => uv.V).V);
}
if (top == int.MaxValue || bottom == int.MinValue)
throw new InvalidDataException("The map has invalid boundaries");
}
else
{
@@ -864,6 +855,28 @@ namespace OpenRA
return png.Save();
}
public (int Top, int Bottom) GetCellSpaceBounds()
{
var top = int.MaxValue;
var bottom = int.MinValue;
// The minimap is drawn in cell space, so we need to
// unproject the PPos bounds to find the MPos boundaries.
// This matches the calculation in RadarWidget that is used ingame
for (var x = Bounds.Left; x < Bounds.Right; x++)
{
var allTop = Unproject(new PPos(x, Bounds.Top));
var allBottom = Unproject(new PPos(x, Bounds.Bottom));
if (allTop.Count > 0)
top = Math.Min(top, allTop.MinBy(uv => uv.V).V);
if (allBottom.Count > 0)
bottom = Math.Max(bottom, allBottom.MaxBy(uv => uv.V).V);
}
return (top, bottom);
}
public bool Contains(CPos cell)
{
if (Grid.Type == MapGridType.RectangularIsometric)

View File

@@ -421,9 +421,30 @@ namespace OpenRA.Mods.Cnc.UtilityCommands
// Calculate Bounds edge tile coordinates.
// Reduce bottom and right by 1 because map.SetBounds() increases them.
var topLeft = new PPos(left, top);
var bottomRight = new PPos(playableAreaWidth + left - 1, playableAreaHeight + unknownHeightPadding + top - 1);
map.SetBounds(topLeft, bottomRight);
if (map.Height.Max() != 0)
{
// Workaround: Some custom TS maps have invalid boundaries, with no padding area at the bottom
// The boundary needs to be reduced until the projections are valid
bool hasValidBoundaries;
var paddingOffset = 1;
do
{
var bottomRight = new PPos(playableAreaWidth + left - 1, playableAreaHeight + unknownHeightPadding + top - paddingOffset);
map.SetBounds(topLeft, bottomRight);
var (topBound, bottomBound) = map.GetCellSpaceBounds();
hasValidBoundaries = topBound != int.MaxValue && bottomBound != int.MinValue;
paddingOffset++;
}
while (!hasValidBoundaries);
}
else
{
var bottomRight = new PPos(playableAreaWidth + left - 1, playableAreaHeight + unknownHeightPadding + top - 1);
map.SetBounds(topLeft, bottomRight);
}
}
protected virtual bool TryHandleOverlayToActorInner(CPos cell, byte[] overlayPack, CellLayer<int> overlayIndex, byte overlayType, out ActorReference actorReference)

View File

@@ -44,7 +44,12 @@ namespace OpenRA.Mods.Common.FileFormats
{
case ';': break;
case '[': currentSection = ProcessSection(line); break;
default: ProcessEntry(line, currentSection); break;
default:
// Skip everything before the first section
if (currentSection != null)
ProcessEntry(line, currentSection);
break;
}
}
}