Changeset - r18444:c1e881f954d6
[Not reviewed]
master
0 19 0
truebrain - 13 years ago 2011-11-23 16:05:19
truebrain@openttd.org
(svn r23298) -Add: track statistics of all incoming and outgoing goods. Incoming based on TownEffect, outgoing based on CargoType (based on patch by Terkhen)
19 files changed with 202 insertions and 142 deletions:
0 comments (0 inline, 0 general)
bin/ai/compat_0.7.nut
Show inline comments
 
@@ -323,6 +323,8 @@ AIList.ChangeItem <- AIList.SetValue;
 
AIRail.ERR_NONUNIFORM_STATIONS_DISABLED <- 0xFFFF;
 

	
 
AICompany.GetCompanyValue <- function(company)
 
{
 
	return AICompany.GetQuarterlyCompanyValue(company, AICompany.CURRENT_QUARTER);
 
}
 

	
 
AITown.GetLastMonthTransported <- AITown.GetLastMonthSupplied;
bin/ai/compat_1.0.nut
Show inline comments
 
@@ -74,6 +74,8 @@ AIList.ChangeItem <- AIList.SetValue;
 
AIRail.ERR_NONUNIFORM_STATIONS_DISABLED <- 0xFFFF;
 

	
 
AICompany.GetCompanyValue <- function(company)
 
{
 
	return AICompany.GetQuarterlyCompanyValue(company, AICompany.CURRENT_QUARTER);
 
}
 

	
 
AITown.GetLastMonthTransported <- AITown.GetLastMonthSupplied;
bin/ai/compat_1.1.nut
Show inline comments
 
@@ -10,6 +10,8 @@
 
AILog.Info("1.1 API compatability in effect.");
 

	
 
AICompany.GetCompanyValue <- function(company)
 
{
 
	return AICompany.GetQuarterlyCompanyValue(company, AICompany.CURRENT_QUARTER);
 
}
 

	
 
AITown.GetLastMonthTransported <- AITown.GetLastMonthSupplied;
src/ai/api/ai_cargo.cpp
Show inline comments
 
@@ -17,12 +17,17 @@
 

	
 
/* static */ bool AICargo::IsValidCargo(CargoID cargo_type)
 
{
 
	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;
 
	const CargoSpec *cargo = ::CargoSpec::Get(cargo_type);
 

	
 
	/* cargo->label is a uint32 packing a 4 character non-terminated string,
src/ai/api/ai_cargo.hpp
Show inline comments
 
@@ -60,12 +60,19 @@ public:
 
	 * @param cargo_type The cargo to check.
 
	 * @return True if and only if the cargo type is valid.
 
	 */
 
	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).
 
	 * @return The cargo label.
 
	 * @note Never use this to check if it is a certain cargo. NewGRF can
 
	 *  redefine all of the names.
src/ai/api/ai_cargo.hpp.sq
Show inline comments
 
@@ -52,15 +52,16 @@ void SQAICargo_Register(Squirrel *engine
 
	SQAICargo.DefSQConst(engine, AICargo::TE_GOODS,        "TE_GOODS");
 
	SQAICargo.DefSQConst(engine, AICargo::TE_WATER,        "TE_WATER");
 
	SQAICargo.DefSQConst(engine, AICargo::TE_FOOD,         "TE_FOOD");
 
	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);
 
}
src/ai/api/ai_changelog.hpp
Show inline comments
 
@@ -20,29 +20,43 @@
 
 * 1.2.0 is not yet released. The following changes are not set in stone yet.
 
 *
 
 * API additions:
 
 *
 
 * \li AICargo::CT_AUTO_REFIT
 
 * \li AICargo::CT_NO_REFIT
 
 * \li AICargo::IsValidTownEffect
 
 * \li AICargoList_StationAccepting
 
 * \li AICompany::GetQuarterlyIncome
 
 * \li AICompany::GetQuarterlyExpenses
 
 * \li AICompany::GetQuarterlyCargoDelivered
 
 * \li AICompany::GetQuarterlyPerformanceRating
 
 * \li AICompany::GetQuarterlyCompanyValue
 
 * \li AIController::GetOpsTillSuspend
 
 * \li AIInfo::AICONFIG_AI_DEVELOPER
 
 * \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
 
 *
 
 * \b 1.1.1
 
 *
src/ai/api/ai_town.cpp
Show inline comments
 
@@ -67,45 +67,42 @@
 
{
 
	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_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)
 
{
 
	if (!IsValidTown(town_id)) return -1;
 
	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)
 
{
 
	return AIMap::DistanceManhattan(tile, GetLocation(town_id));
 
}
src/ai/api/ai_town.hpp
Show inline comments
 
@@ -9,12 +9,13 @@
 

	
 
/** @file ai_town.hpp Everything to query towns. */
 

	
 
#ifndef AI_TOWN_HPP
 
#define AI_TOWN_HPP
 

	
 
#include "ai_cargo.hpp"
 
#include "ai_company.hpp"
 

	
 
/**
 
 * Class that handles all town related functions.
 
 */
 
class AITown : public AIObject {
 
@@ -151,43 +152,51 @@ public:
 
	/**
 
	 * Get the total last month's production of the given cargo at a town.
 
	 * @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 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.
 
	 * @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 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.
 
	 * @param tile The tile to get the distance to.
 
	 * @pre IsValidTown(town_id).
 
	 * @return The distance between town and tile.
src/ai/api/ai_town.hpp.sq
Show inline comments
 
@@ -64,14 +64,15 @@ void SQAITown_Register(Squirrel *engine)
 
	SQAITown.DefSQStaticMethod(engine, &AITown::IsValidTown,                       "IsValidTown",                       2, ".i");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::GetName,                           "GetName",                           2, ".i");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::GetPopulation,                     "GetPopulation",                     2, ".i");
 
	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");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::HasStatue,                         "HasStatue",                         2, ".i");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::IsCity,                            "IsCity",                            2, ".i");
 
	SQAITown.DefSQStaticMethod(engine, &AITown::GetRoadReworkDuration,             "GetRoadReworkDuration",             2, ".i");
src/cargotype.h
Show inline comments
 
@@ -20,18 +20,21 @@
 

	
 
/** Globally unique label of a cargo type. */
 
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. */
 
enum CargoClass {
 
	CC_NOAVAILABLE  = 0,       ///< No cargo class has been specified
 
	CC_PASSENGERS   = 1 <<  0, ///< Passengers
src/economy.cpp
Show inline comments
 
@@ -985,16 +985,15 @@ static Money DeliverGoods(int num_pieces
 
	}
 

	
 
	/* Update company statistics */
 
	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);
 

	
 
	/* Modify profit if a subsidy is in effect */
 
	if (CheckSubsidised(cargo_type, company->index, src_type, src, st))  {
src/newgrf_town.cpp
Show inline comments
 
@@ -88,38 +88,38 @@ uint32 TownGetVariable(byte variable, ui
 
		case 0xAC: return t->ratings[7];
 
		case 0xAD: return GB(t->ratings[7], 8, 8);
 
		case 0xAE: return t->have_ratings;
 
		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;
 
	}
 

	
 
	DEBUG(grf, 1, "Unhandled town variable 0x%X", variable);
 

	
src/saveload/oldloader_sl.cpp
Show inline comments
 
@@ -565,27 +565,27 @@ static const OldChunks town_chunk[] = {
 
	OCL_SVAR( OC_FILE_U32 | OC_VAR_U16, Town, have_ratings ),
 
	OCL_SVAR( OC_FILE_U32 | OC_VAR_U16, Town, statues ),
 
	OCL_NULL( 2 ),         ///< num_houses,        no longer in use
 
	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 ),
 

	
 
	OCL_CNULL( OC_TTD, 8 ),         ///< some junk at the end of the record
 

	
src/saveload/town_sl.cpp
Show inline comments
 
@@ -125,36 +125,36 @@ static const SaveLoad _town_desc[] = {
 
	SLE_CONDARR(Town, ratings,               SLE_INT16, 8,               0, 103),
 
	SLE_CONDARR(Town, ratings,               SLE_INT16, MAX_COMPANIES, 104, SL_MAX_VERSION),
 
	/* failed bribe attempts are stored since savegame format 4 */
 
	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),
 
	SLE_CONDVAR(Town, growth_rate,           SLE_FILE_U8 | SLE_VAR_I16,  0, 53),
 

	
 
	SLE_CONDVAR(Town, time_until_rebuild,    SLE_UINT16,                54, SL_MAX_VERSION),
 
@@ -175,40 +175,77 @@ static const SaveLoad _town_desc[] = {
 
	/* reserve extra space in savegame here. (currently 30 bytes) */
 
	SLE_CONDNULL(30, 2, SL_MAX_VERSION),
 

	
 
	SLE_END()
 
};
 

	
 
static const SaveLoad _town_supplied_desc[] = {
 
	SLE_CONDVAR(TransportedCargoStat<uint32>, old_max, SLE_UINT32, 165, SL_MAX_VERSION),
 
	SLE_CONDVAR(TransportedCargoStat<uint32>, new_max, SLE_UINT32, 165, SL_MAX_VERSION),
 
	SLE_CONDVAR(TransportedCargoStat<uint32>, old_act, SLE_UINT32, 165, SL_MAX_VERSION),
 
	SLE_CONDVAR(TransportedCargoStat<uint32>, new_act, SLE_UINT32, 165, SL_MAX_VERSION),
 

	
 
	SLE_END()
 
};
 

	
 
static const SaveLoad _town_received_desc[] = {
 
	SLE_CONDVAR(TransportedCargoStat<uint16>, old_max, SLE_UINT16, 165, SL_MAX_VERSION),
 
	SLE_CONDVAR(TransportedCargoStat<uint16>, new_max, SLE_UINT16, 165, SL_MAX_VERSION),
 
	SLE_CONDVAR(TransportedCargoStat<uint16>, old_act, SLE_UINT16, 165, SL_MAX_VERSION),
 
	SLE_CONDVAR(TransportedCargoStat<uint16>, new_act, SLE_UINT16, 165, SL_MAX_VERSION),
 

	
 
	SLE_END()
 
};
 

	
 
static void Save_HIDS()
 
{
 
	Save_NewGRFMapping(_house_mngr);
 
}
 

	
 
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);
 
	}
 
}
 

	
 
static void Load_TOWN()
 
{
 
	int index;
 

	
 
	while ((index = SlIterateArray()) != -1) {
 
		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");
 
		}
 
	}
 
}
 

	
src/subsidy.cpp
Show inline comments
 
@@ -167,13 +167,13 @@ static bool CheckSubsidyDuplicate(CargoI
 
static Subsidy *FindSubsidyPassengerRoute()
 
{
 
	assert(Subsidy::CanAllocateItem());
 

	
 
	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;
 
	}
 

	
 
	const Town *dst = Town::GetRandom();
 
	if (dst->population < SUBSIDY_PAX_MIN_POPULATION || src == dst) {
 
		return NULL;
src/town.h
Show inline comments
 
@@ -15,12 +15,13 @@
 
#include "core/pool_type.hpp"
 
#include "viewport_type.h"
 
#include "command_type.h"
 
#include "town_map.h"
 
#include "subsidy_type.h"
 
#include "newgrf_storage.h"
 
#include "cargotype.h"
 
#include <list>
 

	
 
template <typename T>
 
struct BuildingCounts {
 
	T id_count[HOUSE_MAX];
 
	T class_count[HOUSE_CLASS_MAX];
 
@@ -63,22 +64,16 @@ struct Town : TownPool::PoolItem<&_town_
 
	CompanyMask have_ratings;      ///< which companies have a rating
 
	uint8 unwanted[MAX_COMPANIES]; ///< how many months companies aren't wanted by towns (bribe)
 
	CompanyByte exclusivity;       ///< which company has exclusivity
 
	uint8 exclusive_counter;       ///< months till the exclusivity expires
 
	int16 ratings[MAX_COMPANIES];  ///< ratings of each company for this town
 

	
 
	TransportedCargoStat<uint32> pass;  ///< Passenger cargo statistics.
 
	TransportedCargoStat<uint32> mail;  ///< Mail cargo statistics.
 
	TransportedCargoStat<uint16> food;  ///< Food cargo statistics.
 
	TransportedCargoStat<uint16> water; ///< Water cargo statistics.
 
	TransportedCargoStat<uint32> supplied[NUM_CARGO]; ///< Cargo statistics about supplied cargo.
 
	TransportedCargoStat<uint16> 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
 

	
 
	uint16 grow_counter;           ///< counter to count when to grow
 
	int16 growth_rate;             ///< town growth rate
 

	
src/town_cmd.cpp
Show inline comments
 
@@ -482,42 +482,30 @@ static void TileLoop_Town(TileIndex tile
 
			uint amt = GB(callback, 0, 8);
 
			if (amt == 0) continue;
 

	
 
			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());
 
		}
 
	}
 

	
 
	Backup<CompanyByte> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
 

	
 
	if ((hs->building_flags & BUILDING_HAS_1_TILE) &&
 
@@ -1398,14 +1386,14 @@ void UpdateTownRadius(Town *t)
 
		t->squared_town_zone_radius[4] = mass * 3 + 5;
 
	}
 
}
 

	
 
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;
 
}
 

	
 
/**
 
 * Does the actual town creation.
 
 *
 
 * @param t The town
 
@@ -2768,16 +2756,16 @@ static void UpdateTownGrowRate(Town *t)
 
	} else {
 
		m = _grow_count_values[1][min(n, 5)];
 
		if (n == 0 && !Chance16(1, 12)) return;
 
	}
 

	
 
	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
 
	 * this town and the growth rate is set to none. */
 
	uint growth_multiplier = _settings_game.economy.town_growth_rate != 0 ? _settings_game.economy.town_growth_rate - 1 : 1;
 

	
 
@@ -2791,16 +2779,14 @@ static void UpdateTownGrowRate(Town *t)
 

	
 
	SetBit(t->flags, TOWN_IS_FUNDED);
 
}
 

	
 
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);
 
}
 

	
 
static void UpdateTownUnwanted(Town *t)
 
{
src/town_gui.cpp
Show inline comments
 
@@ -365,18 +365,18 @@ public:
 
		uint y = r.top + WD_FRAMERECT_TOP;
 

	
 
		SetDParam(0, this->town->population);
 
		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;
 
		uint cargo_needed_for_growth = 0;
 
		switch (_settings_game.game_creation.landscape) {
 
			case LT_ARCTIC:
 
@@ -403,25 +403,25 @@ public:
 
			StringID food_name       = (food != NULL) ? food->name    : STR_CARGO_PLURAL_FOOD;
 

	
 
			const CargoSpec *water = FindFirstCargoWithTownEffect(TE_WATER);
 
			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);
 
				DrawString(cargo_text_left, cargo_text_right, y += FONT_HEIGHT_NORMAL, required_text);
 
			}
 

	
 
			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);
 
					DrawString(cargo_text_left, cargo_text_right, y += FONT_HEIGHT_NORMAL, required_text);
 
				}
 
			}
0 comments (0 inline, 0 general)