mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-06 06:15:04 +00:00
(svn r13838) -Codechange: Make industry tiles aware of WaterClasses.
This commit is contained in:
parent
ea7ed286a6
commit
16c80d031c
@ -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>
|
||||
|
@ -293,7 +293,7 @@ the array so you can quickly see what is used and what is not.
|
||||
<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>
|
||||
|
@ -147,7 +147,8 @@ Industry::~Industry()
|
||||
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 @@ static void DrawTile_Industry(TileInfo *ti)
|
||||
/* 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 @@ static void TileLoop_Industry(TileIndex tile)
|
||||
IndustryGfx newgfx;
|
||||
IndustryGfx gfx;
|
||||
|
||||
if (IsIndustryTileOnWater(tile)) TileLoop_Water(tile);
|
||||
|
||||
TriggerIndustryTile(tile, INDTILE_TRIGGER_TILE_LOOP);
|
||||
|
||||
if (!IsIndustryCompleted(tile)) {
|
||||
@ -748,14 +757,6 @@ static void TileLoop_Industry(TileIndex tile)
|
||||
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 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, int type, const Ind
|
||||
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);
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include "industry.h"
|
||||
#include "tile_map.h"
|
||||
|
||||
#include "water_map.h"
|
||||
|
||||
|
||||
/**
|
||||
@ -154,6 +154,17 @@ static inline void SetIndustryGfx(TileIndex t, IndustryGfx gfx)
|
||||
SB(_m[t].m6, 2, 1, GB(gfx, 8, 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -161,7 +172,7 @@ static inline void SetIndustryGfx(TileIndex t, IndustryGfx gfx)
|
||||
* @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 @@ static inline void MakeIndustry(TileIndex t, IndustryID index, IndustryGfx gfx,
|
||||
_m[t].m4 = 0;
|
||||
SetIndustryGfx(t, gfx);
|
||||
_me[t].m7 = random;
|
||||
SetWaterClass(t, wc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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 @@ void IndustryDrawTileLayout(const TileInfo *ti, const SpriteGroup *group, byte r
|
||||
|
||||
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;
|
||||
|
@ -2340,8 +2340,8 @@ bool AfterLoadGame()
|
||||
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 @@ bool AfterLoadGame()
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
@ -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
|
||||
|
||||
|
@ -2932,7 +2932,8 @@ void BuildOilRig(TileIndex tile)
|
||||
|
||||
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 @@ void DeleteOilRig(TileIndex tile)
|
||||
{
|
||||
Station *st = GetStationByTile(tile);
|
||||
|
||||
MakeWater(tile);
|
||||
MakeWaterKeepingClass(tile, OWNER_NONE);
|
||||
MarkTileDirtyByTile(tile);
|
||||
|
||||
st->dock_tile = 0;
|
||||
st->airport_tile = 0;
|
||||
|
@ -313,9 +313,10 @@ static inline void MakeDock(TileIndex t, Owner o, StationID sid, DiagDirection d
|
||||
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 */
|
||||
|
@ -15,6 +15,6 @@ void DrawWaterClassGround(const struct TileInfo *ti);
|
||||
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 */
|
||||
|
@ -109,10 +109,20 @@ static void MarkCanalsAndRiversAroundDirty(TileIndex tile)
|
||||
* 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 @@ void SetWaterClassDependingOnSurroundings(TileIndex t)
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ CommandCost CmdBuildShipDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2
|
||||
|
||||
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));
|
||||
|
||||
switch (GetWaterClass(tile)) {
|
||||
WaterClass wc = 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 @@ static bool IsWateredTile(TileIndex tile, Direction from)
|
||||
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 @@ void DrawWaterClassGround(const TileInfo *ti) {
|
||||
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 void FloodVehicle(Vehicle *v)
|
||||
*/
|
||||
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 @@ static FloodingBehaviour GetFloodingBehaviour(TileIndex tile)
|
||||
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;
|
||||
|
@ -16,6 +16,7 @@ enum WaterClass {
|
||||
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 WaterTileType GetWaterTileType(TileIndex t)
|
||||
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user