summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/clear_cmd.cpp3
-rw-r--r--src/industry_cmd.cpp7
-rw-r--r--src/landscape.cpp59
-rw-r--r--src/landscape.h19
-rw-r--r--src/newgrf.cpp20
-rw-r--r--src/newgrf_house.cpp3
-rw-r--r--src/newgrf_spritegroup.cpp3
-rw-r--r--src/newgrf_station.cpp3
-rw-r--r--src/rail_cmd.cpp3
-rw-r--r--src/road_cmd.cpp3
-rw-r--r--src/town_cmd.cpp3
-rw-r--r--src/tree_cmd.cpp7
-rw-r--r--src/tunnelbridge_cmd.cpp3
13 files changed, 122 insertions, 14 deletions
diff --git a/src/clear_cmd.cpp b/src/clear_cmd.cpp
index 4dab24024..08999edb3 100644
--- a/src/clear_cmd.cpp
+++ b/src/clear_cmd.cpp
@@ -16,6 +16,7 @@
#include "tunnel_map.h"
#include "bridge_map.h"
#include "bridge.h"
+#include "landscape.h"
#include "variables.h"
#include "table/sprites.h"
#include "unmovable_map.h"
@@ -620,7 +621,7 @@ void TileLoopClearHelper(TileIndex tile)
/* convert into snowy tiles */
static void TileLoopClearAlps(TileIndex tile)
{
- int k = GetTileZ(tile) - _opt.snow_line + TILE_HEIGHT;
+ int k = GetTileZ(tile) - GetSnowLine() + TILE_HEIGHT;
if (k < 0) { // well below the snow line
if (!IsClearGround(tile, CLEAR_SNOW)) return;
diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp
index 2352c52da..f237dcf7b 100644
--- a/src/industry_cmd.cpp
+++ b/src/industry_cmd.cpp
@@ -12,6 +12,7 @@
#include "table/sprites.h"
#include "map.h"
#include "tile.h"
+#include "landscape.h"
#include "viewport.h"
#include "command.h"
#include "industry.h"
@@ -814,7 +815,7 @@ static void PlantFarmField(TileIndex tile, IndustryID industry)
int type;
if (_opt.landscape == LT_HILLY) {
- if (GetTileZ(tile) + TILE_HEIGHT * 2 >= _opt.snow_line)
+ if (GetTileZ(tile) + TILE_HEIGHT * 2 >= GetSnowLine())
return;
}
@@ -1016,7 +1017,7 @@ static bool CheckNewIndustry_NULL(TileIndex tile)
static bool CheckNewIndustry_Forest(TileIndex tile)
{
if (_opt.landscape == LT_HILLY) {
- if (GetTileZ(tile) < _opt.snow_line + TILE_HEIGHT * 2U) {
+ if (GetTileZ(tile) < HighestSnowLine() + TILE_HEIGHT * 2U) {
_error_message = STR_4831_FOREST_CAN_ONLY_BE_PLANTED;
return false;
}
@@ -1048,7 +1049,7 @@ static bool CheckNewIndustry_OilRig(TileIndex tile)
static bool CheckNewIndustry_Farm(TileIndex tile)
{
if (_opt.landscape == LT_HILLY) {
- if (GetTileZ(tile) + TILE_HEIGHT * 2 >= _opt.snow_line) {
+ if (GetTileZ(tile) + TILE_HEIGHT * 2 >= HighestSnowLine()) {
_error_message = STR_0239_SITE_UNSUITABLE;
return false;
}
diff --git a/src/landscape.cpp b/src/landscape.cpp
index 7c3ada82f..9ed7d9df1 100644
--- a/src/landscape.cpp
+++ b/src/landscape.cpp
@@ -5,6 +5,7 @@
#include "bridge_map.h"
#include "heightmap.h"
#include "clear_map.h"
+#include "date.h"
#include "functions.h"
#include "map.h"
#include "player.h"
@@ -14,6 +15,7 @@
#include <stdarg.h>
#include "viewport.h"
#include "command.h"
+#include "landscape.h"
#include "vehicle.h"
#include "variables.h"
#include "void_map.h"
@@ -61,6 +63,7 @@ const Slope _inclined_tileh[] = {
SLOPE_NWS, SLOPE_WSE, SLOPE_SEN, SLOPE_ENW
};
+SnowLine *_snow_line = NULL;
uint GetPartialZ(int x, int y, Slope corners)
{
@@ -302,6 +305,62 @@ void GetTileDesc(TileIndex tile, TileDesc *td)
_tile_type_procs[GetTileType(tile)]->get_tile_desc_proc(tile, td);
}
+/**
+ * Has a snow line table already been loaded.
+ * @return true if the table has been loaded already.
+ */
+bool IsSnowLineSet(void)
+{
+ return _snow_line != NULL;
+}
+
+/**
+ * Set a variable snow line, as loaded from a newgrf file.
+ * @param table the 12 * 32 byte table containing the snowline for each day
+ */
+void SetSnowLine(byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS])
+{
+ _snow_line = CallocT<SnowLine>(1);
+ memcpy(_snow_line->table, table, sizeof(_snow_line->table));
+
+ for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
+ for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
+ _snow_line->highest_value = max(_snow_line->highest_value, table[i][j]);
+ }
+ }
+}
+
+/**
+ * Get the current snow line, either variable or static.
+ * @return the snow line height.
+ */
+byte GetSnowLine(void)
+{
+ if (_snow_line == NULL) return _opt.snow_line;
+
+ YearMonthDay ymd;
+ ConvertDateToYMD(_date, &ymd);
+ return _snow_line->table[ymd.month][ymd.day];
+}
+
+/**
+ * Get the highest possible snow line height, either variable or static.
+ * @return the highest snow line height.
+ */
+byte HighestSnowLine(void)
+{
+ return _snow_line == NULL ? _opt.snow_line : _snow_line->highest_value;
+}
+
+/**
+ * Clear the variable snow line table and free the memory.
+ */
+void ClearSnowLine(void)
+{
+ free(_snow_line);
+ _snow_line = NULL;
+}
+
/** Clear a piece of landscape
* @param tile tile to clear
* @param flags of operation to conduct
diff --git a/src/landscape.h b/src/landscape.h
new file mode 100644
index 000000000..5cfe80edf
--- /dev/null
+++ b/src/landscape.h
@@ -0,0 +1,19 @@
+/* $Id$ */
+
+/** @file landscape.h */
+
+enum {
+ SNOW_LINE_MONTHS = 12,
+ SNOW_LINE_DAYS = 32,
+};
+
+struct SnowLine {
+ byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
+ byte highest_value;
+};
+
+bool IsSnowLineSet(void);
+void SetSnowLine(byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS]);
+byte GetSnowLine(void);
+byte HighestSnowLine(void);
+void ClearSnowLine(void);
diff --git a/src/newgrf.cpp b/src/newgrf.cpp
index 40185e3d7..6fbcf764f 100644
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -27,6 +27,7 @@
#include "fontcache.h"
#include "date.h"
#include "currency.h"
+#include "landscape.h"
#include "sound.h"
#include "newgrf_config.h"
#include "newgrf_house.h"
@@ -1510,6 +1511,22 @@ static bool GlobalVarChangeInfo(uint gvid, int numinfo, int prop, byte **bufp, i
break;
case 0x10: // 12 * 32 * B Snow line height table
+ if (numinfo > 1 || IsSnowLineSet()) {
+ grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
+ } else if (len < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
+ grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (%d)", len);
+ } else {
+ byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
+
+ for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
+ for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
+ table[i][j] = grf_load_byte(&buf);
+ }
+ }
+ SetSnowLine(table);
+ }
+ break;
+
default:
ret = true;
}
@@ -3973,6 +3990,9 @@ static void ResetNewGRFData()
ResetStationClasses();
ResetCustomStations();
+ /* Reset the snowline table. */
+ ClearSnowLine();
+
/* Reset NewGRF files */
ResetNewGRF();
diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp
index 707825341..888b5764f 100644
--- a/src/newgrf_house.cpp
+++ b/src/newgrf_house.cpp
@@ -8,6 +8,7 @@
#include "variables.h"
#include "debug.h"
#include "viewport.h"
+#include "landscape.h"
#include "date.h"
#include "town.h"
#include "town_map.h"
@@ -252,7 +253,7 @@ static uint32 GetTerrainType(TileIndex tile)
{
switch (_opt.landscape) {
case LT_DESERT: return GetTropicZone(tile) == TROPICZONE_DESERT ? 1 : 2;
- case LT_HILLY: return GetTileZ(tile) >= _opt.snow_line ? 4 : 0;
+ case LT_HILLY: return GetTileZ(tile) >= GetSnowLine() ? 4 : 0;
default: return 0;
}
}
diff --git a/src/newgrf_spritegroup.cpp b/src/newgrf_spritegroup.cpp
index fcde3cc28..7fba72c0f 100644
--- a/src/newgrf_spritegroup.cpp
+++ b/src/newgrf_spritegroup.cpp
@@ -4,6 +4,7 @@
#include "openttd.h"
#include "variables.h"
#include "macros.h"
+#include "landscape.h"
#include "oldpool.h"
#include "newgrf_callbacks.h"
#include "newgrf_spritegroup.h"
@@ -91,7 +92,7 @@ static inline uint32 GetVariable(const ResolverObject *object, byte variable, by
case 0x1A: return UINT_MAX;
case 0x1B: return GB(_display_opt, 0, 6);
case 0x1C: return object->last_value;
- case 0x20: return _opt.landscape == LT_HILLY ? _opt.snow_line : 0xFF;
+ case 0x20: return _opt.landscape == LT_HILLY ? GetSnowLine() : 0xFF;
/* Not a common variable, so evalute the feature specific variables */
default: return object->GetVariable(object, variable, parameter, available);
diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp
index cb975f731..28beec471 100644
--- a/src/newgrf_station.cpp
+++ b/src/newgrf_station.cpp
@@ -6,6 +6,7 @@
#include "openttd.h"
#include "variables.h"
#include "functions.h"
+#include "landscape.h"
#include "debug.h"
#include "sprite.h"
#include "table/sprites.h"
@@ -370,7 +371,7 @@ static uint32 StationGetVariable(const ResolverObject *object, byte variable, by
case 0x40: return GetPlatformInfoHelper(tile, false, false, false);
case 0x41: return GetPlatformInfoHelper(tile, true, false, false);
case 0x42: /* Terrain and rail type */
- return ((_opt.landscape == LT_HILLY && GetTileZ(tile) > _opt.snow_line) ? 4 : 0) |
+ return ((_opt.landscape == LT_HILLY && GetTileZ(tile) > GetSnowLine()) ? 4 : 0) |
(_opt.landscape == LT_DESERT ? GetTropicZone(tile) : 0) |
(GetRailType(tile) << 8);
case 0x43: return st->owner; /* Station owner */
diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp
index 0bb915ec1..6a3f0a043 100644
--- a/src/rail_cmd.cpp
+++ b/src/rail_cmd.cpp
@@ -12,6 +12,7 @@
#include "table/sprites.h"
#include "table/strings.h"
#include "map.h"
+#include "landscape.h"
#include "tile.h"
#include "town_map.h"
#include "tunnel_map.h"
@@ -1738,7 +1739,7 @@ static void TileLoop_Track(TileIndex tile)
switch (_opt.landscape) {
case LT_HILLY:
- if (GetTileZ(tile) > _opt.snow_line) {
+ if (GetTileZ(tile) > GetSnowLine()) {
new_ground = RAIL_GROUND_ICE_DESERT;
goto set_ground;
}
diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp
index f5213a787..fdc03a009 100644
--- a/src/road_cmd.cpp
+++ b/src/road_cmd.cpp
@@ -12,6 +12,7 @@
#include "table/strings.h"
#include "functions.h"
#include "map.h"
+#include "landscape.h"
#include "tile.h"
#include "town_map.h"
#include "vehicle.h"
@@ -864,7 +865,7 @@ static void TileLoop_Road(TileIndex tile)
{
switch (_opt.landscape) {
case LT_HILLY:
- if (IsOnSnow(tile) != (GetTileZ(tile) > _opt.snow_line)) {
+ if (IsOnSnow(tile) != (GetTileZ(tile) > GetSnowLine())) {
ToggleSnow(tile);
MarkTileDirtyByTile(tile);
}
diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp
index ec689b8f1..84166b689 100644
--- a/src/town_cmd.cpp
+++ b/src/town_cmd.cpp
@@ -11,6 +11,7 @@
#include "table/strings.h"
#include "table/sprites.h"
#include "map.h"
+#include "landscape.h"
#include "tile.h"
#include "town_map.h"
#include "tunnel_map.h"
@@ -1700,7 +1701,7 @@ static void UpdateTownGrowRate(Town *t)
}
if (_opt.landscape == LT_HILLY) {
- if (TilePixelHeight(t->xy) >= _opt.snow_line && t->act_food == 0 && t->population > 90)
+ if (TilePixelHeight(t->xy) >= GetSnowLine() && t->act_food == 0 && t->population > 90)
return;
} else if (_opt.landscape == LT_DESERT) {
if (GetTropicZone(t->xy) == TROPICZONE_DESERT && (t->act_food==0 || t->act_water==0) && t->population > 60)
diff --git a/src/tree_cmd.cpp b/src/tree_cmd.cpp
index ca1af6788..d52d0b63a 100644
--- a/src/tree_cmd.cpp
+++ b/src/tree_cmd.cpp
@@ -9,6 +9,7 @@
#include "table/tree_land.h"
#include "functions.h"
#include "map.h"
+#include "landscape.h"
#include "tile.h"
#include "tree_map.h"
#include "viewport.h"
@@ -53,7 +54,7 @@ static void PlaceTree(TileIndex tile, uint32 r)
MakeTree(tile, tree, GB(r, 22, 2), min(GB(r, 16, 3), 6), TREE_GROUND_GRASS, 0);
// above snowline?
- if (_opt.landscape == LT_HILLY && GetTileZ(tile) > _opt.snow_line) {
+ if (_opt.landscape == LT_HILLY && GetTileZ(tile) > GetSnowLine()) {
SetTreeGroundDensity(tile, TREE_GROUND_SNOW_DESERT, 3);
SetTreeCounter(tile, (TreeGround)GB(r, 24, 3));
} else {
@@ -150,7 +151,7 @@ void PlaceTreesRandomly()
j = GetTileZ(tile) / TILE_HEIGHT * 2;
while (j--) {
/* Above snowline more trees! */
- if (_opt.landscape == LT_HILLY && ht > _opt.snow_line) {
+ if (_opt.landscape == LT_HILLY && ht > GetSnowLine()) {
PlaceTreeAtSameHeight(tile, ht);
PlaceTreeAtSameHeight(tile, ht);
};
@@ -496,7 +497,7 @@ static void TileLoopTreesDesert(TileIndex tile)
static void TileLoopTreesAlps(TileIndex tile)
{
- int k = GetTileZ(tile) - _opt.snow_line + TILE_HEIGHT;
+ int k = GetTileZ(tile) - GetSnowLine() + TILE_HEIGHT;
if (k < 0) {
if (GetTreeGround(tile) != TREE_GROUND_SNOW_DESERT) return;
diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp
index 8d04c3211..ae7711f96 100644
--- a/src/tunnelbridge_cmd.cpp
+++ b/src/tunnelbridge_cmd.cpp
@@ -14,6 +14,7 @@
#include "table/strings.h"
#include "functions.h"
#include "map.h"
+#include "landscape.h"
#include "tile.h"
#include "tunnel_map.h"
#include "unmovable_map.h"
@@ -1178,7 +1179,7 @@ static void TileLoop_TunnelBridge(TileIndex tile)
bool snow_or_desert = IsTunnelTile(tile) ? HasTunnelSnowOrDesert(tile) : HasBridgeSnowOrDesert(tile);
switch (_opt.landscape) {
case LT_HILLY:
- if (snow_or_desert != (GetTileZ(tile) > _opt.snow_line)) {
+ if (snow_or_desert != (GetTileZ(tile) > GetSnowLine())) {
if (IsTunnelTile(tile)) {
SetTunnelSnowOrDesert(tile, !snow_or_desert);
} else {