# HG changeset patch # User truebrain # Date 2011-11-23 16:05:19 # Node ID c1e881f954d65ac84e0fb5ba2caea9aee4429ce5 # Parent ceff9a227677802ea1fccbfa9a534d373b737ddf (svn r23298) -Add: track statistics of all incoming and outgoing goods. Incoming based on TownEffect, outgoing based on CargoType (based on patch by Terkhen) diff --git a/bin/ai/compat_0.7.nut b/bin/ai/compat_0.7.nut --- a/bin/ai/compat_0.7.nut +++ b/bin/ai/compat_0.7.nut @@ -326,3 +326,5 @@ AICompany.GetCompanyValue <- function(co { return AICompany.GetQuarterlyCompanyValue(company, AICompany.CURRENT_QUARTER); } + +AITown.GetLastMonthTransported <- AITown.GetLastMonthSupplied; diff --git a/bin/ai/compat_1.0.nut b/bin/ai/compat_1.0.nut --- a/bin/ai/compat_1.0.nut +++ b/bin/ai/compat_1.0.nut @@ -77,3 +77,5 @@ AICompany.GetCompanyValue <- function(co { return AICompany.GetQuarterlyCompanyValue(company, AICompany.CURRENT_QUARTER); } + +AITown.GetLastMonthTransported <- AITown.GetLastMonthSupplied; diff --git a/bin/ai/compat_1.1.nut b/bin/ai/compat_1.1.nut --- a/bin/ai/compat_1.1.nut +++ b/bin/ai/compat_1.1.nut @@ -13,3 +13,5 @@ AICompany.GetCompanyValue <- function(co { return AICompany.GetQuarterlyCompanyValue(company, AICompany.CURRENT_QUARTER); } + +AITown.GetLastMonthTransported <- AITown.GetLastMonthSupplied; diff --git a/src/ai/api/ai_cargo.cpp b/src/ai/api/ai_cargo.cpp --- a/src/ai/api/ai_cargo.cpp +++ b/src/ai/api/ai_cargo.cpp @@ -20,6 +20,11 @@ return (cargo_type < NUM_CARGO && ::CargoSpec::Get(cargo_type)->IsValid()); } +/* static */ bool AICargo::IsValidTownEffect(TownEffect towneffect_type) +{ + return (towneffect_type >= TE_BEGIN && towneffect_type < TE_END); +} + /* static */ char *AICargo::GetCargoLabel(CargoID cargo_type) { if (!IsValidCargo(cargo_type)) return NULL; diff --git a/src/ai/api/ai_cargo.hpp b/src/ai/api/ai_cargo.hpp --- a/src/ai/api/ai_cargo.hpp +++ b/src/ai/api/ai_cargo.hpp @@ -63,6 +63,13 @@ public: static bool IsValidCargo(CargoID cargo_type); /** + * Checks whether the given town effect type is valid. + * @param towneffect_type The town effect to check. + * @return True if and only if the town effect type is valid. + */ + static bool IsValidTownEffect(TownEffect towneffect_type); + + /** * Gets the string representation of the cargo label. * @param cargo_type The cargo to get the string representation of. * @pre AICargo::IsValidCargo(cargo_type). diff --git a/src/ai/api/ai_cargo.hpp.sq b/src/ai/api/ai_cargo.hpp.sq --- a/src/ai/api/ai_cargo.hpp.sq +++ b/src/ai/api/ai_cargo.hpp.sq @@ -55,12 +55,13 @@ void SQAICargo_Register(Squirrel *engine SQAICargo.DefSQConst(engine, AICargo::CT_AUTO_REFIT, "CT_AUTO_REFIT"); SQAICargo.DefSQConst(engine, AICargo::CT_NO_REFIT, "CT_NO_REFIT"); - SQAICargo.DefSQStaticMethod(engine, &AICargo::IsValidCargo, "IsValidCargo", 2, ".i"); - SQAICargo.DefSQStaticMethod(engine, &AICargo::GetCargoLabel, "GetCargoLabel", 2, ".i"); - SQAICargo.DefSQStaticMethod(engine, &AICargo::IsFreight, "IsFreight", 2, ".i"); - SQAICargo.DefSQStaticMethod(engine, &AICargo::HasCargoClass, "HasCargoClass", 3, ".ii"); - SQAICargo.DefSQStaticMethod(engine, &AICargo::GetTownEffect, "GetTownEffect", 2, ".i"); - SQAICargo.DefSQStaticMethod(engine, &AICargo::GetCargoIncome, "GetCargoIncome", 4, ".iii"); + SQAICargo.DefSQStaticMethod(engine, &AICargo::IsValidCargo, "IsValidCargo", 2, ".i"); + SQAICargo.DefSQStaticMethod(engine, &AICargo::IsValidTownEffect, "IsValidTownEffect", 2, ".i"); + SQAICargo.DefSQStaticMethod(engine, &AICargo::GetCargoLabel, "GetCargoLabel", 2, ".i"); + SQAICargo.DefSQStaticMethod(engine, &AICargo::IsFreight, "IsFreight", 2, ".i"); + SQAICargo.DefSQStaticMethod(engine, &AICargo::HasCargoClass, "HasCargoClass", 3, ".ii"); + SQAICargo.DefSQStaticMethod(engine, &AICargo::GetTownEffect, "GetTownEffect", 2, ".i"); + SQAICargo.DefSQStaticMethod(engine, &AICargo::GetCargoIncome, "GetCargoIncome", 4, ".iii"); SQAICargo.PostRegister(engine); } diff --git a/src/ai/api/ai_changelog.hpp b/src/ai/api/ai_changelog.hpp --- a/src/ai/api/ai_changelog.hpp +++ b/src/ai/api/ai_changelog.hpp @@ -23,6 +23,7 @@ * * \li AICargo::CT_AUTO_REFIT * \li AICargo::CT_NO_REFIT + * \li AICargo::IsValidTownEffect * \li AICargoList_StationAccepting * \li AICompany::GetQuarterlyIncome * \li AICompany::GetQuarterlyExpenses @@ -34,12 +35,25 @@ * \li AIOrder::GetOrderRefit * \li AIOrder::IsRefitOrder * \li AIOrder::SetOrderRefit + * \li AITown::GetLastMonthReceived * \li AITown::GetTownAuthority * \li AIVehicle::ERR_VEHICLE_TOO_LONG in case vehicle length limit is reached * + * API renames: + * \li AITown::GetLastMonthTransported to AITown::GetLastMonthSupplied to better + * reflect what it does + * * API removals: * \li AICompany::GetCompanyValue, use AICompany::GetQuarterlyCompanyValue instead. * + * Other changes: + * \li AITown::GetLastMonthProduction no longer has prerequisites based on town + * effects. + * \li AITown::GetLastMonthTransported no longer has prerequisites based on + * town effects. + * \li AITown::GetLastMonthTransportedPercentage no longer has prerequisites + * based on town effects. + * * \b 1.1.2 * * No changes diff --git a/src/ai/api/ai_town.cpp b/src/ai/api/ai_town.cpp --- a/src/ai/api/ai_town.cpp +++ b/src/ai/api/ai_town.cpp @@ -70,25 +70,17 @@ const Town *t = ::Town::Get(town_id); - switch (AICargo::GetTownEffect(cargo_id)) { - case AICargo::TE_PASSENGERS: return t->pass.old_max; - case AICargo::TE_MAIL: return t->mail.old_max; - default: return -1; - } + return t->supplied[cargo_id].old_max; } -/* static */ int32 AITown::GetLastMonthTransported(TownID town_id, CargoID cargo_id) +/* static */ int32 AITown::GetLastMonthSupplied(TownID town_id, CargoID cargo_id) { if (!IsValidTown(town_id)) return -1; if (!AICargo::IsValidCargo(cargo_id)) return -1; const Town *t = ::Town::Get(town_id); - switch (AICargo::GetTownEffect(cargo_id)) { - case AICargo::TE_PASSENGERS: return t->pass.old_act; - case AICargo::TE_MAIL: return t->mail.old_act; - default: return -1; - } + return t->supplied[cargo_id].old_act; } /* static */ int32 AITown::GetLastMonthTransportedPercentage(TownID town_id, CargoID cargo_id) @@ -97,12 +89,17 @@ if (!AICargo::IsValidCargo(cargo_id)) return -1; const Town *t = ::Town::Get(town_id); + return ::ToPercent8(t->GetPercentTransported(cargo_id)); +} - switch (AICargo::GetTownEffect(cargo_id)) { - case AICargo::TE_PASSENGERS: return ::ToPercent8(t->GetPercentPassTransported()); - case AICargo::TE_MAIL: return ::ToPercent8(t->GetPercentMailTransported()); - default: return -1; - } +/* static */ int32 AITown::GetLastMonthReceived(TownID town_id, AICargo::TownEffect towneffect_id) +{ + if (!IsValidTown(town_id)) return -1; + if (!AICargo::IsValidTownEffect(towneffect_id)) return -1; + + const Town *t = ::Town::Get(town_id); + + return t->received[towneffect_id].old_act; } /* static */ int32 AITown::GetDistanceManhattanToTile(TownID town_id, TileIndex tile) diff --git a/src/ai/api/ai_town.hpp b/src/ai/api/ai_town.hpp --- a/src/ai/api/ai_town.hpp +++ b/src/ai/api/ai_town.hpp @@ -12,6 +12,7 @@ #ifndef AI_TOWN_HPP #define AI_TOWN_HPP +#include "ai_cargo.hpp" #include "ai_company.hpp" /** @@ -154,23 +155,21 @@ public: * @param cargo_id The index of the cargo. * @pre IsValidTown(town_id). * @pre AICargo::IsValidCargo(cargo_id). - * @pre AICargo::GetTownEffect(cargo_id) == TE_PASSENGERS || AICargo::GetTownEffect(cargo_id) == TE_MAIL. * @return The last month's production of the given cargo for this town. * @post Return value is always non-negative. */ static int32 GetLastMonthProduction(TownID town_id, CargoID cargo_id); /** - * Get the total amount of cargo transported from a town last month. - * @param town_id The index of the industry. + * Get the total amount of cargo supplied from a town last month. + * @param town_id The index of the town. * @param cargo_id The index of the cargo. * @pre IsValidTown(town_id). * @pre AICargo::IsValidCargo(cargo_id). - * @pre AICargo::GetTownEffect(cargo_id) == TE_PASSENGERS || AICargo::GetTownEffect(cargo_id) == TE_MAIL. - * @return The amount of given cargo transported from this town last month. + * @return The amount of cargo supplied for transport from this town last month. * @post Return value is always non-negative. */ - static int32 GetLastMonthTransported(TownID town_id, CargoID cargo_id); + static int32 GetLastMonthSupplied(TownID town_id, CargoID cargo_id); /** * Get the percentage of transported production of the given cargo at a town. @@ -178,13 +177,23 @@ public: * @param cargo_id The index of the cargo. * @pre IsValidTown(town_id). * @pre AICargo::IsValidCargo(cargo_id). - * @pre AICargo::GetTownEffect(cargo_id) == TE_PASSENGERS || AICargo::GetTownEffect(cargo_id) == TE_MAIL. * @return The percentage of given cargo transported from this town last month. * @post Return value is always non-negative. */ static int32 GetLastMonthTransportedPercentage(TownID town_id, CargoID cargo_id); /** + * Get the total amount of cargo effects received by a town last month. + * @param town_id The index of the town. + * @param towneffect_id The index of the cargo. + * @pre IsValidTown(town_id). + * @pre AICargo::IsValidTownEffect(cargo_id). + * @return The amount of cargo received by this town last month for this cargo effect. + * @post Return value is always non-negative. + */ + static int32 GetLastMonthReceived(TownID town_id, AICargo::TownEffect towneffect_id); + + /** * Get the manhattan distance from the tile to the AITown::GetLocation() * of the town. * @param town_id The town to get the distance to. diff --git a/src/ai/api/ai_town.hpp.sq b/src/ai/api/ai_town.hpp.sq --- a/src/ai/api/ai_town.hpp.sq +++ b/src/ai/api/ai_town.hpp.sq @@ -67,8 +67,9 @@ void SQAITown_Register(Squirrel *engine) SQAITown.DefSQStaticMethod(engine, &AITown::GetHouseCount, "GetHouseCount", 2, ".i"); SQAITown.DefSQStaticMethod(engine, &AITown::GetLocation, "GetLocation", 2, ".i"); SQAITown.DefSQStaticMethod(engine, &AITown::GetLastMonthProduction, "GetLastMonthProduction", 3, ".ii"); - SQAITown.DefSQStaticMethod(engine, &AITown::GetLastMonthTransported, "GetLastMonthTransported", 3, ".ii"); + SQAITown.DefSQStaticMethod(engine, &AITown::GetLastMonthSupplied, "GetLastMonthSupplied", 3, ".ii"); SQAITown.DefSQStaticMethod(engine, &AITown::GetLastMonthTransportedPercentage, "GetLastMonthTransportedPercentage", 3, ".ii"); + SQAITown.DefSQStaticMethod(engine, &AITown::GetLastMonthReceived, "GetLastMonthReceived", 3, ".ii"); SQAITown.DefSQStaticMethod(engine, &AITown::GetDistanceManhattanToTile, "GetDistanceManhattanToTile", 3, ".ii"); SQAITown.DefSQStaticMethod(engine, &AITown::GetDistanceSquareToTile, "GetDistanceSquareToTile", 3, ".ii"); SQAITown.DefSQStaticMethod(engine, &AITown::IsWithinTownInfluence, "IsWithinTownInfluence", 3, ".ii"); diff --git a/src/cargotype.h b/src/cargotype.h --- a/src/cargotype.h +++ b/src/cargotype.h @@ -23,12 +23,15 @@ typedef uint32 CargoLabel; /** Town growth effect when delivering cargo. */ enum TownEffect { - TE_NONE, ///< Cargo has no effect. - TE_PASSENGERS, ///< Cargo behaves passenger-like. - TE_MAIL, ///< Cargo behaves mail-like. - TE_GOODS, ///< Cargo behaves goods/candy-like. - TE_WATER, ///< Cargo behaves water-like. - TE_FOOD, ///< Cargo behaves food/fizzy-drinks-like. + TE_BEGIN = 0, + TE_NONE = TE_BEGIN, ///< Cargo has no effect. + TE_PASSENGERS, ///< Cargo behaves passenger-like. + TE_MAIL, ///< Cargo behaves mail-like. + TE_GOODS, ///< Cargo behaves goods/candy-like. + TE_WATER, ///< Cargo behaves water-like. + TE_FOOD, ///< Cargo behaves food/fizzy-drinks-like. + TE_END, ///< End of town effects. + NUM_TE = TE_END, ///< Amount of town effects. }; /** Cargo classes. */ diff --git a/src/economy.cpp b/src/economy.cpp --- a/src/economy.cpp +++ b/src/economy.cpp @@ -988,10 +988,9 @@ static Money DeliverGoods(int num_pieces company->cur_economy.delivered_cargo += accepted; if (accepted > 0) SetBit(company->cargo_types, cargo_type); - /* Increase town's counter for some special goods types */ + /* Increase town's counter for town effects */ const CargoSpec *cs = CargoSpec::Get(cargo_type); - if (cs->town_effect == TE_FOOD) st->town->food.new_act += accepted; - if (cs->town_effect == TE_WATER) st->town->water.new_act += accepted; + st->town->received[cs->town_effect].new_act += accepted; /* Determine profit */ Money profit = GetTransportedGoodsIncome(accepted, DistanceManhattan(source_tile, st->xy), days_in_transit, cargo_type); diff --git a/src/newgrf_town.cpp b/src/newgrf_town.cpp --- a/src/newgrf_town.cpp +++ b/src/newgrf_town.cpp @@ -91,32 +91,32 @@ uint32 TownGetVariable(byte variable, ui case 0xB2: return t->statues; case 0xB6: return ClampToU16(t->num_houses); case 0xB9: return t->growth_rate; - case 0xBA: return ClampToU16(t->pass.new_max); - case 0xBB: return GB(ClampToU16(t->pass.new_max), 8, 8); - case 0xBC: return ClampToU16(t->mail.new_max); - case 0xBD: return GB(ClampToU16(t->mail.new_max), 8, 8); - case 0xBE: return ClampToU16(t->pass.new_act); - case 0xBF: return GB(ClampToU16(t->pass.new_act), 8, 8); - case 0xC0: return ClampToU16(t->mail.new_act); - case 0xC1: return GB(ClampToU16(t->mail.new_act), 8, 8); - case 0xC2: return ClampToU16(t->pass.old_max); - case 0xC3: return GB(ClampToU16(t->pass.old_max), 8, 8); - case 0xC4: return ClampToU16(t->mail.old_max); - case 0xC5: return GB(ClampToU16(t->mail.old_max), 8, 8); - case 0xC6: return ClampToU16(t->pass.old_act); - case 0xC7: return GB(ClampToU16(t->pass.old_act), 8, 8); - case 0xC8: return ClampToU16(t->mail.old_act); - case 0xC9: return GB(ClampToU16(t->mail.old_act), 8, 8); - case 0xCA: return t->GetPercentPassTransported(); - case 0xCB: return t->GetPercentMailTransported(); - case 0xCC: return t->food.new_act; - case 0xCD: return GB(t->food.new_act, 8, 8); - case 0xCE: return t->water.new_act; - case 0xCF: return GB(t->water.new_act, 8, 8); - case 0xD0: return t->food.old_act; - case 0xD1: return GB(t->food.old_act, 8, 8); - case 0xD2: return t->water.old_act; - case 0xD3: return GB(t->water.old_act, 8, 8); + case 0xBA: return ClampToU16(t->supplied[CT_PASSENGERS].new_max); + case 0xBB: return GB(ClampToU16(t->supplied[CT_PASSENGERS].new_max), 8, 8); + case 0xBC: return ClampToU16(t->supplied[CT_MAIL].new_max); + case 0xBD: return GB(ClampToU16(t->supplied[CT_MAIL].new_max), 8, 8); + case 0xBE: return ClampToU16(t->supplied[CT_PASSENGERS].new_act); + case 0xBF: return GB(ClampToU16(t->supplied[CT_PASSENGERS].new_act), 8, 8); + case 0xC0: return ClampToU16(t->supplied[CT_MAIL].new_act); + case 0xC1: return GB(ClampToU16(t->supplied[CT_MAIL].new_act), 8, 8); + case 0xC2: return ClampToU16(t->supplied[CT_PASSENGERS].old_max); + case 0xC3: return GB(ClampToU16(t->supplied[CT_PASSENGERS].old_max), 8, 8); + case 0xC4: return ClampToU16(t->supplied[CT_MAIL].old_max); + case 0xC5: return GB(ClampToU16(t->supplied[CT_MAIL].old_max), 8, 8); + case 0xC6: return ClampToU16(t->supplied[CT_PASSENGERS].old_act); + case 0xC7: return GB(ClampToU16(t->supplied[CT_PASSENGERS].old_act), 8, 8); + case 0xC8: return ClampToU16(t->supplied[CT_MAIL].old_act); + case 0xC9: return GB(ClampToU16(t->supplied[CT_MAIL].old_act), 8, 8); + case 0xCA: return t->GetPercentTransported(CT_PASSENGERS); + case 0xCB: return t->GetPercentTransported(CT_MAIL); + case 0xCC: return t->received[TE_FOOD].new_act; + case 0xCD: return GB(t->received[TE_FOOD].new_act, 8, 8); + case 0xCE: return t->received[TE_WATER].new_act; + case 0xCF: return GB(t->received[TE_WATER].new_act, 8, 8); + case 0xD0: return t->received[TE_FOOD].old_act; + case 0xD1: return GB(t->received[TE_FOOD].old_act, 8, 8); + case 0xD2: return t->received[TE_WATER].old_act; + case 0xD3: return GB(t->received[TE_WATER].old_act, 8, 8); case 0xD4: return t->road_build_months; case 0xD5: return t->fund_buildings_months; } diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -568,21 +568,21 @@ static const OldChunks town_chunk[] = { OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Town, time_until_rebuild ), OCL_SVAR( OC_FILE_U8 | OC_VAR_I16, Town, growth_rate ), - OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, pass.new_max ), - OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, mail.new_max ), - OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, pass.new_act ), - OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, mail.new_act ), - OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, pass.old_max ), - OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, mail.old_max ), - OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, pass.old_act ), - OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, mail.old_act ), + OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_PASSENGERS].new_max ), + OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_MAIL].new_max ), + OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_PASSENGERS].new_act ), + OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_MAIL].new_act ), + OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_PASSENGERS].old_max ), + OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_MAIL].old_max ), + OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_PASSENGERS].old_act ), + OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_MAIL].old_act ), OCL_NULL( 2 ), ///< pct_pass_transported / pct_mail_transported, now computed on the fly - OCL_SVAR( OC_TTD | OC_UINT16, Town, food.new_act ), - OCL_SVAR( OC_TTD | OC_UINT16, Town, water.new_act ), - OCL_SVAR( OC_TTD | OC_UINT16, Town, food.old_act ), - OCL_SVAR( OC_TTD | OC_UINT16, Town, water.old_act ), + OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TE_FOOD].new_act ), + OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TE_WATER].new_act ), + OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TE_FOOD].old_act ), + OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TE_WATER].old_act ), OCL_SVAR( OC_UINT8, Town, road_build_months ), OCL_SVAR( OC_UINT8, Town, fund_buildings_months ), diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -128,30 +128,30 @@ static const SaveLoad _town_desc[] = { SLE_CONDARR(Town, unwanted, SLE_INT8, 8, 4, 103), SLE_CONDARR(Town, unwanted, SLE_INT8, MAX_COMPANIES, 104, SL_MAX_VERSION), - SLE_CONDVAR(Town, pass.old_max, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), - SLE_CONDVAR(Town, mail.old_max, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), - SLE_CONDVAR(Town, pass.new_max, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), - SLE_CONDVAR(Town, mail.new_max, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), - SLE_CONDVAR(Town, pass.old_act, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), - SLE_CONDVAR(Town, mail.old_act, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), - SLE_CONDVAR(Town, pass.new_act, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), - SLE_CONDVAR(Town, mail.new_act, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), + SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_max, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), + SLE_CONDVAR(Town, supplied[CT_MAIL].old_max, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), + SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_max, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), + SLE_CONDVAR(Town, supplied[CT_MAIL].new_max, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), + SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_act, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), + SLE_CONDVAR(Town, supplied[CT_MAIL].old_act, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), + SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_act, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), + SLE_CONDVAR(Town, supplied[CT_MAIL].new_act, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), - SLE_CONDVAR(Town, pass.old_max, SLE_UINT32, 9, SL_MAX_VERSION), - SLE_CONDVAR(Town, mail.old_max, SLE_UINT32, 9, SL_MAX_VERSION), - SLE_CONDVAR(Town, pass.new_max, SLE_UINT32, 9, SL_MAX_VERSION), - SLE_CONDVAR(Town, mail.new_max, SLE_UINT32, 9, SL_MAX_VERSION), - SLE_CONDVAR(Town, pass.old_act, SLE_UINT32, 9, SL_MAX_VERSION), - SLE_CONDVAR(Town, mail.old_act, SLE_UINT32, 9, SL_MAX_VERSION), - SLE_CONDVAR(Town, pass.new_act, SLE_UINT32, 9, SL_MAX_VERSION), - SLE_CONDVAR(Town, mail.new_act, SLE_UINT32, 9, SL_MAX_VERSION), + SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_max, SLE_UINT32, 9, 164), + SLE_CONDVAR(Town, supplied[CT_MAIL].old_max, SLE_UINT32, 9, 164), + SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_max, SLE_UINT32, 9, 164), + SLE_CONDVAR(Town, supplied[CT_MAIL].new_max, SLE_UINT32, 9, 164), + SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_act, SLE_UINT32, 9, 164), + SLE_CONDVAR(Town, supplied[CT_MAIL].old_act, SLE_UINT32, 9, 164), + SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_act, SLE_UINT32, 9, 164), + SLE_CONDVAR(Town, supplied[CT_MAIL].new_act, SLE_UINT32, 9, 164), SLE_CONDNULL(2, 0, 163), ///< pct_pass_transported / pct_mail_transported, now computed on the fly - SLE_VAR(Town, food.old_act, SLE_UINT16), - SLE_VAR(Town, water.old_act, SLE_UINT16), - SLE_VAR(Town, food.new_act, SLE_UINT16), - SLE_VAR(Town, water.new_act, SLE_UINT16), + SLE_CONDVAR(Town, received[TE_FOOD].old_act, SLE_UINT16, 0, 164), + SLE_CONDVAR(Town, received[TE_WATER].old_act, SLE_UINT16, 0, 164), + SLE_CONDVAR(Town, received[TE_FOOD].new_act, SLE_UINT16, 0, 164), + SLE_CONDVAR(Town, received[TE_WATER].new_act, SLE_UINT16, 0, 164), SLE_CONDVAR(Town, time_until_rebuild, SLE_FILE_U8 | SLE_VAR_U16, 0, 53), SLE_CONDVAR(Town, grow_counter, SLE_FILE_U8 | SLE_VAR_U16, 0, 53), @@ -178,6 +178,24 @@ static const SaveLoad _town_desc[] = { SLE_END() }; +static const SaveLoad _town_supplied_desc[] = { + SLE_CONDVAR(TransportedCargoStat, old_max, SLE_UINT32, 165, SL_MAX_VERSION), + SLE_CONDVAR(TransportedCargoStat, new_max, SLE_UINT32, 165, SL_MAX_VERSION), + SLE_CONDVAR(TransportedCargoStat, old_act, SLE_UINT32, 165, SL_MAX_VERSION), + SLE_CONDVAR(TransportedCargoStat, new_act, SLE_UINT32, 165, SL_MAX_VERSION), + + SLE_END() +}; + +static const SaveLoad _town_received_desc[] = { + SLE_CONDVAR(TransportedCargoStat, old_max, SLE_UINT16, 165, SL_MAX_VERSION), + SLE_CONDVAR(TransportedCargoStat, new_max, SLE_UINT16, 165, SL_MAX_VERSION), + SLE_CONDVAR(TransportedCargoStat, old_act, SLE_UINT16, 165, SL_MAX_VERSION), + SLE_CONDVAR(TransportedCargoStat, new_act, SLE_UINT16, 165, SL_MAX_VERSION), + + SLE_END() +}; + static void Save_HIDS() { Save_NewGRFMapping(_house_mngr); @@ -188,13 +206,25 @@ static void Load_HIDS() Load_NewGRFMapping(_house_mngr); } +static void RealSave_Town(Town *t) +{ + SlObject(t, _town_desc); + + for (CargoID i = 0; i < NUM_CARGO; i++) { + SlObject(&t->supplied[i], _town_supplied_desc); + } + for (int i = TE_BEGIN; i < NUM_TE; i++) { + SlObject(&t->received[i], _town_received_desc); + } +} + static void Save_TOWN() { Town *t; FOR_ALL_TOWNS(t) { SlSetArrayIndex(t->index); - SlObject(t, _town_desc); + SlAutolength((AutolengthProc*)RealSave_Town, t); } } @@ -206,6 +236,13 @@ static void Load_TOWN() Town *t = new (index) Town(); SlObject(t, _town_desc); + for (CargoID i = 0; i < NUM_CARGO; i++) { + SlObject(&t->supplied[i], _town_supplied_desc); + } + for (int i = TE_BEGIN; i < TE_END; i++) { + SlObject(&t->received[i], _town_received_desc); + } + if (t->townnamegrfid == 0 && !IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST)) { SlErrorCorrupt("Invalid town name generator"); } diff --git a/src/subsidy.cpp b/src/subsidy.cpp --- a/src/subsidy.cpp +++ b/src/subsidy.cpp @@ -170,7 +170,7 @@ static Subsidy *FindSubsidyPassengerRout const Town *src = Town::GetRandom(); if (src->population < SUBSIDY_PAX_MIN_POPULATION || - src->GetPercentPassTransported() > SUBSIDY_MAX_PCT_TRANSPORTED) { + src->GetPercentTransported(CT_PASSENGERS) > SUBSIDY_MAX_PCT_TRANSPORTED) { return NULL; } diff --git a/src/town.h b/src/town.h --- a/src/town.h +++ b/src/town.h @@ -18,6 +18,7 @@ #include "town_map.h" #include "subsidy_type.h" #include "newgrf_storage.h" +#include "cargotype.h" #include template @@ -66,16 +67,10 @@ struct Town : TownPool::PoolItem<&_town_ uint8 exclusive_counter; ///< months till the exclusivity expires int16 ratings[MAX_COMPANIES]; ///< ratings of each company for this town - TransportedCargoStat pass; ///< Passenger cargo statistics. - TransportedCargoStat mail; ///< Mail cargo statistics. - TransportedCargoStat food; ///< Food cargo statistics. - TransportedCargoStat water; ///< Water cargo statistics. + TransportedCargoStat supplied[NUM_CARGO]; ///< Cargo statistics about supplied cargo. + TransportedCargoStat received[NUM_TE]; ///< Cargo statistics about received cargotypes. - /** Percentage of passengers transported last month (0xFF=100%) */ - inline byte GetPercentPassTransported() const { return this->pass.old_act * 256 / (this->pass.old_max + 1); } - - /** Percentage of mail transported last month (0xFF=100%) */ - inline byte GetPercentMailTransported() const { return this->mail.old_act * 256 / (this->mail.old_max + 1); } + inline byte GetPercentTransported(CargoID cid) const { return this->supplied[cid].old_act * 256 / (this->supplied[cid].old_max + 1); } uint16 time_until_rebuild; ///< time until we rebuild a house diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -485,36 +485,24 @@ static void TileLoop_Town(TileIndex tile uint moved = MoveGoodsToStation(cargo, amt, ST_TOWN, t->index, stations.GetStations()); const CargoSpec *cs = CargoSpec::Get(cargo); - switch (cs->town_effect) { - case TE_PASSENGERS: - t->pass.new_max += amt; - t->pass.new_act += moved; - break; - - case TE_MAIL: - t->mail.new_max += amt; - t->mail.new_act += moved; - break; - - default: - break; - } + t->supplied[cs->Index()].new_max += amt; + t->supplied[cs->Index()].new_act += moved; } } else { if (GB(r, 0, 8) < hs->population) { uint amt = GB(r, 0, 8) / 8 + 1; if (EconomyIsInRecession()) amt = (amt + 1) >> 1; - t->pass.new_max += amt; - t->pass.new_act += MoveGoodsToStation(CT_PASSENGERS, amt, ST_TOWN, t->index, stations.GetStations()); + t->supplied[CT_PASSENGERS].new_max += amt; + t->supplied[CT_PASSENGERS].new_act += MoveGoodsToStation(CT_PASSENGERS, amt, ST_TOWN, t->index, stations.GetStations()); } if (GB(r, 8, 8) < hs->mail_generation) { uint amt = GB(r, 8, 8) / 8 + 1; if (EconomyIsInRecession()) amt = (amt + 1) >> 1; - t->mail.new_max += amt; - t->mail.new_act += MoveGoodsToStation(CT_MAIL, amt, ST_TOWN, t->index, stations.GetStations()); + t->supplied[CT_MAIL].new_max += amt; + t->supplied[CT_MAIL].new_act += MoveGoodsToStation(CT_MAIL, amt, ST_TOWN, t->index, stations.GetStations()); } } @@ -1401,8 +1389,8 @@ void UpdateTownRadius(Town *t) void UpdateTownMaxPass(Town *t) { - t->pass.old_max = t->population >> 3; - t->mail.old_max = t->population >> 4; + t->supplied[CT_PASSENGERS].old_max = t->population >> 3; + t->supplied[CT_MAIL].old_max = t->population >> 4; } /** @@ -2771,10 +2759,10 @@ static void UpdateTownGrowRate(Town *t) } if (_settings_game.game_creation.landscape == LT_ARCTIC) { - if (TileHeight(t->xy) >= GetSnowLine() && t->food.old_act == 0 && t->population > 90) return; + if (TileHeight(t->xy) >= GetSnowLine() && t->received[TE_FOOD].old_act == 0 && t->population > 90) return; } else if (_settings_game.game_creation.landscape == LT_TROPIC) { - if (GetTropicZone(t->xy) == TROPICZONE_DESERT && (t->food.old_act == 0 || t->water.old_act == 0) && t->population > 60) return; + if (GetTropicZone(t->xy) == TROPICZONE_DESERT && (t->received[TE_FOOD].old_act == 0 || t->received[TE_WATER].old_act == 0) && t->population > 60) return; } /* Use the normal growth rate values if new buildings have been funded in @@ -2794,10 +2782,8 @@ static void UpdateTownGrowRate(Town *t) static void UpdateTownAmounts(Town *t) { - t->pass.NewMonth(); - t->mail.NewMonth(); - t->food.NewMonth(); - t->water.NewMonth(); + for (CargoID i = 0; i < NUM_CARGO; i++) t->supplied[i].NewMonth(); + for (int i = TE_BEGIN; i < TE_END; i++) t->received[i].NewMonth(); SetWindowDirty(WC_TOWN_VIEW, t->index); } diff --git a/src/town_gui.cpp b/src/town_gui.cpp --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -368,12 +368,12 @@ public: SetDParam(1, this->town->num_houses); DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y, STR_TOWN_VIEW_POPULATION_HOUSES); - SetDParam(0, this->town->pass.old_act); - SetDParam(1, this->town->pass.old_max); + SetDParam(0, this->town->supplied[CT_PASSENGERS].old_act); + SetDParam(1, this->town->supplied[CT_PASSENGERS].old_max); DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX); - SetDParam(0, this->town->mail.old_act); - SetDParam(1, this->town->mail.old_max); + SetDParam(0, this->town->supplied[CT_MAIL].old_act); + SetDParam(1, this->town->supplied[CT_MAIL].old_max); DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX); StringID required_text = STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED; @@ -406,9 +406,9 @@ public: CargoID first_water_cargo = (water != NULL) ? water->Index() : (CargoID)CT_INVALID; StringID water_name = (water != NULL) ? water->name : STR_CARGO_PLURAL_WATER; - if (first_food_cargo != CT_INVALID && this->town->food.old_act > 0) { + if (first_food_cargo != CT_INVALID && this->town->received[TE_FOOD].old_act > 0) { SetDParam(0, first_food_cargo); - SetDParam(1, this->town->food.old_act); + SetDParam(1, this->town->received[TE_FOOD].old_act); DrawString(cargo_text_left, cargo_text_right, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_LAST_MONTH); } else { SetDParam(0, food_name); @@ -416,9 +416,9 @@ public: } if (cargo_needed_for_growth > 1) { - if (first_water_cargo != CT_INVALID && this->town->water.old_act > 0) { + if (first_water_cargo != CT_INVALID && this->town->received[TE_WATER].old_act > 0) { SetDParam(0, first_water_cargo); - SetDParam(1, this->town->water.old_act); + SetDParam(1, this->town->received[TE_WATER].old_act); DrawString(cargo_text_left, cargo_text_right, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_LAST_MONTH); } else { SetDParam(0, water_name);