Changeset - r16551:27c24a326035
[Not reviewed]
master
0 2 0
frosch - 14 years ago 2010-11-21 17:42:18
frosch@openttd.org
(svn r21289) -Fix [FS#4133]: Make terraforming and tunnel-excavation handle DC_AUTO-clearable multitile objects.
2 files changed with 43 insertions and 16 deletions:
0 comments (0 inline, 0 general)
src/terraform_cmd.cpp
Show inline comments
 
@@ -17,6 +17,7 @@
 
#include "functions.h"
 
#include "economy_func.h"
 
#include "genworld.h"
 
#include "object_base.h"
 

	
 
#include "table/strings.h"
 

	
 
@@ -275,8 +276,10 @@ CommandCost CmdTerraformLand(TileIndex t
 
		total_cost.AddCost(cost);
 
	}
 

	
 
	/* Check if the terraforming is valid wrt. tunnels, bridges and objects on the surface */
 
	{
 
	/* Check if the terraforming is valid wrt. tunnels, bridges and objects on the surface
 
	 * Pass == 0: Collect tileareas which are caused to be auto-cleared.
 
	 * Pass == 1: Collect the actual cost. */
 
	for (int pass = 0; pass < 2; pass++) {
 
		TileIndex *ti = ts.tile_table;
 

	
 
		for (int count = ts.tile_table_count; count != 0; count--, ti++) {
 
@@ -315,16 +318,31 @@ CommandCost CmdTerraformLand(TileIndex t
 
				_terraform_err_tile = tile; // highlight the tile above the tunnel
 
				return_cmd_error(STR_ERROR_EXCAVATION_WOULD_DAMAGE);
 
			}
 

	
 
			/* Is the tile already cleared? */
 
			const ClearedObjectArea *coa = FindClearedObject(tile);
 
			bool indirectly_cleared = coa != NULL && coa->first_tile != tile;
 

	
 
			/* Check tiletype-specific things, and add extra-cost */
 
			const bool curr_gen = _generating_world;
 
			if (_game_mode == GM_EDITOR) _generating_world = true; // used to create green terraformed land
 
			CommandCost cost = _tile_type_procs[GetTileType(tile)]->terraform_tile_proc(tile, flags | DC_AUTO | DC_FORCE_CLEAR_TILE, z_min * TILE_HEIGHT, tileh);
 
			DoCommandFlag tile_flags = flags | DC_AUTO | DC_FORCE_CLEAR_TILE;
 
			if (pass == 0) {
 
				tile_flags &= ~DC_EXEC;
 
				tile_flags |= DC_NO_MODIFY_TOWN_RATING;
 
			}
 
			CommandCost cost;
 
			if (indirectly_cleared) {
 
				cost = DoCommand(tile, 0, 0, tile_flags, CMD_LANDSCAPE_CLEAR);
 
			} else {
 
				cost = _tile_type_procs[GetTileType(tile)]->terraform_tile_proc(tile, tile_flags, z_min * TILE_HEIGHT, tileh);
 
			}
 
			_generating_world = curr_gen;
 
			if (cost.Failed()) {
 
				_terraform_err_tile = tile;
 
				return cost;
 
			}
 
			total_cost.AddCost(cost);
 
			if (pass == 1) total_cost.AddCost(cost);
 
		}
 
	}
 

	
src/tunnelbridge_cmd.cpp
Show inline comments
 
@@ -38,6 +38,7 @@
 
#include "pbs.h"
 
#include "company_base.h"
 
#include "newgrf_railtype.h"
 
#include "object_base.h"
 

	
 
#include "table/sprites.h"
 
#include "table/strings.h"
 
@@ -583,23 +584,31 @@ CommandCost CmdBuildTunnel(TileIndex sta
 

	
 
	if (IsWaterTile(end_tile)) return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER);
 

	
 
	/* Clear the tile in any case */
 
	ret = DoCommand(end_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
	if (ret.Failed()) return_cmd_error(STR_ERROR_UNABLE_TO_EXCAVATE_LAND);
 
	cost.AddCost(ret);
 

	
 
	/* slope of end tile must be complementary to the slope of the start tile */
 
	if (end_tileh != ComplementSlope(start_tileh)) {
 
		/* Check if there is a structure on the terraformed tile. Do not add the cost, that will be done by the terraforming
 
		 * Note: Currently the town rating is also affected by this clearing-test. So effectivly the player is punished twice for clearing
 
		 *       the tree on end_tile.
 
		 */
 
		ret = DoCommand(end_tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR);
 
		/* Mark the tile as already cleared for the terraform command.
 
		 * Do this for all tiles (like trees), not only objects. */
 
		ClearedObjectArea *coa = FindClearedObject(end_tile);
 
		if (coa == NULL) {
 
			coa = _cleared_object_areas.Append();
 
			coa->first_tile = end_tile;
 
			coa->area = TileArea(end_tile, 1, 1);
 
		}
 

	
 
		/* Hide the tile from the terraforming command */
 
		TileIndex old_first_tile = coa->first_tile;
 
		coa->first_tile = INVALID_TILE;
 
		ret = DoCommand(end_tile, end_tileh & start_tileh, 0, flags, CMD_TERRAFORM_LAND);
 
		coa->first_tile = old_first_tile;
 
		if (ret.Failed()) return_cmd_error(STR_ERROR_UNABLE_TO_EXCAVATE_LAND);
 

	
 
		ret = DoCommand(end_tile, end_tileh & start_tileh, 0, flags, CMD_TERRAFORM_LAND);
 
		if (ret.Failed()) return_cmd_error(STR_ERROR_UNABLE_TO_EXCAVATE_LAND);
 
	} else {
 
		ret = DoCommand(end_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
		if (ret.Failed()) return ret;
 
		cost.AddCost(ret);
 
	}
 
	cost.AddCost(_price[PR_BUILD_TUNNEL]);
 
	cost.AddCost(ret);
 

	
 
	/* Pay for the rail/road in the tunnel including entrances */
 
	switch (transport_type) {
0 comments (0 inline, 0 general)