summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/clear_cmd.cpp92
-rw-r--r--src/clear_func.h2
-rw-r--r--src/clear_map.h66
-rw-r--r--src/industry_cmd.cpp24
-rw-r--r--src/saveload/afterload.cpp22
-rw-r--r--src/table/clear_land.h14
-rw-r--r--src/tree_cmd.cpp3
7 files changed, 161 insertions, 62 deletions
diff --git a/src/clear_cmd.cpp b/src/clear_cmd.cpp
index 748318262..7d89c311d 100644
--- a/src/clear_cmd.cpp
+++ b/src/clear_cmd.cpp
@@ -61,22 +61,44 @@ void DrawHillyLandTile(const TileInfo *ti)
}
}
-void DrawClearLandFence(const TileInfo *ti)
+static void DrawClearLandFence(const TileInfo *ti)
{
- bool fence_sw = GetFenceSW(ti->tile) != 0;
- bool fence_se = GetFenceSE(ti->tile) != 0;
+ /* combine fences into one sprite object */
+ StartSpriteCombine();
- if (!fence_sw && !fence_se) return;
+ int maxz = GetSlopeMaxPixelZ(ti->tileh);
- int z = GetSlopePixelZInCorner(ti->tileh, CORNER_S);
+ bool fence_nw = GetFenceNW(ti->tile) != 0;
+ if (fence_nw) {
+ int z = GetSlopePixelZInCorner(ti->tileh, CORNER_W);
+ SpriteID sprite = _clear_land_fence_sprites[GetFenceNW(ti->tile) - 1] + _fence_mod_by_tileh_nw[ti->tileh];
+ AddSortableSpriteToDraw(sprite, PAL_NONE, ti->x, ti->y - 15, 16, 31, maxz - z + 4, ti->z + z, false, 0, 15, -z);
+ }
- if (fence_sw) {
- DrawGroundSpriteAt(_clear_land_fence_sprites[GetFenceSW(ti->tile) - 1] + _fence_mod_by_tileh_sw[ti->tileh], PAL_NONE, 0, 0, z);
+ bool fence_ne = GetFenceNE(ti->tile) != 0;
+ if (fence_ne) {
+ int z = GetSlopePixelZInCorner(ti->tileh, CORNER_E);
+ SpriteID sprite = _clear_land_fence_sprites[GetFenceNE(ti->tile) - 1] + _fence_mod_by_tileh_ne[ti->tileh];
+ AddSortableSpriteToDraw(sprite, PAL_NONE, ti->x - 15, ti->y, 31, 16, maxz - z + 4, ti->z + z, false, 15, 0, -z);
}
- if (fence_se) {
- DrawGroundSpriteAt(_clear_land_fence_sprites[GetFenceSE(ti->tile) - 1] + _fence_mod_by_tileh_se[ti->tileh], PAL_NONE, 0, 0, z);
+ bool fence_sw = GetFenceSW(ti->tile) != 0;
+ bool fence_se = GetFenceSE(ti->tile) != 0;
+
+ if (fence_sw || fence_se) {
+ int z = GetSlopePixelZInCorner(ti->tileh, CORNER_S);
+
+ if (fence_sw) {
+ SpriteID sprite = _clear_land_fence_sprites[GetFenceSW(ti->tile) - 1] + _fence_mod_by_tileh_sw[ti->tileh];
+ AddSortableSpriteToDraw(sprite, PAL_NONE, ti->x, ti->y, 16, 16, maxz - z + 4, ti->z + z, false, 0, 0, -z);
+ }
+
+ if (fence_se) {
+ SpriteID sprite = _clear_land_fence_sprites[GetFenceSE(ti->tile) - 1] + _fence_mod_by_tileh_se[ti->tileh];
+ AddSortableSpriteToDraw(sprite, PAL_NONE, ti->x, ti->y, 16, 16, maxz - z + 4, ti->z + z, false, 0, 0, -z);
+ }
}
+ EndSpriteCombine();
}
static void DrawTile_Clear(TileInfo *ti)
@@ -96,6 +118,7 @@ static void DrawTile_Clear(TileInfo *ti)
case CLEAR_FIELDS:
DrawGroundSprite(_clear_land_sprites_farmland[GetFieldType(ti->tile)] + SlopeToSpriteOffset(ti->tileh), PAL_NONE);
+ DrawClearLandFence(ti);
break;
case CLEAR_SNOW:
@@ -104,7 +127,6 @@ static void DrawTile_Clear(TileInfo *ti)
break;
}
- DrawClearLandFence(ti);
DrawBridgeMiddle(ti);
}
@@ -121,35 +143,33 @@ static Foundation GetFoundation_Clear(TileIndex tile, Slope tileh)
return FOUNDATION_NONE;
}
-void TileLoopClearHelper(TileIndex tile)
+static void UpdateFences(TileIndex tile)
{
- bool self = (IsTileType(tile, MP_CLEAR) && IsClearGround(tile, CLEAR_FIELDS));
+ assert(IsTileType(tile, MP_CLEAR) && IsClearGround(tile, CLEAR_FIELDS));
bool dirty = false;
bool neighbour = (IsTileType(TILE_ADDXY(tile, 1, 0), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 1, 0), CLEAR_FIELDS));
- if (GetFenceSW(tile) == 0) {
- if (self != neighbour) {
- SetFenceSW(tile, 3);
- dirty = true;
- }
- } else {
- if (self == 0 && neighbour == 0) {
- SetFenceSW(tile, 0);
- dirty = true;
- }
+ if (!neighbour && GetFenceSW(tile) == 0) {
+ SetFenceSW(tile, 3);
+ dirty = true;
}
neighbour = (IsTileType(TILE_ADDXY(tile, 0, 1), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 0, 1), CLEAR_FIELDS));
- if (GetFenceSE(tile) == 0) {
- if (self != neighbour) {
- SetFenceSE(tile, 3);
- dirty = true;
- }
- } else {
- if (self == 0 && neighbour == 0) {
- SetFenceSE(tile, 0);
- dirty = true;
- }
+ if (!neighbour && GetFenceSE(tile) == 0) {
+ SetFenceSE(tile, 3);
+ dirty = true;
+ }
+
+ neighbour = (IsTileType(TILE_ADDXY(tile, -1, 0), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, -1, 0), CLEAR_FIELDS));
+ if (!neighbour && GetFenceNE(tile) == 0) {
+ SetFenceNE(tile, 3);
+ dirty = true;
+ }
+
+ neighbour = (IsTileType(TILE_ADDXY(tile, 0, -1), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 0, -1), CLEAR_FIELDS));
+ if (!neighbour && GetFenceNW(tile) == 0) {
+ SetFenceNW(tile, 3);
+ dirty = true;
}
if (dirty) MarkTileDirtyByTile(tile);
@@ -239,7 +259,6 @@ static void TileLoop_Clear(TileIndex tile)
return;
}
}
- TileLoopClearHelper(tile);
AmbientSoundEffectCallback(tile);
switch (_settings_game.game_creation.landscape) {
@@ -264,8 +283,8 @@ static void TileLoop_Clear(TileIndex tile)
}
break;
- case CLEAR_FIELDS: {
- uint field_type;
+ case CLEAR_FIELDS:
+ UpdateFences(tile);
if (_game_mode == GM_EDITOR) return;
@@ -280,12 +299,11 @@ static void TileLoop_Clear(TileIndex tile)
/* This farmfield is no longer farmfield, so make it grass again */
MakeClear(tile, CLEAR_GRASS, 2);
} else {
- field_type = GetFieldType(tile);
+ uint field_type = GetFieldType(tile);
field_type = (field_type < 8) ? field_type + 1 : 0;
SetFieldType(tile, field_type);
}
break;
- }
default:
return;
diff --git a/src/clear_func.h b/src/clear_func.h
index e85a5d1ae..b128288d1 100644
--- a/src/clear_func.h
+++ b/src/clear_func.h
@@ -16,7 +16,5 @@
void DrawHillyLandTile(const TileInfo *ti);
void DrawClearLandTile(const TileInfo *ti, byte set);
-void DrawClearLandFence(const TileInfo *ti);
-void TileLoopClearHelper(TileIndex tile);
#endif /* CLEAR_FUNC_H */
diff --git a/src/clear_map.h b/src/clear_map.h
index 8a346fd4e..293b7970f 100644
--- a/src/clear_map.h
+++ b/src/clear_map.h
@@ -216,12 +216,12 @@ static inline void SetIndustryIndexOfField(TileIndex t, IndustryID i)
/**
* Is there a fence at the south eastern border?
* @param t the tile to check for fences
- * @pre IsTileType(t, MP_CLEAR) || IsTileType(t, MP_TREES)
+ * @pre IsClearGround(t, CLEAR_FIELDS)
* @return 0 if there is no fence, otherwise the fence type
*/
static inline uint GetFenceSE(TileIndex t)
{
- assert(IsTileType(t, MP_CLEAR) || IsTileType(t, MP_TREES));
+ assert(IsClearGround(t, CLEAR_FIELDS));
return GB(_m[t].m4, 2, 3);
}
@@ -230,23 +230,23 @@ static inline uint GetFenceSE(TileIndex t)
* eastern border.
* @param t the tile to check for fences
* @param h 0 if there is no fence, otherwise the fence type
- * @pre IsTileType(t, MP_CLEAR) || IsTileType(t, MP_TREES)
+ * @pre IsClearGround(t, CLEAR_FIELDS)
*/
static inline void SetFenceSE(TileIndex t, uint h)
{
- assert(IsTileType(t, MP_CLEAR) || IsTileType(t, MP_TREES)); // XXX incomplete
+ assert(IsClearGround(t, CLEAR_FIELDS));
SB(_m[t].m4, 2, 3, h);
}
/**
* Is there a fence at the south western border?
* @param t the tile to check for fences
- * @pre IsTileType(t, MP_CLEAR) || IsTileType(t, MP_TREES)
+ * @pre IsClearGround(t, CLEAR_FIELDS)
* @return 0 if there is no fence, otherwise the fence type
*/
static inline uint GetFenceSW(TileIndex t)
{
- assert(IsTileType(t, MP_CLEAR) || IsTileType(t, MP_TREES));
+ assert(IsClearGround(t, CLEAR_FIELDS));
return GB(_m[t].m4, 5, 3);
}
@@ -255,14 +255,64 @@ static inline uint GetFenceSW(TileIndex t)
* western border.
* @param t the tile to check for fences
* @param h 0 if there is no fence, otherwise the fence type
- * @pre IsTileType(t, MP_CLEAR) || IsTileType(t, MP_TREES)
+ * @pre IsClearGround(t, CLEAR_FIELDS)
*/
static inline void SetFenceSW(TileIndex t, uint h)
{
- assert(IsTileType(t, MP_CLEAR) || IsTileType(t, MP_TREES)); // XXX incomplete
+ assert(IsClearGround(t, CLEAR_FIELDS));
SB(_m[t].m4, 5, 3, h);
}
+/**
+ * Is there a fence at the north eastern border?
+ * @param t the tile to check for fences
+ * @pre IsClearGround(t, CLEAR_FIELDS)
+ * @return 0 if there is no fence, otherwise the fence type
+ */
+static inline uint GetFenceNE(TileIndex t)
+{
+ assert(IsClearGround(t, CLEAR_FIELDS));
+ return GB(_m[t].m3, 5, 3);
+}
+
+/**
+ * Sets the type of fence (and whether there is one) for the north
+ * eastern border.
+ * @param t the tile to check for fences
+ * @param h 0 if there is no fence, otherwise the fence type
+ * @pre IsClearGround(t, CLEAR_FIELDS)
+ */
+static inline void SetFenceNE(TileIndex t, uint h)
+{
+ assert(IsClearGround(t, CLEAR_FIELDS));
+ SB(_m[t].m3, 5, 3, h);
+}
+
+/**
+ * Is there a fence at the north western border?
+ * @param t the tile to check for fences
+ * @pre IsClearGround(t, CLEAR_FIELDS)
+ * @return 0 if there is no fence, otherwise the fence type
+ */
+static inline uint GetFenceNW(TileIndex t)
+{
+ assert(IsClearGround(t, CLEAR_FIELDS));
+ return GB(_m[t].m6, 2, 3);
+}
+
+/**
+ * Sets the type of fence (and whether there is one) for the north
+ * western border.
+ * @param t the tile to check for fences
+ * @param h 0 if there is no fence, otherwise the fence type
+ * @pre IsClearGround(t, CLEAR_FIELDS)
+ */
+static inline void SetFenceNW(TileIndex t, uint h)
+{
+ assert(IsClearGround(t, CLEAR_FIELDS));
+ SB(_m[t].m6, 2, 3, h);
+}
+
/**
* Make a clear tile.
diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp
index 668749678..e57be90e7 100644
--- a/src/industry_cmd.cpp
+++ b/src/industry_cmd.cpp
@@ -955,20 +955,28 @@ static bool IsBadFarmFieldTile2(TileIndex tile)
}
}
-static void SetupFarmFieldFence(TileIndex tile, int size, byte type, Axis direction)
+static void SetupFarmFieldFence(TileIndex tile, int size, byte type, Axis direction, bool north)
{
do {
tile = TILE_MASK(tile);
- if (IsTileType(tile, MP_CLEAR) || IsTileType(tile, MP_TREES)) {
+ if (IsTileType(tile, MP_CLEAR) && IsClearGround(tile, CLEAR_FIELDS)) {
byte or_ = type;
if (or_ == 1 && Chance16(1, 7)) or_ = 2;
if (direction == AXIS_X) {
- SetFenceSE(tile, or_);
+ if (north) {
+ SetFenceNW(tile, or_);
+ } else {
+ SetFenceSE(tile, or_);
+ }
} else {
- SetFenceSW(tile, or_);
+ if (north) {
+ SetFenceNE(tile, or_);
+ } else {
+ SetFenceSW(tile, or_);
+ }
}
}
@@ -1021,10 +1029,10 @@ static void PlantFarmField(TileIndex tile, IndustryID industry)
type = _plantfarmfield_type[Random() & 0xF];
}
- SetupFarmFieldFence(ta.tile - TileDiffXY(1, 0), ta.h, type, AXIS_Y);
- SetupFarmFieldFence(ta.tile - TileDiffXY(0, 1), ta.w, type, AXIS_X);
- SetupFarmFieldFence(ta.tile + TileDiffXY(ta.w - 1, 0), ta.h, type, AXIS_Y);
- SetupFarmFieldFence(ta.tile + TileDiffXY(0, ta.h - 1), ta.w, type, AXIS_X);
+ SetupFarmFieldFence(ta.tile, ta.h, type, AXIS_Y, true);
+ SetupFarmFieldFence(ta.tile, ta.w, type, AXIS_X, true);
+ SetupFarmFieldFence(ta.tile + TileDiffXY(ta.w - 1, 0), ta.h, type, AXIS_Y, false);
+ SetupFarmFieldFence(ta.tile + TileDiffXY(0, ta.h - 1), ta.w, type, AXIS_X, false);
}
void PlantRandomFarmField(const Industry *i)
diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp
index 3d660db37..2fc3e0e5e 100644
--- a/src/saveload/afterload.cpp
+++ b/src/saveload/afterload.cpp
@@ -1267,10 +1267,6 @@ bool AfterLoadGame()
if (IsTileType(t, MP_CLEAR) && IsClearGround(t, CLEAR_FIELDS)) {
/* remove fields */
MakeClear(t, CLEAR_GRASS, 3);
- } else if (IsTileType(t, MP_CLEAR) || IsTileType(t, MP_TREES)) {
- /* remove fences around fields */
- SetFenceSE(t, 0);
- SetFenceSW(t, 0);
}
}
@@ -2653,6 +2649,24 @@ bool AfterLoadGame()
_settings_game.game_creation.snow_line_height /= TILE_HEIGHT;
}
+ if (IsSavegameVersionBefore(164) && !IsSavegameVersionBefore(32)) {
+ /* We store 4 fences in the field tiles instead of only SE and SW. */
+ for (TileIndex t = 0; t < map_size; t++) {
+ if (!IsTileType(t, MP_CLEAR) && !IsTileType(t, MP_TREES)) continue;
+ if (IsTileType(t, MP_CLEAR) && IsClearGround(t, CLEAR_FIELDS)) continue;
+ uint fence = GB(_m[t].m4, 5, 3);
+ if (fence != 0 && IsTileType(TILE_ADDXY(t, 1, 0), MP_CLEAR) && IsClearGround(TILE_ADDXY(t, 1, 0), CLEAR_FIELDS)) {
+ SetFenceNE(TILE_ADDXY(t, 1, 0), fence);
+ }
+ fence = GB(_m[t].m4, 2, 3);
+ if (fence != 0 && IsTileType(TILE_ADDXY(t, 0, 1), MP_CLEAR) && IsClearGround(TILE_ADDXY(t, 0, 1), CLEAR_FIELDS)) {
+ SetFenceNW(TILE_ADDXY(t, 0, 1), fence);
+ }
+ SB(_m[t].m4, 2, 3, 0);
+ SB(_m[t].m4, 5, 3, 0);
+ }
+ }
+
/* When any NewGRF has been changed the availability of some vehicles might
* have been changed too. e->company_avail must be set to 0 in that case
* which is done by StartupEngines(). */
diff --git a/src/table/clear_land.h b/src/table/clear_land.h
index 86c0bb582..a6554802f 100644
--- a/src/table/clear_land.h
+++ b/src/table/clear_land.h
@@ -34,6 +34,20 @@ static const byte _fence_mod_by_tileh_se[32] = {
1, 1, 5, 5, 3, 3, 3, 1,
};
+static const byte _fence_mod_by_tileh_ne[32] = {
+ 0, 0, 0, 0, 4, 4, 4, 4,
+ 2, 2, 2, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 4, 4, 4, 4,
+ 2, 2, 2, 2, 0, 0, 0, 0,
+};
+
+static const byte _fence_mod_by_tileh_nw[32] = {
+ 1, 5, 1, 5, 1, 5, 1, 5,
+ 3, 1, 3, 1, 3, 1, 3, 1,
+ 1, 5, 1, 5, 1, 5, 1, 5,
+ 3, 1, 3, 1, 3, 1, 3, 1,
+};
+
static const SpriteID _clear_land_fence_sprites[7] = {
SPR_HEDGE_BUSHES,
diff --git a/src/tree_cmd.cpp b/src/tree_cmd.cpp
index c31d09834..37886a944 100644
--- a/src/tree_cmd.cpp
+++ b/src/tree_cmd.cpp
@@ -453,8 +453,6 @@ static void DrawTile_Trees(TileInfo *ti)
default: DrawGroundSprite(_clear_land_sprites_snow_desert[GetTreeDensity(ti->tile)] + SlopeToSpriteOffset(ti->tileh), PAL_NONE); break;
}
- DrawClearLandFence(ti);
-
/* Do not draw trees when the invisible trees setting is set */
if (IsInvisibilitySet(TO_TREES)) return;
@@ -630,7 +628,6 @@ static void TileLoop_Trees(TileIndex tile)
}
AmbientSoundEffectCallback(tile);
- TileLoopClearHelper(tile);
uint treeCounter = GetTreeCounter(tile);