summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormaedhros <maedhros@openttd.org>2007-03-20 13:47:00 +0000
committermaedhros <maedhros@openttd.org>2007-03-20 13:47:00 +0000
commit48f2bf9bb1bd7b8859d3527c6c205386471cc4e4 (patch)
treea58aa837d70b430e5ab2ea0f71158e3b6032453b /src
parent7812f7fd0ac617a9df41730e6770519154bc5344 (diff)
downloadopenttd-48f2bf9bb1bd7b8859d3527c6c205386471cc4e4.tar.xz
(svn r9371) -Feature: Add support for variable snow lines in the arctic climate, supplied
by newgrf files. When this is enabled forests cannot be built below the highest snow line, and farms can't be built above it. Houses still use the _opt.snow_line so they are all consistent, so to make them respect the snowline you may want to use some newhouses features as well.
Diffstat (limited to 'src')
-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 {