File diff r26193:4bc7915a2156 → r26194:f7347205838e
src/station_cmd.cpp
Show inline comments
 
@@ -64,6 +64,8 @@
 

	
 
#include "safeguards.h"
 

	
 
#include "company_func.h"
 

	
 
/**
 
 * Static instance of FlowStat::SharesMap.
 
 * Note: This instance is created on task start.
 
@@ -238,23 +240,9 @@ static bool FindNearIndustryName(TileInd
 
	return !sni->indtypes[indtype];
 
}
 

	
 
static StringID GenerateStationName(Station *st, TileIndex tile, StationNaming name_class)
 
/** Fetch the available station names. Patchpack moves this code from GenerateStationName. Should be easy to see what was moved if you do a diff :) */
 
static void FetchAvailableStationNames(uint32& free_names, bool* indtypes, Station* st, const Town* t)
 
{
 
	static const uint32 _gen_station_name_bits[] = {
 
		0,                                       // STATIONNAMING_RAIL
 
		0,                                       // STATIONNAMING_ROAD
 
		1U << M(STR_SV_STNAME_AIRPORT),          // STATIONNAMING_AIRPORT
 
		1U << M(STR_SV_STNAME_OILFIELD),         // STATIONNAMING_OILRIG
 
		1U << M(STR_SV_STNAME_DOCKS),            // STATIONNAMING_DOCK
 
		1U << M(STR_SV_STNAME_HELIPORT),         // STATIONNAMING_HELIPORT
 
	};
 

	
 
	const Town *t = st->town;
 
	uint32 free_names = UINT32_MAX;
 

	
 
	bool indtypes[NUM_INDUSTRYTYPES];
 
	memset(indtypes, 0, sizeof(indtypes));
 

	
 
	for (const Station *s : Station::Iterate()) {
 
		if (s != st && s->town == t) {
 
			if (s->indtype != IT_INVALID) {
 
@@ -278,6 +266,56 @@ static StringID GenerateStationName(Stat
 
			}
 
		}
 
	}
 
}
 

	
 
/** Callback proc for CircularTileSearch */
 
static bool FindNearPatchpackIndustryName(TileIndex tile, void *user_data)
 
{
 
	/* Is this an industry tile? If not, skip it */
 
	if (!IsTileType(tile, MP_INDUSTRY)) return false;
 

	
 
	uint32 free_names = UINT32_MAX;
 
	bool indtypes[NUM_INDUSTRYTYPES];
 
	memset(indtypes, 0, sizeof(indtypes));
 
	FetchAvailableStationNames(free_names, indtypes, (Station*)user_data, Industry::GetByTile(tile)->town);
 

	
 
	IndustryType indtype = GetIndustryType(tile);
 

	
 
	return !indtypes[indtype];
 
}
 

	
 
/** Generates station names */
 
static StringID GenerateStationName(Station *st, TileIndex tile, StationNaming name_class)
 
{
 
	if (_settings_game.construction.name_stations_based_on_industries == 2)
 
	{
 
		/** I love having this as an in-game patch setting. DEM SETTINGS */
 
		TileIndex indtile = tile;
 
		if (CircularTileSearch(&indtile, 7, FindNearPatchpackIndustryName, (void*)st)) {
 
			IndustryType indtype = GetIndustryType(indtile);
 
			const IndustrySpec *indsp = GetIndustrySpec(indtype);
 
			st->indtype = indtype;
 
			st->town = Industry::GetByTile(indtile)->town;
 
			return STR_SV_STNAME_FALLBACK;
 
		}
 
	}
 

	
 
	static const uint32 _gen_station_name_bits[] = {
 
		0,                                       // STATIONNAMING_RAIL
 
		0,                                       // STATIONNAMING_ROAD
 
		1U << M(STR_SV_STNAME_AIRPORT),          // STATIONNAMING_AIRPORT
 
		1U << M(STR_SV_STNAME_OILFIELD),         // STATIONNAMING_OILRIG
 
		1U << M(STR_SV_STNAME_DOCKS),            // STATIONNAMING_DOCK
 
		1U << M(STR_SV_STNAME_HELIPORT),         // STATIONNAMING_HELIPORT
 
	};
 

	
 
	const Town *t = st->town;
 

	
 
	/* Fetch a list of available station names so we know which ones have already been used and are unavailable (including industry newGRF names) */
 
	uint32 free_names = UINT32_MAX;
 
	bool indtypes[NUM_INDUSTRYTYPES];
 
	memset(indtypes, 0, sizeof(indtypes));
 
	FetchAvailableStationNames(free_names, indtypes, st, t);
 

	
 
	TileIndex indtile = tile;
 
	StationNameInformation sni = { free_names, indtypes };
 
@@ -286,7 +324,7 @@ static StringID GenerateStationName(Stat
 
		IndustryType indtype = GetIndustryType(indtile);
 
		const IndustrySpec *indsp = GetIndustrySpec(indtype);
 
		/* STR_NULL means it only disables oil rig/mines */
 
		if (indsp->station_name != STR_NULL) {
 
		if (indsp->station_name != STR_NULL && (_settings_game.construction.name_stations_based_on_industries == 1)) {
 
			st->indtype = indtype;
 
			return STR_SV_STNAME_FALLBACK;
 
		}
 
@@ -843,7 +881,7 @@ CommandCost CheckBuildableTile(TileIndex
 
 */
 
static CommandCost CheckFlatLandAirport(AirportTileTableIterator tile_iter, DoCommandFlag flags)
 
{
 
	CommandCost cost(EXPENSES_CONSTRUCTION);
 
	CommandCost cost(EXPENSES_T_AIRCRAFT_CON);
 
	int allowed_z = -1;
 

	
 
	for (; tile_iter != INVALID_TILE; ++tile_iter) {
 
@@ -875,7 +913,7 @@ static CommandCost CheckFlatLandAirport(
 
 */
 
static CommandCost CheckFlatLandRailStation(TileArea tile_area, DoCommandFlag flags, Axis axis, StationID *station, RailType rt, std::vector<Train *> &affected_vehicles, StationClassID spec_class, byte spec_index, byte plat_len, byte numtracks)
 
{
 
	CommandCost cost(EXPENSES_CONSTRUCTION);
 
	CommandCost cost(EXPENSES_T_TRAIN_CON);
 
	int allowed_z = -1;
 
	uint invalid_dirs = 5 << axis;
 

	
 
@@ -961,7 +999,7 @@ static CommandCost CheckFlatLandRailStat
 
 */
 
static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags, uint invalid_dirs, bool is_drive_through, bool is_truck_stop, Axis axis, StationID *station, RoadType rt)
 
{
 
	CommandCost cost(EXPENSES_CONSTRUCTION);
 
	CommandCost cost(EXPENSES_T_ROAD_CON);
 
	int allowed_z = -1;
 

	
 
	for (TileIndex cur_tile : tile_area) {
 
@@ -1552,7 +1590,7 @@ CommandCost RemoveFromRailBaseStation(Ti
 
{
 
	/* Count of the number of tiles removed */
 
	int quantity = 0;
 
	CommandCost total_cost(EXPENSES_CONSTRUCTION);
 
	CommandCost total_cost(EXPENSES_T_TRAIN_CON);
 
	/* Accumulator for the errors seen during clearing. If no errors happen,
 
	 * and the quantity is 0 there is no station. Otherwise it will be one
 
	 * of the other error that got accumulated. */
 
@@ -1721,7 +1759,7 @@ CommandCost RemoveRailStation(T *st, DoC
 

	
 
	assert(ta.w != 0 && ta.h != 0);
 

	
 
	CommandCost cost(EXPENSES_CONSTRUCTION);
 
	CommandCost cost(EXPENSES_T_TRAIN_CON);
 
	/* clear all areas of the station */
 
	for (TileIndex tile : ta) {
 
		/* only remove tiles that are actually train station tiles */
 
@@ -1853,7 +1891,7 @@ CommandCost CmdBuildRoadStop(DoCommandFl
 
	bool is_truck_stop = stop_type != ROADSTOP_BUS;
 

	
 
	/* Total road stop cost. */
 
	CommandCost cost(EXPENSES_CONSTRUCTION, roadstop_area.w * roadstop_area.h * _price[is_truck_stop ? PR_BUILD_STATION_TRUCK : PR_BUILD_STATION_BUS]);
 
	CommandCost cost(EXPENSES_T_ROAD_CON, roadstop_area.w * roadstop_area.h * _price[is_truck_stop ? PR_BUILD_STATION_TRUCK : PR_BUILD_STATION_BUS]);
 
	StationID est = INVALID_STATION;
 
	ret = CheckFlatLandRoadStop(roadstop_area, flags, is_drive_through ? 5 << axis : 1 << ddir, is_drive_through, is_truck_stop, axis, &est, rt);
 
	if (ret.Failed()) return ret;
 
@@ -2045,7 +2083,7 @@ static CommandCost RemoveRoadStop(TileIn
 
		}
 
	}
 

	
 
	return CommandCost(EXPENSES_CONSTRUCTION, _price[is_truck ? PR_CLEAR_STATION_TRUCK : PR_CLEAR_STATION_BUS]);
 
	return CommandCost(EXPENSES_T_ROAD_CON, _price[is_truck ? PR_CLEAR_STATION_TRUCK : PR_CLEAR_STATION_BUS]);
 
}
 

	
 
/**
 
@@ -2070,7 +2108,7 @@ CommandCost CmdRemoveRoadStop(DoCommandF
 

	
 
	TileArea roadstop_area(tile, width, height);
 

	
 
	CommandCost cost(EXPENSES_CONSTRUCTION);
 
	CommandCost cost(EXPENSES_T_ROAD_CON);
 
	CommandCost last_error(STR_ERROR_THERE_IS_NO_STATION);
 
	bool had_success = false;
 

	
 
@@ -2350,7 +2388,7 @@ static CommandCost RemoveAirport(TileInd
 

	
 
	tile = st->airport.tile;
 

	
 
	CommandCost cost(EXPENSES_CONSTRUCTION);
 
	CommandCost cost(EXPENSES_T_AIRCRAFT_CON);
 

	
 
	for (const Aircraft *a : Aircraft::Iterate()) {
 
		if (!a->IsNormalAircraft()) continue;
 
@@ -2496,7 +2534,7 @@ CommandCost CmdBuildDock(DoCommandFlag f
 

	
 
	if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
 

	
 
	CommandCost cost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_STATION_DOCK]);
 
	CommandCost cost(EXPENSES_T_SHIP_CON, _price[PR_BUILD_STATION_DOCK]);
 
	ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
 
	if (ret.Failed()) return ret;
 
	cost.AddCost(ret);
 
@@ -2696,7 +2734,7 @@ static CommandCost RemoveDock(TileIndex 
 
		}
 
	}
 

	
 
	return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_STATION_DOCK]);
 
	return CommandCost(EXPENSES_T_SHIP_CON, _price[PR_CLEAR_STATION_DOCK]);
 
}
 

	
 
#include "table/station_land.h"
 
@@ -2994,7 +3032,6 @@ draw_default_foundation:
 
	}
 

	
 
	if (HasStationRail(ti->tile) && HasRailCatenaryDrawn(GetRailType(ti->tile))) DrawRailCatenary(ti);
 

	
 
	if (IsRoadStop(ti->tile)) {
 
		RoadType road_rt = GetRoadTypeRoad(ti->tile);
 
		RoadType tram_rt = GetRoadTypeTram(ti->tile);
 
@@ -3565,6 +3602,64 @@ static void UpdateStationRating(Station 
 
		}
 
	}
 

	
 
	// station dilapidation
 
	{
 
		if (_settings_game.economy.dilapidation_max_amount > 0) {
 
			bool dilapidation_calc = false;
 
			uint16 dilapidation_pop = 0;
 
			uint pop_count = st->goods[CT_PASSENGERS].cargo.AvailableCount();
 
			if (Company::IsValidID(st->owner)) {
 
				if ((st->facilities & FACIL_TRAIN) != 0) {
 
					dilapidation_calc = true;
 
					if (_settings_game.economy.dilapidation_pop_rail > dilapidation_pop) {
 
						dilapidation_pop = _settings_game.economy.dilapidation_pop_rail;
 
					}
 
				}
 
				if (((st->facilities & FACIL_BUS_STOP) != 0) || ((st->facilities & FACIL_TRUCK_STOP) != 0)) {
 
					dilapidation_calc = true;
 
					if (_settings_game.economy.dilapidation_pop_road > dilapidation_pop) {
 
						dilapidation_pop = _settings_game.economy.dilapidation_pop_road;
 
					}
 
				}
 
				if ((st->facilities & FACIL_DOCK) != 0) {
 
					dilapidation_calc = true;
 
					if (_settings_game.economy.dilapidation_pop_water > dilapidation_pop) {
 
						dilapidation_pop = _settings_game.economy.dilapidation_pop_water;
 
					}
 
				}
 
				if ((st->facilities & FACIL_AIRPORT) != 0) {
 
					dilapidation_calc = true;
 
					if (_settings_game.economy.dilapidation_pop_air > dilapidation_pop) {
 
						dilapidation_pop = _settings_game.economy.dilapidation_pop_air;
 
					}
 
				}
 
			}
 
			if (dilapidation_calc && pop_count > (uint)dilapidation_pop) {
 
				// increase the dilapidation, preventing overflow
 
				uint16 top_boundary = 65535 - _settings_game.economy.dilapidation_increase;
 
				if (st->dilapidation >= top_boundary) {
 
					st->dilapidation = 65535;
 
				}
 
				else {
 
					st->dilapidation += _settings_game.economy.dilapidation_increase;
 
				}
 
			}
 
			else
 
			{
 
				// decrease the dilapidation, preventing underflow
 
				if (st->dilapidation <= _settings_game.economy.dilapidation_decrease) {
 
					st->dilapidation = 0;
 
				}
 
				else {
 
					st->dilapidation -= _settings_game.economy.dilapidation_decrease;
 
				}
 
			}
 
		}
 
		if (st->dilapidation > _settings_game.economy.dilapidation_max_amount) {
 
			st->dilapidation = _settings_game.economy.dilapidation_max_amount;
 
		}
 
	}
 

	
 
	StationID index = st->index;
 
	if (waiting_changed) {
 
		SetWindowDirty(WC_STATION_VIEW, index); // update whole window
 
@@ -3803,6 +3898,40 @@ void OnTick_Station()
 
	}
 
}
 

	
 
/** Charges player for dilapidation at station */
 
void ChargePlayerForDilapidation(Station *st)
 
{
 
	if (st->dilapidation > 0 && Company::IsValidID(st->owner)) {
 
		uint32 dilapidation_fine = 0;
 
		if ((st->facilities & FACIL_TRAIN) != 0) {
 
			if (_settings_game.economy.dilapidation_fine_rail > dilapidation_fine) {
 
				dilapidation_fine = _settings_game.economy.dilapidation_fine_rail;
 
			}
 
		}
 
		if (((st->facilities & FACIL_BUS_STOP) != 0) || ((st->facilities & FACIL_TRUCK_STOP) != 0)) {
 
			if (_settings_game.economy.dilapidation_fine_road > dilapidation_fine) {
 
				dilapidation_fine = _settings_game.economy.dilapidation_fine_road;
 
			}
 
		}
 
		if ((st->facilities & FACIL_DOCK) != 0) {
 
			if (_settings_game.economy.dilapidation_fine_water > dilapidation_fine) {
 
				dilapidation_fine = _settings_game.economy.dilapidation_fine_water;
 
			}
 
		}
 
		if ((st->facilities & FACIL_AIRPORT) != 0) {
 
			if (_settings_game.economy.dilapidation_fine_air > dilapidation_fine) {
 
				dilapidation_fine = _settings_game.economy.dilapidation_fine_air;
 
			}
 
		}
 
		Money actual_fine = dilapidation_fine;
 
		actual_fine *= st->dilapidation;
 
		actual_fine *= (_economy.inflation_prices >> 16);
 
		if (actual_fine > 0) {
 
			SubtractMoneyFromCompanyFract(st->owner, CommandCost(EXPENSES_T_DILAPIDATION, actual_fine << 8));
 
		}
 
	}
 
}
 

	
 
/** Monthly loop for stations. */
 
void StationMonthlyLoop()
 
{
 
@@ -3812,6 +3941,7 @@ void StationMonthlyLoop()
 
			SB(ge->status, GoodsEntry::GES_LAST_MONTH, 1, GB(ge->status, GoodsEntry::GES_CURRENT_MONTH, 1));
 
			ClrBit(ge->status, GoodsEntry::GES_CURRENT_MONTH);
 
		}
 
		ChargePlayerForDilapidation(st);
 
	}
 
}
 

	
 
@@ -4302,11 +4432,11 @@ static CommandCost TerraformTile_Station
 
					DiagDirection direction = AxisToDiagDir(GetRailStationAxis(tile));
 
					if (!AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, direction)) break;
 
					if (!AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, ReverseDiagDir(direction))) break;
 
					return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
 
					return CommandCost(EXPENSES_T_TRAIN_CON, _price[PR_BUILD_FOUNDATION]);
 
				}
 

	
 
				case STATION_AIRPORT:
 
					return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
 
					return CommandCost(EXPENSES_T_AIRCRAFT_CON, _price[PR_BUILD_FOUNDATION]);
 

	
 
				case STATION_TRUCK:
 
				case STATION_BUS: {
 
@@ -4315,7 +4445,7 @@ static CommandCost TerraformTile_Station
 
					if (IsDriveThroughStopTile(tile)) {
 
						if (!AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, ReverseDiagDir(direction))) break;
 
					}
 
					return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
 
					return CommandCost(EXPENSES_T_ROAD_CON, _price[PR_BUILD_FOUNDATION]);
 
				}
 

	
 
				default: break;