Mercurial > hg > openttd
changeset 9718:3c66bb36c785 draft
(svn r13838) -Codechange: Make industry tiles aware of WaterClasses.
author | frosch <frosch@openttd.org> |
---|---|
date | Sat, 26 Jul 2008 16:14:10 +0000 |
parents | 57549f1e5133 |
children | 273a2779fd2b |
files | docs/landscape.html docs/landscape_grid.html src/industry_cmd.cpp src/industry_map.h src/newgrf_industrytiles.cpp src/openttd.cpp src/saveload.cpp src/station_cmd.cpp src/station_map.h src/water.h src/water_cmd.cpp src/water_map.h |
diffstat | 12 files changed, 110 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/docs/landscape.html +++ b/docs/landscape.html @@ -1035,6 +1035,7 @@ <ul> <li>m1 bit 7: clear = under construction <ul> + <li>m1 bits 6..5 : Water class (sea, canal, river or land) <li>m1 bits 3..2: construction counter, for buildings under construction incremented on every periodic tile processing</li> <li>m1 bits 1..0: stage of construction (<tt>3</tt> = completed), incremented when the construction counter wraps around<br> the meaning is different for some animated tiles which are never under construction (types <tt>01</tt>, <tt>1E</tt>..<tt>20</tt>, <tt>30</tt>, <tt>58</tt>; see above)</li>
--- a/docs/landscape_grid.html +++ b/docs/landscape_grid.html @@ -293,7 +293,7 @@ <td>8</td> <td class="caption">industry</td> <td class="bits">XXXX XXXX</td> - <td class="bits">X<span class="free">OOO</span> <span class="abuse"> + <td class="bits">XXX<span class="free">O</span> <span class="abuse"> XXXX</span></td> <td class="bits">XXXX XXXX XXXX XXXX</td> <td class="bits">XXXX XXXX</td>
--- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -147,7 +147,8 @@ BEGIN_TILE_LOOP(tile_cur, this->width, this->height, this->xy); if (IsTileType(tile_cur, MP_INDUSTRY)) { if (GetIndustryIndex(tile_cur) == this->index) { - DoClearSquare(tile_cur); + /* MakeWaterKeepingClass() can also handle 'land' */ + MakeWaterKeepingClass(tile_cur, OWNER_NONE); } } else if (IsTileType(tile_cur, MP_STATION) && IsOilRig(tile_cur)) { DeleteOilRig(tile_cur); @@ -300,7 +301,13 @@ /* DrawFoundation() modifes ti->z and ti->tileh */ if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED); - DrawGroundSprite(image, pal); + /* If the ground sprite is the default flat water sprite, draw also canal/river borders. + * Do not do this if the tile's WaterClass is 'land'. */ + if (image == SPR_FLAT_WATER_TILE && IsIndustryTileOnWater(ti->tile)) { + DrawWaterClassGround(ti); + } else { + DrawGroundSprite(image, pal); + } /* If industries are transparent and invisible, do not draw the upper part */ if (IsInvisibilitySet(TO_INDUSTRIES)) return; @@ -724,6 +731,8 @@ IndustryGfx newgfx; IndustryGfx gfx; + if (IsIndustryTileOnWater(tile)) TileLoop_Water(tile); + TriggerIndustryTile(tile, INDTILE_TRIGGER_TILE_LOOP); if (!IsIndustryCompleted(tile)) { @@ -748,14 +757,6 @@ gfx = GetIndustryGfx(tile); switch (gfx) { - case GFX_OILRIG_1: // coast line at oilrigs - case GFX_OILRIG_2: - case GFX_OILRIG_3: - case GFX_OILRIG_4: - case GFX_OILRIG_5: - TileLoop_Water(tile); - break; - case GFX_COAL_MINE_TOWER_NOT_ANIMATED: case GFX_COPPER_MINE_TOWER_NOT_ANIMATED: case GFX_GOLD_MINE_TOWER_NOT_ANIMATED: @@ -1548,9 +1549,11 @@ size = it->ti.y; if (size > i->height)i->height = size; + WaterClass wc = (IsWaterTile(cur_tile) ? GetWaterClass(cur_tile) : WATER_CLASS_INVALID); + DoCommand(cur_tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); - MakeIndustry(cur_tile, i->index, it->gfx, Random()); + MakeIndustry(cur_tile, i->index, it->gfx, Random(), wc); if (_generating_world) { SetIndustryConstructionCounter(cur_tile, 3);
--- a/src/industry_map.h +++ b/src/industry_map.h @@ -7,7 +7,7 @@ #include "industry.h" #include "tile_map.h" - +#include "water_map.h" /** @@ -155,13 +155,24 @@ } /** + * Tests if the industry tile was built on water. + * @param t the industry tile + * @return true iff on water + */ +static inline bool IsIndustryTileOnWater(TileIndex t) +{ + assert(IsTileType(t, MP_INDUSTRY)); + return (GetWaterClass(t) != WATER_CLASS_INVALID); +} + +/** * Make the given tile an industry tile * @param t the tile to make an industry tile * @param index the industry this tile belongs to * @param gfx the graphics to use for the tile * @param random the random value */ -static inline void MakeIndustry(TileIndex t, IndustryID index, IndustryGfx gfx, uint8 random) +static inline void MakeIndustry(TileIndex t, IndustryID index, IndustryGfx gfx, uint8 random, WaterClass wc) { SetTileType(t, MP_INDUSTRY); _m[t].m1 = 0; @@ -170,6 +181,7 @@ _m[t].m4 = 0; SetIndustryGfx(t, gfx); _me[t].m7 = random; + SetWaterClass(t, wc); } /**
--- a/src/newgrf_industrytiles.cpp +++ b/src/newgrf_industrytiles.cpp @@ -25,6 +25,7 @@ #include "town.h" #include "command_func.h" #include "animated_tile_func.h" +#include "water.h" #include "table/sprites.h" #include "table/strings.h" @@ -185,7 +186,15 @@ if (IS_CUSTOM_SPRITE(image)) image += stage; - if (GB(image, 0, SPRITE_WIDTH) != 0) DrawGroundSprite(image, pal); + if (GB(image, 0, SPRITE_WIDTH) != 0) { + /* If the ground sprite is the default flat water sprite, draw also canal/river borders + * Do not do this if the tile's WaterClass is 'land'. */ + if (image == SPR_FLAT_WATER_TILE && IsIndustryTileOnWater(ti->tile)) { + DrawWaterClassGround(ti); + } else { + DrawGroundSprite(image, pal); + } + } foreach_draw_tile_seq(dtss, dts->seq) { if (GB(dtss->image.sprite, 0, SPRITE_WIDTH) == 0) continue;
--- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -2340,8 +2340,8 @@ for (TileIndex t = 0; t < map_size; t++) { if (GetTileSlope(t, NULL) != SLOPE_FLAT) continue; - if (IsTileType(t, MP_WATER) && IsLock(t)) SetWaterClassDependingOnSurroundings(t); - if (IsTileType(t, MP_STATION) && (IsDock(t) || IsBuoy(t))) SetWaterClassDependingOnSurroundings(t); + if (IsTileType(t, MP_WATER) && IsLock(t)) SetWaterClassDependingOnSurroundings(t, false); + if (IsTileType(t, MP_STATION) && (IsDock(t) || IsBuoy(t))) SetWaterClassDependingOnSurroundings(t, false); } } @@ -2438,6 +2438,22 @@ } } + if (CheckSavegameVersion(99)) { + /* Set newly introduced WaterClass of industry tiles */ + for (TileIndex t = 0; t < map_size; t++) { + if (IsTileType(t, MP_STATION) && IsOilRig(t)) { + SetWaterClassDependingOnSurroundings(t, true); + } + if (IsTileType(t, MP_INDUSTRY)) { + if ((GetIndustrySpec(GetIndustryType(t))->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0) { + SetWaterClassDependingOnSurroundings(t, true); + } else { + SetWaterClass(t, WATER_CLASS_INVALID); + } + } + } + } + GamelogPrintDebug(1); return InitializeWindowsAndCaches();
--- a/src/saveload.cpp +++ b/src/saveload.cpp @@ -36,7 +36,7 @@ #include "table/strings.h" -extern const uint16 SAVEGAME_VERSION = 98; +extern const uint16 SAVEGAME_VERSION = 99; SavegameType _savegame_type; ///< type of savegame we are loading
--- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -2932,7 +2932,8 @@ st->string_id = GenerateStationName(st, tile, STATIONNAMING_OILRIG); - MakeOilrig(tile, st->index); + assert(IsTileType(tile, MP_INDUSTRY)); + MakeOilrig(tile, st->index, GetWaterClass(tile)); st->owner = OWNER_NONE; st->airport_flags = 0; @@ -2967,7 +2968,8 @@ { Station *st = GetStationByTile(tile); - MakeWater(tile); + MakeWaterKeepingClass(tile, OWNER_NONE); + MarkTileDirtyByTile(tile); st->dock_tile = 0; st->airport_tile = 0;
--- a/src/station_map.h +++ b/src/station_map.h @@ -313,9 +313,10 @@ SetWaterClass(t + TileOffsByDiagDir(d), wc); } -static inline void MakeOilrig(TileIndex t, StationID sid) +static inline void MakeOilrig(TileIndex t, StationID sid, WaterClass wc) { MakeStation(t, OWNER_NONE, sid, STATION_OILRIG, 0); + SetWaterClass(t, wc); } #endif /* STATION_MAP_H */
--- a/src/water.h +++ b/src/water.h @@ -15,6 +15,6 @@ void DrawShoreTile(Slope tileh); void MakeWaterKeepingClass(TileIndex tile, Owner o); -void SetWaterClassDependingOnSurroundings(TileIndex t); +void SetWaterClassDependingOnSurroundings(TileIndex t, bool include_invalid_water_class); #endif /* WATER_H */
--- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -109,10 +109,20 @@ * whether the tile used to be canal or 'normal' water. * @param t the tile to change. * @param o the owner of the new tile. + * @param include_invalid_water_class Also consider WATER_CLASS_INVALID, i.e. industry tiles on land */ -void SetWaterClassDependingOnSurroundings(TileIndex t) +void SetWaterClassDependingOnSurroundings(TileIndex t, bool include_invalid_water_class) { - assert(GetTileSlope(t, NULL) == SLOPE_FLAT); + /* If the slope is not flat, we always assume 'land' (if allowed). Also for one-corner-raised-shores. + * Note: Wrt. autosloping under industry tiles this is the most fool-proof behaviour. */ + if (GetTileSlope(t, NULL) != SLOPE_FLAT) { + if (include_invalid_water_class) { + SetWaterClass(t, WATER_CLASS_INVALID); + return; + } else { + NOT_REACHED(); + } + } /* Mark tile dirty in all cases */ MarkTileDirtyByTile(t); @@ -158,6 +168,11 @@ } } + if (!has_water && !has_canal && !has_river && include_invalid_water_class) { + SetWaterClass(t, WATER_CLASS_INVALID); + return; + } + if (has_river && !has_canal) { SetWaterClass(t, WATER_CLASS_RIVER); } else if (has_canal || !has_water) { @@ -219,12 +234,21 @@ void MakeWaterKeepingClass(TileIndex tile, Owner o) { - assert(IsTileType(tile, MP_WATER) || (IsTileType(tile, MP_STATION) && (IsBuoy(tile) || IsDock(tile)))); + assert(IsTileType(tile, MP_WATER) || (IsTileType(tile, MP_STATION) && (IsBuoy(tile) || IsDock(tile) || IsOilRig(tile))) || IsTileType(tile, MP_INDUSTRY)); + + WaterClass wc = GetWaterClass(tile); - switch (GetWaterClass(tile)) { + /* Autoslope might turn an originally canal or river tile into land */ + uint z; + if (GetTileSlope(tile, &z) != SLOPE_FLAT) wc = WATER_CLASS_INVALID; + + if (wc == WATER_CLASS_SEA && z > 0) wc = WATER_CLASS_CANAL; + + switch (wc) { case WATER_CLASS_SEA: MakeWater(tile); break; case WATER_CLASS_CANAL: MakeCanal(tile, o, Random()); break; case WATER_CLASS_RIVER: MakeRiver(tile, Random()); break; + default: DoClearSquare(tile); break; } } @@ -512,7 +536,7 @@ return false; case MP_STATION: return IsOilRig(tile) || (IsDock(tile) && GetTileSlope(tile, NULL) == SLOPE_FLAT) || IsBuoy(tile); - case MP_INDUSTRY: return (GetIndustrySpec(GetIndustryType(tile))->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0; + case MP_INDUSTRY: return IsIndustryTileOnWater(tile); case MP_TUNNELBRIDGE: return GetTunnelBridgeTransportType(tile) == TRANSPORT_WATER && ReverseDiagDir(GetTunnelBridgeDirection(tile)) == DirToDiagDir(from); default: return false; } @@ -671,6 +695,7 @@ case WATER_CLASS_SEA: DrawSeaWater(ti->tile); break; case WATER_CLASS_CANAL: DrawCanalWater(ti->tile); break; case WATER_CLASS_RIVER: DrawRiverWater(ti); break; + default: NOT_REACHED(); } } @@ -882,9 +907,9 @@ */ static FloodingBehaviour GetFloodingBehaviour(TileIndex tile) { - /* FLOOD_ACTIVE: 'single-corner-raised'-coast, sea, sea-shipdepots, sea-buoys, sea-docks (water part), rail with flooded halftile + /* FLOOD_ACTIVE: 'single-corner-raised'-coast, sea, sea-shipdepots, sea-buoys, sea-docks (water part), rail with flooded halftile, sea-water-industries, sea-oilrigs * FLOOD_DRYUP: coast with more than one corner raised, coast with rail-track, coast with trees - * FLOOD_PASSIVE: oilrig, water-industries + * FLOOD_PASSIVE: (not used) * FLOOD_NONE: canals, rivers, everything else */ switch (GetTileType(tile)) { @@ -906,13 +931,13 @@ return (GetTreeGround(tile) == TREE_GROUND_SHORE ? FLOOD_DRYUP : FLOOD_NONE); case MP_STATION: - if (IsBuoy(tile) || (IsDock(tile) && GetTileSlope(tile, NULL) == SLOPE_FLAT)) { + if (IsBuoy(tile) || (IsDock(tile) && GetTileSlope(tile, NULL) == SLOPE_FLAT) || IsOilRig(tile)) { return (GetWaterClass(tile) == WATER_CLASS_SEA ? FLOOD_ACTIVE : FLOOD_NONE); } - return (IsOilRig(tile) ? FLOOD_PASSIVE : FLOOD_NONE); + return FLOOD_NONE; case MP_INDUSTRY: - return ((GetIndustrySpec(GetIndustryType(tile))->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0 ? FLOOD_PASSIVE : FLOOD_NONE); + return ((IsIndustryTileOnWater(tile) && GetWaterClass(tile) == WATER_CLASS_SEA) ? FLOOD_ACTIVE : FLOOD_NONE); default: return FLOOD_NONE;
--- a/src/water_map.h +++ b/src/water_map.h @@ -16,6 +16,7 @@ WATER_CLASS_SEA, WATER_CLASS_CANAL, WATER_CLASS_RIVER, + WATER_CLASS_INVALID, ///< Used for industry tiles on land (also for oilrig if newgrf says so) }; enum DepotPart { @@ -45,14 +46,18 @@ static inline WaterClass GetWaterClass(TileIndex t) { - assert(IsTileType(t, MP_WATER) || IsTileType(t, MP_STATION)); - return (WaterClass)GB(_m[t].m3, 0, 2); + assert(IsTileType(t, MP_WATER) || IsTileType(t, MP_STATION) || IsTileType(t, MP_INDUSTRY)); + return (WaterClass)(IsTileType(t, MP_INDUSTRY) ? GB(_m[t].m1, 5, 2) : GB(_m[t].m3, 0, 2)); } static inline void SetWaterClass(TileIndex t, WaterClass wc) { - assert(IsTileType(t, MP_WATER) || IsTileType(t, MP_STATION)); - SB(_m[t].m3, 0, 2, wc); + assert(IsTileType(t, MP_WATER) || IsTileType(t, MP_STATION) || IsTileType(t, MP_INDUSTRY)); + if (IsTileType(t, MP_INDUSTRY)) { + SB(_m[t].m1, 5, 2, wc); + } else { + SB(_m[t].m3, 0, 2, wc); + } } /** IsWater return true if any type of clear water like ocean, river, canal */