Changeset - r7641:2b26b5be3fd7
[Not reviewed]
master
0 13 1
rubidium - 17 years ago 2007-09-26 16:12:43
rubidium@openttd.org
(svn r11172) -Codechange: rewrite of town road building and addition of the possibility to clean up unconnected road bits during the local road reconstructions. Based on a patch by skidd13.
14 files changed with 389 insertions and 162 deletions:
0 comments (0 inline, 0 general)
projects/openttd.vcproj
Show inline comments
 
@@ -327,6 +327,9 @@
 
				RelativePath=".\..\src\rev.cpp">
 
			</File>
 
			<File
 
				RelativePath=".\..\src\road.cpp">
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload.cpp">
 
			</File>
 
			<File
projects/openttd_vs80.vcproj
Show inline comments
 
@@ -668,6 +668,10 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\road.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\saveload.cpp"
 
				>
 
			</File>
source.list
Show inline comments
 
@@ -58,6 +58,7 @@ players.cpp
 
queue.cpp
 
rail.cpp
 
rev.cpp
 
road.cpp
 
saveload.cpp
 
screenshot.cpp
 
#if SDL
src/direction.h
Show inline comments
 
@@ -165,6 +165,9 @@ enum DiagDirDiff {
 
	DIAGDIRDIFF_90LEFT  = 3         ///< 90 degrees left
 
};
 

	
 
/** Allow incrementing of DiagDirDiff variables */
 
DECLARE_POSTFIX_INCREMENT(DiagDirDiff);
 

	
 
/**
 
 * Applies a difference on a DiagDirection
 
 *
src/lang/english.txt
Show inline comments
 
@@ -1187,6 +1187,7 @@ STR_CONFIG_PATCHES_TOWN_GROWTH_VERY_FAST
 
STR_CONFIG_PATCHES_LARGER_TOWNS                                 :{LTBLUE}Proportion of towns that will become cities: {ORANGE}1 in {STRING1}
 
STR_CONFIG_PATCHES_LARGER_TOWNS_DISABLED                        :{LTBLUE}Proportion of towns that will become cities: {ORANGE}None
 
STR_CONFIG_PATCHES_CITY_SIZE_MULTIPLIER                         :{LTBLUE}Initial city size multiplier: {ORANGE}{STRING1}
 
STR_CONFIG_MODIFIED_ROAD_REBUILD                                :{LTBLUE}Remove absurd road-elements during the road construction
 

	
 
STR_CONFIG_PATCHES_GUI                                          :{BLACK}Interface
 
STR_CONFIG_PATCHES_CONSTRUCTION                                 :{BLACK}Construction
src/map.h
Show inline comments
 
@@ -390,6 +390,18 @@ static inline TileIndexDiff TileOffsByDi
 
}
 

	
 
/**
 
 * Adds a DiagDir to a tile.
 
 *
 
 * @param tile The current tile
 
 * @param dir The direction in which we want to step
 
 * @return the moved tile
 
 */
 
static inline TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
 
{
 
	return TILE_ADD(tile, TileOffsByDiagDir(dir));
 
}
 

	
 
/**
 
 * A callback function type for searching tiles.
 
 *
 
 * @param tile The tile to test
src/road.cpp
Show inline comments
 
new file 100644
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "functions.h"
 
#include "rail_map.h"
 
#include "road.h"
 
#include "road_map.h"
 
#include "water_map.h"
 
#include "macros.h"
 

	
 
bool IsPossibleCrossing(const TileIndex tile, Axis ax)
 
{
 
	return (IsTileType(tile, MP_RAILWAY) &&
 
		!HasSignals(tile) &&
 
		GetTrackBits(tile) == (ax == AXIS_X ?  TRACK_BIT_Y : TRACK_BIT_X) &&
 
		GetTileSlope(tile, NULL) == SLOPE_FLAT);
 
}
 

	
 
RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb)
 
{
 
	for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
 
		const TileIndex neighbor_tile = TileAddByDiagDir(tile, dir);
 

	
 
		/* Get the Roadbit pointing to the neighbor_tile */
 
		const RoadBits target_rb = DiagDirToRoadBits(dir);
 

	
 
		/* If the roadbit is in the current plan */
 
		if (org_rb & target_rb) {
 
			bool connective = false;
 
			const RoadBits mirrored_rb = MirrorRoadBits(target_rb);
 

	
 
			switch (GetTileType(neighbor_tile)) {
 
				/* Allways connective ones */
 
				case MP_CLEAR: case MP_TREES:
 
					connective = true;
 
					break;
 

	
 
				/* The conditionaly connective ones */
 
				case MP_TUNNELBRIDGE:
 
				case MP_STATION:
 
				case MP_ROAD: {
 
					const RoadBits neighbor_rb = GetAnyRoadBits(neighbor_tile, ROADTYPE_ROAD) | GetAnyRoadBits(neighbor_tile, ROADTYPE_TRAM);
 

	
 
					/* Accept only connective tiles */
 
					connective = (neighbor_rb & mirrored_rb) || // Neighbor has got the fitting RoadBit
 
							COUNTBITS(neighbor_rb) == 1; // Neighbor has got only one Roadbit
 

	
 
				} break;
 

	
 
				case MP_RAILWAY:
 
					connective = IsPossibleCrossing(neighbor_tile, DiagDirToAxis(dir));
 
					break;
 

	
 
				case MP_WATER:
 
					/* Check for real water tile */
 
					connective = !IsWater(neighbor_tile);
 
					break;
 

	
 
				/* The defentetly not connective ones */
 
				default: break;
 
			}
 

	
 
			/* If the neighbor tile is inconnective remove the planed road connection to it */
 
			if (!connective) org_rb ^= target_rb;
 

	
 
		}
 
	}
 

	
 
	return org_rb;
 
}
src/road.h
Show inline comments
 
@@ -116,6 +116,36 @@ static inline RoadBits ComplementRoadBit
 
}
 

	
 
/**
 
 * Calculate the mirrored RoadBits
 
 *
 
 * Simply move the bits to their new position.
 
 *
 
 * @param r The given RoadBits value
 
 * @return the mirrored
 
 */
 
static inline RoadBits MirrorRoadBits(RoadBits r)
 
{
 
	return (RoadBits)(GB(r, 0, 2) << 2 | GB(r, 2, 2));
 
}
 

	
 
/**
 
 * Calculate rotated RoadBits
 
 *
 
 * Move the Roadbits clockwise til they are in their final position.
 
 *
 
 * @param r The given RoadBits value
 
 * @param rot The given Rotation angle
 
 * @return the rotated
 
 */
 
static inline RoadBits RotateRoadBits(RoadBits r, DiagDirDiff rot)
 
{
 
	for (; rot > (DiagDirDiff)0; rot--){
 
		r = (RoadBits)(GB(r, 0, 1) << 3 | GB(r, 1, 3));
 
	}
 
	return r;
 
}
 

	
 
/**
 
 * Create the road-part which belongs to the given DiagDirection
 
 *
 
 * This function returns a RoadBits value which belongs to
 
@@ -130,6 +160,16 @@ static inline RoadBits DiagDirToRoadBits
 
}
 

	
 
/**
 
 * Return if the tile is a valid tile for a crossing.
 
 *
 
 * @note function is overloaded
 
 * @param tile the curent tile
 
 * @param ax the axis of the road over the rail
 
 * @return true if it is a valid tile
 
 */
 
bool IsPossibleCrossing(const TileIndex tile, Axis ax);
 

	
 
/**
 
 * Checks whether the trackdir means that we are reversing.
 
 * @param dir the trackdir to check
 
 * @return true if it is a reversing road trackdir
 
@@ -150,6 +190,14 @@ static inline bool IsStraightRoadTrackdi
 
}
 

	
 
/**
 
 * Clean up unneccesary RoadBits of a planed tile.
 
 * @param tile current tile
 
 * @param org_rb planed RoadBits
 
 * @return optimised RoadBits
 
 */
 
RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb);
 

	
 
/**
 
 * Is it allowed to remove the given road bits from the given tile?
 
 * @param tile      the tile to remove the road from
 
 * @param remove    the roadbits that are going to be removed
src/road_cmd.cpp
Show inline comments
 
@@ -259,70 +259,121 @@ CommandCost CmdRemoveRoad(TileIndex tile
 
static const RoadBits _valid_tileh_slopes_road[][15] = {
 
	/* set of normal ones */
 
	{
 
		ROAD_ALL, ROAD_NONE, ROAD_NONE,
 
		ROAD_X,   ROAD_NONE, ROAD_NONE,  // 3, 4, 5
 
		ROAD_Y,   ROAD_NONE, ROAD_NONE,
 
		ROAD_Y,   ROAD_NONE, ROAD_NONE,  // 9, 10, 11
 
		ROAD_X,   ROAD_NONE, ROAD_NONE
 
		ROAD_ALL,  // SLOPE_FLAT
 
		ROAD_NONE, // SLOPE_W
 
		ROAD_NONE, // SLOPE_S
 

	
 
		ROAD_X,    // SLOPE_SW
 
		ROAD_NONE, // SLOPE_E
 
		ROAD_NONE, // SLOPE_EW
 

	
 
		ROAD_Y,    // SLOPE_SE
 
		ROAD_NONE, // SLOPE_WSE
 
		ROAD_NONE, // SLOPE_N
 

	
 
		ROAD_Y,    // SLOPE_NW
 
		ROAD_NONE, // SLOPE_NS
 
		ROAD_NONE, // SLOPE_NE
 

	
 
		ROAD_X,    // SLOPE_ENW
 
		ROAD_NONE, // SLOPE_SEN
 
		ROAD_NONE  // SLOPE_ELEVATED
 
	},
 
	/* allowed road for an evenly raised platform */
 
	{
 
		ROAD_NONE,
 
		ROAD_SW | ROAD_NW,
 
		ROAD_SW | ROAD_SE,
 
		ROAD_Y  | ROAD_SW,
 
		ROAD_NONE,         // SLOPE_FLAT
 
		ROAD_SW | ROAD_NW, // SLOPE_W
 
		ROAD_SW | ROAD_SE, // SLOPE_S
 

	
 
		ROAD_Y  | ROAD_SW, // SLOPE_SW
 
		ROAD_SE | ROAD_NE, // SLOPE_E
 
		ROAD_ALL,          // SLOPE_EW
 

	
 
		ROAD_X  | ROAD_SE, // SLOPE_SE
 
		ROAD_ALL,          // SLOPE_WSE
 
		ROAD_NW | ROAD_NE, // SLOPE_N
 

	
 
		ROAD_X  | ROAD_NW, // SLOPE_NW
 
		ROAD_ALL,          // SLOPE_NS
 
		ROAD_ALL,          // SLOPE_NE
 

	
 
		ROAD_SE | ROAD_NE, // 4
 
		ROAD_ALL,
 
		ROAD_X  | ROAD_SE,
 
		ROAD_ALL,
 
		ROAD_Y  | ROAD_NE, // SLOPE_ENW
 
		ROAD_ALL,          // SLOPE_SEN
 
		ROAD_ALL           // SLOPE_ELEVATED
 
	},
 
	/* Singe bits on slopes */
 
	{
 
		ROAD_ALL,          // SLOPE_FLAT
 
		ROAD_NE | ROAD_SE, // SLOPE_W
 
		ROAD_NE | ROAD_NW, // SLOPE_S
 

	
 
		ROAD_NW | ROAD_NE, // 8
 
		ROAD_X  | ROAD_NW,
 
		ROAD_ALL,
 
		ROAD_ALL,
 
		ROAD_NE,           // SLOPE_SW
 
		ROAD_NW | ROAD_SW, // SLOPE_E
 
		ROAD_ALL,          // SLOPE_EW
 

	
 
		ROAD_NW,           // SLOPE_SE
 
		ROAD_ALL,          // SLOPE_WSE
 
		ROAD_SE | ROAD_SW, // SLOPE_N
 

	
 
		ROAD_Y  | ROAD_NE, // 12
 
		ROAD_ALL,
 
		ROAD_ALL
 
		ROAD_SE,           // SLOPE_NW
 
		ROAD_ALL,          // SLOPE_NS
 
		ROAD_ALL,          // SLOPE_NE
 

	
 
		ROAD_SW,           // SLOPE_ENW
 
		ROAD_ALL,          // SLOPE_SEN
 
		ROAD_ALL,          // SLOPE_ELEVATED
 
	},
 
};
 

	
 

	
 
/**
 
 * Calculate the costs for roads on slopes
 
 *  Aside modify the RoadBits to fit on the slopes
 
 *
 
 * @note The RoadBits are modified too!
 
 * @param tileh The current slope
 
 * @param pieces The RoadBits we want to add
 
 * @param existing The existent RoadBits
 
 * @return The costs for these RoadBits on this slope
 
 */
 
static CommandCost CheckRoadSlope(Slope tileh, RoadBits* pieces, RoadBits existing)
 
{
 
	RoadBits road_bits;
 
	if (IsSteepSlope(tileh)) {
 
		/* Force straight roads. */
 
		*pieces |= MirrorRoadBits(*pieces);
 

	
 
	if (IsSteepSlope(tileh)) {
 
		/* force full pieces. */
 
		*pieces |= (RoadBits)((*pieces & 0xC) >> 2);
 
		*pieces |= (RoadBits)((*pieces & 0x3) << 2);
 

	
 
		if (existing == 0 || existing == *pieces) {
 
		if (existing == ROAD_NONE || existing == *pieces) {
 
			if (*pieces == ROAD_X || *pieces == ROAD_Y) return _price.terraform;
 
		}
 
		return CMD_ERROR;
 
	}
 
	road_bits = *pieces | existing;
 

	
 
	RoadBits road_bits = *pieces | existing;
 

	
 
	/* Single bits on slopes.
 
	 * We check for the roads that need at least 2 bits */
 
	if (_patches.build_on_slopes && !_is_old_ai_player &&
 
			existing == ROAD_NONE && COUNTBITS(*pieces) == 1 &&
 
			(_valid_tileh_slopes_road[2][tileh] & *pieces) == ROAD_NONE) {
 
		return CommandCost(_price.terraform);
 
	}
 

	
 
	/* no special foundation */
 
	if ((~_valid_tileh_slopes_road[0][tileh] & road_bits) == 0) {
 
	if ((~_valid_tileh_slopes_road[0][tileh] & road_bits) == ROAD_NONE) {
 
		/* force that all bits are set when we have slopes */
 
		if (tileh != SLOPE_FLAT) *pieces |= _valid_tileh_slopes_road[0][tileh];
 
		return CommandCost(); // no extra cost
 
	}
 

	
 
	/* foundation is used. Whole tile is leveled up */
 
	if ((~_valid_tileh_slopes_road[1][tileh] & road_bits) == 0) {
 
		return CommandCost(existing != 0 ? 0 : _price.terraform);
 
	if ((~_valid_tileh_slopes_road[1][tileh] & road_bits) == ROAD_NONE) {
 
		return CommandCost(existing != ROAD_NONE ? 0 : _price.terraform);
 
	}
 

	
 
	*pieces |= (RoadBits)((*pieces & 0xC) >> 2);
 
	*pieces |= (RoadBits)((*pieces & 0x3) << 2);
 
	/* Force straight roads. */
 
	*pieces |= MirrorRoadBits(*pieces);
 

	
 
	/* partly leveled up tile, only if there's no road on that tile */
 
	if ((existing == 0 || existing == *pieces) && (tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N)) {
 
		/* force full pieces. */
 
	if ((existing == ROAD_NONE || existing == *pieces) && (tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N)) {
 
		if (*pieces == ROAD_X || *pieces == ROAD_Y) return _price.terraform;
 
	}
 
	return CMD_ERROR;
 
@@ -1182,8 +1233,8 @@ static void TileLoop_Road(TileIndex tile
 

	
 
	if (GetRoadTileType(tile) == ROAD_TILE_DEPOT) return;
 

	
 
	const Town* t = ClosestTownFromTile(tile, (uint)-1);
 
	if (!HasRoadWorks(tile)) {
 
		const Town* t = ClosestTownFromTile(tile, (uint)-1);
 
		int grp = 0;
 

	
 
		if (t != NULL) {
 
@@ -1192,8 +1243,8 @@ static void TileLoop_Road(TileIndex tile
 
			/* Show an animation to indicate road work */
 
			if (t->road_build_months != 0 &&
 
					(DistanceManhattan(t->xy, tile) < 8 || grp != 0) &&
 
					GetRoadTileType(tile) == ROAD_TILE_NORMAL && (GetAllRoadBits(tile) == ROAD_X || GetAllRoadBits(tile) == ROAD_Y)) {
 
				if (GetTileSlope(tile, NULL) == SLOPE_FLAT && EnsureNoVehicleOnGround(tile) && CHANCE16(1, 20)) {
 
					GetRoadTileType(tile) == ROAD_TILE_NORMAL && COUNTBITS(GetAllRoadBits(tile)) > 1 ) {
 
				if (GetTileSlope(tile, NULL) == SLOPE_FLAT && EnsureNoVehicleOnGround(tile) && CHANCE16(1, 40)) {
 
					StartRoadWorks(tile);
 

	
 
					SndPlayTileFx(SND_21_JACKHAMMER, tile);
 
@@ -1231,6 +1282,17 @@ static void TileLoop_Road(TileIndex tile
 
		}
 
	} else if (IncreaseRoadWorksCounter(tile)) {
 
		TerminateRoadWorks(tile);
 

	
 
		if (_patches.mod_road_rebuild) {
 
			/* Generate a nicer town surface */
 
			const RoadBits old_rb = GetAnyRoadBits(tile, ROADTYPE_ROAD);
 
			const RoadBits new_rb = CleanUpRoadBits(tile, old_rb);
 

	
 
			if (old_rb != new_rb) {
 
				DoCommand(tile, (old_rb ^ new_rb), t->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_REMOVE_ROAD);
 
			}
 
		}
 

	
 
		MarkTileDirtyByTile(tile);
 
	}
 
}
src/saveload.cpp
Show inline comments
 
@@ -29,7 +29,7 @@
 
#include "strings.h"
 
#include <list>
 

	
 
extern const uint16 SAVEGAME_VERSION = 76;
 
extern const uint16 SAVEGAME_VERSION = 77;
 
uint16 _sl_version;       ///< the major savegame version identifier
 
byte   _sl_minor_version; ///< the minor savegame version, DO NOT USE!
 

	
src/settings.cpp
Show inline comments
 
@@ -1438,6 +1438,7 @@ const SettingDesc _patch_settings[] = {
 
	SDT_CONDVAR(Patches, town_growth_rate,  SLE_UINT8, 54, SL_MAX_VERSION, 0, MS, 2, 0,   4, 0, STR_CONFIG_PATCHES_TOWN_GROWTH,          NULL),
 
	SDT_CONDVAR(Patches, larger_towns,      SLE_UINT8, 54, SL_MAX_VERSION, 0, D0, 4, 0, 255, 1, STR_CONFIG_PATCHES_LARGER_TOWNS,         NULL),
 
	SDT_CONDVAR(Patches, initial_city_size, SLE_UINT8, 56, SL_MAX_VERSION, 0, 0,  2, 1,  10, 1, STR_CONFIG_PATCHES_CITY_SIZE_MULTIPLIER, NULL),
 
	SDT_CONDBOOL(Patches, mod_road_rebuild,            77, SL_MAX_VERSION, 0, 0, false,         STR_CONFIG_MODIFIED_ROAD_REBUILD,        NULL),
 

	
 
	/***************************************************************************/
 
	/* AI section of the GUI-configure patches window */
src/settings_gui.cpp
Show inline comments
 
@@ -672,7 +672,6 @@ static const char *_patches_construction
 
	"drag_signals_density",
 
	"oil_refinery_limit",
 
	"semaphore_build_before",
 
	"town_layout",
 
};
 

	
 
static const char *_patches_stations[] = {
 
@@ -700,6 +699,8 @@ static const char *_patches_economy[] = 
 
	"ending_year",
 
	"smooth_economy",
 
	"allow_shares",
 
	"town_layout",
 
	"mod_road_rebuild",
 
	"town_growth_rate",
 
	"larger_towns",
 
	"initial_city_size",
src/town_cmd.cpp
Show inline comments
 
@@ -133,18 +133,6 @@ static inline DiagDirection RandomDiagDi
 
}
 

	
 
/**
 
 * Move a TileIndex into a diagonal direction.
 
 *
 
 * @param tile The current tile
 
 * @param dir The direction in which we want to step
 
 * @return the moved tile
 
 */
 
static inline TileIndex AddDiagDirToTileIndex(TileIndex tile, DiagDirection dir)
 
{
 
	return TILE_ADD(tile, TileOffsByDiagDir(dir));
 
}
 

	
 
/**
 
 * House Tile drawing handler.
 
 * Part of the tile loop process
 
 * @param ti TileInfo of the tile to draw
 
@@ -661,7 +649,7 @@ static RoadBits GetTownRoadBits(TileInde
 
 */
 
static bool IsNeighborRoadTile(TileIndex tile, DiagDirection dir, uint dist_multi)
 
{
 
	static TileIndexDiff tid_lt[3]; ///< lookup table for the used diff values
 
	static TileIndexDiff tid_lt[3]; // lookup table for the used diff values
 
	tid_lt[0] = TileOffsByDiagDir(ChangeDiagDir(dir, DIAGDIRDIFF_90RIGHT));
 
	tid_lt[1] = TileOffsByDiagDir(ChangeDiagDir(dir, DIAGDIRDIFF_90LEFT));
 
	tid_lt[2] = TileOffsByDiagDir(ReverseDiagDir(dir));
 
@@ -681,7 +669,7 @@ static bool IsNeighborRoadTile(TileIndex
 
		cur += tid_lt[(pos & 1) ? 0 : 1];
 
		if (pos & 2) cur += tid_lt[2];
 

	
 
		cur = (uint)(pos / 4) * cur; ///< Multiply for the fitting distance
 
		cur = (uint)(pos / 4) * cur; // Multiply for the fitting distance
 
		if (GetTownRoadBits(TILE_ADD(tile, cur)) & DiagDirToRoadBits((pos & 2) ? dir : ReverseDiagDir(dir))) return true;
 
	}
 
	return false;
 
@@ -797,7 +785,7 @@ static void LevelTownLand(TileIndex tile
 
static RoadBits GetTownRoadGridElement(Town* t, TileIndex tile, DiagDirection dir)
 
{
 
	/* align the grid to the downtown */
 
	TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile); ///< Vector from downtown to the tile
 
	TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile); // Vector from downtown to the tile
 
	RoadBits rcmd = ROAD_NONE;
 

	
 
	switch (_patches.town_layout) {
 
@@ -849,32 +837,110 @@ static RoadBits GetTownRoadGridElement(T
 
}
 

	
 
/**
 
 * Check there are enough neighbor house tiles next to the current tile
 
 * Grows the town with an extra house.
 
 *  Check if there are enough neighbor house tiles
 
 *  next to the current tile. If there are enough
 
 *  add another house.
 
 *
 
 * @param tile current tile
 
 * @return true if there are more than 2 house tiles next
 
 *  to the current one
 
 * @param t The current town
 
 * @param tile The target tile for the extra house
 
 * @return true if an extra house has been added
 
 */
 
static bool AreNeighborsHouseTiles(TileIndex tile)
 
static bool GrowTownWithExtraHouse(Town *t, TileIndex tile)
 
{
 
	uint counter = 0; ///< counts the house neighbor tiles
 

	
 
	/* We can't look further than that. */
 
	if (TileX(tile) < 1 || TileY(tile) < 1) {
 
		return false;
 
	if (TileX(tile) < 2 || TileY(tile) < 2 || MapMaxX() <= TileX(tile) || MapMaxY() <= TileY(tile)) return false;
 

	
 
	uint counter = 0; // counts the house neighbor tiles
 

	
 
	/* Check the tiles E,N,W and S of the current tile for houses */
 
	for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
 

	
 
		if (IsTileType(TileAddByDiagDir(tile, dir), MP_HOUSE)) counter++;
 

	
 
		/* If there are enough neighbors stop here */
 
		if (counter >= 3) {
 
			if (BuildTownHouse(t, tile)) {
 
				_grow_town_result = -1;
 
				return true;
 
			}
 
			return false;
 
		}
 
	}
 
	return false;
 
}
 

	
 
/**
 
 * Grows the town with a road piece.
 
 *
 
 * @param t The current town
 
 * @param tile The current tile
 
 * @param rcmd The RoadBits we want to build on the tile
 
 * @return true if the RoadBits have been added else false
 
 */
 
static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd)
 
{
 
	if (CmdSucceeded(DoCommand(tile, rcmd, t->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD))) {
 
		_grow_town_result = -1;
 
		return true;
 
	}
 

	
 
	/* Check the tiles E,N,W and S of the current tile. */
 
	for (DiagDirection i = DIAGDIR_BEGIN; i < DIAGDIR_END; i++) {
 
		if (IsTileType(AddDiagDirToTileIndex(tile, i), MP_HOUSE)) {
 
			counter++;
 
	return false;
 
}
 

	
 
/**
 
 * Grows the town with a bridge.
 
 *  At first we check if a bridge is reasonable.
 
 *  If so we check if we are able to build it.
 
 *
 
 * @param t The current town
 
 * @param tile The current tile
 
 * @param rcmd The RoadBits which are possible on this tile
 
 * @return true if a bridge has been build else false
 
 */
 
static bool GrowTownWithBridge(const Town *t, TileIndex tile, RoadBits rcmd)
 
{
 
	DiagDirection bridge_dir; // The direction of a bridge we maybe want to build
 

	
 
	/* Determine direction of slope,
 
	 *  and build a road if not a special slope. */
 
	switch (GetTileSlope(tile, NULL)) {
 
		case SLOPE_SW: bridge_dir = DIAGDIR_NE; break;
 
		case SLOPE_SE: bridge_dir = DIAGDIR_NW; break;
 
		case SLOPE_NW: bridge_dir = DIAGDIR_SE; break;
 
		case SLOPE_NE: bridge_dir = DIAGDIR_SW; break;
 

	
 
		default: return false;
 
	}
 

	
 
	/* Check if the bridge will be compatible to the RoadBits */
 
	if (!(rcmd & DiagDirToRoadBits(ReverseDiagDir(bridge_dir)))) return false;
 

	
 
	/* We are in the right direction */
 
	uint32 bridge_length = 0;     // This value stores the length of the possible bridge
 
	TileIndex bridge_tile = tile; // Used to store the other waterside
 

	
 
	do {
 
		if (bridge_length++ >= 11) {
 
			/* Max 11 tile long bridges */
 
			return false;
 
		}
 

	
 
		/* If there are enougth neighbor's stop it here */
 
		if (counter >= 3) {
 
		bridge_tile = TILE_MASK(bridge_tile + TileOffsByDiagDir(bridge_dir));
 
	} while (IsClearWaterTile(bridge_tile));
 

	
 
	/* no water tiles in between? */
 
	if (bridge_length == 1) return false;
 

	
 
	for (uint8 times = 0; times <= 22; times++) {
 
		byte bridge_type = RandomRange(MAX_BRIDGES - 1);
 

	
 
		/* Can we actually build the bridge? */
 
		if (CmdSucceeded(DoCommand(tile, bridge_tile, bridge_type | ((0x80 | ROADTYPES_ROAD) << 8), DC_AUTO, CMD_BUILD_BRIDGE))) {
 
			DoCommand(tile, bridge_tile, bridge_type | ((0x80 | ROADTYPES_ROAD) << 8), DC_EXEC | DC_AUTO, CMD_BUILD_BRIDGE);
 
			_grow_town_result--;
 
			return true;
 
		}
 
	}
 
	/* Quit if it selecting an appropiate bridge type fails a large number of times. */
 
	return false;
 
}
 

	
 
@@ -882,25 +948,24 @@ static bool AreNeighborsHouseTiles(TileI
 
 * Grows the given town.
 
 * There are at the moment 3 possible way's for
 
 * the town expansion:
 
 * @li Generate a random tile and check if there is a road allowed
 
 * 	@li TL_ORIGINAL
 
 * 	@li TL_BETTER_ROADS
 
 * @li Check if the town geometry allows a road and which one
 
 * 	@li TL_2X2_GRID
 
 * 	@li TL_3X3_GRID
 
 * @li Forbid roads, only build houses
 
 * 	@li TL_NO_ROADS
 
 *  @li Generate a random tile and check if there is a road allowed
 
 *  @li TL_ORIGINAL
 
 *  @li TL_BETTER_ROADS
 
 *  @li Check if the town geometry allows a road and which one
 
 *  @li TL_2X2_GRID
 
 *  @li TL_3X3_GRID
 
 *  @li Forbid roads, only build houses
 
 *  @li TL_NO_ROADS
 
 *
 
 * @param tile_ptr The current tile
 
 * @param cur_rb The current tiles RoadBits
 
 * @param target_dir The target road dir
 
 * @param t1 The current town
 
 */
 
static void GrowTownInTile(TileIndex* tile_ptr, RoadBits cur_rb, DiagDirection target_dir, Town* t1)
 
static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection target_dir, Town *t1)
 
{
 
	RoadBits rcmd = ROAD_NONE;  ///< RoadBits for the road construction command
 
	TileIndex tmptile;          ///< Dummy tile for various things
 
	TileIndex tile = *tile_ptr; ///< The main tile on which we base our growth
 
	RoadBits rcmd = ROAD_NONE;  // RoadBits for the road construction command
 
	TileIndex tile = *tile_ptr; // The main tile on which we base our growth
 

	
 
	TILE_ASSERT(tile);
 

	
 
@@ -936,14 +1001,14 @@ static void GrowTownInTile(TileIndex* ti
 
					do target_dir = RandomDiagDir(); while (target_dir == source_dir);
 
				}
 

	
 
				if (!IsRoadAllowedHere(AddDiagDirToTileIndex(tile, target_dir), target_dir)) {
 
				if (!IsRoadAllowedHere(TileAddByDiagDir(tile, target_dir), target_dir)) {
 
					/* A road is not allowed to continue the randomized road,
 
					 *  return if the road we're trying to build is curved. */
 
					if (target_dir != ReverseDiagDir(source_dir)) return;
 

	
 
					/* Return if neither side of the new road is a house */
 
					if (!IsTileType(AddDiagDirToTileIndex(tile, ChangeDiagDir(target_dir, DIAGDIRDIFF_90RIGHT)), MP_HOUSE) &&
 
							!IsTileType(AddDiagDirToTileIndex(tile, ChangeDiagDir(target_dir, DIAGDIRDIFF_90LEFT)), MP_HOUSE)) {
 
					if (!IsTileType(TileAddByDiagDir(tile, ChangeDiagDir(target_dir, DIAGDIRDIFF_90RIGHT)), MP_HOUSE) &&
 
							!IsTileType(TileAddByDiagDir(tile, ChangeDiagDir(target_dir, DIAGDIRDIFF_90LEFT)), MP_HOUSE)) {
 
						return;
 
					}
 

	
 
@@ -955,7 +1020,7 @@ static void GrowTownInTile(TileIndex* ti
 
				break;
 
		}
 

	
 
	} else if (target_dir < (DiagDirection)5 && !(cur_rb & DiagDirToRoadBits(ReverseDiagDir(target_dir)))) {
 
	} else if (target_dir < DIAGDIR_END && !(cur_rb & DiagDirToRoadBits(ReverseDiagDir(target_dir)))) {
 
		/* Continue building on a partial road.
 
		 * Should be allways OK, so we only generate
 
		 * the fitting RoadBits */
 
@@ -978,8 +1043,7 @@ static void GrowTownInTile(TileIndex* ti
 
				break;
 
		}
 
	} else {
 
		bool allow_house = false; ///< Value which decides if we want to construct a house
 
		TileIndex tmptile2;       ///< Yet another dummy tile
 
		bool allow_house = false; // Value which decides if we want to construct a house
 

	
 
		/* Reached a tunnel/bridge? Then continue at the other side of it. */
 
		if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 
@@ -997,10 +1061,10 @@ static void GrowTownInTile(TileIndex* ti
 
		if (cur_rb & DiagDirToRoadBits(target_dir)) return;
 

	
 
		/* This is the tile we will reach if we extend to this direction. */
 
		tmptile = AddDiagDirToTileIndex(tile, target_dir);
 
		TileIndex house_tile = TileAddByDiagDir(tile, target_dir); // position of a possible house
 

	
 
		/* Don't walk into water. */
 
		if (IsClearWaterTile(tmptile)) return;
 
		if (IsClearWaterTile(house_tile)) return;
 

	
 
		switch (_patches.town_layout) {
 
			default: NOT_REACHED();
 
@@ -1010,41 +1074,35 @@ static void GrowTownInTile(TileIndex* ti
 
				break;
 

	
 
			case TL_3X3_GRID: /* Use 2x2 grid afterwards! */
 
				/* Fill gap if house has enougth neighbors */
 
				tmptile2 = AddDiagDirToTileIndex(tmptile, target_dir);
 
				if (AreNeighborsHouseTiles(tmptile2) && BuildTownHouse(t1, tmptile2)) {
 
					_grow_town_result = -1;
 
				}
 
				GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir));
 
				/* FALL THROUGH */
 

	
 
			case TL_2X2_GRID:
 
				rcmd = GetTownRoadGridElement(t1, tmptile, target_dir);
 
				rcmd = GetTownRoadGridElement(t1, house_tile, target_dir);
 
				allow_house = (rcmd == ROAD_NONE);
 
				break;
 

	
 
			case TL_BETTER_ROADS: /* Use original afterwards! */
 
				/* Fill gap if house has enougth neighbors */
 
				tmptile2 = AddDiagDirToTileIndex(tmptile, target_dir);
 
				if (AreNeighborsHouseTiles(tmptile2) && BuildTownHouse(t1, tmptile2)) {
 
					_grow_town_result = -1;
 
				}
 
				GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir));
 
				/* FALL THROUGH */
 

	
 
			case TL_ORIGINAL:
 
				 /* Allow a house at the edge. 60% chance or
 
				  * always ok if no road allowed. */
 
				rcmd = DiagDirToRoadBits(target_dir);
 
				allow_house = (!IsRoadAllowedHere(tmptile, target_dir) || CHANCE16(6, 10));
 
				allow_house = (!IsRoadAllowedHere(house_tile, target_dir) || CHANCE16(6, 10));
 
				break;
 
		}
 

	
 
		if (allow_house) {
 
			/* Build a house, but not if there already is a house there. */
 
			if (!IsTileType(tmptile, MP_HOUSE)) {
 
			if (!IsTileType(house_tile, MP_HOUSE)) {
 
				/* Level the land if possible */
 
				LevelTownLand(tmptile);
 
				LevelTownLand(house_tile);
 

	
 
				/* And build a house.
 
				 * Set result to -1 if we managed to build it. */
 
				if (BuildTownHouse(t1, tmptile)) {
 
				if (BuildTownHouse(t1, house_tile)) {
 
					_grow_town_result = -1;
 
				}
 
			}
 
@@ -1057,51 +1115,13 @@ static void GrowTownInTile(TileIndex* ti
 
	/* Return if a water tile */
 
	if (IsClearWaterTile(tile)) return;
 

	
 
	DiagDirection bridge_dir; ///< The direction of a bridge we maybe want to build
 
	/* Determine direction of slope,
 
	 *  and build a road if not a special slope. */
 
	switch (GetTileSlope(tile, NULL)) {
 
		case SLOPE_SW: bridge_dir = DIAGDIR_NE; break;
 
		case SLOPE_SE: bridge_dir = DIAGDIR_NW; break;
 
		case SLOPE_NW: bridge_dir = DIAGDIR_SE; break;
 
		case SLOPE_NE: bridge_dir = DIAGDIR_SW; break;
 

	
 
		default:
 
build_road_and_exit:
 
			if (CmdSucceeded(DoCommand(tile, rcmd, t1->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD))) {
 
				_grow_town_result = -1;
 
			}
 
			return;
 
	}
 

	
 
	/* Check if the bridge is in the right direction */
 
	if (!(rcmd & DiagDirToRoadBits(bridge_dir))) goto build_road_and_exit;
 

	
 
	/* We are in the right direction */
 
	uint32 bridge_length = 0; ///< This value stores the length of the possible bridge
 
	tmptile = tile;           ///< Now we use this dummy to store the other waterside
 
	do {
 
		if (bridge_length++ >= 11) {
 
			/* Max 11 tile long bridges */
 
			goto build_road_and_exit;
 
		}
 
		tmptile = TILE_MASK(tmptile + TileOffsByDiagDir(bridge_dir));
 
	} while (IsClearWaterTile(tmptile));
 

	
 
	/* no water tiles in between? */
 
	if (bridge_length == 1) goto build_road_and_exit;
 

	
 
	for (uint times = 0; times <= 22; times++) {
 
		byte bridge_type = RandomRange(MAX_BRIDGES - 1);
 

	
 
		/* Can we actually build the bridge? */
 
		if (CmdSucceeded(DoCommand(tile, tmptile, bridge_type | ((0x80 | ROADTYPES_ROAD) << 8), DC_AUTO, CMD_BUILD_BRIDGE))) {
 
			DoCommand(tile, tmptile, bridge_type | ((0x80 | ROADTYPES_ROAD) << 8), DC_EXEC | DC_AUTO, CMD_BUILD_BRIDGE);
 
			_grow_town_result = -1;
 
			return;
 
		}
 
	}
 
	/* Quit if it selecting an appropiate bridge type fails a large number of times. */
 
	/* Make the roads look nicer */
 
	rcmd = CleanUpRoadBits(tile, rcmd);
 
	if (rcmd == ROAD_NONE) return;
 

	
 
	if (GrowTownWithBridge(t1, tile, rcmd)) return;
 

	
 
	GrowTownWithRoad(t1, tile, rcmd);
 
}
 

	
 
/** Returns "growth" if a house was built, or no if the build failed.
 
@@ -1114,7 +1134,7 @@ static int GrowTownAtRoad(Town *t, TileI
 
	/* Special case.
 
	 * @see GrowTownInTile Check the else if
 
	 */
 
	DiagDirection target_dir = (DiagDirection)5; ///< The direction in which we want to extend the town
 
	DiagDirection target_dir = DIAGDIR_END; // The direction in which we want to extend the town
 

	
 
	TILE_ASSERT(tile);
 

	
 
@@ -1137,7 +1157,7 @@ static int GrowTownAtRoad(Town *t, TileI
 
	}
 

	
 
	do {
 
		RoadBits cur_rb = GetTownRoadBits(tile); ///< The RoadBits of the current tile
 
		RoadBits cur_rb = GetTownRoadBits(tile); // The RoadBits of the current tile
 

	
 
		/* Try to grow the town from this point */
 
		GrowTownInTile(&tile, cur_rb, target_dir, t);
 
@@ -1151,7 +1171,7 @@ static int GrowTownAtRoad(Town *t, TileI
 
		/* Select a random bit from the blockmask, walk a step
 
		 * and continue the search from there. */
 
		do target_dir = RandomDiagDir(); while (!(cur_rb & DiagDirToRoadBits(target_dir)));
 
		tile = AddDiagDirToTileIndex(tile, target_dir);
 
		tile = TileAddByDiagDir(tile, target_dir);
 

	
 
		if (IsTileType(tile, MP_ROAD)) {
 
			/* Don't allow building over roads of other cities */
 
@@ -1220,7 +1240,7 @@ static bool GrowTown(Town *t)
 
	PlayerID old_player = _current_player;
 
	_current_player = OWNER_TOWN;
 

	
 
	TileIndex tile = t->xy; ///< The tile we are working with ATM
 
	TileIndex tile = t->xy; // The tile we are working with ATM
 

	
 
	/* Find a road that we can base the construction on. */
 
	for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
 
@@ -2110,8 +2130,8 @@ static void UpdateTownGrowRate(Town *t)
 
	/** Towns are processed every TOWN_GROWTH_FREQUENCY ticks, and this is the
 
	 * number of times towns are processed before a new building is built. */
 
	static const uint16 _grow_count_values[2][6] = {
 
		{ 120, 120, 120, 100,  80,  60 }, ///< Fund new buildings has been activated
 
		{ 320, 420, 300, 220, 160, 100 }  ///< Normal values
 
		{ 120, 120, 120, 100,  80,  60 }, // Fund new buildings has been activated
 
		{ 320, 420, 300, 220, 160, 100 }  // Normal values
 
	};
 

	
 
	if (t->fund_buildings_months != 0) {
 
@@ -2252,9 +2272,9 @@ void ChangeTownRating(Town *t, int add, 
 
/* penalty for removing town-owned stuff */
 
static const int _default_rating_settings [3][3] = {
 
	/* ROAD_REMOVE, TUNNELBRIDGE_REMOVE, INDUSTRY_REMOVE */
 
	{  0, 128, 384}, ///< Permissive
 
	{ 48, 192, 480}, ///< Neutral
 
	{ 96, 384, 768}, ///< Hostile
 
	{  0, 128, 384}, // Permissive
 
	{ 48, 192, 480}, // Neutral
 
	{ 96, 384, 768}, // Hostile
 
};
 

	
 
bool CheckforTownRating(uint32 flags, Town *t, byte type)
src/variables.h
Show inline comments
 
@@ -242,6 +242,8 @@ struct Patches {
 
	bool timetable_in_ticks; ///< Whether to show the timetable in ticks rather than days.
 

	
 
	bool autoslope;          ///< Allow terraforming under things.
 

	
 
	bool mod_road_rebuild;   ///< Roadworks remove unneccesary RoadBits
 
};
 

	
 
VARDEF Patches _patches;
0 comments (0 inline, 0 general)