(svn r23415) -Feature: Infrastructure maintenance costs.

This commit is contained in:
michi_cc 2011-12-03 23:40:46 +00:00
parent f98312eb77
commit d3b7b89493
21 changed files with 300 additions and 32 deletions

View File

@ -34,6 +34,9 @@
#include "rail.h"
#include "engine_base.h"
#include "window_func.h"
#include "road_func.h"
#include "water.h"
#include "station_func.h"
#include "table/strings.h"
@ -1624,6 +1627,8 @@ enum CompanyInfrastructureWindowWidgets {
CIW_WIDGET_WATER_COUNT,
CIW_WIDGET_STATION_DESC,
CIW_WIDGET_STATION_COUNT,
CIW_WIDGET_TOTAL_DESC,
CIW_WIDGET_TOTAL,
};
static const NWidgetPart _nested_company_infrastructure_widgets[] = {
@ -1651,6 +1656,10 @@ static const NWidgetPart _nested_company_infrastructure_widgets[] = {
NWidget(WWT_EMPTY, COLOUR_GREY, CIW_WIDGET_STATION_DESC), SetMinimalTextLines(3, 0), SetFill(1, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, CIW_WIDGET_STATION_COUNT), SetMinimalTextLines(3, 0), SetFill(0, 1),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2),
NWidget(WWT_EMPTY, COLOUR_GREY, CIW_WIDGET_TOTAL_DESC), SetFill(1, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, CIW_WIDGET_TOTAL), SetFill(0, 1),
EndContainer(),
EndContainer(),
EndContainer(),
};
@ -1663,6 +1672,8 @@ struct CompanyInfrastructureWindow : Window
RailTypes railtypes; ///< Valid railtypes.
RoadTypes roadtypes; ///< Valid roadtypes.
uint total_width; ///< String width of the total cost line.
CompanyInfrastructureWindow(const WindowDesc *desc, WindowNumber window_number) : Window()
{
this->UpdateRailRoadTypes();
@ -1697,6 +1708,27 @@ struct CompanyInfrastructureWindow : Window
}
}
/** Get total infrastructure maintenance cost. */
Money GetTotalMaintenanceCost() const
{
const Company *c = Company::Get((CompanyID)this->window_number);
Money total;
for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
if (HasBit(this->railtypes, rt)) total += RailMaintenanceCost(rt, c->infrastructure.rail[rt]);
}
total += SignalMaintenanceCost(c->infrastructure.signal);
if (HasBit(this->roadtypes, ROADTYPE_ROAD)) total += RoadMaintenanceCost(ROADTYPE_ROAD, c->infrastructure.road[ROADTYPE_ROAD]);
if (HasBit(this->roadtypes, ROADTYPE_TRAM)) total += RoadMaintenanceCost(ROADTYPE_TRAM, c->infrastructure.road[ROADTYPE_TRAM]);
total += CanalMaintenanceCost(c->infrastructure.water);
total += StationMaintenanceCost(c->infrastructure.station);
total += AirportMaintenanceCost(c->index);
return total;
}
virtual void SetStringParameters(int widget) const
{
switch (widget) {
@ -1749,22 +1781,42 @@ struct CompanyInfrastructureWindow : Window
case CIW_WIDGET_RAIL_COUNT:
case CIW_WIDGET_ROAD_COUNT:
case CIW_WIDGET_WATER_COUNT:
case CIW_WIDGET_STATION_COUNT: {
case CIW_WIDGET_STATION_COUNT:
case CIW_WIDGET_TOTAL: {
/* Find the maximum count that is displayed. */
uint32 max_val = 100000; // Some random number to reserve enough space.
Money max_cost = 100000; // Some random number to reserve enough space.
for (RailType rt = RAILTYPE_BEGIN; rt < RAILTYPE_END; rt++) {
max_val = max(max_val, c->infrastructure.rail[rt]);
max_cost = max(max_cost, RailMaintenanceCost(rt, c->infrastructure.rail[rt]));
}
max_val = max(max_val, c->infrastructure.signal);
max_cost = max(max_cost, SignalMaintenanceCost(c->infrastructure.signal));
for (RoadType rt = ROADTYPE_BEGIN; rt < ROADTYPE_END; rt++) {
max_val = max(max_val, c->infrastructure.road[rt]);
max_cost = max(max_cost, RoadMaintenanceCost(rt, c->infrastructure.road[rt]));
}
max_val = max(max_val, c->infrastructure.water);
max_cost = max(max_cost, CanalMaintenanceCost(c->infrastructure.water));
max_val = max(max_val, c->infrastructure.station);
max_cost = max(max_cost, StationMaintenanceCost(c->infrastructure.station));
max_val = max(max_val, c->infrastructure.airport);
max_cost = max(max_cost, AirportMaintenanceCost(c->index));
SetDParam(0, max_val);
size->width = max(size->width, GetStringBoundingBox(STR_WHITE_COMMA).width + 15); // Reserve some wiggle room.
SetDParam(1, max_cost * 12); // Convert to per year
size->width = max(size->width, GetStringBoundingBox(_settings_game.economy.infrastructure_maintenance ? STR_COMPANY_INFRASTRUCTURE_VIEW_COST : STR_WHITE_COMMA).width + 20); // Reserve some wiggle room.
if (_settings_game.economy.infrastructure_maintenance) {
SetDParam(0, this->GetTotalMaintenanceCost());
this->total_width = GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL).width + 20;
size->width = max(size->width, this->total_width);
}
/* Set height of the total line. */
if (widget == CIW_WIDGET_TOTAL) {
size->height = _settings_game.economy.infrastructure_maintenance ? max(size->height, EXP_LINESPACE + FONT_HEIGHT_NORMAL) : 0;
}
break;
}
}
@ -1803,12 +1855,14 @@ struct CompanyInfrastructureWindow : Window
for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
if (HasBit(this->railtypes, rt)) {
SetDParam(0, c->infrastructure.rail[rt]);
DrawString(r.left, r.right, y += FONT_HEIGHT_NORMAL, STR_WHITE_COMMA);
SetDParam(1, RailMaintenanceCost(rt, c->infrastructure.rail[rt]) * 12); // Convert to per year
DrawString(r.left, r.right, y += FONT_HEIGHT_NORMAL, _settings_game.economy.infrastructure_maintenance ? STR_COMPANY_INFRASTRUCTURE_VIEW_COST : STR_WHITE_COMMA);
}
}
if (this->railtypes != RAILTYPES_NONE) {
SetDParam(0, c->infrastructure.signal);
DrawString(r.left, r.right, y += FONT_HEIGHT_NORMAL, STR_WHITE_COMMA);
SetDParam(1, SignalMaintenanceCost(c->infrastructure.signal) * 12); // Convert to per year
DrawString(r.left, r.right, y += FONT_HEIGHT_NORMAL, _settings_game.economy.infrastructure_maintenance ? STR_COMPANY_INFRASTRUCTURE_VIEW_COST : STR_WHITE_COMMA);
}
break;
@ -1828,11 +1882,13 @@ struct CompanyInfrastructureWindow : Window
case CIW_WIDGET_ROAD_COUNT:
if (HasBit(this->roadtypes, ROADTYPE_ROAD)) {
SetDParam(0, c->infrastructure.road[ROADTYPE_ROAD]);
DrawString(r.left, r.right, y += FONT_HEIGHT_NORMAL, STR_WHITE_COMMA);
SetDParam(1, RoadMaintenanceCost(ROADTYPE_ROAD, c->infrastructure.road[ROADTYPE_ROAD]) * 12); // Convert to per year
DrawString(r.left, r.right, y += FONT_HEIGHT_NORMAL, _settings_game.economy.infrastructure_maintenance ? STR_COMPANY_INFRASTRUCTURE_VIEW_COST : STR_WHITE_COMMA);
}
if (HasBit(this->roadtypes, ROADTYPE_TRAM)) {
SetDParam(0, c->infrastructure.road[ROADTYPE_TRAM]);
DrawString(r.left, r.right, y += FONT_HEIGHT_NORMAL, STR_WHITE_COMMA);
SetDParam(1, RoadMaintenanceCost(ROADTYPE_TRAM, c->infrastructure.road[ROADTYPE_TRAM]) * 12); // Convert to per year
DrawString(r.left, r.right, y += FONT_HEIGHT_NORMAL, _settings_game.economy.infrastructure_maintenance ? STR_COMPANY_INFRASTRUCTURE_VIEW_COST : STR_WHITE_COMMA);
}
break;
@ -1843,7 +1899,17 @@ struct CompanyInfrastructureWindow : Window
case CIW_WIDGET_WATER_COUNT:
SetDParam(0, c->infrastructure.water);
DrawString(r.left, r.right, y += FONT_HEIGHT_NORMAL, STR_WHITE_COMMA);
SetDParam(1, CanalMaintenanceCost(c->infrastructure.water) * 12); // Convert to per year
DrawString(r.left, r.right, y += FONT_HEIGHT_NORMAL, _settings_game.economy.infrastructure_maintenance ? STR_COMPANY_INFRASTRUCTURE_VIEW_COST : STR_WHITE_COMMA);
break;
case CIW_WIDGET_TOTAL:
if (_settings_game.economy.infrastructure_maintenance) {
GfxFillRect(r.left, y, r.left + this->total_width, y, PC_WHITE);
y += EXP_LINESPACE;
SetDParam(0, this->GetTotalMaintenanceCost() * 12); // Convert to per year
DrawString(r.left, r.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL);
}
break;
case CIW_WIDGET_STATION_DESC:
@ -1854,9 +1920,11 @@ struct CompanyInfrastructureWindow : Window
case CIW_WIDGET_STATION_COUNT:
SetDParam(0, c->infrastructure.station);
DrawString(r.left, r.right, y += FONT_HEIGHT_NORMAL, STR_WHITE_COMMA);
SetDParam(1, StationMaintenanceCost(c->infrastructure.station) * 12); // Convert to per year
DrawString(r.left, r.right, y += FONT_HEIGHT_NORMAL, _settings_game.economy.infrastructure_maintenance ? STR_COMPANY_INFRASTRUCTURE_VIEW_COST : STR_WHITE_COMMA);
SetDParam(0, c->infrastructure.airport);
DrawString(r.left, r.right, y += FONT_HEIGHT_NORMAL, STR_WHITE_COMMA);
SetDParam(1, AirportMaintenanceCost(c->index) * 12); // Convert to per year
DrawString(r.left, r.right, y += FONT_HEIGHT_NORMAL, _settings_game.economy.infrastructure_maintenance ? STR_COMPANY_INFRASTRUCTURE_VIEW_COST : STR_WHITE_COMMA);
break;
}
}

View File

@ -46,3 +46,33 @@ int GreatestCommonDivisor(int a, int b)
return a;
}
/**
* Compute the integer square root.
* @param num Radicand.
* @return Rounded integer square root.
* @note Algorithm taken from http://en.wikipedia.org/wiki/Methods_of_computing_square_roots
*/
uint32 IntSqrt(uint32 num)
{
uint32 res = 0;
uint32 bit = 1UL << 30; // Second to top bit number.
/* 'bit' starts at the highest power of four <= the argument. */
while (bit > num) bit >>= 2;
while (bit != 0) {
if (num >= res + bit) {
num -= res + bit;
res = (res >> 1) + bit;
} else {
res >>= 1;
}
bit >>= 2;
}
/* Arithmetic rounding to nearest integer. */
if (num > res) res++;
return res;
}

View File

@ -346,4 +346,6 @@ static FORCEINLINE int RoundDivSU(int a, uint b)
}
}
uint32 IntSqrt(uint32 num);
#endif /* MATH_FUNC_HPP */

View File

@ -46,6 +46,7 @@
#include "core/pool_func.hpp"
#include "newgrf.h"
#include "core/backup_type.hpp"
#include "water.h"
#include "table/strings.h"
#include "table/pricebase.h"
@ -584,17 +585,39 @@ static void CompaniesGenStatistics()
Station *st;
Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
FOR_ALL_STATIONS(st) {
cur_company.Change(st->owner);
CommandCost cost(EXPENSES_PROPERTY, _price[PR_STATION_VALUE] >> 1);
SubtractMoneyFromCompany(cost);
Company *c;
if (!_settings_game.economy.infrastructure_maintenance) {
FOR_ALL_STATIONS(st) {
cur_company.Change(st->owner);
CommandCost cost(EXPENSES_PROPERTY, _price[PR_STATION_VALUE] >> 1);
SubtractMoneyFromCompany(cost);
}
} else {
/* Improved monthly infrastructure costs. */
FOR_ALL_COMPANIES(c) {
cur_company.Change(c->index);
CommandCost cost(EXPENSES_PROPERTY);
for (RailType rt = RAILTYPE_BEGIN; rt < RAILTYPE_END; rt++) {
if (c->infrastructure.rail[rt] != 0) cost.AddCost(RailMaintenanceCost(rt, c->infrastructure.rail[rt]));
}
cost.AddCost(SignalMaintenanceCost(c->infrastructure.signal));
for (RoadType rt = ROADTYPE_BEGIN; rt < ROADTYPE_END; rt++) {
if (c->infrastructure.road[rt] != 0) cost.AddCost(RoadMaintenanceCost(rt, c->infrastructure.road[rt]));
}
cost.AddCost(CanalMaintenanceCost(c->infrastructure.water));
cost.AddCost(StationMaintenanceCost(c->infrastructure.station));
cost.AddCost(AirportMaintenanceCost(c->index));
SubtractMoneyFromCompany(cost);
}
}
cur_company.Restore();
/* Only run the economic statics and update company stats every 3rd month (1st of quarter). */
if (!HasBit(1 << 0 | 1 << 3 | 1 << 6 | 1 << 9, _cur_month)) return;
Company *c;
FOR_ALL_COMPANIES(c) {
memmove(&c->old_economy[1], &c->old_economy[0], sizeof(c->old_economy) - sizeof(c->old_economy[0]));
c->old_economy[0] = c->cur_economy;
@ -713,6 +736,7 @@ void RecomputePrices()
SetWindowClassesDirty(WC_BUILD_VEHICLE);
SetWindowClassesDirty(WC_REPLACE_VEHICLE);
SetWindowClassesDirty(WC_VEHICLE_DETAILS);
SetWindowClassesDirty(WC_COMPANY_INFRASTRUCTURE);
InvalidateWindowData(WC_PAYMENT_RATES, 0);
}

View File

@ -132,6 +132,11 @@ enum Price {
PR_CLEAR_AQUEDUCT,
PR_BUILD_LOCK,
PR_CLEAR_LOCK,
PR_INFRASTRUCTURE_RAIL,
PR_INFRASTRUCTURE_ROAD,
PR_INFRASTRUCTURE_WATER,
PR_INFRASTRUCTURE_STATION,
PR_INFRASTRUCTURE_AIRPORT,
PR_END,
INVALID_PRICE = 0xFF

View File

@ -1156,6 +1156,7 @@ STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :{LTBLUE}Allow d
STR_CONFIG_SETTING_ADJACENT_STATIONS :{LTBLUE}Allow building adjacent stations: {ORANGE}{STRING}
STR_CONFIG_SETTING_DYNAMIC_ENGINES :{LTBLUE}Enable multiple NewGRF engine sets: {ORANGE}{STRING}
STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}Changing this setting is not possible when there are vehicles
STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :{LTBLUE}Infrastructure maintenance: {ORANGE}{STRING1}
STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :{LTBLUE}Airports never expire: {ORANGE}{STRING1}
@ -2788,6 +2789,8 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Canals
STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stations:
STR_COMPANY_INFRASTRUCTURE_VIEW_STATIONS :{WHITE}Station tiles
STR_COMPANY_INFRASTRUCTURE_VIEW_AIRPORTS :{WHITE}Airports
STR_COMPANY_INFRASTRUCTURE_VIEW_COST :{WHITE}{1:CURRENCY_LONG}/yr ({0:COMMA})
STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENCY_LONG}/yr
# Industry directory
STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industries

View File

@ -3635,6 +3635,10 @@ static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, B
_string_to_grf_mapping[&as->name] = _cur.grffile->grfid;
break;
case 0x11: // Maintenance cost factor
as->maintenance_cost = buf->ReadWord();
break;
default:
ret = CIR_UNKNOWN;
break;
@ -3941,6 +3945,10 @@ static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteR
_string_to_grf_mapping[&rti->strings.name] = _cur.grffile->grfid;
break;
case 0x1C: // Maintenance cost factor
rti->maintenance_multiplier = buf->ReadWord();
break;
default:
ret = CIR_UNKNOWN;
break;
@ -3984,6 +3992,7 @@ static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, Byte
case 0x13: // Construction cost
case 0x14: // Speed limit
case 0x1B: // Name of railtype
case 0x1C: // Maintenance cost factor
buf->ReadWord();
break;

View File

@ -76,6 +76,7 @@ struct AirportSpec {
TTDPAirportType ttd_airport_type; ///< ttdpatch airport type (Small/Large/Helipad/Oilrig)
AirportClassID cls_id; ///< the class to which this airport type belongs
SpriteID preview_sprite; ///< preview sprite for this airport
uint16 maintenance_cost; ///< maintenance cost mulltiplier
/* Newgrf data */
bool enabled; ///< entity still avaible (by default true).newgrf can disable it, though
struct GRFFileProps grf_prop; ///< properties related the the grf file

View File

@ -20,6 +20,7 @@
#include "slope_type.h"
#include "strings_type.h"
#include "date_type.h"
#include "core/math_func.hpp"
/** Railtype flags. */
enum RailTypeFlags {
@ -188,6 +189,11 @@ struct RailtypeInfo {
*/
uint16 cost_multiplier;
/**
* Cost multiplier for maintenance of this rail type
*/
uint16 maintenance_multiplier;
/**
* Acceleration type of this rail type
*/
@ -363,6 +369,28 @@ static inline Money RailConvertCost(RailType from, RailType to)
return rebuildcost;
}
/**
* Calculates the maintenance cost of a number of track bits.
* @param railtype The railtype to get the cost of.
* @param num Number of track bits.
* @return Total cost.
*/
static inline Money RailMaintenanceCost(RailType railtype, uint32 num)
{
assert(railtype < RAILTYPE_END);
return (_price[PR_INFRASTRUCTURE_RAIL] * GetRailTypeInfo(railtype)->maintenance_multiplier * num * (1 + IntSqrt(num))) >> 11; // 4 bits fraction for the multiplier and 7 bits scaling.
}
/**
* Calculates the maintenance cost of a number of signals.
* @param num Number of signals.
* @return Total cost.
*/
static inline Money SignalMaintenanceCost(uint32 num)
{
return (_price[PR_INFRASTRUCTURE_RAIL] * 15 * num * (1 + IntSqrt(num))) >> 8; // 1 bit fraction for the multiplier and 7 bits scaling.
}
void DrawTrainDepotSprite(int x, int y, int image, RailType railtype);
int TicksToLeaveDepot(const Train *v);

View File

@ -17,6 +17,7 @@
#include "direction_type.h"
#include "company_type.h"
#include "tile_type.h"
#include "economy_func.h"
/**
* Iterate through each set RoadType in a RoadTypes value.
@ -148,6 +149,19 @@ static inline RoadBits AxisToRoadBits(Axis a)
return a == AXIS_X ? ROAD_X : ROAD_Y;
}
/**
* Calculates the maintenance cost of a number of road bits.
* @param roadtype Road type to get the cost for.
* @param num Number of road bits.
* @return Total cost.
*/
static inline Money RoadMaintenanceCost(RoadType roadtype, uint32 num)
{
assert(roadtype < ROADTYPE_END);
return (_price[PR_INFRASTRUCTURE_ROAD] * (roadtype == ROADTYPE_TRAM ? 3 : 2) * num * (1 + IntSqrt(num))) >> 9; // 2 bits fraction for the multiplier and 7 bits scaling.
}
bool HasRoadTypesAvail(const CompanyID company, const RoadTypes rts);
bool ValParamRoadType(const RoadType rt);
RoadTypes GetCompanyRoadtypes(const CompanyID company);

View File

@ -230,8 +230,9 @@
* 163 22767
* 164 23290
* 165 23304
* 166 23415
*/
extern const uint16 SAVEGAME_VERSION = 165; ///< Current savegame version of OpenTTD.
extern const uint16 SAVEGAME_VERSION = 166; ///< Current savegame version of OpenTTD.
SavegameType _savegame_type; ///< type of savegame we are loading

View File

@ -946,6 +946,17 @@ static bool RedrawTownAuthority(int32 p1)
return true;
}
/**
* Invalidate the company infrastructure details window after a infrastructure maintenance setting change.
* @param p1 Unused.
* @return Always true.
*/
static bool InvalidateCompanyInfrastructureWindow(int32 p1)
{
InvalidateWindowClassesData(WC_COMPANY_INFRASTRUCTURE);
return true;
}
/*
* A: competitors
* B: competitor start time. Deprecated since savegame version 110.

View File

@ -1492,6 +1492,7 @@ static SettingEntry _settings_economy[] = {
SettingEntry("economy.inflation"),
SettingEntry("economy.smooth_economy"),
SettingEntry("economy.feeder_payment_share"),
SettingEntry("economy.infrastructure_maintenance"),
};
/** Economy sub-page */
static SettingsPage _settings_economy_page = {_settings_economy, lengthof(_settings_economy)};

View File

@ -416,6 +416,7 @@ struct EconomySettings {
bool station_noise_level; ///< build new airports when the town noise level is still within accepted limits
uint16 town_noise_population[3]; ///< population to base decision on noise evaluation (@see town_council_tolerance)
bool allow_town_level_crossings; ///< towns are allowed to build level crossings
bool infrastructure_maintenance; ///< enable monthly maintenance fee for owner infrastructure
};
/** Settings related to stations. */

View File

@ -523,3 +523,22 @@ StationRect& StationRect::operator = (const Rect &src)
this->bottom = src.bottom;
return *this;
}
/**
* Calculates the maintenance cost of all airports of a company.
* @param owner Company.
* @return Total cost.
*/
Money AirportMaintenanceCost(Owner owner)
{
Money total_cost = 0;
const Station *st;
FOR_ALL_STATIONS(st) {
if (st->owner == owner && (st->facilities & FACIL_AIRPORT)) {
total_cost += _price[PR_INFRASTRUCTURE_AIRPORT] * st->airport.GetSpec()->maintenance_cost;
}
}
/* 3 bits fraction for the maintenance cost factor. */
return total_cost >> 3;
}

View File

@ -18,6 +18,7 @@
#include "road_type.h"
#include "cargo_type.h"
#include "company_type.h"
#include "economy_func.h"
void ModifyStationRatingAround(TileIndex tile, Owner owner, int amount, uint radius);
@ -46,4 +47,16 @@ bool IsStationTileElectrifiable(TileIndex tile);
void UpdateAirportsNoise();
/**
* Calculates the maintenance cost of a number of station tiles.
* @param num Number of station tiles.
* @return Total cost.
*/
static inline Money StationMaintenanceCost(uint32 num)
{
return (_price[PR_INFRASTRUCTURE_STATION] * num * (1 + IntSqrt(num))) >> 7; // 7 bits scaling.
}
Money AirportMaintenanceCost(Owner owner);
#endif /* STATION_FUNC_H */

View File

@ -381,36 +381,36 @@ static Direction _default_airports_rotation[] = {
#undef MKEND
/** General AirportSpec definition. */
#define AS_GENERIC(fsm, att, rot, att_len, depot_tbl, num_depots, size_x, size_y, noise, catchment, min_year, max_year, ttdpatch_type, class_id, name, preview, enabled) \
{fsm, att, rot, att_len, depot_tbl, num_depots, size_x, size_y, noise, catchment, min_year, max_year, name, ttdpatch_type, class_id, preview, enabled, GRFFileProps(AT_INVALID)}
#define AS_GENERIC(fsm, att, rot, att_len, depot_tbl, num_depots, size_x, size_y, noise, catchment, min_year, max_year, maint_cost, ttdpatch_type, class_id, name, preview, enabled) \
{fsm, att, rot, att_len, depot_tbl, num_depots, size_x, size_y, noise, catchment, min_year, max_year, name, ttdpatch_type, class_id, preview, maint_cost, enabled, GRFFileProps(AT_INVALID)}
/** AirportSpec definition for airports without any depot. */
#define AS_ND(ap_name, size_x, size_y, min_year, max_year, catchment, noise, ttdpatch_type, class_id, name, preview) \
#define AS_ND(ap_name, size_x, size_y, min_year, max_year, catchment, noise, maint_cost, ttdpatch_type, class_id, name, preview) \
AS_GENERIC(&_airportfta_##ap_name, _tile_table_##ap_name, _default_airports_rotation, lengthof(_tile_table_##ap_name), NULL, 0, \
size_x, size_y, noise, catchment, min_year, max_year, ttdpatch_type, class_id, name, preview, true)
size_x, size_y, noise, catchment, min_year, max_year, maint_cost, ttdpatch_type, class_id, name, preview, true)
/** AirportSpec definition for airports with at least one depot. */
#define AS(ap_name, size_x, size_y, min_year, max_year, catchment, noise, ttdpatch_type, class_id, name, preview) \
#define AS(ap_name, size_x, size_y, min_year, max_year, catchment, noise, maint_cost, ttdpatch_type, class_id, name, preview) \
AS_GENERIC(&_airportfta_##ap_name, _tile_table_##ap_name, _default_airports_rotation, lengthof(_tile_table_##ap_name), _airport_depots_##ap_name, lengthof(_airport_depots_##ap_name), \
size_x, size_y, noise, catchment, min_year, max_year, ttdpatch_type, class_id, name, preview, true)
size_x, size_y, noise, catchment, min_year, max_year, maint_cost, ttdpatch_type, class_id, name, preview, true)
/* The helidepot and helistation have ATP_TTDP_SMALL because they are at ground level */
extern const AirportSpec _origin_airport_specs[] = {
AS(country, 4, 3, 0, 1959, 4, 3, ATP_TTDP_SMALL, APC_SMALL, STR_AIRPORT_SMALL, SPR_AIRPORT_PREVIEW_SMALL),
AS(city, 6, 6, 1955, MAX_YEAR, 5, 5, ATP_TTDP_LARGE, APC_LARGE, STR_AIRPORT_CITY, SPR_AIRPORT_PREVIEW_LARGE),
AS_ND(heliport, 1, 1, 1963, MAX_YEAR, 4, 1, ATP_TTDP_HELIPORT, APC_HELIPORT, STR_AIRPORT_HELIPORT, SPR_AIRPORT_PREVIEW_HELIPORT),
AS(metropolitan, 6, 6, 1980, MAX_YEAR, 6, 8, ATP_TTDP_LARGE, APC_LARGE, STR_AIRPORT_METRO, SPR_AIRPORT_PREVIEW_METROPOLITAN),
AS(international, 7, 7, 1990, MAX_YEAR, 8, 17, ATP_TTDP_LARGE, APC_HUB, STR_AIRPORT_INTERNATIONAL, SPR_AIRPORT_PREVIEW_INTERNATIONAL),
AS(commuter, 5, 4, 1983, MAX_YEAR, 4, 4, ATP_TTDP_SMALL, APC_SMALL, STR_AIRPORT_COMMUTER, SPR_AIRPORT_PREVIEW_COMMUTER),
AS(helidepot, 2, 2, 1976, MAX_YEAR, 4, 2, ATP_TTDP_SMALL, APC_HELIPORT, STR_AIRPORT_HELIDEPOT, SPR_AIRPORT_PREVIEW_HELIDEPOT),
AS(intercontinental, 9, 11, 2002, MAX_YEAR, 10, 25, ATP_TTDP_LARGE, APC_HUB, STR_AIRPORT_INTERCONTINENTAL, SPR_AIRPORT_PREVIEW_INTERCONTINENTAL),
AS(helistation, 4, 2, 1980, MAX_YEAR, 4, 3, ATP_TTDP_SMALL, APC_HELIPORT, STR_AIRPORT_HELISTATION, SPR_AIRPORT_PREVIEW_HELISTATION),
AS_GENERIC(&_airportfta_oilrig, NULL, _default_airports_rotation, 0, NULL, 0, 1, 1, 0, 4, 0, 0, ATP_TTDP_OILRIG, APC_HELIPORT, STR_NULL, 0, false),
AS(country, 4, 3, 0, 1959, 4, 3, 7, ATP_TTDP_SMALL, APC_SMALL, STR_AIRPORT_SMALL, SPR_AIRPORT_PREVIEW_SMALL),
AS(city, 6, 6, 1955, MAX_YEAR, 5, 5, 24, ATP_TTDP_LARGE, APC_LARGE, STR_AIRPORT_CITY, SPR_AIRPORT_PREVIEW_LARGE),
AS_ND(heliport, 1, 1, 1963, MAX_YEAR, 4, 1, 4, ATP_TTDP_HELIPORT, APC_HELIPORT, STR_AIRPORT_HELIPORT, SPR_AIRPORT_PREVIEW_HELIPORT),
AS(metropolitan, 6, 6, 1980, MAX_YEAR, 6, 8, 28, ATP_TTDP_LARGE, APC_LARGE, STR_AIRPORT_METRO, SPR_AIRPORT_PREVIEW_METROPOLITAN),
AS(international, 7, 7, 1990, MAX_YEAR, 8, 17, 42, ATP_TTDP_LARGE, APC_HUB, STR_AIRPORT_INTERNATIONAL, SPR_AIRPORT_PREVIEW_INTERNATIONAL),
AS(commuter, 5, 4, 1983, MAX_YEAR, 4, 4, 20, ATP_TTDP_SMALL, APC_SMALL, STR_AIRPORT_COMMUTER, SPR_AIRPORT_PREVIEW_COMMUTER),
AS(helidepot, 2, 2, 1976, MAX_YEAR, 4, 2, 7, ATP_TTDP_SMALL, APC_HELIPORT, STR_AIRPORT_HELIDEPOT, SPR_AIRPORT_PREVIEW_HELIDEPOT),
AS(intercontinental, 9, 11, 2002, MAX_YEAR, 10, 25, 72, ATP_TTDP_LARGE, APC_HUB, STR_AIRPORT_INTERCONTINENTAL, SPR_AIRPORT_PREVIEW_INTERCONTINENTAL),
AS(helistation, 4, 2, 1980, MAX_YEAR, 4, 3, 14, ATP_TTDP_SMALL, APC_HELIPORT, STR_AIRPORT_HELISTATION, SPR_AIRPORT_PREVIEW_HELISTATION),
AS_GENERIC(&_airportfta_oilrig, NULL, _default_airports_rotation, 0, NULL, 0, 1, 1, 0, 4, 0, 0, 0, ATP_TTDP_OILRIG, APC_HELIPORT, STR_NULL, 0, false),
};
assert_compile(NEW_AIRPORT_OFFSET == lengthof(_origin_airport_specs));
AirportSpec AirportSpec::dummy = AS_GENERIC(&_airportfta_dummy, NULL, _default_airports_rotation, 0, NULL, 0, 0, 0, 0, 0, MIN_YEAR, MIN_YEAR, ATP_TTDP_LARGE, APC_BEGIN, STR_NULL, 0, false);
AirportSpec AirportSpec::dummy = AS_GENERIC(&_airportfta_dummy, NULL, _default_airports_rotation, 0, NULL, 0, 0, 0, 0, 0, MIN_YEAR, MIN_YEAR, 0, ATP_TTDP_LARGE, APC_BEGIN, STR_NULL, 0, false);
#undef AS
#undef AS_ND

View File

@ -76,5 +76,10 @@ extern const PriceBaseSpec _price_base_specs[] = {
{ 2000, PCAT_CONSTRUCTION, GSF_END, PR_CLEAR_BRIDGE }, ///< PR_CLEAR_AQUEDUCT
{ 7500, PCAT_CONSTRUCTION, GSF_END, PR_CLEAR_WATER }, ///< PR_BUILD_LOCK
{ 2000, PCAT_CONSTRUCTION, GSF_END, PR_CLEAR_WATER }, ///< PR_CLEAR_LOCK
{ 12, PCAT_RUNNING, GSF_END, PR_BUILD_RAIL }, ///< PR_INFRASTRUCTURE_RAIL
{ 10, PCAT_RUNNING, GSF_END, PR_BUILD_ROAD }, ///< PR_INFRASTRUCTURE_ROAD
{ 8, PCAT_RUNNING, GSF_END, PR_BUILD_CANAL }, ///< PR_INFRASTRUCTURE_WATER
{ 100, PCAT_RUNNING, GSF_END, PR_STATION_VALUE }, ///< PR_INFRASTRUCTURE_STATION
{ 5000, PCAT_RUNNING, GSF_END, PR_BUILD_STATION_AIRPORT}, ///< PR_INFRASTRUCTURE_AIRPORT
};
assert_compile(lengthof(_price_base_specs) == PR_END);

View File

@ -81,6 +81,9 @@ static const RailtypeInfo _original_railtypes[] = {
/* cost multiplier */
8,
/* maintenance cost multiplier */
8,
/* acceleration type */
0,
@ -175,6 +178,9 @@ static const RailtypeInfo _original_railtypes[] = {
/* cost multiplier */
12,
/* maintenance cost multiplier */
12,
/* acceleration type */
0,
@ -265,6 +271,9 @@ static const RailtypeInfo _original_railtypes[] = {
/* cost multiplier */
16,
/* maintenance cost multiplier */
16,
/* acceleration type */
1,
@ -355,6 +364,9 @@ static const RailtypeInfo _original_railtypes[] = {
/* cost multiplier */
24,
/* maintenance cost multiplier */
24,
/* acceleration type */
2,

View File

@ -39,6 +39,7 @@ static bool InvalidateNewGRFChangeWindows(int32 p1);
static bool InvalidateIndustryViewWindow(int32 p1);
static bool InvalidateAISettingsWindow(int32 p1);
static bool RedrawTownAuthority(int32 p1);
static bool InvalidateCompanyInfrastructureWindow(int32 p1);
extern bool UpdateNewGRFConfigPalette(int32 p1);
static bool ZoomMinMaxChanged(int32 p1);
@ -1237,6 +1238,14 @@ def = 4000
min = 800
max = 65535
[SDT_BOOL]
base = GameSettings
var = economy.infrastructure_maintenance
from = 166
def = false
str = STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE
proc = InvalidateCompanyInfrastructureWindow
##
[SDT_VAR]
base = GameSettings

View File

@ -16,6 +16,8 @@
#include "company_type.h"
#include "slope_type.h"
#include "water_map.h"
#include "economy_func.h"
#include "core/math_func.hpp"
/**
* Describes the behaviour of a tile during flooding.
@ -43,4 +45,14 @@ void MakeWaterKeepingClass(TileIndex tile, Owner o);
bool RiverModifyDesertZone(TileIndex tile, void *data);
/**
* Calculates the maintenance cost of a number of canal tiles.
* @param num Number of canal tiles.
* @return Total cost.
*/
static inline Money CanalMaintenanceCost(uint32 num)
{
return (_price[PR_INFRASTRUCTURE_WATER] * num * (1 + IntSqrt(num))) >> 6; // 6 bits scaling.
}
#endif /* WATER_H */