1
0
Fork 0

Codechange: Simplify storage of WaterTileType in map. (#13030)

pull/13031/head
Peter Nelson 2024-10-26 10:17:44 +01:00 committed by GitHub
parent e50c1774fc
commit 4f9c10d35f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 144 additions and 120 deletions

View File

@ -1050,98 +1050,92 @@
<li>m1 bits 4..0: <a href="#OwnershipInfo">owner</a> (for sea, rivers, and coasts normally <tt>11</tt>)</li>
<li>m2: Depot index (for depots only)</li>
<li>m4: Random data for canal or river tiles</li>
<li>m5: tile type:
<li>m5 bits 7..4: Water tile type:
<table>
<tr>
<td nowrap valign=top><tt>00</tt>&nbsp; </td>
<td align=left>water, canal or river</td>
</tr>
<tr>
<td nowrap valign=top><tt>01</tt>&nbsp; </td>
<td align=left>coast or riverbank</td>
</tr>
<tr>
<td nowrap valign=top><tt>10</tt>..<tt>1B</tt>&nbsp; </td>
<td align=left>canal locks
<table>
<tr>
<td nowrap valign=top><tt>10</tt>&nbsp; </td>
<td align=left>middle part, (SW-NE direction)</td>
</tr>
<tr>
<td nowrap valign=top><tt>11</tt>&nbsp; </td>
<td align=left>middle part, (NW-SE direction)</td>
</tr>
<tr>
<td nowrap valign=top><tt>12</tt>&nbsp; </td>
<td align=left>middle part, (NE-SW direction)</td>
</tr>
<tr>
<td nowrap valign=top><tt>13</tt>&nbsp; </td>
<td align=left>middle part, (SE-NW direction)</td>
</tr>
<tr>
<td nowrap valign=top><tt>14</tt>&nbsp; </td>
<td align=left>lower part, (SW-NE direction)</td>
</tr>
<tr>
<td nowrap valign=top><tt>15</tt>&nbsp; </td>
<td align=left>lower part, (NW-SE direction)</td>
</tr>
<tr>
<td nowrap valign=top><tt>16</tt>&nbsp; </td>
<td align=left>lower part, (NE-SW direction)</td>
</tr>
<tr>
<td nowrap valign=top><tt>17</tt>&nbsp; </td>
<td align=left>lower part, (SE-NW direction)</td>
</tr>
<tr>
<td nowrap valign=top><tt>18</tt>&nbsp; </td>
<td align=left>upper part, (SW-NE direction)</td>
</tr>
<tr>
<td nowrap valign=top><tt>19</tt>&nbsp; </td>
<td align=left>upper part, (NW-SE direction)</td>
</tr>
<tr>
<td nowrap valign=top><tt>1A</tt>&nbsp; </td>
<td align=left>upper part, (NE-SW direction)</td>
</tr>
<tr>
<td nowrap valign=top><tt>1B</tt>&nbsp; </td>
<td align=left>upper part, (SE-NW direction)</td>
</tr>
</table>
</td>
</tr>
<tr>
<td nowrap valign=top><tt>80</tt>..<tt>83</tt>&nbsp; </td>
<td align=left>ship depots
<table>
<tr>
<td nowrap valign=top><tt>80</tt>&nbsp; </td>
<td align=left>ship depot, NE part (X direction)</td>
</tr>
<tr>
<td nowrap valign=top><tt>81</tt>&nbsp; </td>
<td align=left>ship depot, SW part (X direction)</td>
</tr>
<tr>
<td nowrap valign=top><tt>82</tt>&nbsp; </td>
<td align=left>ship depot, NW part (Y direction)</td>
</tr>
<tr>
<td nowrap valign=top><tt>83</tt>&nbsp; </td>
<td align=left>ship depot, SE part (Y direction)</td>
</tr>
</table>
</td>
</tr>
</table>
<tr>
<td><tt>0</tt>&nbsp; </td>
<td>water, canal or river</td>
</tr>
<tr>
<td><tt>1</tt>&nbsp; </td>
<td>coast or riverbank</td>
</tr>
<tr>
<td nowrap valign=top><tt>2</tt>&nbsp; </td>
<td>canal lock<br>
<ul>
<li>m5 bits 3..2: Lock part
<table>
<tr>
<td><tt>0</tt>&nbsp; </td>
<td>Middle part</td>
</tr>
<tr>
<td><tt>1</tt>&nbsp; </td>
<td>Lower part</td>
</tr>
<tr>
<td><tt>2</tt>&nbsp; </td>
<td>Upper part</td>
</tr>
</table>
</li>
<li>m5 bits 1..0: Lock direction
<table>
<tr>
<td><tt>0</tt>&nbsp; </td>
<td>NE raised</td>
</tr>
<tr>
<td><tt>1</tt>&nbsp; </td>
<td>SE raised</td>
</tr>
<tr>
<td><tt>2</tt>&nbsp; </td>
<td>SW raised</td>
</tr>
<tr>
<td><tt>3</tt>&nbsp; </td>
<td>NW raised</td>
</tr>
</table>
</li>
</ul>
</td>
</tr>
<tr>
<td nowrap valign=top><tt>3</tt>&nbsp; </td>
<td>depot<br>
<ul>
<li>m5 bit 1: Depot axis
<table>
<tr>
<td><tt>0</tt>&nbsp; </td>
<td>X direction (NE-SW)</td>
</tr>
<tr>
<td><tt>1</tt>&nbsp; </td>
<td>Y direction (NW-SE)</td>
</tr>
</table>
</li>
<li>m5 bit 0: Depot part
<table>
<tr>
<td><tt>0</tt>&nbsp; </td>
<td>North part</td>
</tr>
<tr>
<td><tt>1</tt>&nbsp; </td>
<td>South part</td>
</tr>
</table>
</li>
</ul>
</td>
</tr>
</table>
</li>
</li>
</ul>
</td>

View File

@ -240,32 +240,37 @@ the array so you can quickly see what is used and what is not.
<td class="bits"><span class="free">OOOO OOOO</span></td>
</tr>
<tr>
<td rowspan=4>6</td>
<td class="caption">sea, shore</td>
<td class="bits" rowspan=4><span class="used" title="Ship docking tile status">X</span> <span class="used" title="Water class">XX</span> <span class="used" title="Owner">XXXXX</span></td>
<td class="bits" rowspan=3><span class="free">OOOO OOOO OOOO OOOO</span></td>
<td class="bits" rowspan=4><span class="free">OOOO OOOO</span></td>
<td class="bits"><span class="free">OOOO OOOO</span></td>
<td class="bits"><span class="used" title="Water tile type: coast, clear, lock, depot">O<span class="usable">OO</span>O</span> <span class="free">OOO</span><span class="used" title="Sea shore flag">X</span></td>
<td class="bits" rowspan=4><span class="free">OOOO OOOO</span></td>
<td class="bits" rowspan=4><span class="free">OOOO OOOO</td>
<td rowspan=5>6</td>
<td class="caption">sea</td>
<td class="bits" rowspan=5><span class="used" title="Ship docking tile status">X</span> <span class="used" title="Water class">XX</span> <span class="used" title="Owner">XXXXX</span></td>
<td class="bits" rowspan=4><span class="free">OOOO OOOO OOOO OOOO</span></td>
<td class="bits" rowspan=5><span class="free">OOOO OOOO</span></td>
<td class="bits"><span class="free">OOOO OOOO</span></td>
<td class="bits"><span class="used" title="Water tile type: coast, clear, lock, depot">0000</span> <span class="free">OOO0</span></td>
<td class="bits" rowspan=5><span class="free">OOOO OOOO</span></td>
<td class="bits" rowspan=5><span class="free">OOOO OOOO</td>
<td class="bits" rowspan=5><span class="free">OOOO OOOO OOOO OOOO</span></td>
</tr>
<tr>
<td class="caption">canal, river</td>
<td class="bits"><span class="used" title="Canal/river random bits">XXXX XXXX</span></td>
<td class="bits"><span class="used" title="Water tile type: coast, clear, lock, depot">O<span class="usable">OO</span>O</span> <span class="free">OOOO</span></td>
<td class="bits"><span class="used" title="Water tile type: coast, clear, lock, depot">0000</span> <span class="free">OOOO</span></td>
</tr>
<tr>
<td class="caption">shore</td>
<td class="bits"><span class="free">OOOO OOOO</span></td>
<td class="bits"><span class="used" title="Water tile type: coast, clear, lock, depot">0001</span> <span class="free">OOOO</span></td>
</tr>
<tr>
<td class="caption">lock</td>
<td class="bits"><span class="free">OOOO OOOO</span></td>
<td class="bits"><span class="used" title="Water tile type: coast, clear, lock, depot">O<span class="usable">OO</span>1</span> <span class="used" title="Lock part">XX</span> <span class="used" title="Lock orientation m5[1..0]">XX</span></td>
<td class="bits"><span class="used" title="Water tile type: coast, clear, lock, depot">0010</span> <span class="used" title="Lock part">XX</span><span class="used" title="Lock orientation m5[1..0]">XX</span></td>
</tr>
<tr>
<td class="caption">shipdepot</td>
<td class="bits"><span class="pool" title="Depot index on pool">XXXX XXXX XXXX XXXX</span></td>
<td class="bits"><span class="free">OOOO OOOO</span></td>
<td class="bits"><span class="used" title="Water tile type: coast, clear, lock, depot">1<span class="usable">OOO</span></span> <span class="free">OO</span><span class="used" title="Depot axis">X</span> <span class="used" title="Depot part">X</span></td>
<td class="bits"><span class="used" title="Water tile type: coast, clear, lock, depot">0011</span> <span class="free">OO</span><span class="used" title="Depot axis">X</span><span class="used" title="Depot part">X</span></td>
</tr>
<tr>
<td rowspan=2>8</td>

View File

@ -840,6 +840,27 @@ bool AfterLoadGame()
cp->current_station = cp->front->last_station_visited;
}
if (IsSavegameVersionBefore(SLV_WATER_TILE_TYPE)) {
/* Prior to SLV_WATER_TILE_TYPE, the water tile type was stored differently from the enumeration. This has to be
* converted before SLV_72 and SLV_82 conversions which use GetWaterTileType. */
static constexpr uint8_t WBL_COAST_FLAG = 0; ///< Flag for coast.
for (auto t : Map::Iterate()) {
if (!IsTileType(t, MP_WATER)) continue;
switch (GB(t.m5(), 4, 4)) {
case 0x0: /* Previously WBL_TYPE_NORMAL, Clear water or coast. */
SetWaterTileType(t, HasBit(t.m5(), WBL_COAST_FLAG) ? WATER_TILE_COAST : WATER_TILE_CLEAR);
break;
case 0x1: SetWaterTileType(t, WATER_TILE_LOCK); break; /* Previously WBL_TYPE_LOCK */
case 0x8: SetWaterTileType(t, WATER_TILE_DEPOT); break; /* Previously WBL_TYPE_DEPOT */
default: SetWaterTileType(t, WATER_TILE_CLEAR); break; /* Shouldn't happen... */
}
}
}
if (IsSavegameVersionBefore(SLV_72)) {
/* Locks in very old savegames had OWNER_WATER as owner */
for (auto t : Map::Iterate()) {

View File

@ -387,6 +387,7 @@ enum SaveLoadVersion : uint16_t {
SLV_ROAD_STOP_TILE_DATA, ///< 340 PR#12883 Move storage of road stop tile data, also save for road waypoints.
SLV_COMPANY_ALLOW_LIST_V2, ///< 341 PR#12908 Fixed savegame format for saving of list of client keys that are allowed to join this company.
SLV_WATER_TILE_TYPE, ///< 342 PR#13030 Simplify water tile type.
SL_MAX_VERSION, ///< Highest possible saveload version
};

View File

@ -20,12 +20,6 @@ enum WaterTileTypeBitLayout {
WBL_TYPE_BEGIN = 4, ///< Start of the 'type' bitfield.
WBL_TYPE_COUNT = 4, ///< Length of the 'type' bitfield.
WBL_TYPE_NORMAL = 0x0, ///< Clear water or coast ('type' bitfield).
WBL_TYPE_LOCK = 0x1, ///< Lock ('type' bitfield).
WBL_TYPE_DEPOT = 0x8, ///< Depot ('type' bitfield).
WBL_COAST_FLAG = 0, ///< Flag for coast.
WBL_LOCK_ORIENT_BEGIN = 0, ///< Start of lock orientation bitfield.
WBL_LOCK_ORIENT_COUNT = 2, ///< Length of lock orientation bitfield.
WBL_LOCK_PART_BEGIN = 2, ///< Start of lock part bitfield.
@ -79,20 +73,25 @@ enum LockPart {
bool IsPossibleDockingTile(Tile t);
/**
* Get the water tile type at a tile.
* Get the water tile type of a tile.
* @param t Water tile to query.
* @return Water tile type at the tile.
*/
inline WaterTileType GetWaterTileType(Tile t)
{
assert(IsTileType(t, MP_WATER));
return static_cast<WaterTileType>(GB(t.m5(), WBL_TYPE_BEGIN, WBL_TYPE_COUNT));
}
switch (GB(t.m5(), WBL_TYPE_BEGIN, WBL_TYPE_COUNT)) {
case WBL_TYPE_NORMAL: return HasBit(t.m5(), WBL_COAST_FLAG) ? WATER_TILE_COAST : WATER_TILE_CLEAR;
case WBL_TYPE_LOCK: return WATER_TILE_LOCK;
case WBL_TYPE_DEPOT: return WATER_TILE_DEPOT;
default: NOT_REACHED();
}
/**
* Set the water tile type of a tile.
* @param t Water tile to set.
* @param type Water tile type of the tile.
*/
inline void SetWaterTileType(Tile t, WaterTileType type)
{
assert(IsTileType(t, MP_WATER));
SB(t.m5(), WBL_TYPE_BEGIN, WBL_TYPE_COUNT, to_underlying(type));
}
/**
@ -390,7 +389,8 @@ inline void MakeShore(Tile t)
t.m2() = 0;
t.m3() = 0;
t.m4() = 0;
t.m5() = WBL_TYPE_NORMAL << WBL_TYPE_BEGIN | 1 << WBL_COAST_FLAG;
t.m5() = 0;
SetWaterTileType(t, WATER_TILE_COAST);
SB(t.m6(), 2, 4, 0);
t.m7() = 0;
}
@ -411,7 +411,8 @@ inline void MakeWater(Tile t, Owner o, WaterClass wc, uint8_t random_bits)
t.m2() = 0;
t.m3() = 0;
t.m4() = random_bits;
t.m5() = WBL_TYPE_NORMAL << WBL_TYPE_BEGIN;
t.m5() = 0;
SetWaterTileType(t, WATER_TILE_CLEAR);
SB(t.m6(), 2, 4, 0);
t.m7() = 0;
}
@ -465,7 +466,8 @@ inline void MakeShipDepot(Tile t, Owner o, DepotID did, DepotPart part, Axis a,
t.m2() = did;
t.m3() = 0;
t.m4() = 0;
t.m5() = WBL_TYPE_DEPOT << WBL_TYPE_BEGIN | part << WBL_DEPOT_PART | a << WBL_DEPOT_AXIS;
t.m5() = part << WBL_DEPOT_PART | a << WBL_DEPOT_AXIS;
SetWaterTileType(t, WATER_TILE_DEPOT);
SB(t.m6(), 2, 4, 0);
t.m7() = 0;
}
@ -488,7 +490,8 @@ inline void MakeLockTile(Tile t, Owner o, LockPart part, DiagDirection dir, Wate
t.m2() = 0;
t.m3() = 0;
t.m4() = 0;
t.m5() = WBL_TYPE_LOCK << WBL_TYPE_BEGIN | part << WBL_LOCK_PART_BEGIN | dir << WBL_LOCK_ORIENT_BEGIN;
t.m5() = part << WBL_LOCK_PART_BEGIN | dir << WBL_LOCK_ORIENT_BEGIN;
SetWaterTileType(t, WATER_TILE_LOCK);
SB(t.m6(), 2, 4, 0);
t.m7() = 0;
}