Changeset - r6422:5983361e241a
[Not reviewed]
master
0 21 0
belugas - 18 years ago 2007-04-04 03:21:14
belugas@openttd.org
(svn r9558) -Documentation: doxygen and comment changes: 'T' now. Almost done
21 files changed with 435 insertions and 370 deletions:
0 comments (0 inline, 0 general)
src/console.cpp
Show inline comments
 
@@ -411,7 +411,7 @@ void IConsolePrint(uint16 color_code, co
 
/**
 
 * Handle the printing of text entered into the console or redirected there
 
 * by any other means. Uses printf() style format, for more information look
 
 * at @IConsolePrint()
 
 * at IConsolePrint()
 
 */
 
void CDECL IConsolePrintF(uint16 color_code, const char *s, ...)
 
{
src/terraform_gui.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file terraform_gui.cpp */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "bridge_map.h"
 
@@ -91,11 +93,11 @@ static void GenerateRockyArea(TileIndex 
 

	
 
/**
 
 * A central place to handle all X_AND_Y dragged GUI functions.
 
 * @param e @WindowEvent variable holding in its higher bits (excluding the lower
 
 * @param e WindowEvent variable holding in its higher bits (excluding the lower
 
 * 4, since that defined the X_Y drag) the type of action to be performed
 
 * @return Returns true if the action was found and handled, and false otherwise. This
 
 * allows for additional implements that are more local. For example X_Y drag
 
 * of convertrail which belongs in rail_gui.c and not terraform_gui.c
 
 * of convertrail which belongs in rail_gui.cpp and not terraform_gui.cpp
 
 **/
 
bool GUIPlaceProcDragXY(const WindowEvent *e)
 
{
src/texteff.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file texteff.cpp */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "functions.h"
 
@@ -121,7 +123,7 @@ void InitTextMessage()
 
	}
 
}
 

	
 
/* Hide the textbox */
 
/** Hide the textbox */
 
void UndrawTextMessage()
 
{
 
	if (_textmessage_visible) {
 
@@ -172,7 +174,7 @@ void UndrawTextMessage()
 
	}
 
}
 

	
 
/* Check if a message is expired every day */
 
/** Check if a message is expired every day */
 
void TextMessageDailyLoop()
 
{
 
	uint i;
 
@@ -196,7 +198,7 @@ void TextMessageDailyLoop()
 
	}
 
}
 

	
 
/* Draw the textmessage-box */
 
/** Draw the textmessage-box */
 
void DrawTextMessage()
 
{
 
	if (!_textmessage_dirty) return;
src/tgp.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file tgp.cpp OTTD Perlin Noise Landscape Generator, aka TerraGenesis Perlin */
 

	
 
#include "stdafx.h"
 
#include <math.h>
 
#include "openttd.h"
 
@@ -17,7 +19,6 @@
 
#include "helpers.hpp"
 

	
 
/*
 
 * OTTD Perlin Noise Landscape Generator, aka TerraGenesis Perlin
 
 *
 
 * Quickie guide to Perlin Noise
 
 * Perlin noise is a predictable pseudo random number sequence. By generating
 
@@ -167,11 +168,11 @@ static const int amplitude_decimal_bits 
 
/** Height map - allocated array of heights (MapSizeX() + 1) x (MapSizeY() + 1) */
 
struct HeightMap
 
{
 
	height_t *h;         //! array of heights
 
	uint     dim_x;      //! height map size_x MapSizeX() + 1
 
	uint     total_size; //! height map total size
 
	uint     size_x;     //! MapSizeX()
 
	uint     size_y;     //! MapSizeY()
 
	height_t *h;         //< array of heights
 
	uint     dim_x;      //< height map size_x MapSizeX() + 1
 
	uint     total_size; //< height map total size
 
	uint     size_x;     //< MapSizeX()
 
	uint     size_y;     //< MapSizeY()
 
};
 

	
 
/** Global height map instance */
 
@@ -200,13 +201,13 @@ static HeightMap _height_map = {NULL, 0,
 
/** Noise amplitudes (multiplied by 1024)
 
 * - indexed by "smoothness setting" and log2(frequency) */
 
static const amplitude_t _amplitudes_by_smoothness_and_frequency[4][12] = {
 
	// Very smooth
 
	/* Very smooth */
 
	{1000,  350,  123,   43,   15,    1,     1,    0,    0,    0,    0,    0},
 
	// Smooth
 
	/* Smooth */
 
	{1000, 1000,  403,  200,   64,    8,     1,    0,    0,    0,    0,    0},
 
	// Rough
 
	/* Rough */
 
	{1000, 1200,  800,  500,  200,   16,     4,    0,    0,    0,    0,    0},
 
	// Very Rough
 
	/* Very Rough */
 
	{1500, 1000, 1200, 1000,  500,   32,    20,    0,    0,    0,    0,    0},
 
};
 

	
 
@@ -215,13 +216,17 @@ static const amplitude_t _water_percent[
 

	
 
/** Desired maximum height - indexed by _opt.diff.terrain_type */
 
static const int8 _max_height[4] = {
 
	6,       // Very flat
 
	9,       // Flat
 
	12,      // Hilly
 
	15       // Mountainous
 
	6,       ///< Very flat
 
	9,       ///< Flat
 
	12,      ///< Hilly
 
	15       ///< Mountainous
 
};
 

	
 
/** Check if a X/Y set are within the map. */
 
/** Check if a X/Y set are within the map.
 
 * @param x coordinate x
 
 * @param y coordinate y
 
 * @return true if within the map
 
 */
 
static inline bool IsValidXY(uint x, uint y)
 
{
 
	return ((int)x) >= 0 && x < _height_map.size_x && ((int)y) >= 0 && y < _height_map.size_y;
 
@@ -680,10 +685,10 @@ static inline int perlin_landXY(uint x, 
 

	
 
/* The following decimals are the octave power modifiers for the Perlin noise */
 
static const double _perlin_p_values[][7] = {    // perlin frequency per power
 
	{ 0.35, 0.35, 0.35, 0.35, 0.35, 0.25, 0.539 }, // Very smooth
 
	{ 0.45, 0.55, 0.45, 0.45, 0.35, 0.25, 0.89  }, // Smooth
 
	{ 0.85, 0.80, 0.70, 0.45, 0.45, 0.35, 1.825 }, // Rough 1.825
 
	{ 0.95, 0.85, 0.80, 0.55, 0.55, 0.45, 2.245 }  // Very Rough 2.25
 
	{ 0.35, 0.35, 0.35, 0.35, 0.35, 0.25, 0.539 }, ///< Very smooth
 
	{ 0.45, 0.55, 0.45, 0.45, 0.35, 0.25, 0.89  }, ///< Smooth
 
	{ 0.85, 0.80, 0.70, 0.45, 0.45, 0.35, 1.825 }, ///< Rough 1.825
 
	{ 0.95, 0.85, 0.80, 0.55, 0.55, 0.45, 2.245 }  //< Very Rough 2.25
 
};
 

	
 
/**
src/tgp.h
Show inline comments
 
/* $Id$ */
 

	
 
/** @file tgp.h */
 

	
 
#ifndef TGP_H
 
#define TGP_H
 

	
src/thread.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file thread.cpp */
 

	
 
#include "stdafx.h"
 
#include "thread.h"
 
#include <stdlib.h>
src/thread.h
Show inline comments
 
/* $Id$ */
 

	
 
/** @file thread.h */
 

	
 
#ifndef THREAD_H
 
#define THREAD_H
 

	
src/tile.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file tile.cpp */
 

	
 
#include "stdafx.h"
 
#include "tile.h"
 

	
src/tile.h
Show inline comments
 
/* $Id$ */
 

	
 
/** @file tile.h */
 

	
 
#ifndef TILE_H
 
#define TILE_H
 

	
src/town.h
Show inline comments
 
/* $Id$ */
 

	
 
/** @file town.h */
 

	
 
#ifndef TOWN_H
 
#define TOWN_H
 

	
 
@@ -76,34 +78,34 @@ struct BuildingCounts {
 
struct Town {
 
	TileIndex xy;
 

	
 
	// Current population of people and amount of houses.
 
	/* Current population of people and amount of houses. */
 
	uint16 num_houses;
 
	uint32 population;
 

	
 
	// Town name
 
	/* Town name */
 
	uint16 townnametype;
 
	uint32 townnameparts;
 

	
 
	// NOSAVE: Location of name sign, UpdateTownVirtCoord updates this.
 
	/* NOSAVE: Location of name sign, UpdateTownVirtCoord updates this. */
 
	ViewportSign sign;
 

	
 
	// Makes sure we don't build certain house types twice.
 
	// bit 0 = Building funds received
 
	// bit 1 = CHURCH
 
	// bit 2 = STADIUM
 
	/* Makes sure we don't build certain house types twice.
 
	 * bit 0 = Building funds received
 
	 * bit 1 = CHURCH
 
	 * bit 2 = STADIUM */
 
	byte flags12;
 

	
 
	// Which players have a statue?
 
	/* Which players have a statue? */
 
	byte statues;
 

	
 
	// Player ratings as well as a mask that determines which players have a rating.
 
	/* Player ratings as well as a mask that determines which players have a rating. */
 
	byte have_ratings;
 
	uint8 unwanted[MAX_PLAYERS]; // how many months companies aren't wanted by towns (bribe)
 
	PlayerByte exclusivity;        // which player has exslusivity
 
	uint8 exclusive_counter;     // months till the exclusivity expires
 
	uint8 unwanted[MAX_PLAYERS]; ///< how many months companies aren't wanted by towns (bribe)
 
	PlayerByte exclusivity;      ///< which player has exslusivity
 
	uint8 exclusive_counter;     ///< months till the exclusivity expires
 
	int16 ratings[MAX_PLAYERS];
 

	
 
	// Maximum amount of passengers and mail that can be transported.
 
	/* Maximum amount of passengers and mail that can be transported. */
 
	uint32 max_pass;
 
	uint32 max_mail;
 
	uint32 new_max_pass;
 
@@ -113,36 +115,36 @@ struct Town {
 
	uint32 new_act_pass;
 
	uint32 new_act_mail;
 

	
 
	// Amount of passengers that were transported.
 
	/* Amount of passengers that were transported. */
 
	byte pct_pass_transported;
 
	byte pct_mail_transported;
 

	
 
	// Amount of food and paper that was transported. Actually a bit mask would be enough.
 
	/* Amount of food and paper that was transported. Actually a bit mask would be enough. */
 
	uint16 act_food;
 
	uint16 act_water;
 
	uint16 new_act_food;
 
	uint16 new_act_water;
 

	
 
	// Time until we rebuild a house.
 
	/* Time until we rebuild a house. */
 
	byte time_until_rebuild;
 

	
 
	// When to grow town next time.
 
	/* When to grow town next time. */
 
	byte grow_counter;
 
	byte growth_rate;
 

	
 
	// Fund buildings program in action?
 
	/* Fund buildings program in action? */
 
	byte fund_buildings_months;
 

	
 
	// Fund road reconstruction in action?
 
	/* Fund road reconstruction in action? */
 
	byte road_build_months;
 

	
 
	// Index in town array
 
	/* Index in town array */
 
	TownID index;
 

	
 
	// NOSAVE: UpdateTownRadius updates this given the house count.
 
	/* NOSAVE: UpdateTownRadius updates this given the house count. */
 
	uint16 radius[5];
 

	
 
	// NOSAVE: The number of each type of building in the town.
 
	/* NOSAVE: The number of each type of building in the town. */
 
	BuildingCounts building_counts;
 
};
 

	
 
@@ -197,8 +199,8 @@ enum {
 
};
 

	
 
enum {
 
	// These refer to the maximums, so Appalling is -1000 to -400
 
	// MAXIMUM RATINGS BOUNDARIES
 
	/* These refer to the maximums, so Appalling is -1000 to -400
 
	 * MAXIMUM RATINGS BOUNDARIES */
 
	RATING_MINIMUM     = -1000,
 
	RATING_APPALLING   =  -400,
 
	RATING_VERYPOOR    =  -200,
 
@@ -207,11 +209,11 @@ enum {
 
	RATING_GOOD        =   400,
 
	RATING_VERYGOOD    =   600,
 
	RATING_EXCELLENT   =   800,
 
	RATING_OUTSTANDING =  1000,         // OUTSTANDING
 
	RATING_OUTSTANDING =  1000,         ///< OUTSTANDING
 

	
 
	RATING_MAXIMUM = RATING_OUTSTANDING,
 

	
 
	// RATINGS AFFECTING NUMBERS
 
	/* RATINGS AFFECTING NUMBERS */
 
	RATING_TREE_DOWN_STEP = -35,
 
	RATING_TREE_MINIMUM   = RATING_MINIMUM,
 
	RATING_TREE_UP_STEP   = 7,
 
@@ -241,16 +243,16 @@ enum {
 
	TOWN_HOUSE_COMPLETED  =  3,
 
};
 

	
 
/* This enum is used in conjonction with town->flags12.
 
/** This enum is used in conjonction with town->flags12.
 
 * IT simply states what bit is used for.
 
 * It is pretty unrealistic (IMHO) to only have one church/stadium
 
 * per town, NO MATTER the population of it.
 
 * And there are 5 more bits available on flags12...
 
 */
 
enum {
 
	TOWN_IS_FUNDED      = 0,   // Town has received some funds for
 
	TOWN_HAS_CHURCH     = 1,   // There can be only one church by town.
 
	TOWN_HAS_STADIUM    = 2    // There can be only one stadium by town.
 
	TOWN_IS_FUNDED      = 0,   ///< Town has received some funds for
 
	TOWN_HAS_CHURCH     = 1,   ///< There can be only one church by town.
 
	TOWN_HAS_STADIUM    = 2    ///< There can be only one stadium by town.
 
};
 

	
 
bool CheckforTownRating(uint32 flags, Town *t, byte type);
 
@@ -267,12 +269,19 @@ static inline HouseSpec *GetHouseSpecs(H
 

	
 
/**
 
 * Check if a Town really exists.
 
 * @param town to inquiry
 
 * @return true if it exists
 
 */
 
static inline bool IsValidTown(const Town* town)
 
{
 
	return town->xy != 0;
 
}
 

	
 
/**
 
 * Check if a TownID is valid.
 
 * @param TownID to inquiry
 
 * @return true if it exists
 
 */
 
static inline bool IsValidTownID(TownID index)
 
{
 
	return index < GetTownPoolSize() && IsValidTown(GetTown(index));
src/town_cmd.cpp
Show inline comments
 
@@ -198,10 +198,10 @@ static void AnimateTile_Town(TileIndex t
 

	
 
	if (_tick_counter & 3) return;
 

	
 
	// If the house is not one with a lift anymore, then stop this animating.
 
	// Not exactly sure when this happens, but probably when a house changes.
 
	// Before this was just a return...so it'd leak animated tiles..
 
	// That bug seems to have been here since day 1??
 
	/* If the house is not one with a lift anymore, then stop this animating.
 
	 * Not exactly sure when this happens, but probably when a house changes.
 
	 * Before this was just a return...so it'd leak animated tiles..
 
	 * That bug seems to have been here since day 1?? */
 
	if (!(GetHouseSpecs(GetHouseType(tile))->building_flags & BUILDING_IS_ANIMATED)) {
 
		DeleteAnimatedTile(tile);
 
		return;
 
@@ -210,7 +210,7 @@ static void AnimateTile_Town(TileIndex t
 
	if (!LiftHasDestination(tile)) {
 
		int i;
 

	
 
		/** Building has 6 floors, number 0 .. 6, where 1 is illegal.
 
		/*  Building has 6 floors, number 0 .. 6, where 1 is illegal.
 
		 *  This is due to the fact that the first floor is, in the graphics,
 
		 *  the height of 2 'normal' floors.
 
		 *  Furthermore, there are 6 lift positions from floor N (incl) to floor N + 1 (excl) */
 
@@ -328,7 +328,7 @@ static void TileLoop_Town(TileIndex tile
 
	if (house_id >= NEW_HOUSE_OFFSET && !NewHouseTileLoop(tile)) return;
 

	
 
	if (!IsHouseCompleted(tile)) {
 
		/*Construction is not completed. See if we can go further in construction*/
 
		/* Construction is not completed. See if we can go further in construction*/
 
		MakeTownHouseBigger(tile);
 
		return;
 
	}
 
@@ -367,7 +367,7 @@ static void TileLoop_Town(TileIndex tile
 

	
 
		ClearTownHouse(t, tile);
 

	
 
		// rebuild with another house?
 
		/* rebuild with another house? */
 
		if (GB(r, 24, 8) >= 12) DoBuildTownHouse(t, tile);
 
	}
 

	
 
@@ -446,8 +446,8 @@ static const TileIndexDiffC _roadblock_t
 
	{ 0,  1},
 
	{-1,  0},
 

	
 
	// Store the first 3 elements again.
 
	// Lets us rotate without using &3.
 
	/* Store the first 3 elements again.
 
	 * Lets us rotate without using &3. */
 
	{ 0, -1},
 
	{ 1,  0},
 
	{ 0,  1}
 
@@ -510,16 +510,16 @@ static bool IsRoadAllowedHere(TileIndex 
 
	Slope k;
 
	Slope slope;
 

	
 
	// If this assertion fails, it might be because the world contains
 
	//  land at the edges. This is not ok.
 
	/* If this assertion fails, it might be because the world contains
 
	 *  land at the edges. This is not ok. */
 
	TILE_ASSERT(tile);
 

	
 
	for (;;) {
 
		// Check if there already is a road at this point?
 
		/* Check if there already is a road at this point? */
 
		if (GetAnyRoadTrackBits(tile) == 0) {
 
			// No, try to build one in the direction.
 
			// if that fails clear the land, and if that fails exit.
 
			// This is to make sure that we can build a road here later.
 
			/* No, try to build one in the direction.
 
			 * if that fails clear the land, and if that fails exit.
 
			 * This is to make sure that we can build a road here later. */
 
			if (CmdFailed(DoCommand(tile, (dir & 1 ? ROAD_X : ROAD_Y), 0, DC_AUTO, CMD_BUILD_ROAD)) &&
 
					CmdFailed(DoCommand(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR)))
 
				return false;
 
@@ -528,20 +528,20 @@ static bool IsRoadAllowedHere(TileIndex 
 
		slope = GetTileSlope(tile, NULL);
 
		if (slope == SLOPE_FLAT) {
 
no_slope:
 
			// Tile has no slope
 
			// Disallow the road if any neighboring tile has a road.
 
			/* Tile has no slope
 
			 * Disallow the road if any neighboring tile has a road. */
 
			if (HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir+1]))), dir^2) ||
 
					HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir+3]))), dir^2) ||
 
					HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir+1]) + ToTileIndexDiff(_roadblock_tileadd[dir+2]))), dir) ||
 
					HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir+3]) + ToTileIndexDiff(_roadblock_tileadd[dir+2]))), dir))
 
				return false;
 

	
 
			// Otherwise allow
 
			/* Otherwise allow */
 
			return true;
 
		}
 

	
 
		// If the tile is not a slope in the right direction, then
 
		// maybe terraform some.
 
		/* If the tile is not a slope in the right direction, then
 
		 * maybe terraform some. */
 
		k = (dir & 1) ? SLOPE_NE : SLOPE_NW;
 
		if (k != slope && ComplementSlope(k) != slope) {
 
			uint32 r = Random();
 
@@ -557,7 +557,7 @@ no_slope:
 
					                      CMD_TERRAFORM_LAND);
 
				}
 
				if (CmdFailed(res) && CHANCE16I(1, 3, r)) {
 
					// We can consider building on the slope, though.
 
					/* We can consider building on the slope, though. */
 
					goto no_slope;
 
				}
 
			}
 
@@ -585,12 +585,12 @@ static void LevelTownLand(TileIndex tile
 

	
 
	TILE_ASSERT(tile);
 

	
 
	// Don't terraform if land is plain or if there's a house there.
 
	/* Don't terraform if land is plain or if there's a house there. */
 
	if (IsTileType(tile, MP_HOUSE)) return;
 
	tileh = GetTileSlope(tile, NULL);
 
	if (tileh == SLOPE_FLAT) return;
 

	
 
	// First try up, then down
 
	/* First try up, then down */
 
	if (!TerraformTownTile(tile, ~tileh & 0xF, 1)) {
 
		TerraformTownTile(tile, tileh & 0xF, 0);
 
	}
 
@@ -610,17 +610,17 @@ static void GrowTownInTile(TileIndex* ti
 
		int a;
 
		int b;
 

	
 
		// Tile has no road. First reset the status counter
 
		// to say that this is the last iteration.
 
		/* Tile has no road. First reset the status counter
 
		 * to say that this is the last iteration. */
 
		_grow_town_result = 0;
 

	
 
		// Remove hills etc
 
		/* Remove hills etc */
 
		LevelTownLand(tile);
 

	
 
		// Is a road allowed here?
 
		/* Is a road allowed here? */
 
		if (!IsRoadAllowedHere(tile, block)) return;
 

	
 
		// Randomize new road block numbers
 
		/* Randomize new road block numbers */
 
		a = block;
 
		b = block ^ 2;
 
		if (CHANCE16(1, 4)) {
 
@@ -630,29 +630,29 @@ static void GrowTownInTile(TileIndex* ti
 
		}
 

	
 
		if (!IsRoadAllowedHere(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a])), a)) {
 
			// A road is not allowed to continue the randomized road,
 
			//   return if the road we're trying to build is curved.
 
			/* A road is not allowed to continue the randomized road,
 
			 *   return if the road we're trying to build is curved. */
 
			if (a != (b ^ 2)) return;
 

	
 
			// Return if neither side of the new road is a house
 
			/* Return if neither side of the new road is a house */
 
			if (!IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a + 1])), MP_HOUSE) &&
 
					!IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a + 3])), MP_HOUSE))
 
				return;
 

	
 
			// That means that the road is only allowed if there is a house
 
			//  at any side of the new road.
 
			/* That means that the road is only allowed if there is a house
 
			 *  at any side of the new road. */
 
		}
 
		rcmd = (RoadBits)((1 << a) + (1 << b));
 

	
 
	} else if (block < 5 && !HASBIT(mask,block^2)) {
 
		// Continue building on a partial road.
 
		// Always OK.
 
		/* Continue building on a partial road.
 
		 * Always OK. */
 
		_grow_town_result = 0;
 
		rcmd = (RoadBits)(1 << (block ^ 2));
 
	} else {
 
		int i;
 

	
 
		// Reached a tunnel/bridge? Then continue at the other side of it.
 
		/* Reached a tunnel/bridge? Then continue at the other side of it. */
 
		if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 
			if (IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_ROAD) {
 
				*tile_ptr = GetOtherTunnelEnd(tile);
 
@@ -662,27 +662,27 @@ static void GrowTownInTile(TileIndex* ti
 
			return;
 
		}
 

	
 
		// Possibly extend the road in a direction.
 
		// Randomize a direction and if it has a road, bail out.
 
		/* Possibly extend the road in a direction.
 
		 * Randomize a direction and if it has a road, bail out. */
 
		i = GB(Random(), 0, 2);
 
		if (HASBIT(mask, i)) return;
 

	
 
		// This is the tile we will reach if we extend to this direction.
 
		/* This is the tile we will reach if we extend to this direction. */
 
		tmptile = TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[i]));
 

	
 
		// Don't do it if it reaches to water.
 
		/* Don't do it if it reaches to water. */
 
		if (IsClearWaterTile(tmptile)) return;
 

	
 
		// Build a house at the edge. 60% chance or
 
		//  always ok if no road allowed.
 
		/* Build a house at the edge. 60% chance or
 
		 *  always ok if no road allowed. */
 
		if (!IsRoadAllowedHere(tmptile, i) || CHANCE16(6, 10)) {
 
			// But not if there already is a house there.
 
			/* But not if there already is a house there. */
 
			if (!IsTileType(tmptile, MP_HOUSE)) {
 
				// Level the land if possible
 
				/* Level the land if possible */
 
				LevelTownLand(tmptile);
 

	
 
				// And build a house.
 
				// Set result to -1 if we managed to build it.
 
				/* And build a house.
 
				 * Set result to -1 if we managed to build it. */
 
				if (BuildTownHouse(t1, tmptile)) _grow_town_result = -1;
 
			}
 
			return;
 
@@ -692,11 +692,11 @@ static void GrowTownInTile(TileIndex* ti
 
		rcmd = (RoadBits)(1 << i);
 
	}
 

	
 
	// Return if a water tile
 
	/* Return if a water tile */
 
	if (IsClearWaterTile(tile)) return;
 

	
 
	// Determine direction of slope,
 
	//  and build a road if not a special slope.
 
	/* Determine direction of slope,
 
	 *  and build a road if not a special slope. */
 
	switch (GetTileSlope(tile, NULL)) {
 
		case SLOPE_SW: i = DIAGDIR_NE; break;
 
		case SLOPE_SE: i = DIAGDIR_NW; break;
 
@@ -713,7 +713,7 @@ build_road_and_exit:
 

	
 
	tmptile = tile;
 

	
 
	// Now it contains the direction of the slope
 
	/* Now it contains the direction of the slope */
 
	j = -11; // max 11 tile long bridges
 
	do {
 
		if (++j == 0)
 
@@ -721,11 +721,11 @@ build_road_and_exit:
 
		tmptile = TILE_MASK(tmptile + TileOffsByDiagDir(i));
 
	} while (IsClearWaterTile(tmptile));
 

	
 
	// no water tiles in between?
 
	/* no water tiles in between? */
 
	if (j == -10)
 
		goto build_road_and_exit;
 

	
 
	// Quit if it selecting an appropiate bridge type fails a large number of times.
 
	/* Quit if it selecting an appropiate bridge type fails a large number of times. */
 
	j = 22;
 
	{
 
		int32 bridge_len = GetBridgeLength(tile, tmptile);
 
@@ -735,38 +735,42 @@ build_road_and_exit:
 
				if (!CmdFailed(DoCommand(tile, tmptile, 0x8000 + bridge_type, DC_EXEC | DC_AUTO, CMD_BUILD_BRIDGE)))
 
					_grow_town_result = -1;
 

	
 
				// obviously, if building any bridge would fail, there is no need to try other bridge-types
 
				/* obviously, if building any bridge would fail, there is no need to try other bridge-types */
 
				return;
 
			}
 
		} while (--j != 0);
 
	}
 
}
 

	
 
// Returns true if a house was built, or no if the build failed.
 
/** Returns "growth" if a house was built, or no if the build failed.
 
 * @param t town to inquiry
 
 * @param tile to inquiry
 
 * @return something other than zero(0)if town expansion was possible
 
 */
 
static int GrowTownAtRoad(Town *t, TileIndex tile)
 
{
 
	int block = 5; // special case
 

	
 
	TILE_ASSERT(tile);
 

	
 
	// Number of times to search.
 
	/* Number of times to search. */
 
	_grow_town_result = 10 + t->num_houses * 4 / 9;
 

	
 
	do {
 
		// Get a bitmask of the road blocks on a tile
 
		/* Get a bitmask of the road blocks on a tile */
 
		RoadBits mask = GetTownRoadMask(tile);
 

	
 
		// Try to grow the town from this point
 
		GrowTownInTile(&tile,mask,block,t);
 
		/* Try to grow the town from this point */
 
		GrowTownInTile(&tile, mask, block, t);
 

	
 
		// Exclude the source position from the bitmask
 
		// and return if no more road blocks available
 
		/* Exclude the source position from the bitmask
 
		 * and return if no more road blocks available */
 
		ClrBitT(mask, (block ^ 2));
 
		if (mask == 0)
 
			return _grow_town_result;
 

	
 
		// Select a random bit from the blockmask, walk a step
 
		// and continue the search from there.
 
		/* Select a random bit from the blockmask, walk a step
 
		 * and continue the search from there. */
 
		do block = Random() & 3; while (!HASBIT(mask,block));
 
		tile += ToTileIndexDiff(_roadblock_tileadd[block]);
 

	
 
@@ -782,15 +786,15 @@ static int GrowTownAtRoad(Town *t, TileI
 
			}
 
		}
 

	
 
		// Max number of times is checked.
 
		/* Max number of times is checked. */
 
	} while (--_grow_town_result >= 0);
 

	
 
	return (_grow_town_result == -2);
 
}
 

	
 
// Generate a random road block
 
// The probability of a straight road
 
// is somewhat higher than a curved.
 
/** Generate a random road block
 
 * The probability of a straight road
 
 * is somewhat higher than a curved. */
 
static RoadBits GenRandomRoadBits()
 
{
 
	uint32 r = Random();
 
@@ -800,8 +804,8 @@ static RoadBits GenRandomRoadBits()
 
	return (RoadBits)((1 << a) + (1 << b));
 
}
 

	
 
// Grow the town
 
// Returns true if a house was built, or no if the build failed.
 
/** Grow the town
 
 * @Return true if a house was built, or no if the build failed. */
 
static bool GrowTown(Town *t)
 
{
 
	TileIndex tile;
 
@@ -824,11 +828,11 @@ static bool GrowTown(Town *t)
 
		{ 0,  0}
 
	};
 

	
 
	// Current player is a town
 
	/* Current player is a town */
 
	old_player = _current_player;
 
	_current_player = OWNER_TOWN;
 

	
 
	// Find a road that we can base the construction on.
 
	/* Find a road that we can base the construction on. */
 
	tile = t->xy;
 
	for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
 
		if (GetAnyRoadTrackBits(tile) != 0) {
 
@@ -839,8 +843,8 @@ static bool GrowTown(Town *t)
 
		tile = TILE_ADD(tile, ToTileIndexDiff(*ptr));
 
	}
 

	
 
	// No road available, try to build a random road block by
 
	// clearing some land and then building a road there.
 
	/* No road available, try to build a random road block by
 
	 * clearing some land and then building a road there. */
 
	tile = t->xy;
 
	for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
 
		/* Only work with plain land that not already has a house */
 
@@ -890,11 +894,11 @@ static void UpdateTownRadius(Town *t)
 
		memcpy(t->radius, _town_radius_data[t->num_houses / 4], sizeof(t->radius));
 
	} else {
 
		int mass = t->num_houses / 8;
 
		// At least very roughly extrapolate. Empirical numbers dancing between
 
		// overwhelming by cottages and skyscrapers outskirts.
 
		/* At least very roughly extrapolate. Empirical numbers dancing between
 
		 * overwhelming by cottages and skyscrapers outskirts. */
 
		t->radius[0] = mass * mass;
 
		// Actually we are proportional to sqrt() but that's right because
 
		// we are covering an area.
 
		/* Actually we are proportional to sqrt() but that's right because
 
		 * we are covering an area. */
 
		t->radius[1] = mass * 7;
 
		t->radius[2] = 0;
 
		t->radius[3] = mass * 4;
 
@@ -926,12 +930,12 @@ restart:
 
		SetDParam(0, r);
 
		GetString(buf1, townnametype, lastof(buf1));
 

	
 
		// Check size and width
 
		/* Check size and width */
 
		if (strlen(buf1) >= 31 || GetStringBoundingBox(buf1).width > 130) continue;
 

	
 
		FOR_ALL_TOWNS(t2) {
 
			// We can't just compare the numbers since
 
			// several numbers may map to a single name.
 
			/* We can't just compare the numbers since
 
			 * several numbers may map to a single name. */
 
			SetDParam(0, t2->index);
 
			GetString(buf2, STR_TOWN, lastof(buf2));
 
			if (strcmp(buf1, buf2) == 0) {
 
@@ -954,7 +958,7 @@ static void DoCreateTown(Town *t, TileIn
 
{
 
	int x, i;
 

	
 
	// clear the town struct
 
	/* clear the town struct */
 
	i = t->index;
 
	memset(t, 0, sizeof(Town));
 
	t->index = i;
 
@@ -1046,6 +1050,7 @@ static Town *AllocateTown()
 
 * This obviously only works in the scenario editor. Function not removed
 
 * as it might be possible in the future to fund your own town :)
 
 * @param tile coordinates where town is built
 
 * @param flags type of operation
 
 * @param p1 size of the town (0 = random, 1 = small, 2 = medium, 3 = large)
 
 * @param p2 unused
 
 */
 
@@ -1059,28 +1064,28 @@ int32 CmdBuildTown(TileIndex tile, uint3
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_OTHER);
 

	
 
	// Check if too close to the edge of map
 
	/* Check if too close to the edge of map */
 
	if (DistanceFromEdge(tile) < 12)
 
		return_cmd_error(STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP);
 

	
 
	// Can only build on clear flat areas, possibly with trees.
 
	/* Can only build on clear flat areas, possibly with trees. */
 
	if ((!IsTileType(tile, MP_CLEAR) && !IsTileType(tile, MP_TREES)) || GetTileSlope(tile, NULL) != SLOPE_FLAT) {
 
		return_cmd_error(STR_0239_SITE_UNSUITABLE);
 
	}
 

	
 
	// Check distance to all other towns.
 
	/* Check distance to all other towns. */
 
	if (IsCloseToTown(tile, 20))
 
		return_cmd_error(STR_0238_TOO_CLOSE_TO_ANOTHER_TOWN);
 

	
 
	// Get a unique name for the town.
 
	/* Get a unique name for the town. */
 
	if (!CreateTownName(&townnameparts))
 
		return_cmd_error(STR_023A_TOO_MANY_TOWNS);
 

	
 
	// Allocate town struct
 
	/* Allocate town struct */
 
	t = AllocateTown();
 
	if (t == NULL) return_cmd_error(STR_023A_TOO_MANY_TOWNS);
 

	
 
	// Create the town
 
	/* Create the town */
 
	if (flags & DC_EXEC) {
 
		_generating_world = true;
 
		DoCreateTown(t, tile, townnameparts, p1);
 
@@ -1096,20 +1101,20 @@ Town *CreateRandomTown(uint attempts, ui
 
	uint32 townnameparts;
 

	
 
	do {
 
		// Generate a tile index not too close from the edge
 
		/* Generate a tile index not too close from the edge */
 
		tile = RandomTile();
 
		if (DistanceFromEdge(tile) < 20) continue;
 

	
 
		// Make sure the tile is plain
 
		/* Make sure the tile is plain */
 
		if (!IsTileType(tile, MP_CLEAR) || GetTileSlope(tile, NULL) != SLOPE_FLAT) continue;
 

	
 
		// Check not too close to a town
 
		/* Check not too close to a town */
 
		if (IsCloseToTown(tile, 20)) continue;
 

	
 
		// Get a unique name for the town.
 
		/* Get a unique name for the town. */
 
		if (!CreateTownName(&townnameparts)) break;
 

	
 
		// Allocate a town struct
 
		/* Allocate a town struct */
 
		t = AllocateTown();
 
		if (t == NULL) break;
 

	
 
@@ -1130,11 +1135,11 @@ bool GenerateTowns()
 

	
 
	do {
 
		IncreaseGeneratingWorldProgress(GWP_TOWN);
 
		// try 20 times to create a random-sized town for the first loop.
 
		/* try 20 times to create a random-sized town for the first loop. */
 
		if (CreateRandomTown(20, 0) != NULL) num++;
 
	} while (--n);
 

	
 
	// give it a last try, but now more aggressive
 
	/* give it a last try, but now more aggressive */
 
	if (num == 0 && CreateRandomTown(10000, 0) == NULL) {
 
		if (GetNumTowns() == 0) {
 
			/* XXX - can we handle that more gracefully? */
 
@@ -1223,10 +1228,10 @@ static void DoBuildTownHouse(Town *t, Ti
 
	uint oneof = 0;
 
	HouseSpec *hs;
 

	
 
	// Above snow?
 
	/* Above snow? */
 
	slope = GetTileSlope(tile, &z);
 

	
 
	// Get the town zone type
 
	/* Get the town zone type */
 
	{
 
		uint rad = GetTownRadiusGroup(t, tile);
 

	
 
@@ -1236,16 +1241,16 @@ static void DoBuildTownHouse(Town *t, Ti
 
		bitmask = (1 << rad) + (1 << (land + 12));
 
	}
 

	
 
	// bits 0-4 are used
 
	// bits 11-15 are used
 
	// bits 5-10 are not used.
 
	/* bits 0-4 are used
 
	 * bits 11-15 are used
 
	 * bits 5-10 are not used. */
 
	{
 
		HouseID houses[HOUSE_MAX];
 
		int num = 0;
 
		uint cumulative_probs[HOUSE_MAX];
 
		uint probability_max = 0;
 

	
 
		// Generate a list of all possible houses that can be built.
 
		/* Generate a list of all possible houses that can be built. */
 
		for (i = 0; i < HOUSE_MAX; i++) {
 
			hs = GetHouseSpecs(i);
 
			if ((~hs->building_availability & bitmask) == 0 && hs->enabled) {
 
@@ -1282,7 +1287,7 @@ static void DoBuildTownHouse(Town *t, Ti
 

	
 
			if (_cur_year < hs->min_date || _cur_year > hs->max_date) continue;
 

	
 
			// Special houses that there can be only one of.
 
			/* Special houses that there can be only one of. */
 
			if (hs->building_flags & BUILDING_IS_CHURCH) {
 
				SETBIT(oneof, TOWN_HAS_CHURCH);
 
			} else if (hs->building_flags & BUILDING_IS_STADIUM) {
 
@@ -1293,7 +1298,7 @@ static void DoBuildTownHouse(Town *t, Ti
 

	
 
			if (HASBITS(t->flags12 , oneof)) continue;
 

	
 
			// Make sure there is no slope?
 
			/* Make sure there is no slope? */
 
			if (hs->building_flags & TILE_NOT_SLOPED && slope != SLOPE_FLAT) continue;
 

	
 
			if (hs->building_flags & TILE_SIZE_2x2) {
 
@@ -1327,7 +1332,7 @@ static void DoBuildTownHouse(Town *t, Ti
 
	t->num_houses++;
 
	IncreaseBuildingCount(t, house);
 

	
 
	// Special houses that there can be only one of.
 
	/* Special houses that there can be only one of. */
 
	t->flags12 |= oneof;
 

	
 
	{
 
@@ -1379,7 +1384,7 @@ void ClearTownHouse(Town *t, TileIndex t
 

	
 
	assert(IsTileType(tile, MP_HOUSE));
 

	
 
	// need to align the tile to point to the upper left corner of the house
 
	/* need to align the tile to point to the upper left corner of the house */
 
	if (house >= 3) { // house id 0,1,2 MUST be single tile houses, or this code breaks.
 
		if (GetHouseSpecs(house-1)->building_flags & TILE_SIZE_2x1) {
 
			house--;
 
@@ -1398,7 +1403,7 @@ void ClearTownHouse(Town *t, TileIndex t
 

	
 
	hs = GetHouseSpecs(house);
 

	
 
	// Remove population from the town if the house is finished.
 
	/* Remove population from the town if the house is finished. */
 
	if (IsHouseCompleted(tile)) {
 
		ChangePopulation(t, -hs->population);
 
	}
 
@@ -1406,14 +1411,14 @@ void ClearTownHouse(Town *t, TileIndex t
 
	t->num_houses--;
 
	DecreaseBuildingCount(t, house);
 

	
 
	// Clear flags for houses that only may exist once/town.
 
	/* Clear flags for houses that only may exist once/town. */
 
	if (hs->building_flags & BUILDING_IS_CHURCH) {
 
		CLRBIT(t->flags12, TOWN_HAS_CHURCH);
 
	} else if (hs->building_flags & BUILDING_IS_STADIUM) {
 
		CLRBIT(t->flags12, TOWN_HAS_STADIUM);
 
	}
 

	
 
	// Do the actual clearing of tiles
 
	/* Do the actual clearing of tiles */
 
	eflags = hs->building_flags;
 
	DoClearTownHouseHelper(tile);
 
	if (eflags & BUILDING_2_TILES_X)   DoClearTownHouseHelper(tile + TileDiffXY(1, 0));
 
@@ -1423,6 +1428,7 @@ void ClearTownHouse(Town *t, TileIndex t
 

	
 
/** Rename a town (server-only).
 
 * @param tile unused
 
 * @param flags type of operation
 
 * @param p1 town ID to rename
 
 * @param p2 unused
 
 */
 
@@ -1452,7 +1458,7 @@ int32 CmdRenameTown(TileIndex tile, uint
 
	return 0;
 
}
 

	
 
// Called from GUI
 
/** Called from GUI */
 
void ExpandTown(Town *t)
 
{
 
	int amount, n;
 
@@ -1555,16 +1561,16 @@ static void TownActionBuildStatue(Town* 
 
	TileIndex tile = t->xy;
 

	
 
	if (CircularTileSearch(tile, 9, SearchTileForStatue, t->index))
 
		SETBIT(t->statues, _current_player); ///< Once found and built, "inform" the Town
 
		SETBIT(t->statues, _current_player); // Once found and built, "inform" the Town
 
}
 

	
 
static void TownActionFundBuildings(Town* t)
 
{
 
	// Build next tick
 
	/* Build next tick */
 
	t->grow_counter = 1;
 
	// If we were not already growing
 
	/* If we were not already growing */
 
	SETBIT(t->flags12, TOWN_IS_FUNDED);
 
	// And grow for 3 months
 
	/* And grow for 3 months */
 
	t->fund_buildings_months = 3;
 
}
 

	
 
@@ -1581,18 +1587,18 @@ static void TownActionBribe(Town* t)
 
	if (!RandomRange(15)) {
 
		Station *st;
 

	
 
		// set as unwanted for 6 months
 
		/* set as unwanted for 6 months */
 
		t->unwanted[_current_player] = 6;
 

	
 
		// set all close by station ratings to 0
 
		/* set all close by station ratings to 0 */
 
		FOR_ALL_STATIONS(st) {
 
			if (st->town == t && st->owner == _current_player) {
 
				for (CargoID i = 0; i < NUM_CARGO; i++) st->goods[i].rating = 0;
 
			}
 
		}
 

	
 
		// only show errormessage to the executing player. All errors are handled command.c
 
		// but this is special, because it can only 'fail' on a DC_EXEC
 
		/* only show errormessage to the executing player. All errors are handled command.c
 
		 * but this is special, because it can only 'fail' on a DC_EXEC */
 
		if (IsLocalPlayer()) ShowErrorMessage(STR_BRIBE_FAILED_2, STR_BRIBE_FAILED, 0, 0);
 

	
 
		/* decrease by a lot!
 
@@ -1625,6 +1631,7 @@ extern uint GetMaskOfTownActions(int *nu
 
 * This performs an action such as advertising, building a statue, funding buildings,
 
 * but also bribing the town-council
 
 * @param tile unused
 
 * @param flags type of operation
 
 * @param p1 town to do the action at
 
 * @param p2 action to perform, @see _town_action_proc for the list of available actions
 
 */
 
@@ -1658,7 +1665,7 @@ static void UpdateTownGrowRate(Town *t)
 
	byte m;
 
	Player *p;
 

	
 
	// Reset player ratings if they're low
 
	/* Reset player ratings if they're low */
 
	FOR_ALL_PLAYERS(p) {
 
		if (p->is_active && t->ratings[p->index] <= 200) {
 
			t->ratings[p->index] += 5;
 
@@ -1715,7 +1722,7 @@ static void UpdateTownGrowRate(Town *t)
 

	
 
static void UpdateTownAmounts(Town *t)
 
{
 
	// Using +1 here to prevent overflow and division by zero
 
	/* Using +1 here to prevent overflow and division by zero */
 
	t->pct_pass_transported = t->new_act_pass * 256 / (t->new_max_pass + 1);
 

	
 
	t->max_pass = t->new_max_pass; t->new_max_pass = 0;
 
@@ -1723,7 +1730,7 @@ static void UpdateTownAmounts(Town *t)
 
	t->act_food = t->new_act_food; t->new_act_food = 0;
 
	t->act_water = t->new_act_water; t->new_act_water = 0;
 

	
 
	// Using +1 here to prevent overflow and division by zero
 
	/* Using +1 here to prevent overflow and division by zero */
 
	t->pct_mail_transported = t->new_act_mail * 256 / (t->new_max_mail + 1);
 
	t->max_mail = t->new_max_mail; t->new_max_mail = 0;
 
	t->act_mail = t->new_act_mail; t->new_act_mail = 0;
 
@@ -1793,7 +1800,7 @@ void ChangeTownRating(Town *t, int add, 
 
{
 
	int rating;
 

	
 
	// if magic_bulldozer cheat is active, town doesn't penaltize for removing stuff
 
	/* if magic_bulldozer cheat is active, town doesn't penaltize for removing stuff */
 
	if (t == NULL ||
 
			!IsValidPlayer(_current_player) ||
 
			(_cheats.magic_bulldozer.value && add < 0)) {
 
@@ -1820,17 +1827,17 @@ 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
 
	/* ROAD_REMOVE, TUNNELBRIDGE_REMOVE, INDUSTRY_REMOVE */
 
	{  0, 128, 384}, ///< Permissive
 
	{ 48, 192, 480}, ///< Neutral
 
	{ 96, 384, 768}, ///< Hostile
 
};
 

	
 
bool CheckforTownRating(uint32 flags, Town *t, byte type)
 
{
 
	int modemod;
 

	
 
	// if magic_bulldozer cheat is active, town doesn't restrict your destructive actions
 
	/* if magic_bulldozer cheat is active, town doesn't restrict your destructive actions */
 
	if (t == NULL || !IsValidPlayer(_current_player) || _cheats.magic_bulldozer.value)
 
		return true;
 

	
 
@@ -1900,7 +1907,7 @@ extern const TileTypeProcs _tile_type_to
 
};
 

	
 

	
 
// Save and load of towns.
 
/** Save and load of towns. */
 
static const SaveLoad _town_desc[] = {
 
	SLE_CONDVAR(Town, xy,                    SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
 
	SLE_CONDVAR(Town, xy,                    SLE_UINT32,                 6, SL_MAX_VERSION),
 
@@ -1916,12 +1923,12 @@ static const SaveLoad _town_desc[] = {
 
	    SLE_VAR(Town, flags12,               SLE_UINT8),
 
	    SLE_VAR(Town, statues,               SLE_UINT8),
 

	
 
	// sort_index_obsolete was stored here in savegame format 0 - 1
 
	/* sort_index_obsolete was stored here in savegame format 0 - 1 */
 
	SLE_CONDNULL(1, 0, 1),
 

	
 
	    SLE_VAR(Town, have_ratings,          SLE_UINT8),
 
	    SLE_ARR(Town, ratings,               SLE_INT16, 8),
 
	// failed bribe attempts are stored since savegame format 4
 
	/* failed bribe attempts are stored since savegame format 4 */
 
	SLE_CONDARR(Town, unwanted,              SLE_INT8, 8, 4,SL_MAX_VERSION),
 

	
 
	SLE_CONDVAR(Town, max_pass,              SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
 
@@ -1958,7 +1965,7 @@ static const SaveLoad _town_desc[] = {
 

	
 
	    SLE_VAR(Town, exclusivity,           SLE_UINT8),
 
	    SLE_VAR(Town, exclusive_counter,     SLE_UINT8),
 
	// reserve extra space in savegame here. (currently 30 bytes)
 
	/* reserve extra space in savegame here. (currently 30 bytes) */
 
	SLE_CONDNULL(30, 2, SL_MAX_VERSION),
 

	
 
	SLE_END()
src/town_gui.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file town_gui.cpp */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "debug.h"
 
@@ -32,9 +34,9 @@ static const Widget _town_authority_widg
 
extern const byte _town_action_costs[8];
 

	
 
/** Get a list of available actions to do at a town.
 
 * @param *nump if not NULL add put the number of available actions in it
 
 * @param nump if not NULL add put the number of available actions in it
 
 * @param pid the player that is querying the town
 
 * @param *t the town that is queried
 
 * @param t the town that is queried
 
 * @return bitmasked value of enabled actions
 
 */
 
uint GetMaskOfTownActions(int *nump, PlayerID pid, const Town *t)
 
@@ -47,9 +49,9 @@ uint GetMaskOfTownActions(int *nump, Pla
 
	if (pid != PLAYER_SPECTATOR) {
 
		uint i;
 

	
 
		// bribe option enabled?
 
		/* bribe option enabled? */
 
		if (_patches.bribe) {
 
			// if unwanted, disable everything.
 
			/* if unwanted, disable everything. */
 
			if (t->unwanted[pid]) {
 
				avail_buttons = 0;
 
			} else if (t->ratings[pid] < RATING_BRIBE_MAXIMUM) {
 
@@ -57,7 +59,7 @@ uint GetMaskOfTownActions(int *nump, Pla
 
			}
 
		}
 

	
 
		// Things worth more than this are not shown
 
		/* Things worth more than this are not shown */
 
		avail = GetPlayer(pid)->player_money + _price.station_value * 200;
 
		ref = _price.build_industry >> 8;
 

	
 
@@ -119,7 +121,7 @@ static void TownAuthorityWndProc(Window 
 

	
 
			DrawString(2, 15, STR_2023_TRANSPORT_COMPANY_RATINGS, 0);
 

	
 
			// Draw list of players
 
			/* Draw list of players */
 
			y = 25;
 
			FOR_ALL_PLAYERS(p) {
 
				if (p->is_active && (HASBIT(t->have_ratings, p->index) || t->exclusivity == p->index)) {
 
@@ -150,7 +152,7 @@ static void TownAuthorityWndProc(Window 
 
			}
 
		}
 

	
 
		// Draw actions list
 
		/* Draw actions list */
 
		{
 
			int y = 107, i;
 
			int pos = w->vscroll.pos;
 
@@ -234,7 +236,7 @@ static void TownViewWndProc(Window *w, W
 

	
 
	switch (e->event) {
 
	case WE_PAINT:
 
		// disable renaming town in network games if you are not the server
 
		/* disable renaming town in network games if you are not the server */
 
		SetWindowWidgetDisabledState(w, 8, _networking && !_network_server);
 

	
 
		SetDParam(0, t->index);
 
@@ -365,7 +367,7 @@ static const Widget _town_directory_widg
 
};
 

	
 

	
 
// used to get a sorted list of the towns
 
/* used to get a sorted list of the towns */
 
static uint _num_town_sort;
 

	
 
static char _bufcache[64];
src/town_map.h
Show inline comments
 
@@ -127,7 +127,7 @@ static inline byte GetLiftPosition(TileI
 
/**
 
 * Set the position of the lift on this animated house
 
 * @param t the tile
 
 * @param pos from 0 to 36
 
 * @param pos position, from 0 to 36
 
 */
 
static inline void SetLiftPosition(TileIndex t, byte pos)
 
{
src/train.h
Show inline comments
 
/* $Id$ */
 

	
 
/** @file train.h */
 

	
 
#ifndef TRAIN_H
 
#define TRAIN_H
 

	
 
@@ -14,12 +16,12 @@
 
 */
 

	
 
enum TrainSubtype {
 
	Train_Front             = 0, // Leading engine of a train
 
	Train_Articulated_Part  = 1, // Articulated part of an engine
 
	Train_Wagon             = 2, // Wagon
 
	Train_Engine            = 3, // Engine, that can be front engines, but might be placed behind another engine
 
	Train_Free_Wagon        = 4, // First in a wagon chain (in depot)
 
	Train_Multiheaded       = 5, // Engine is a multiheaded
 
	Train_Front             = 0, ///< Leading engine of a train
 
	Train_Articulated_Part  = 1, ///< Articulated part of an engine
 
	Train_Wagon             = 2, ///< Wagon
 
	Train_Engine            = 3, ///< Engine, that can be front engines, but might be placed behind another engine
 
	Train_Free_Wagon        = 4, ///< First in a wagon chain (in depot)
 
	Train_Multiheaded       = 5, ///< Engine is a multiheaded
 
};
 

	
 

	
src/train_cmd.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file train_cmd.cpp */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "bridge_map.h"
 
@@ -105,24 +107,24 @@ static void TrainCargoChanged(Vehicle* v
 
	for (Vehicle *u = v; u != NULL; u = u->next) {
 
		uint32 vweight = GetCargo(u->cargo_type)->weight * u->cargo_count * FreightWagonMult(u->cargo_type) / 16;
 

	
 
		// Vehicle weight is not added for articulated parts.
 
		/* Vehicle weight is not added for articulated parts. */
 
		if (!IsArticulatedPart(u)) {
 
			// vehicle weight is the sum of the weight of the vehicle and the weight of its cargo
 
			/* vehicle weight is the sum of the weight of the vehicle and the weight of its cargo */
 
			vweight += RailVehInfo(u->engine_type)->weight;
 

	
 
			// powered wagons have extra weight added
 
			/* powered wagons have extra weight added */
 
			if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON))
 
				vweight += RailVehInfo(u->u.rail.first_engine)->pow_wag_weight;
 
		}
 

	
 
		// consist weight is the sum of the weight of all vehicles in the consist
 
		/* consist weight is the sum of the weight of all vehicles in the consist */
 
		weight += vweight;
 

	
 
		// store vehicle weight in cache
 
		/* store vehicle weight in cache */
 
		u->u.rail.cached_veh_weight = vweight;
 
	}
 

	
 
	// store consist weight in cache
 
	/* store consist weight in cache */
 
	v->u.rail.cached_weight = weight;
 

	
 
	/* Now update train power (tractive effort is dependent on weight) */
 
@@ -151,10 +153,10 @@ void TrainConsistChanged(Vehicle* v)
 
	for (Vehicle *u = v; u != NULL; u = u->next) {
 
		const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type);
 

	
 
		// Update the v->first cache. This is faster than having to brute force it later.
 
		/* Update the v->first cache. This is faster than having to brute force it later. */
 
		if (u->first == NULL) u->first = v;
 

	
 
		// update the 'first engine'
 
		/* update the 'first engine' */
 
		u->u.rail.first_engine = v == u ? INVALID_ENGINE : first_engine;
 
		u->u.rail.railtype = rvi_u->railtype;
 

	
 
@@ -164,13 +166,13 @@ void TrainConsistChanged(Vehicle* v)
 
			u->u.rail.cached_vis_effect = rvi_u->visual_effect;
 
		} else {
 
			if (IsTrainWagon(u) || IsArticulatedPart(u)) {
 
				// Wagons and articulated parts have no effect by default
 
				/* Wagons and articulated parts have no effect by default */
 
				u->u.rail.cached_vis_effect = 0x40;
 
			} else if (rvi_u->engclass == 0) {
 
				// Steam is offset by -4 units
 
				/* Steam is offset by -4 units */
 
				u->u.rail.cached_vis_effect = 4;
 
			} else {
 
				// Diesel fumes and sparks come from the centre
 
				/* Diesel fumes and sparks come from the centre */
 
				u->u.rail.cached_vis_effect = 8;
 
			}
 
		}
 
@@ -204,13 +206,13 @@ void TrainConsistChanged(Vehicle* v)
 
				u->u.rail.compatible_railtypes |= (1 << RAILTYPE_RAIL);
 
			}
 

	
 
			// max speed is the minimum of the speed limits of all vehicles in the consist
 
			/* max speed is the minimum of the speed limits of all vehicles in the consist */
 
			if ((rvi_u->railveh_type != RAILVEH_WAGON || _patches.wagon_speed_limits) &&
 
				rvi_u->max_speed != 0 && !UsesWagonOverride(u))
 
				max_speed = min(rvi_u->max_speed, max_speed);
 
		}
 

	
 
		// check the vehicle length (callback)
 
		/* check the vehicle length (callback) */
 
		uint16 veh_len = CALLBACK_FAILED;
 
		if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_VEHICLE_LENGTH)) {
 
			veh_len = GetVehicleCallback(CBID_TRAIN_VEHICLE_LENGTH, 0, 0, u->engine_type, u);
 
@@ -221,10 +223,10 @@ void TrainConsistChanged(Vehicle* v)
 
		v->u.rail.cached_total_length += u->u.rail.cached_veh_length;
 
	}
 

	
 
	// store consist weight/max speed in cache
 
	/* store consist weight/max speed in cache */
 
	v->u.rail.cached_max_speed = max_speed;
 

	
 
	// recalculate cached weights and power too (we do this *after* the rest, so it is known which wagons are powered and need extra weight added)
 
	/* recalculate cached weights and power too (we do this *after* the rest, so it is known which wagons are powered and need extra weight added) */
 
	TrainCargoChanged(v);
 
}
 

	
 
@@ -263,8 +265,8 @@ static bool TrainShouldStop(const Vehicl
 
	StationID sid = GetStationIndex(tile);
 

	
 
	assert(v->type == VEH_TRAIN);
 
	//When does a train drive through a station
 
	//first we deal with the "new nonstop handling"
 
	/* When does a train drive through a station
 
	 * first we deal with the "new nonstop handling" */
 
	if (_patches.new_nonstop && o->flags & OF_NON_STOP && sid == o->dest) {
 
		return false;
 
	}
 
@@ -278,14 +280,14 @@ static bool TrainShouldStop(const Vehicl
 
	return true;
 
}
 

	
 
//new acceleration
 
/** new acceleration*/
 
static int GetTrainAcceleration(Vehicle *v, bool mode)
 
{
 
	int max_speed = 2000;
 
	int speed = v->cur_speed * 10 / 16; //[mph]
 
	int curvecount[2] = {0, 0};
 

	
 
	//first find the curve speed limit
 
	/*first find the curve speed limit */
 
	int numcurve = 0;
 
	int sum = 0;
 
	int pos = 0;
 
@@ -309,7 +311,7 @@ static int GetTrainAcceleration(Vehicle 
 
			}
 
		}
 

	
 
		//if we have a 90 degree turn, fix the speed limit to 60
 
		/*if we have a 90 degree turn, fix the speed limit to 60 */
 
		if (_curve_neighbours90[dir][0] == ndir ||
 
				_curve_neighbours90[dir][1] == ndir) {
 
			max_speed = 61;
 
@@ -402,7 +404,7 @@ static int GetTrainAcceleration(Vehicle 
 
				break;
 
		}
 
	} else {
 
		//"kickoff" acceleration
 
		/* "kickoff" acceleration */
 
		force = (mode == AM_ACCEL && v->u.rail.railtype != RAILTYPE_MAGLEV) ? min(max_te, power) : power;
 
		force = max(force, (mass * 8) + resistance);
 
	}
 
@@ -521,7 +523,7 @@ static void AddArticulatedParts(Vehicle 
 
		bool flip_image = HASBIT(callback, 7);
 
		const RailVehicleInfo *rvi_artic = RailVehInfo(engine_type);
 

	
 
		// get common values from first engine
 
		/* get common values from first engine */
 
		u->direction = v->direction;
 
		u->owner = v->owner;
 
		u->tile = v->tile;
 
@@ -535,7 +537,7 @@ static void AddArticulatedParts(Vehicle 
 
		u->vehstatus = v->vehstatus & ~VS_STOPPED;
 
		u->u.rail.first_engine = v->engine_type;
 

	
 
		// get more settings from rail vehicle info
 
		/* get more settings from rail vehicle info */
 
		u->spritenum = rvi_artic->image_index;
 
		if (flip_image) u->spritenum++;
 
		u->cargo_type = rvi_artic->cargo_type;
 
@@ -645,7 +647,7 @@ static int32 CmdBuildRailWagon(EngineID 
 
	return value;
 
}
 

	
 
// Move all free vehicles in the depot to the train
 
/** Move all free vehicles in the depot to the train */
 
static void NormalizeTrainVehInDepot(const Vehicle* u)
 
{
 
	const Vehicle* v;
 
@@ -697,6 +699,7 @@ static void AddRearEngineToMultiheadedTr
 

	
 
/** Build a railroad vehicle.
 
 * @param tile tile of the depot where rail-vehicle is built
 
 * @param flags type of operation
 
 * @param p1 engine type id
 
 * @param p2 bit 0 when set, the train will get number 0, otherwise it will get a free number
 
 *           bit 1 prevents any free cars from being added to the train
 
@@ -874,7 +877,7 @@ inline bool CheckTrainIsInsideDepot(cons
 
 */
 
static Vehicle *UnlinkWagon(Vehicle *v, Vehicle *first)
 
{
 
	// unlinking the first vehicle of the chain?
 
	/* unlinking the first vehicle of the chain? */
 
	if (v == first) {
 
		v = GetNextVehicle(v);
 
		if (v == NULL) return NULL;
 
@@ -898,7 +901,7 @@ static Vehicle *FindGoodVehiclePos(const
 

	
 
	FOR_ALL_VEHICLES(dst) {
 
		if (dst->type == VEH_TRAIN && IsFreeWagon(dst) && dst->tile == tile) {
 
			// check so all vehicles in the line have the same engine.
 
			/* check so all vehicles in the line have the same engine. */
 
			Vehicle *v = dst;
 

	
 
			while (v->engine_type == eng) {
 
@@ -950,6 +953,7 @@ static void NormaliseTrainConsist(Vehicl
 

	
 
/** Move a rail vehicle around inside the depot.
 
 * @param tile unused
 
 * @param flags type of operation
 
 * @param p1 various bitstuffed elements
 
 * - p1 (bit  0 - 15) source vehicle index
 
 * - p1 (bit 16 - 31) what wagon to put the source wagon AFTER, XXX - INVALID_VEHICLE to make a new line
 
@@ -966,7 +970,7 @@ int32 CmdMoveRailVehicle(TileIndex tile,
 

	
 
	if (src->type != VEH_TRAIN || !CheckOwnership(src->owner)) return CMD_ERROR;
 

	
 
	// if nothing is selected as destination, try and find a matching vehicle to drag to.
 
	/* if nothing is selected as destination, try and find a matching vehicle to drag to. */
 
	Vehicle *dst;
 
	if (d == INVALID_VEHICLE) {
 
		dst = IsTrainEngine(src) ? NULL : FindGoodVehiclePos(src);
 
@@ -976,13 +980,13 @@ int32 CmdMoveRailVehicle(TileIndex tile,
 
		if (dst->type != VEH_TRAIN || !CheckOwnership(dst->owner)) return CMD_ERROR;
 
	}
 

	
 
	// if an articulated part is being handled, deal with its parent vehicle
 
	/* if an articulated part is being handled, deal with its parent vehicle */
 
	while (IsArticulatedPart(src)) src = GetPrevVehicleInChain(src);
 
	if (dst != NULL) {
 
		while (IsArticulatedPart(dst)) dst = GetPrevVehicleInChain(dst);
 
	}
 

	
 
	// don't move the same vehicle..
 
	/* don't move the same vehicle.. */
 
	if (src == dst) return 0;
 

	
 
	/* locate the head of the two chains */
 
@@ -991,7 +995,7 @@ int32 CmdMoveRailVehicle(TileIndex tile,
 
	if (dst != NULL) {
 
		dst_head = GetFirstVehicleInChain(dst);
 
		if (dst_head->tile != src_head->tile) return CMD_ERROR;
 
		// Now deal with articulated part of destination wagon
 
		/* Now deal with articulated part of destination wagon */
 
		dst = GetLastEnginePart(dst);
 
	} else {
 
		dst_head = NULL;
 
@@ -1004,7 +1008,7 @@ int32 CmdMoveRailVehicle(TileIndex tile,
 
			dst = GetPrevVehicleInChain(dst);
 
			/* Now if the vehicle we want to link to is the vehicle itself, drop out */
 
			if (dst == src) return CMD_ERROR;
 
			// if dst is NULL, it means that dst got a rear multiheaded engine as first engine. We can't use that
 
			/* if dst is NULL, it means that dst got a rear multiheaded engine as first engine. We can't use that */
 
			if (dst == NULL) return CMD_ERROR;
 
		} else {
 
			/* there are more units on this train, so we will add the wagon after the next one*/
 
@@ -1032,51 +1036,51 @@ int32 CmdMoveRailVehicle(TileIndex tile,
 

	
 
	if (IsMultiheaded(src) && !IsTrainEngine(src)) return_cmd_error(STR_REAR_ENGINE_FOLLOW_FRONT_ERROR);
 

	
 
	// when moving all wagons, we can't have the same src_head and dst_head
 
	/* when moving all wagons, we can't have the same src_head and dst_head */
 
	if (HASBIT(p2, 0) && src_head == dst_head) return 0;
 

	
 
	{
 
		int max_len = _patches.mammoth_trains ? 100 : 9;
 

	
 
		// check if all vehicles in the source train are stopped inside a depot.
 
		/* check if all vehicles in the source train are stopped inside a depot. */
 
		int src_len = CheckTrainStoppedInDepot(src_head);
 
		if (src_len < 0) return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
 

	
 
		// check the destination row if the source and destination aren't the same.
 
		/* check the destination row if the source and destination aren't the same. */
 
		if (src_head != dst_head) {
 
			int dst_len = 0;
 

	
 
			if (dst_head != NULL) {
 
				// check if all vehicles in the dest train are stopped.
 
				/* check if all vehicles in the dest train are stopped. */
 
				dst_len = CheckTrainStoppedInDepot(dst_head);
 
				if (dst_len < 0) return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
 
			}
 

	
 
			// We are moving between rows, so only count the wagons from the source
 
			// row that are being moved.
 
			/* We are moving between rows, so only count the wagons from the source
 
			 * row that are being moved. */
 
			if (HASBIT(p2, 0)) {
 
				const Vehicle *u;
 
				for (u = src_head; u != src && u != NULL; u = GetNextVehicle(u))
 
					src_len--;
 
			} else {
 
				// If moving only one vehicle, just count that.
 
				/* If moving only one vehicle, just count that. */
 
				src_len = 1;
 
			}
 

	
 
			if (src_len + dst_len > max_len) {
 
				// Abort if we're adding too many wagons to a train.
 
				/* Abort if we're adding too many wagons to a train. */
 
				if (dst_head != NULL && IsFrontEngine(dst_head)) return_cmd_error(STR_8819_TRAIN_TOO_LONG);
 
				// Abort if we're making a train on a new row.
 
				/* Abort if we're making a train on a new row. */
 
				if (dst_head == NULL && IsTrainEngine(src)) return_cmd_error(STR_8819_TRAIN_TOO_LONG);
 
			}
 
		} else {
 
			// Abort if we're creating a new train on an existing row.
 
			/* Abort if we're creating a new train on an existing row. */
 
			if (src_len > max_len && src == src_head && IsTrainEngine(GetNextVehicle(src_head)))
 
				return_cmd_error(STR_8819_TRAIN_TOO_LONG);
 
		}
 
	}
 

	
 
	// moving a loco to a new line?, then we need to assign a unitnumber.
 
	/* moving a loco to a new line?, then we need to assign a unitnumber. */
 
	if (dst == NULL && !IsFrontEngine(src) && IsTrainEngine(src)) {
 
		UnitID unit_num = GetFreeUnitNumber(VEH_TRAIN);
 
		if (unit_num > _patches.max_trains)
 
@@ -1104,7 +1108,7 @@ int32 CmdMoveRailVehicle(TileIndex tile,
 
		for (Vehicle *u = dst_head; u != NULL; u = u->next) u->first = NULL;
 

	
 
		if (HASBIT(p2, 0)) {
 
			// unlink ALL wagons
 
			/* unlink ALL wagons */
 
			if (src != src_head) {
 
				Vehicle *v = src_head;
 
				while (GetNextVehicle(v) != src) v = GetNextVehicle(v);
 
@@ -1114,9 +1118,9 @@ int32 CmdMoveRailVehicle(TileIndex tile,
 
				src_head = NULL;
 
			}
 
		} else {
 
			// if moving within the same chain, dont use dst_head as it may get invalidated
 
			/* if moving within the same chain, dont use dst_head as it may get invalidated */
 
			if (src_head == dst_head) dst_head = NULL;
 
			// unlink single wagon from linked list
 
			/* unlink single wagon from linked list */
 
			src_head = UnlinkWagon(src, src_head);
 
			GetLastEnginePart(src)->next = NULL;
 
		}
 
@@ -1125,10 +1129,10 @@ int32 CmdMoveRailVehicle(TileIndex tile,
 
			/* We make a new line in the depot, so we know already that we invalidate the window data */
 
			InvalidateWindowData(WC_VEHICLE_DEPOT, src->tile);
 

	
 
			// move the train to an empty line. for locomotives, we set the type to TS_Front. for wagons, 4.
 
			/* move the train to an empty line. for locomotives, we set the type to TS_Front. for wagons, 4. */
 
			if (IsTrainEngine(src)) {
 
				if (!IsFrontEngine(src)) {
 
					// setting the type to 0 also involves setting up the orders field.
 
					/* setting the type to 0 also involves setting up the orders field. */
 
					SetFrontEngine(src);
 
					assert(src->orders == NULL);
 
					src->num_orders = 0;
 
@@ -1139,7 +1143,7 @@ int32 CmdMoveRailVehicle(TileIndex tile,
 
			dst_head = src;
 
		} else {
 
			if (IsFrontEngine(src)) {
 
				// the vehicle was previously a loco. need to free the order list and delete vehicle windows etc.
 
				/* the vehicle was previously a loco. need to free the order list and delete vehicle windows etc. */
 
				DeleteWindowById(WC_VEHICLE_VIEW, src->index);
 
				DeleteVehicleOrders(src);
 
			}
 
@@ -1151,7 +1155,7 @@ int32 CmdMoveRailVehicle(TileIndex tile,
 
				src->unitnumber = 0; // doesn't occupy a unitnumber anymore.
 
			}
 

	
 
			// link in the wagon(s) in the chain.
 
			/* link in the wagon(s) in the chain. */
 
			{
 
				Vehicle *v;
 

	
 
@@ -1165,7 +1169,7 @@ int32 CmdMoveRailVehicle(TileIndex tile,
 
				src_head = src_head->next;
 
			}
 
			AddWagonToConsist(src->u.rail.other_multiheaded_part, src);
 
			// previous line set the front engine to the old front. We need to clear that
 
			/* previous line set the front engine to the old front. We need to clear that */
 
			src->u.rail.other_multiheaded_part->first = NULL;
 
		}
 

	
 
@@ -1184,7 +1188,7 @@ int32 CmdMoveRailVehicle(TileIndex tile,
 
			}
 
			if (engine != NULL && engine->u.rail.other_multiheaded_part != NULL) {
 
				AddWagonToConsist(engine->u.rail.other_multiheaded_part, engine);
 
				// previous line set the front engine to the old front. We need to clear that
 
				/* previous line set the front engine to the old front. We need to clear that */
 
				engine->u.rail.other_multiheaded_part->first = NULL;
 
			}
 
		}
 
@@ -1233,6 +1237,7 @@ int32 CmdMoveRailVehicle(TileIndex tile,
 

	
 
/** Start/Stop a train.
 
 * @param tile unused
 
 * @param flags type of operation
 
 * @param p1 train to start/stop
 
 * @param p2 unused
 
 */
 
@@ -1269,6 +1274,7 @@ int32 CmdStartStopTrain(TileIndex tile, 
 

	
 
/** Sell a (single) train wagon/engine.
 
 * @param tile unused
 
 * @param flags type of operation
 
 * @param p1 the wagon/engine index
 
 * @param p2 the selling mode
 
 * - p2 = 0: only sell the single dragged wagon/engine (and any belonging rear-engines)
 
@@ -1290,7 +1296,7 @@ int32 CmdSellRailWagon(TileIndex tile, u
 
	while (IsArticulatedPart(v)) v = GetPrevVehicleInChain(v);
 
	Vehicle *first = GetFirstVehicleInChain(v);
 

	
 
	// make sure the vehicle is stopped in the depot
 
	/* make sure the vehicle is stopped in the depot */
 
	if (CheckTrainStoppedInDepot(first) < 0) {
 
		return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
 
	}
 
@@ -1596,8 +1602,8 @@ static void AdvanceWagons(Vehicle *v, bo
 
	uint length = CountVehiclesInChain(v);
 

	
 
	while (length > 2) {
 
		// find pairwise matching wagon
 
		// start<>end, start+1<>end-1, ...
 
		/* find pairwise matching wagon
 
		 * start<>end, start+1<>end-1, ... */
 
		Vehicle *last = first;
 
		for (uint i = length - 3; i > 0; i--) last = last->next;
 

	
 
@@ -1605,7 +1611,7 @@ static void AdvanceWagons(Vehicle *v, bo
 
		if (before) differential *= -1;
 

	
 
		if (differential > 0) {
 
			// disconnect last car to make sure only this subset moves
 
			/* disconnect last car to make sure only this subset moves */
 
			Vehicle *tempnext = last->next;
 
			last->next = NULL;
 

	
 
@@ -1643,7 +1649,7 @@ static void ReverseTrainDirection(Vehicl
 
		DisableTrainCrossing(tile);
 
	}
 

	
 
	// count number of vehicles
 
	/* count number of vehicles */
 
	int r = -1;
 
	const Vehicle *u = v;
 
	do r++; while ( (u = u->next) != NULL );
 
@@ -1667,6 +1673,7 @@ static void ReverseTrainDirection(Vehicl
 

	
 
/** Reverse train.
 
 * @param tile unused
 
 * @param flags type of operation
 
 * @param p1 train to reverse
 
 * @param p2 if true, reverse a unit in a train (needs to be in a depot)
 
 */
 
@@ -1679,14 +1686,14 @@ int32 CmdReverseTrainDirection(TileIndex
 
	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (p2) {
 
		// turn a single unit around
 
		/* turn a single unit around */
 

	
 
		if (IsMultiheaded(v) || HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_ARTIC_ENGINE)) {
 
			return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT);
 
		}
 

	
 
		Vehicle *front = GetFirstVehicleInChain(v);
 
		// make sure the vehicle is stopped in the depot
 
		/* make sure the vehicle is stopped in the depot */
 
		if (CheckTrainStoppedInDepot(front) < 0) {
 
			return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
 
		}
 
@@ -1697,7 +1704,7 @@ int32 CmdReverseTrainDirection(TileIndex
 
			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
		}
 
	} else {
 
		//turn the whole train around
 
		/*turn the whole train around */
 
		if (v->u.rail.crash_anim_pos != 0 || v->breakdown_ctr != 0) return CMD_ERROR;
 

	
 
		if (flags & DC_EXEC) {
 
@@ -1715,6 +1722,7 @@ int32 CmdReverseTrainDirection(TileIndex
 

	
 
/** Force a train through a red signal
 
 * @param tile unused
 
 * @param flags type of operation
 
 * @param p1 train to ignore the red signal
 
 * @param p2 unused
 
 */
 
@@ -1733,6 +1741,7 @@ int32 CmdForceTrainProceed(TileIndex til
 

	
 
/** Refits a train to the specified cargo type.
 
 * @param tile unused
 
 * @param flags type of operation
 
 * @param p1 vehicle ID of the train to refit
 
 * param p2 various bitstuffed elements
 
 * - p2 = (bit 0-7) - the new cargo type to refit to
 
@@ -1854,8 +1863,8 @@ static bool NtpCallbFindDepot(TileIndex 
 
	return false;
 
}
 

	
 
// returns the tile of a depot to goto to. The given vehicle must not be
 
// crashed!
 
/** returns the tile of a depot to goto to. The given vehicle must not be
 
 * crashed! */
 
static TrainFindDepotData FindClosestTrainDepot(Vehicle *v, int max_distance)
 
{
 
	assert(!(v->vehstatus & VS_CRASHED));
 
@@ -1893,7 +1902,7 @@ static TrainFindDepotData FindClosestTra
 
			if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) tfdd.reverse = true;
 
		}
 
	} else {
 
		// search in the forward direction first.
 
		/* search in the forward direction first. */
 
		DiagDirection i = DirToDiagDir(v->direction);
 
		if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) {
 
			i = ChangeDiagDir(i, DIAGDIRDIFF_90LEFT);
 
@@ -1901,7 +1910,7 @@ static TrainFindDepotData FindClosestTra
 
		NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
 
		if (tfdd.best_length == (uint)-1){
 
			tfdd.reverse = true;
 
			// search in backwards direction
 
			/* search in backwards direction */
 
			i = ReverseDiagDir(DirToDiagDir(v->direction));
 
			if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) {
 
				i = ChangeDiagDir(i, DIAGDIRDIFF_90LEFT);
 
@@ -1915,6 +1924,7 @@ static TrainFindDepotData FindClosestTra
 

	
 
/** Send a train to a depot
 
 * @param tile unused
 
 * @param flags type of operation
 
 * @param p1 train to send to the depot
 
 * @param p2 various bitmasked elements
 
 * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
 
@@ -2010,7 +2020,7 @@ static void HandleLocomotiveSmokeCloud(c
 
		byte effect_type = GB(v->u.rail.cached_vis_effect, 4, 2);
 
		bool disable_effect = HASBIT(v->u.rail.cached_vis_effect, 6);
 

	
 
		// no smoke?
 
		/* no smoke? */
 
		if ((rvi->railveh_type == RAILVEH_WAGON && effect_type == 0) ||
 
				disable_effect ||
 
				rvi->railtype > RAILTYPE_ELECTRIC ||
 
@@ -2018,14 +2028,14 @@ static void HandleLocomotiveSmokeCloud(c
 
			continue;
 
		}
 

	
 
		// No smoke in depots or tunnels
 
		/* No smoke in depots or tunnels */
 
		if (IsTileDepotType(v->tile, TRANSPORT_RAIL) || IsTunnelTile(v->tile)) continue;
 

	
 
		// No sparks for electric vehicles on nonelectrified tracks
 
		/* No sparks for electric vehicles on nonelectrified tracks */
 
		if (!HasPowerOnRail(v->u.rail.railtype, GetTileRailType(v->tile))) continue;
 

	
 
		if (effect_type == 0) {
 
			// Use default effect type for engine class.
 
			/* Use default effect type for engine class. */
 
			effect_type = rvi->engclass;
 
		} else {
 
			effect_type--;
 
@@ -2041,7 +2051,7 @@ static void HandleLocomotiveSmokeCloud(c
 

	
 
		switch (effect_type) {
 
		case 0:
 
			// steam smoke.
 
			/* steam smoke. */
 
			if (GB(v->tick_counter, 0, 4) == 0) {
 
				CreateEffectVehicleRel(v, x, y, 10, EV_STEAM_SMOKE);
 
				sound = true;
 
@@ -2049,7 +2059,7 @@ static void HandleLocomotiveSmokeCloud(c
 
			break;
 

	
 
		case 1:
 
			// diesel smoke
 
			/* diesel smoke */
 
			if (u->cur_speed <= 40 && CHANCE16(15, 128)) {
 
				CreateEffectVehicleRel(v, 0, 0, 10, EV_DIESEL_SMOKE);
 
				sound = true;
 
@@ -2057,7 +2067,7 @@ static void HandleLocomotiveSmokeCloud(c
 
			break;
 

	
 
		case 2:
 
			// blue spark
 
			/* blue spark */
 
			if (GB(v->tick_counter, 0, 2) == 0 && CHANCE16(1, 45)) {
 
				CreateEffectVehicleRel(v, 0, 0, 10, EV_ELECTRIC_SPARK);
 
				sound = true;
 
@@ -2094,12 +2104,12 @@ static void TrainPlayLeaveStationSound(c
 

	
 
static bool CheckTrainStayInDepot(Vehicle *v)
 
{
 
	// bail out if not all wagons are in the same depot or not in a depot at all
 
	/* bail out if not all wagons are in the same depot or not in a depot at all */
 
	for (const Vehicle *u = v; u != NULL; u = u->next) {
 
		if (u->u.rail.track != TRACK_BIT_DEPOT || u->tile != v->tile) return false;
 
	}
 

	
 
	// if the train got no power, then keep it in the depot
 
	/* if the train got no power, then keep it in the depot */
 
	if (v->u.rail.cached_power == 0) {
 
		v->vehstatus |= VS_STOPPED;
 
		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
 
@@ -2151,10 +2161,10 @@ struct TrainTrackFollowerData {
 

	
 
static bool NtpCallbFindStation(TileIndex tile, TrainTrackFollowerData *ttfd, Trackdir track, uint length)
 
{
 
	// heading for nowhere?
 
	/* heading for nowhere? */
 
	if (ttfd->dest_coords == 0) return false;
 

	
 
	// did we reach the final station?
 
	/* did we reach the final station? */
 
	if ((ttfd->station_index == INVALID_STATION && tile == ttfd->dest_coords) || (
 
				IsTileType(tile, MP_STATION) &&
 
				IsRailwayStation(tile) &&
 
@@ -2163,12 +2173,13 @@ static bool NtpCallbFindStation(TileInde
 
		/* We do not check for dest_coords if we have a station_index,
 
		 * because in that case the dest_coords are just an
 
		 * approximation of where the station is */
 
		// found station
 

	
 
		/* found station */
 
		ttfd->best_track = track;
 
		ttfd->best_bird_dist = 0;
 
		return true;
 
	} else {
 
		// didn't find station, keep track of the best path so far.
 
		/* didn't find station, keep track of the best path so far. */
 
		uint dist = DistanceManhattan(tile, ttfd->dest_coords);
 
		if (dist < ttfd->best_bird_dist) {
 
			ttfd->best_bird_dist = dist;
 
@@ -2205,12 +2216,12 @@ static const uint32 _reachable_tracks[4]
 
};
 

	
 
static const byte _search_directions[6][4] = {
 
	{ 0, 9, 2, 9 }, // track 1
 
	{ 9, 1, 9, 3 }, // track 2
 
	{ 9, 0, 3, 9 }, // track upper
 
	{ 1, 9, 9, 2 }, // track lower
 
	{ 3, 2, 9, 9 }, // track left
 
	{ 9, 9, 1, 0 }, // track right
 
	{ 0, 9, 2, 9 }, ///< track 1
 
	{ 9, 1, 9, 3 }, ///< track 2
 
	{ 9, 0, 3, 9 }, ///< track upper
 
	{ 1, 9, 9, 2 }, ///< track lower
 
	{ 3, 2, 9, 9 }, ///< track left
 
	{ 9, 9, 1, 0 }, ///< track right
 
};
 

	
 
static const byte _pick_track_table[6] = {1, 3, 2, 2, 0, 0};
 
@@ -2219,7 +2230,7 @@ static const byte _pick_track_table[6] =
 
static Track ChooseTrainTrack(Vehicle* v, TileIndex tile, DiagDirection enterdir, TrackBits tracks)
 
{
 
	Track best_track;
 
	// pathfinders are able to tell that route was only 'guessed'
 
	/* pathfinders are able to tell that route was only 'guessed' */
 
	bool path_not_found = false;
 

	
 
#ifdef PF_BENCHMARK
 
@@ -2250,9 +2261,9 @@ static Track ChooseTrainTrack(Vehicle* v
 
		NPFFoundTargetData ftd = NPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes);
 

	
 
		if (ftd.best_trackdir == 0xff) {
 
			/* We are already at our target. Just do something */
 
			//TODO: maybe display error?
 
			//TODO: go straight ahead if possible?
 
			/* We are already at our target. Just do something
 
			 * @todo maybe display error?
 
			 * @todo: go straight ahead if possible? */
 
			best_track = FindFirstTrack(tracks);
 
		} else {
 
			/* If ftd.best_bird_dist is 0, we found our target and ftd.best_trackdir contains
 
@@ -2280,11 +2291,11 @@ static Track ChooseTrainTrack(Vehicle* v
 
		NewTrainPathfind(tile - TileOffsByDiagDir(enterdir), v->dest_tile,
 
			v->u.rail.compatible_railtypes, enterdir, (NTPEnumProc*)NtpCallbFindStation, &fd);
 

	
 
		// check whether the path was found or only 'guessed'
 
		/* check whether the path was found or only 'guessed' */
 
		if (fd.best_bird_dist != 0) path_not_found = true;
 

	
 
		if (fd.best_track == 0xff) {
 
			// blaha
 
			/* blaha */
 
			best_track = FindFirstTrack(tracks);
 
		} else {
 
			best_track = TrackdirToTrack(fd.best_track);
 
@@ -2293,13 +2304,13 @@ static Track ChooseTrainTrack(Vehicle* v
 
		int time = NpfEndInterval(perf);
 
		DEBUG(yapf, 4, "[NTPT] %d us - %d rounds - %d open - %d closed -- ", time, 0, 0, 0);
 
	}
 
	// handle "path not found" state
 
	/* handle "path not found" state */
 
	if (path_not_found) {
 
		// PF didn't find the route
 
		/* PF didn't find the route */
 
		if (!HASBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) {
 
			// it is first time the problem occurred, set the "path not found" flag
 
			/* it is first time the problem occurred, set the "path not found" flag */
 
			SETBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION);
 
			// and notify user about the event
 
			/* and notify user about the event */
 
			if (_patches.lost_train_warn && v->owner == _local_player) {
 
				SetDParam(0, v->unitnumber);
 
				AddNewsItem(
 
@@ -2310,11 +2321,11 @@ static Track ChooseTrainTrack(Vehicle* v
 
			}
 
		}
 
	} else {
 
		// route found, is the train marked with "path not found" flag?
 
		/* route found, is the train marked with "path not found" flag? */
 
		if (HASBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) {
 
			// clear the flag as the PF's problem was solved
 
			/* clear the flag as the PF's problem was solved */
 
			CLRBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION);
 
			// can we also delete the "News" item somehow?
 
			/* can we also delete the "News" item somehow? */
 
		}
 
	}
 

	
 
@@ -2440,14 +2451,14 @@ static bool ProcessTrainOrder(Vehicle *v
 
		default: break;
 
	}
 

	
 
	// check if we've reached the waypoint?
 
	/* check if we've reached the waypoint? */
 
	bool at_waypoint = false;
 
	if (v->current_order.type == OT_GOTO_WAYPOINT && v->tile == v->dest_tile) {
 
		v->cur_order_index++;
 
		at_waypoint = true;
 
	}
 

	
 
	// check if we've reached a non-stop station while TTDPatch nonstop is enabled..
 
	/* check if we've reached a non-stop station while TTDPatch nonstop is enabled.. */
 
	if (_patches.new_nonstop &&
 
			v->current_order.flags & OF_NON_STOP &&
 
			IsTileType(v->tile, MP_STATION) &&
 
@@ -2455,25 +2466,25 @@ static bool ProcessTrainOrder(Vehicle *v
 
		v->cur_order_index++;
 
	}
 

	
 
	// Get the current order
 
	/* Get the current order */
 
	if (v->cur_order_index >= v->num_orders) v->cur_order_index = 0;
 

	
 
	const Order *order = GetVehicleOrder(v, v->cur_order_index);
 

	
 
	// If no order, do nothing.
 
	/* If no order, do nothing. */
 
	if (order == NULL) {
 
		v->current_order.Free();
 
		v->dest_tile = 0;
 
		return false;
 
	}
 

	
 
	// If it is unchanged, keep it.
 
	/* If it is unchanged, keep it. */
 
	if (order->type  == v->current_order.type &&
 
			order->flags == v->current_order.flags &&
 
			order->dest  == v->current_order.dest)
 
		return false;
 

	
 
	// Otherwise set it, and determine the destination tile.
 
	/* Otherwise set it, and determine the destination tile. */
 
	v->current_order = *order;
 

	
 
	v->dest_tile = 0;
 
@@ -2516,7 +2527,7 @@ static void HandleTrainLoading(Vehicle *
 
		case OT_LOADING: {
 
			if (mode) return;
 

	
 
			// don't mark the train as lost if we're loading on the final station.
 
			/* don't mark the train as lost if we're loading on the final station. */
 
			if (v->current_order.flags & OF_NON_STOP) {
 
				v->u.rail.days_since_order_progr = 0;
 
			}
 
@@ -2527,13 +2538,13 @@ static void HandleTrainLoading(Vehicle *
 
						v->current_order.flags & OF_FULL_LOAD ||
 
						(_patches.gradual_loading && !HASBIT(v->vehicle_flags, VF_LOADING_FINISHED))
 
					)) {
 
				v->u.rail.days_since_order_progr = 0; /* Prevent a train lost message for full loading trains */
 
				v->u.rail.days_since_order_progr = 0; // Prevent a train lost message for full loading trains
 
				SET_EXPENSES_TYPE(EXPENSES_TRAIN_INC);
 
				if (LoadUnloadVehicle(v, false)) {
 
					InvalidateWindow(WC_TRAINS_LIST, v->owner);
 
					MarkTrainDirty(v);
 

	
 
					// need to update acceleration and cached values since the goods on the train changed.
 
					/* need to update acceleration and cached values since the goods on the train changed. */
 
					TrainCargoChanged(v);
 
					UpdateTrainAcceleration(v);
 
				}
 
@@ -2545,7 +2556,7 @@ static void HandleTrainLoading(Vehicle *
 
			Order b = v->current_order;
 
			v->LeaveStation();
 

	
 
			// If this was not the final order, don't remove it from the list.
 
			/* If this was not the final order, don't remove it from the list. */
 
			if (!(b.flags & OF_NON_STOP)) return;
 
			break;
 
		}
 
@@ -2614,16 +2625,16 @@ static void TrainEnterStation(Vehicle *v
 
		);
 
	}
 

	
 
	// Did we reach the final destination?
 
	/* Did we reach the final destination? */
 
	if (v->current_order.type == OT_GOTO_STATION &&
 
			v->current_order.dest == station) {
 
		// Yeah, keep the load/unload flags
 
		// Non Stop now means if the order should be increased.
 
		/* Yeah, keep the load/unload flags
 
		 * Non Stop now means if the order should be increased. */
 
		v->BeginLoading();
 
		v->current_order.flags &= OF_FULL_LOAD | OF_UNLOAD | OF_TRANSFER;
 
		v->current_order.flags |= OF_NON_STOP;
 
	} else {
 
		// No, just do a simple load
 
		/* No, just do a simple load */
 
		v->BeginLoading();
 
		v->current_order.flags = 0;
 
	}
 
@@ -2641,7 +2652,7 @@ static void TrainEnterStation(Vehicle *v
 

	
 
static byte AfterSetTrainPos(Vehicle *v, bool new_tile)
 
{
 
	// need this hint so it returns the right z coordinate on bridges.
 
	/* need this hint so it returns the right z coordinate on bridges. */
 
	byte new_z = GetSlopeZ(v->x_pos, v->y_pos);
 

	
 
	byte old_z = v->z_pos;
 
@@ -2654,7 +2665,7 @@ static byte AfterSetTrainPos(Vehicle *v,
 
		if (new_z != old_z) {
 
			TileIndex tile = TileVirtXY(v->x_pos, v->y_pos);
 

	
 
			// XXX workaround, whole UP/DOWN detection needs overhaul
 
			/* XXX workaround, whole UP/DOWN detection needs overhaul */
 
			if (!IsTunnelTile(tile)) {
 
				SETBIT(v->u.rail.flags, (new_z > old_z) ? VRF_GOINGUP : VRF_GOINGDOWN);
 
			}
 
@@ -2727,13 +2738,13 @@ struct RailtypeSlowdownParams {
 

	
 
static const RailtypeSlowdownParams _railtype_slowdown[] = {
 
	// normal accel
 
	{256 / 4, 256 / 2, 256 / 4, 2}, // normal
 
	{256 / 4, 256 / 2, 256 / 4, 2}, // electrified
 
	{256 / 4, 256 / 2, 256 / 4, 2}, // monorail
 
	{0,       256 / 2, 256 / 4, 2}, // maglev
 
	{256 / 4, 256 / 2, 256 / 4, 2}, ///< normal
 
	{256 / 4, 256 / 2, 256 / 4, 2}, ///< electrified
 
	{256 / 4, 256 / 2, 256 / 4, 2}, ///< monorail
 
	{0,       256 / 2, 256 / 4, 2}, ///< maglev
 
};
 

	
 
/* Modify the speed of the vehicle due to a turn */
 
/** Modify the speed of the vehicle due to a turn */
 
static void AffectSpeedByDirChange(Vehicle* v, Direction new_dir)
 
{
 
	if (_patches.realistic_acceleration) return;
 
@@ -2745,7 +2756,7 @@ static void AffectSpeedByDirChange(Vehic
 
	v->cur_speed -= (diff == DIRDIFF_45RIGHT || diff == DIRDIFF_45LEFT ? rsp->small_turn : rsp->large_turn) * v->cur_speed >> 8;
 
}
 

	
 
/* Modify the speed of the vehicle due to a change in altitude */
 
/** Modify the speed of the vehicle due to a change in altitude */
 
static void AffectSpeedByZChange(Vehicle *v, byte old_z)
 
{
 
	if (old_z == v->z_pos || _patches.realistic_acceleration) return;
 
@@ -2820,7 +2831,7 @@ static uint CountPassengersInTrain(const
 
	return num;
 
}
 

	
 
/*
 
/**
 
 * Checks whether the specified train has a collision with another vehicle. If
 
 * so, destroys this vehicle, and the other vehicle if its subtype has TS_Front.
 
 * Reports the incident in a flashy news item, modifies station ratings and
 
@@ -2848,10 +2859,10 @@ static void CheckTrainCollision(Vehicle 
 
			(v->u.rail.track == TRACK_BIT_WORMHOLE && (v->direction & 2) != (realcoll->direction & 2)))
 
		return;
 

	
 
	//two drivers + passangers killed in train v
 
	/* two drivers + passangers killed in train v */
 
	uint num = 2 + CountPassengersInTrain(v);
 
	if (!(coll->vehstatus & VS_CRASHED))
 
		//two drivers + passangers killed in train coll (if it was not crashed already)
 
		/* two drivers + passangers killed in train coll (if it was not crashed already) */
 
		num += 2 + CountPassengersInTrain(coll);
 

	
 
	SetVehicleCrashed(v);
 
@@ -2959,8 +2970,8 @@ static void TrainController(Vehicle *v, 
 

	
 
					/* Check if it's a red signal and that force proceed is not clicked. */
 
					if ((tracks >> 16) & chosen_track && v->u.rail.force_proceed == 0) {
 
						// In front of a red signal
 
						/* find the first set bit in ts. need to do it in 2 steps, since
 
						/* In front of a red signal
 
						 * find the first set bit in ts. need to do it in 2 steps, since
 
						 * FIND_FIRST_BIT only handles 6 bits at a time. */
 
						Trackdir i = FindFirstTrackdir((TrackdirBits)(uint16)ts);
 

	
 
@@ -3300,7 +3311,7 @@ static bool TrainCheckIfLineEnds(Vehicle
 
			return false;
 
		}
 
		if ((ts &= (ts >> 16)) == 0) {
 
			// make a rail/road crossing red
 
			/* make a rail/road crossing red */
 
			if (IsLevelCrossingTile(tile)) {
 
				if (!IsCrossingBarred(tile)) {
 
					BarCrossing(tile);
 
@@ -3316,7 +3327,7 @@ static bool TrainCheckIfLineEnds(Vehicle
 
		return false;
 
	}
 

	
 
	// slow down
 
	/* slow down */
 
	v->vehstatus |= VS_TRAIN_SLOWING;
 
	uint16 break_speed = _breakdown_speeds[x & 0xF];
 
	if (!(v->direction & 1)) break_speed >>= 1;
 
@@ -3369,7 +3380,7 @@ static void TrainLocoHandler(Vehicle *v,
 

	
 
	int j = UpdateTrainSpeed(v);
 
	if (j == 0) {
 
		// if the vehicle has speed 0, update the last_speed field.
 
		/* if the vehicle has speed 0, update the last_speed field. */
 
		if (v->cur_speed != 0) return;
 
	} else {
 
		TrainCheckIfLineEnds(v);
 
@@ -3396,11 +3407,11 @@ void Train_Tick(Vehicle *v)
 
	if (IsFrontEngine(v)) {
 
		TrainLocoHandler(v, false);
 

	
 
		// make sure vehicle wasn't deleted.
 
		/* make sure vehicle wasn't deleted. */
 
		if (v->type == VEH_TRAIN && IsFrontEngine(v))
 
			TrainLocoHandler(v, true);
 
	} else if (IsFreeWagon(v) && HASBITS(v->vehstatus, VS_CRASHED)) {
 
		// Delete flooded standalone wagon
 
		/* Delete flooded standalone wagon */
 
		if (++v->u.rail.crash_anim_pos >= 4400)
 
			DeleteVehicle(v);
 
	}
 
@@ -3415,8 +3426,8 @@ static void CheckIfTrainNeedsService(Veh
 
	if (v->vehstatus & VS_STOPPED)                      return;
 
	if (_patches.gotodepot && VehicleHasDepotOrders(v)) return;
 

	
 
	// Don't interfere with a depot visit scheduled by the user, or a
 
	// depot visit by the order list.
 
	/* Don't interfere with a depot visit scheduled by the user, or a
 
	 * depot visit by the order list. */
 
	if (v->current_order.type == OT_GOTO_DEPOT &&
 
			(v->current_order.flags & (OF_HALT_IN_DEPOT | OF_PART_OF_ORDERS)) != 0)
 
		return;
 
@@ -3507,7 +3518,7 @@ void TrainsYearlyLoop()
 

	
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->type == VEH_TRAIN && IsFrontEngine(v)) {
 
			// show warning if train is not generating enough income last 2 years (corresponds to a red icon in the vehicle list)
 
			/* show warning if train is not generating enough income last 2 years (corresponds to a red icon in the vehicle list) */
 
			if (_patches.train_income_warn && v->owner == _local_player && v->age >= 730 && v->profit_this_year < 0) {
 
				SetDParam(1, v->profit_this_year);
 
				SetDParam(0, v->unitnumber);
 
@@ -3579,7 +3590,7 @@ void ConnectMultiheadedTrains()
 
	}
 
}
 

	
 
/*
 
/**
 
 *  Converts all trains to the new subtype format introduced in savegame 16.2
 
 *  It also links multiheaded engines or make them forget they are multiheaded if no suitable partner is found
 
 */
src/train_gui.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file train_gui.cpp */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "debug.h"
 
@@ -22,7 +24,7 @@ void CcBuildWagon(bool success, TileInde
 

	
 
	if (!success) return;
 

	
 
	// find a locomotive in the depot.
 
	/* find a locomotive in the depot. */
 
	found = NULL;
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->type == VEH_TRAIN && IsFrontEngine(v) &&
 
@@ -33,10 +35,10 @@ void CcBuildWagon(bool success, TileInde
 
		}
 
	}
 

	
 
	// if we found a loco,
 
	/* if we found a loco, */
 
	if (found != NULL) {
 
		found = GetLastVehicleInChain(found);
 
		// put the new wagon at the end of the loco.
 
		/* put the new wagon at the end of the loco. */
 
		DoCommandP(0, _new_vehicle_id | (found->index << 16), 0, NULL, CMD_MOVE_RAIL_VEHICLE);
 
		RebuildVehicleLists();
 
	}
 
@@ -447,7 +449,7 @@ static void DrawTrainDetailsWindow(Windo
 
	y = 57;
 
	sel = w->vscroll.pos;
 

	
 
	// draw the first 3 details tabs
 
	/* draw the first 3 details tabs */
 
	if (det_tab != 3) {
 
		x = 1;
 
		for (;;) {
 
@@ -470,7 +472,7 @@ static void DrawTrainDetailsWindow(Windo
 
					default: NOT_REACHED();
 
					case 0: TrainDetailsCargoTab(   v, px, py); break;
 
					case 1:
 
						// Only show name and value for the 'real' part
 
						/* Only show name and value for the 'real' part */
 
						if (!IsArticulatedPart(v)) {
 
							TrainDetailsInfoTab(v, px, py);
 
						}
 
@@ -481,7 +483,7 @@ static void DrawTrainDetailsWindow(Windo
 

	
 
				v = u;
 
			} else {
 
				// Move to the next line
 
				/* Move to the next line */
 
				do {
 
					v = v->next;
 
				} while (v != NULL && IsArticulatedPart(v) && v->cargo_cap == 0);
 
@@ -489,7 +491,7 @@ static void DrawTrainDetailsWindow(Windo
 
			if (v == NULL) return;
 
		}
 
	} else {
 
		// draw total cargo tab
 
		/* draw total cargo tab */
 
		DrawString(x, y + 2, STR_013F_TOTAL_CAPACITY_TEXT, 0);
 
		for (CargoID i = 0; i < NUM_CARGO; i++) {
 
			if (max_cargo[i] > 0 && --sel < 0 && sel > -w->vscroll.cap) {
src/tree_cmd.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file tree_cmd.cpp */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "bridge_map.h"
 
@@ -53,7 +55,7 @@ static void PlaceTree(TileIndex tile, ui
 
	if (tree != TREE_INVALID) {
 
		MakeTree(tile, tree, GB(r, 22, 2), min(GB(r, 16, 3), 6), TREE_GROUND_GRASS, 0);
 

	
 
		// above snowline?
 
		/* above snowline? */
 
		if (_opt.landscape == LT_ARCTIC && GetTileZ(tile) > GetSnowLine()) {
 
			SetTreeGroundDensity(tile, TREE_GROUND_SNOW_DESERT, 3);
 
			SetTreeCounter(tile, (TreeGround)GB(r, 24, 3));
 
@@ -207,6 +209,7 @@ void GenerateTrees()
 

	
 
/** Plant a tree.
 
 * @param tile start tile of area-drag of tree plantation
 
 * @param flags type of operation
 
 * @param p1 tree type, -1 means random.
 
 * @param p2 end tile of area-drag
 
 */
 
@@ -240,7 +243,7 @@ int32 CmdPlantTree(TileIndex tile, uint3
 

	
 
			switch (GetTileType(tile)) {
 
				case MP_TREES:
 
					// no more space for trees?
 
					/* no more space for trees? */
 
					if (_game_mode != GM_EDITOR && GetTreeCount(tile) == 3) {
 
						msg = STR_2803_TREE_ALREADY_HERE;
 
						continue;
 
@@ -250,7 +253,7 @@ int32 CmdPlantTree(TileIndex tile, uint3
 
						AddTreeCount(tile, 1);
 
						MarkTileDirtyByTile(tile);
 
					}
 
					// 2x as expensive to add more trees to an existing tile
 
					/* 2x as expensive to add more trees to an existing tile */
 
					cost += _price.build_trees * 2;
 
					break;
 

	
 
@@ -622,7 +625,7 @@ void OnTick_Trees()
 
		MakeTree(tile, tree, 0, 0, ct == CLEAR_ROUGH ? TREE_GROUND_ROUGH : TREE_GROUND_GRASS, 0);
 
	}
 

	
 
	// byte underflow
 
	/* byte underflow */
 
	if (--_trees_tick_ctr != 0) return;
 

	
 
	/* place a tree at a random spot */
src/tree_map.h
Show inline comments
 
/* $Id$ */
 

	
 
/** @file tree_map.h */
 

	
 
#ifndef TREE_MAP_H
 
#define TREE_MAP_H
 

	
 
@@ -26,9 +28,9 @@ enum {
 
/* ground type, m2 bits 4...5
 
 * valid densities (bits 6...7) in comments after the enum */
 
enum TreeGround {
 
	TREE_GROUND_GRASS       = 0, // 0
 
	TREE_GROUND_ROUGH       = 1, // 0
 
	TREE_GROUND_SNOW_DESERT = 2  // 0-3 for snow, 3 for desert
 
	TREE_GROUND_GRASS       = 0, ///< 0
 
	TREE_GROUND_ROUGH       = 1, ///< 0
 
	TREE_GROUND_SNOW_DESERT = 2  ///< 0-3 for snow, 3 for desert
 
};
 

	
 

	
src/tunnel_map.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file tunnel_map.cpp */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "tile.h"
src/tunnel_map.h
Show inline comments
 
/* $Id$ */
 

	
 
/** @file tunnel_map.h */
 

	
 
#ifndef TUNNEL_MAP_H
 
#define TUNNEL_MAP_H
 

	
src/tunnelbridge_cmd.cpp
Show inline comments
 
@@ -61,8 +61,9 @@ const Bridge orig_bridge[] = {
 
Bridge _bridge[MAX_BRIDGES];
 

	
 

	
 
// calculate the price factor for building a long bridge.
 
// basically the cost delta is 1,1, 1, 2,2, 3,3,3, 4,4,4,4, 5,5,5,5,5, 6,6,6,6,6,6,  7,7,7,7,7,7,7,  8,8,8,8,8,8,8,8,
 
/** calculate the price factor for building a long bridge.
 
 * basically the cost delta is 1,1, 1, 2,2, 3,3,3, 4,4,4,4, 5,5,5,5,5, 6,6,6,6,6,6,  7,7,7,7,7,7,7,  8,8,8,8,8,8,8,8,
 
 */
 
int CalcBridgeLenCostFactor(int x)
 
{
 
	int n;
 
@@ -79,11 +80,11 @@ int CalcBridgeLenCostFactor(int x)
 

	
 
#define M(x) (1 << (x))
 
enum BridgeFoundation {
 
	// foundation, whole tile is leveled up --> 3 corners raised
 
	/* foundation, whole tile is leveled up --> 3 corners raised */
 
	BRIDGE_FULL_LEVELED_FOUNDATION = M(SLOPE_WSE) | M(SLOPE_NWS) | M(SLOPE_ENW) | M(SLOPE_SEN),
 
	// foundation, tile is partly leveled up --> 1 corner raised
 
	/* foundation, tile is partly leveled up --> 1 corner raised */
 
	BRIDGE_PARTLY_LEVELED_FOUNDATION = M(SLOPE_W) | M(SLOPE_S) | M(SLOPE_E) | M(SLOPE_N),
 
	// no foundations (X,Y direction)
 
	/* no foundations (X,Y direction) */
 
	BRIDGE_NO_FOUNDATION = M(SLOPE_FLAT) | M(SLOPE_SW) | M(SLOPE_SE) | M(SLOPE_NW) | M(SLOPE_NE),
 
	BRIDGE_HORZ_RAMP = (BRIDGE_PARTLY_LEVELED_FOUNDATION | BRIDGE_NO_FOUNDATION) & ~M(SLOPE_FLAT)
 
};
 
@@ -167,6 +168,7 @@ bool CheckBridge_Stuff(byte bridge_type,
 

	
 
/** Build a Bridge
 
 * @param end_tile end tile
 
 * @param flags type of operation
 
 * @param p1 packed start tile coords (~ dx)
 
 * @param p2 various bitstuffed elements
 
 * - p2 = (bit 0- 7) - bridge type (hi bh)
 
@@ -202,7 +204,7 @@ int32 CmdBuildBridge(TileIndex end_tile,
 

	
 
	if (p1 >= MapSize()) return CMD_ERROR;
 

	
 
	// type of bridge
 
	/* type of bridge */
 
	if (HASBIT(p2, 15)) {
 
		railtype = INVALID_RAILTYPE; // road bridge
 
	} else {
 
@@ -255,7 +257,7 @@ int32 CmdBuildBridge(TileIndex end_tile,
 

	
 
	if (z_start != z_end) return_cmd_error(STR_5009_LEVEL_LAND_OR_WATER_REQUIRED);
 

	
 
	// Towns are not allowed to use bridges on slopes.
 
	/* Towns are not allowed to use bridges on slopes. */
 
	allow_on_slopes = (!_is_old_ai_player
 
	                   && _current_player != OWNER_TOWN && _patches.build_on_slopes);
 

	
 
@@ -315,7 +317,7 @@ int32 CmdBuildBridge(TileIndex end_tile,
 
		if (CmdFailed(ret)) return ret;
 
		cost += ret;
 

	
 
		// false - end tile slope check
 
		/* false - end tile slope check */
 
		terraformcost = CheckBridgeSlopeSouth(direction, tileh_end);
 
		if (CmdFailed(terraformcost) || (terraformcost != 0 && !allow_on_slopes))
 
			return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 
@@ -439,6 +441,7 @@ not_valid_below:;
 

	
 
/** Build Tunnel.
 
 * @param tile start tile of tunnel
 
 * @param flags type of operation
 
 * @param p1 railtype, 0x200 for road tunnel
 
 * @param p2 unused
 
 */
 
@@ -496,10 +499,10 @@ int32 CmdBuildTunnel(TileIndex start_til
 
	/* Add the cost of the entrance */
 
	cost += _price.build_tunnel + ret;
 

	
 
	// if the command fails from here on we want the end tile to be highlighted
 
	/* if the command fails from here on we want the end tile to be highlighted */
 
	_build_tunnel_endtile = end_tile;
 

	
 
	// slope of end tile must be complementary to the slope of the start tile
 
	/* slope of end tile must be complementary to the slope of the start tile */
 
	if (end_tileh != ComplementSlope(start_tileh)) {
 
		ret = DoCommand(end_tile, end_tileh & start_tileh, 0, flags, CMD_TERRAFORM_LAND);
 
		if (CmdFailed(ret)) return_cmd_error(STR_5005_UNABLE_TO_EXCAVATE_LAND);
 
@@ -591,12 +594,12 @@ static int32 DoClearTunnel(TileIndex til
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		// We first need to request the direction before calling DoClearSquare
 
		//  else the direction is always 0.. dah!! ;)
 
		/* We first need to request the direction before calling DoClearSquare
 
		 *  else the direction is always 0.. dah!! ;) */
 
		DiagDirection dir = GetTunnelDirection(tile);
 
		Track track;
 

	
 
		// Adjust the town's player rating. Do this before removing the tile owner info.
 
		/* Adjust the town's player rating. Do this before removing the tile owner info. */
 
		if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
 
			ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
 

	
 
@@ -661,8 +664,8 @@ static int32 DoClearBridge(TileIndex til
 
		TileIndex c;
 
		Track track;
 

	
 
		//checks if the owner is town then decrease town rating by RATING_TUNNEL_BRIDGE_DOWN_STEP until
 
		// you have a "Poor" (0) town rating
 
		/* checks if the owner is town then decrease town rating by RATING_TUNNEL_BRIDGE_DOWN_STEP until
 
		 * you have a "Poor" (0) town rating */
 
		if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
 
			ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
 

	
 
@@ -717,7 +720,7 @@ int32 DoConvertTunnelBridgeRail(TileInde
 

	
 
		if (GetRailType(tile) == totype) return CMD_ERROR;
 

	
 
		// 'hidden' elrails can't be downgraded to normal rail when elrails are disabled
 
		/* 'hidden' elrails can't be downgraded to normal rail when elrails are disabled */
 
		if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailType(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR;
 

	
 
		endtile = CheckTunnelBusy(tile, &length);
 
@@ -829,7 +832,7 @@ uint GetBridgeFoundation(Slope tileh, Ax
 

	
 
	if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) return tileh;
 

	
 
	// inclined sloped building
 
	/* inclined sloped building */
 
	switch (tileh) {
 
		case SLOPE_W:
 
		case SLOPE_STEEP_W: i = 0; break;
 
@@ -850,6 +853,7 @@ uint GetBridgeFoundation(Slope tileh, Ax
 
 * For tunnels, this is rather simple, as you only needa draw the entrance.
 
 * Bridges are a bit more complex. base_offset is where the sprite selection comes into play
 
 * and it works a bit like a bitmask.<p> For bridge heads:
 
 * @param ti TileInfo of the structure to draw
 
 * <ul><li>Bit 0: direction</li>
 
 * <li>Bit 1: northern or southern heads</li>
 
 * <li>Bit 2: Set if the bridge head is sloped</li>
 
@@ -884,7 +888,7 @@ static void DrawTile_TunnelBridge(TileIn
 

	
 
		if (GetBridgeTransportType(ti->tile) == TRANSPORT_RAIL) {
 
			base_offset = GetRailTypeInfo(GetRailType(ti->tile))->bridge_offset;
 
			assert(base_offset != 8); /* This one is used for roads */
 
			assert(base_offset != 8); // This one is used for roads
 
		} else {
 
			base_offset = 8;
 
		}
 
@@ -897,7 +901,7 @@ static void DrawTile_TunnelBridge(TileIn
 
			if (f != 0) DrawFoundation(ti, f);
 
		}
 

	
 
		// HACK Wizardry to convert the bridge ramp direction into a sprite offset
 
		/* HACK Wizardry to convert the bridge ramp direction into a sprite offset */
 
		base_offset += (6 - GetBridgeRampDirection(ti->tile)) % 4;
 

	
 
		if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head
 
@@ -915,7 +919,7 @@ static void DrawTile_TunnelBridge(TileIn
 

	
 
		image = psid->sprite;
 

	
 
		// draw ramp
 
		/* draw ramp */
 
		if (_display_opt & DO_TRANS_BUILDINGS) {
 
			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
 
			pal = PALETTE_TO_TRANSPARENT;
 
@@ -1030,7 +1034,7 @@ void DrawBridgeMiddle(const TileInfo* ti
 
		pal = psid->pal;
 
	}
 

	
 
	// draw roof, the component of the bridge which is logically between the vehicle and the camera
 
	/* draw roof, the component of the bridge which is logically between the vehicle and the camera */
 
	if (axis == AXIS_X) {
 
		y += 12;
 
		if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, pal, x, y, 16, 1, 0x28, z);
 
@@ -1043,7 +1047,7 @@ void DrawBridgeMiddle(const TileInfo* ti
 

	
 
	psid++;
 
	if (ti->z + 5 == z) {
 
		// draw poles below for small bridges
 
		/* draw poles below for small bridges */
 
		if (psid->sprite != 0) {
 
			image = psid->sprite;
 
			if (_display_opt & DO_TRANS_BUILDINGS) {
 
@@ -1056,7 +1060,7 @@ void DrawBridgeMiddle(const TileInfo* ti
 
			DrawGroundSpriteAt(image, pal, x, y, z);
 
		}
 
	} else if (_patches.bridge_pillars) {
 
		// draw pillars below for high bridges
 
		/* draw pillars below for high bridges */
 
		DrawBridgePillars(psid, ti, axis, type, x, y, z);
 
	}
 
}
 
@@ -1073,13 +1077,13 @@ static uint GetSlopeZ_TunnelBridge(TileI
 
	if (IsTunnel(tile)) {
 
		uint pos = (DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? y : x);
 

	
 
		// In the tunnel entrance?
 
		/* In the tunnel entrance? */
 
		if (5 <= pos && pos <= 10) return z;
 
	} else {
 
		DiagDirection dir = GetBridgeRampDirection(tile);
 
		uint pos = (DiagDirToAxis(dir) == AXIS_X ? y : x);
 

	
 
		// On the bridge ramp?
 
		/* On the bridge ramp? */
 
		if (5 <= pos && pos <= 10) {
 
			uint delta;
 

	
 
@@ -1302,7 +1306,7 @@ static uint32 VehicleEnter_TunnelBridge(
 
			dir = GetTunnelDirection(tile);
 
			vdir = DirToDiagDir(v->direction);
 

	
 
			// Enter tunnel?
 
			/* Enter tunnel? */
 
			if (v->u.road.state != RVSB_WORMHOLE && dir == vdir) {
 
				if (fc == _tunnel_fractcoord_4[dir] ||
 
						fc == _tunnel_fractcoord_5[dir]) {
0 comments (0 inline, 0 general)