(svn r12029) -Feature: Allow trees on shore.
authorfrosch
Thu, 31 Jan 2008 17:54:13 +0000
changeset 8459 86e0352eb993
parent 8458 38fe72ff1402
child 8460 bc721eeb78ee
(svn r12029) -Feature: Allow trees on shore.
docs/landscape.html
src/industry_cmd.cpp
src/newgrf_commons.cpp
src/terraform_gui.cpp
src/tree_cmd.cpp
src/tree_map.h
src/water_cmd.cpp
--- a/docs/landscape.html	Thu Jan 31 17:46:08 2008 +0000
+++ b/docs/landscape.html	Thu Jan 31 17:54:13 2008 +0000
@@ -701,18 +701,23 @@
       <table>
 
        <tr>
-        <td nowrap valign=top><tt>0</tt>&nbsp; </td>
-        <td align=left>on grass</td>
+        <td align=left><tt>0</tt>&nbsp; </td>
+        <td>on grass</td>
        </tr>
 
        <tr>
-        <td nowrap valign=top><tt>1</tt>&nbsp; </td>
-        <td align=left>on rough land (density must be 3)</td>
+        <td align=left><tt>1</tt>&nbsp; </td>
+        <td>on rough land (density must be 3)</td>
        </tr>
 
        <tr>
-        <td nowrap valign=top><tt>2</tt>&nbsp; </td>
-        <td align=left>on snow or desert</td>
+        <td align=left><tt>2</tt>&nbsp; </td>
+        <td>on snow or desert</td>
+       </tr>
+
+       <tr>
+        <td align=left><tt>3</tt>&nbsp; </td>
+        <td>on shore (density must be 3)</td>
        </tr>
       </table>
      </li>
--- a/src/industry_cmd.cpp	Thu Jan 31 17:46:08 2008 +0000
+++ b/src/industry_cmd.cpp	Thu Jan 31 17:54:13 2008 +0000
@@ -841,7 +841,7 @@
 {
 	switch (GetTileType(tile)) {
 		case MP_CLEAR: return IsClearGround(tile, CLEAR_FIELDS) || IsClearGround(tile, CLEAR_SNOW) || IsClearGround(tile, CLEAR_DESERT);
-		case MP_TREES: return false;
+		case MP_TREES: return (GetTreeGround(tile) == TREE_GROUND_SHORE);
 		default:       return true;
 	}
 }
@@ -850,7 +850,7 @@
 {
 	switch (GetTileType(tile)) {
 		case MP_CLEAR: return IsClearGround(tile, CLEAR_SNOW) || IsClearGround(tile, CLEAR_DESERT);
-		case MP_TREES: return false;
+		case MP_TREES: return (GetTreeGround(tile) == TREE_GROUND_SHORE);
 		default:       return true;
 	}
 }
--- a/src/newgrf_commons.cpp	Thu Jan 31 17:46:08 2008 +0000
+++ b/src/newgrf_commons.cpp	Thu Jan 31 17:54:13 2008 +0000
@@ -15,6 +15,7 @@
 #include "tile_map.h"
 #include "station_map.h"
 #include "settings_type.h"
+#include "tree_map.h"
 
 /** Constructor of generic class
  * @param offset end of original data for this entity. i.e: houses = 110
@@ -296,6 +297,9 @@
 {
 	TileType tile_type = GetTileType(tile);
 
+	/* Fake tile type for trees on shore */
+	if (IsTileType(tile, MP_TREES) && GetTreeGround(tile) == TREE_GROUND_SHORE) tile_type = MP_WATER;
+
 	uint z;
 	Slope tileh = GetTileSlope(tile, &z);
 	byte terrain_type = GetTerrainType(tile) << 2 | (tile_type == MP_WATER ? 1 : 0) << 1;
--- a/src/terraform_gui.cpp	Thu Jan 31 17:46:08 2008 +0000
+++ b/src/terraform_gui.cpp	Thu Jan 31 17:54:13 2008 +0000
@@ -22,6 +22,7 @@
 #include "textbuf_gui.h"
 #include "genworld.h"
 #include "settings_type.h"
+#include "tree_map.h"
 
 #include "table/sprites.h"
 #include "table/strings.h"
@@ -83,8 +84,10 @@
 
 	BEGIN_TILE_LOOP(tile, size_x, size_y, TileXY(sx, sy)) {
 		switch (GetTileType(tile)) {
+			case MP_TREES:
+				if (GetTreeGround(tile) == TREE_GROUND_SHORE) continue;
+			/* FALL THROUGH */
 			case MP_CLEAR:
-			case MP_TREES:
 				MakeClear(tile, CLEAR_ROCKS, 3);
 				break;
 
--- a/src/tree_cmd.cpp	Thu Jan 31 17:46:08 2008 +0000
+++ b/src/tree_cmd.cpp	Thu Jan 31 17:54:13 2008 +0000
@@ -20,6 +20,8 @@
 #include "player_func.h"
 #include "sound_func.h"
 #include "settings_type.h"
+#include "water_map.h"
+#include "water.h"
 
 #include "table/strings.h"
 #include "table/sprites.h"
@@ -44,11 +46,18 @@
  * @param allow_desert Allow planting trees on CLEAR_DESERT?
  * @return true if trees can be built.
  */
-static inline bool CanPlantTreesOnTile(TileIndex tile, bool allow_desert)
+static bool CanPlantTreesOnTile(TileIndex tile, bool allow_desert)
 {
-	return IsTileType(tile, MP_CLEAR) && !IsBridgeAbove(tile) &&
-	       !IsClearGround(tile, CLEAR_FIELDS) && !IsClearGround(tile, CLEAR_ROCKS) &&
-	       (allow_desert || !IsClearGround(tile, CLEAR_DESERT));
+	switch (GetTileType(tile)) {
+		case MP_WATER:
+			return !IsBridgeAbove(tile) && IsCoast(tile) && !IsSlopeWithOneCornerRaised(GetTileSlope(tile, NULL));
+
+		case MP_CLEAR:
+			return !IsBridgeAbove(tile) && !IsClearGround(tile, CLEAR_FIELDS) && !IsClearGround(tile, CLEAR_ROCKS) &&
+			       (allow_desert || !IsClearGround(tile, CLEAR_DESERT));
+
+		default: return false;
+	}
 }
 
 /**
@@ -69,10 +78,21 @@
 
 	TreeGround ground;
 	uint density = 3;
-	switch (GetClearGround(tile)) {
-		case CLEAR_GRASS:  ground = TREE_GROUND_GRASS;       density = GetClearDensity(tile); break;
-		case CLEAR_ROUGH:  ground = TREE_GROUND_ROUGH;                                        break;
-		default:           ground = TREE_GROUND_SNOW_DESERT; density = GetClearDensity(tile); break;
+
+	switch (GetTileType(tile)) {
+		case MP_WATER:
+			ground = TREE_GROUND_SHORE;
+			break;
+
+		case MP_CLEAR:
+			switch (GetClearGround(tile)) {
+				case CLEAR_GRASS:  ground = TREE_GROUND_GRASS;       density = GetClearDensity(tile); break;
+				case CLEAR_ROUGH:  ground = TREE_GROUND_ROUGH;                                        break;
+				default:           ground = TREE_GROUND_SNOW_DESERT; density = GetClearDensity(tile); break;
+			}
+			break;
+
+		default: NOT_REACHED();
 	}
 
 	MakeTree(tile, treetype, count, growth, ground, density);
@@ -126,8 +146,9 @@
 	if (tree != TREE_INVALID) {
 		PlantTreesOnTile(tile, tree, GB(r, 22, 2), min(GB(r, 16, 3), 6));
 
-		/* Rerandomize ground, if not snow */
-		if (GetTreeGround(tile) != TREE_GROUND_SNOW_DESERT) {
+		/* Rerandomize ground, if neither snow nor shore */
+		TreeGround ground = GetTreeGround(tile);
+		if (ground != TREE_GROUND_SNOW_DESERT && ground != TREE_GROUND_SHORE) {
 			SetTreeGroundDensity(tile, (TreeGround)GB(r, 28, 1), 3);
 		}
 
@@ -341,27 +362,30 @@
 					break;
 
 				case MP_WATER:
-					msg = STR_3807_CAN_T_BUILD_ON_WATER;
-					continue;
-					break;
-
+					if (!IsCoast(tile) || IsSlopeWithOneCornerRaised(GetTileSlope(tile, NULL))) {
+						msg = STR_3807_CAN_T_BUILD_ON_WATER;
+						continue;
+					}
+				/* FALL THROUGH */
 				case MP_CLEAR:
 					if (IsBridgeAbove(tile)) {
 						msg = STR_2804_SITE_UNSUITABLE;
 						continue;
 					}
 
-					/* Remove fields or rocks. Note that the ground will get barrened */
-					switch (GetClearGround(tile)) {
-						case CLEAR_FIELDS:
-						case CLEAR_ROCKS: {
-							CommandCost ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
-							if (CmdFailed(ret)) return ret;
-							cost.AddCost(ret);
-							break;
+					if (IsTileType(tile, MP_CLEAR)) {
+						/* Remove fields or rocks. Note that the ground will get barrened */
+						switch (GetClearGround(tile)) {
+							case CLEAR_FIELDS:
+							case CLEAR_ROCKS: {
+								CommandCost ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+								if (CmdFailed(ret)) return ret;
+								cost.AddCost(ret);
+								break;
+							}
+
+							default: break;
 						}
-
-						default: break;
 					}
 
 					if (_game_mode != GM_EDITOR && IsValidPlayer(_current_player)) {
@@ -416,6 +440,7 @@
 	byte z;
 
 	switch (GetTreeGround(ti->tile)) {
+		case TREE_GROUND_SHORE: DrawShoreTile(ti->tileh); break;
 		case TREE_GROUND_GRASS: DrawClearLandTile(ti, GetTreeDensity(ti->tile)); break;
 		case TREE_GROUND_ROUGH: DrawHillyLandTile(ti); break;
 		default: DrawGroundSprite(_tree_sprites_1[GetTreeDensity(ti->tile)] + _tileh_to_sprite[ti->tileh], PAL_NONE); break;
@@ -608,9 +633,13 @@
 
 static void TileLoop_Trees(TileIndex tile)
 {
-	switch (_opt.landscape) {
-		case LT_TROPIC: TileLoopTreesDesert(tile); break;
-		case LT_ARCTIC: TileLoopTreesAlps(tile);   break;
+	if (GetTreeGround(tile) == TREE_GROUND_SHORE) {
+		TileLoop_Water(tile);
+	} else {
+		switch (_opt.landscape) {
+			case LT_TROPIC: TileLoopTreesDesert(tile); break;
+			case LT_ARCTIC: TileLoopTreesAlps(tile);   break;
+		}
 	}
 
 	TileLoopClearHelper(tile);
@@ -660,7 +689,7 @@
 						if (!CanPlantTreesOnTile(tile, false)) return;
 
 						/* Don't plant trees, if ground was freshly cleared */
-						if (GetClearGround(tile) == CLEAR_GRASS && GetClearDensity(tile) != 3) return;
+						if (IsTileType(tile, MP_CLEAR) && GetClearGround(tile) == CLEAR_GRASS && GetClearDensity(tile) != 3) return;
 
 						PlantTreesOnTile(tile, treetype, 0, 0);
 
@@ -681,6 +710,7 @@
 			} else {
 				/* just one tree, change type into MP_CLEAR */
 				switch (GetTreeGround(tile)) {
+					case TREE_GROUND_SHORE: MakeShore(tile); break;
 					case TREE_GROUND_GRASS: MakeClear(tile, CLEAR_GRASS, GetTreeDensity(tile)); break;
 					case TREE_GROUND_ROUGH: MakeClear(tile, CLEAR_ROUGH, 3); break;
 					default: // snow or desert
--- a/src/tree_map.h	Thu Jan 31 17:46:08 2008 +0000
+++ b/src/tree_map.h	Thu Jan 31 17:54:13 2008 +0000
@@ -49,7 +49,8 @@
 enum TreeGround {
 	TREE_GROUND_GRASS       = 0, ///< normal grass
 	TREE_GROUND_ROUGH       = 1, ///< some rough tile
-	TREE_GROUND_SNOW_DESERT = 2  ///< a desert or snow tile, depend on landscape
+	TREE_GROUND_SNOW_DESERT = 2, ///< a desert or snow tile, depend on landscape
+	TREE_GROUND_SHORE       = 3, ///< shore
 };
 
 
--- a/src/water_cmd.cpp	Thu Jan 31 17:46:08 2008 +0000
+++ b/src/water_cmd.cpp	Thu Jan 31 17:54:13 2008 +0000
@@ -34,6 +34,7 @@
 #include "player_func.h"
 #include "settings_type.h"
 #include "clear_map.h"
+#include "tree_map.h"
 
 #include "table/sprites.h"
 #include "table/strings.h"
@@ -129,6 +130,11 @@
 				has_water |= (GetRailGroundType(neighbour) == RAIL_GROUND_WATER);
 				break;
 
+			case MP_TREES:
+				/* trees on shore */
+				has_water |= (GetTreeGround(neighbour) == TREE_GROUND_SHORE);
+				break;
+
 			default: break;
 		}
 	}
@@ -826,7 +832,7 @@
 static FloodingBehaviour GetFloodingBehaviour(TileIndex tile)
 {
 	/* FLOOD_ACTIVE:  'single-corner-raised'-coast, sea, sea-shipdepots, sea-buoys, rail with flooded halftile
-	 * FLOOD_DRYUP:   coast with more than one corner raised, coast with rail-track
+	 * FLOOD_DRYUP:   coast with more than one corner raised, coast with rail-track, coast with trees
 	 * FLOOD_PASSIVE: oilrig, dock, water-industries
 	 * FLOOD_NONE:    canals, rivers, everything else
 	 */
@@ -845,6 +851,9 @@
 			}
 			return FLOOD_NONE;
 
+		case MP_TREES:
+			return (GetTreeGround(tile) == TREE_GROUND_SHORE ? FLOOD_DRYUP : FLOOD_NONE);
+
 		case MP_STATION:
 			if (IsSeaBuoyTile(tile)) return FLOOD_ACTIVE;
 			if (IsOilRig(tile) || IsDock(tile)) return FLOOD_PASSIVE;
@@ -869,7 +878,8 @@
 
 	_current_player = OWNER_WATER;
 
-	if (GetTileSlope(target, NULL) != SLOPE_FLAT) {
+	Slope tileh = GetTileSlope(target, NULL);
+	if (tileh != SLOPE_FLAT) {
 		/* make coast.. */
 		switch (GetTileType(target)) {
 			case MP_RAILWAY: {
@@ -883,8 +893,15 @@
 				break;
 			}
 
+			case MP_TREES:
+				if (!IsSlopeWithOneCornerRaised(tileh)) {
+					SetTreeGroundDensity(target, TREE_GROUND_SHORE, 3);
+					MarkTileDirtyByTile(target);
+					flooded = true;
+					break;
+				}
+			/* FALL THROUGH */
 			case MP_CLEAR:
-			case MP_TREES:
 				if (CmdSucceeded(DoCommand(target, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR))) {
 					MakeShore(target);
 					MarkTileDirtyByTile(target);
@@ -943,6 +960,11 @@
 			MarkTileDirtyByTile(tile);
 			break;
 
+		case MP_TREES:
+			SetTreeGroundDensity(tile, TREE_GROUND_GRASS, 3);
+			MarkTileDirtyByTile(tile);
+			break;
+
 		case MP_WATER:
 			assert(IsCoast(tile));