Changeset - r12648:24c912bd53f6
[Not reviewed]
master
0 28 1
smatz - 15 years ago 2009-08-08 16:42:55
smatz@openttd.org
(svn r17113) -Change [FS#265][FS#2094][FS#2589]: apply the subsidy when subsidy's destination is in station's catchment area and cargo packets originate from subsidy's source
-Change [FS#1134]: subsidies aren't bound to stations after awarding anymore, they still apply to town or industry, no matter what station is used for loading and unloading. Awarded subsidies from older savegames are lost
-Change [NoAI]: due to these changes, AISubsidy::GetSource and AISubsidy::GetDestination now return STATION_INVALID for awarded subsidies
29 files changed with 311 insertions and 179 deletions:
0 comments (0 inline, 0 general)
projects/openttd_vs80.vcproj
Show inline comments
 
@@ -1488,6 +1488,10 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\subsidy_type.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\tar_type.h"
 
				>
 
			</File>
projects/openttd_vs90.vcproj
Show inline comments
 
@@ -1485,6 +1485,10 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\subsidy_type.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\tar_type.h"
 
				>
 
			</File>
source.list
Show inline comments
 
@@ -300,6 +300,7 @@ strings_func.h
 
strings_type.h
 
subsidy_base.h
 
subsidy_func.h
 
subsidy_type.h
 
tar_type.h
 
terraform_gui.h
 
textbuf_gui.h
src/ai/api/ai_changelog.hpp
Show inline comments
 
@@ -29,6 +29,8 @@
 
 * \li WaypointID was replaced by StationID. All WaypointIDs from previous
 
 *     savegames are invalid
 
 * \li WAYPOINT_INVALID is now deprecated, use STATION_INVALID instead
 
 * \li AISubsidy::GetSource and AISubsidy::GetDestination return STATION_INVALID
 
 *     for awarded subsidies
 
 * \li AIs can create subclasses of API classes and use API constants as part
 
 *     of their own constants
 
 * \li AIVehicleList_Station now also works for waypoints
src/ai/api/ai_subsidy.cpp
Show inline comments
 
@@ -4,6 +4,7 @@
 

	
 
#include "ai_subsidy.hpp"
 
#include "ai_date.hpp"
 
#include "ai_log.hpp"
 
#include "../../subsidy_base.h"
 
#include "../../station_base.h"
 
#include "../../cargotype.h"
 
@@ -24,7 +25,7 @@
 
{
 
	if (!IsAwarded(subsidy_id)) return AICompany::COMPANY_INVALID;
 

	
 
	return (AICompany::CompanyID)((byte)::Station::Get(::Subsidy::Get(subsidy_id)->src)->owner);
 
	return (AICompany::CompanyID)((byte)::Subsidy::Get(subsidy_id)->awarded);
 
}
 

	
 
/* static */ int32 AISubsidy::GetExpireDate(SubsidyID subsidy_id)
 
@@ -34,11 +35,7 @@
 
	int year = AIDate::GetYear(AIDate::GetCurrentDate());
 
	int month = AIDate::GetMonth(AIDate::GetCurrentDate());
 

	
 
	if (IsAwarded(subsidy_id)) {
 
		month += 24 - ::Subsidy::Get(subsidy_id)->age;
 
	} else {
 
		month += 12 - ::Subsidy::Get(subsidy_id)->age;
 
	}
 
	month += ::Subsidy::Get(subsidy_id)->remaining;
 

	
 
	year += (month - 1) / 12;
 
	month = ((month - 1) % 12) + 1;
 
@@ -64,6 +61,11 @@
 
{
 
	if (!IsValidSubsidy(subsidy_id)) return INVALID_STATION;
 

	
 
	if (IsAwarded(subsidy_id)) {
 
		AILog::Error("AISubsidy::GetSource returned INVALID_STATION due to internal changes in the Subsidy logic.");
 
		return INVALID_STATION;
 
	}
 

	
 
	return ::Subsidy::Get(subsidy_id)->src;
 
}
 

	
 
@@ -78,5 +80,10 @@
 
{
 
	if (!IsValidSubsidy(subsidy_id)) return INVALID_STATION;
 

	
 
	if (IsAwarded(subsidy_id)) {
 
		AILog::Error("AISubsidy::GetDestination returned INVALID_STATION due to internal changes in the Subsidy logic.");
 
		return INVALID_STATION;
 
	}
 

	
 
	return ::Subsidy::Get(subsidy_id)->dst;
 
}
src/ai/api/ai_subsidy.hpp
Show inline comments
 
@@ -69,12 +69,12 @@ public:
 

	
 
	/**
 
	 * Return the source TownID/IndustryID/StationID the subsidy is for.
 
	 * 1) IsAwarded(subsidy_id) -> return the StationID the subsidy is awarded to.
 
	 * 2) !IsAwarded(subsidy_id) && SourceIsTown(subsidy_id) -> return the TownID.
 
	 * 3) !IsAwarded(subsidy_id) && !SourceIsTown(subsidy_id) -> return the IndustryID.
 
	 * \li IsAwarded(subsidy_id) -> return INVALID_STATION.
 
	 * \li !IsAwarded(subsidy_id) && SourceIsTown(subsidy_id) -> return the TownID.
 
	 * \li !IsAwarded(subsidy_id) && !SourceIsTown(subsidy_id) -> return the IndustryID.
 
	 * @param subsidy_id The SubsidyID to check.
 
	 * @pre IsValidSubsidy(subsidy_id).
 
	 * @return One of TownID/IndustryID/StationID.
 
	 * @return One of TownID/IndustryID/INVALID_STATION.
 
	 */
 
	static int32 GetSource(SubsidyID subsidy_id);
 

	
 
@@ -88,12 +88,12 @@ public:
 

	
 
	/**
 
	 * Return the destination TownID/IndustryID/StationID the subsidy is for.
 
	 * 1) IsAwarded(subsidy_id) -> return the StationID the subsidy is awarded to.
 
	 * 2) !IsAwarded(subsidy_id) && SourceIsTown(subsidy_id) -> return the TownID.
 
	 * 3) !IsAwarded(subsidy_id) && !SourceIsTown(subsidy_id) -> return the IndustryID.
 
	 * \li IsAwarded(subsidy_id) -> return INVALID_STATION.
 
	 * \li !IsAwarded(subsidy_id) && DestinationIsTown(subsidy_id) -> return the TownID.
 
	 * \li !IsAwarded(subsidy_id) && !DestinationIsTown(subsidy_id) -> return the IndustryID.
 
	 * @param subsidy_id the SubsidyID to check.
 
	 * @pre IsValidSubsidy(subsidy_id).
 
	 * @return One of TownID/IndustryID/StationID.
 
	 * @return One of TownID/IndustryID/INVALID_STATION.
 
	 */
 
	static int32 GetDestination(SubsidyID subsidy_id);
 
};
src/cargo_type.h
Show inline comments
 
@@ -85,15 +85,15 @@ public:
 
};
 

	
 

	
 
/** Types of subsidy source and destination */
 
/** Types of cargo source and destination */
 
enum SourceType {
 
	ST_INDUSTRY, ///< Source/destination is an industry
 
	ST_TOWN,     ///< Source/destination is a town
 
	ST_STATION,  ///< Source/destination is a station
 
	ST_INDUSTRY,     ///< Source/destination is an industry
 
	ST_TOWN,         ///< Source/destination is a town
 
	ST_HEADQUARTERS, ///< Source/destination are company headquarters
 
};
 
typedef SimpleTinyEnumT<SourceType, byte> SourceTypeByte;
 

	
 
typedef uint16 SourceID; ///< Contains either industry ID, town ID or station ID (or INVALID_SOURCE)
 
typedef uint16 SourceID; ///< Contains either industry ID, town ID or company ID (or INVALID_SOURCE)
 
static const SourceID INVALID_SOURCE = 0xFFFF; ///< Invalid/unknown index of source
 

	
 
#endif /* CARGO_TYPE_H */
src/cargopacket.cpp
Show inline comments
 
@@ -16,17 +16,33 @@ void InitializeCargoPackets()
 
	_cargopacket_pool.CleanPool();
 
}
 

	
 
CargoPacket::CargoPacket(StationID source, uint16 count)
 
CargoPacket::CargoPacket(StationID source, uint16 count, SourceType source_type, SourceID source_id)
 
{
 
	if (source != INVALID_STATION) assert(count != 0);
 

	
 
	this->source          = source;
 
//	this->feeder_share    = 0; // no need to zero already zeroed data (by operator new)
 
	this->source_xy       = (source != INVALID_STATION) ? Station::Get(source)->xy : 0;
 
	this->loaded_at_xy    = this->source_xy;
 
	this->source          = source;
 

	
 
	this->count           = count;
 
	this->days_in_transit = 0;
 
	this->feeder_share    = 0;
 
//	this->days_in_transit = 0;
 

	
 
	this->source_type     = source_type;
 
	this->source_id       = source_id;
 
}
 

	
 
/**
 
 * Invalidates (sets source_id to INVALID_SOURCE) all cargo packets from given source
 
 * @param src_type type of source
 
 * @param src index of source
 
 */
 
/* static */ void CargoPacket::InvalidateAllFrom(SourceType src_type, SourceID src)
 
{
 
	CargoPacket *cp;
 
	FOR_ALL_CARGOPACKETS(cp) {
 
		if (cp->source_type == src_type && cp->source_id == src) cp->source_id = INVALID_SOURCE;
 
	}
 
}
 

	
 
/*
 
@@ -149,6 +165,9 @@ bool CargoList::MoveTo(CargoList *dest, 
 
				cp_new->days_in_transit = cp->days_in_transit;
 
				cp_new->feeder_share    = fs;
 

	
 
				cp_new->source_type     = cp->source_type;
 
				cp_new->source_id       = cp->source_id;
 

	
 
				cp_new->count = count;
 
				dest->packets.push_back(cp_new);
 

	
src/cargopacket.h
Show inline comments
 
@@ -9,6 +9,7 @@
 
#include "economy_type.h"
 
#include "tile_type.h"
 
#include "station_type.h"
 
#include "cargo_type.h"
 
#include <list>
 

	
 
typedef uint32 CargoPacketID;
 
@@ -30,13 +31,16 @@ struct CargoPacket : CargoPacketPool::Po
 
	uint16 count;           ///< The amount of cargo in this packet
 
	byte days_in_transit;   ///< Amount of days this packet has been in transit
 

	
 
	SourceTypeByte source_type; ///< Type of #source_id
 
	SourceID source_id;         ///< Index of source, INVALID_SOURCE if unknown/invalid
 

	
 
	/**
 
	 * Creates a new cargo packet
 
	 * @param source the source of the packet
 
	 * @param count  the number of cargo entities to put in this packet
 
	 * @pre count != 0 || source == INVALID_STATION
 
	 */
 
	CargoPacket(StationID source = INVALID_STATION, uint16 count = 0);
 
	CargoPacket(StationID source = INVALID_STATION, uint16 count = 0, SourceType source_type = ST_INDUSTRY, SourceID source_id = INVALID_SOURCE);
 

	
 
	/** Destroy the packet */
 
	~CargoPacket() { }
 
@@ -49,8 +53,11 @@ struct CargoPacket : CargoPacketPool::Po
 
	 */
 
	FORCEINLINE bool SameSource(const CargoPacket *cp) const
 
	{
 
		return this->source_xy == cp->source_xy && this->days_in_transit == cp->days_in_transit;
 
		return this->source_xy == cp->source_xy && this->days_in_transit == cp->days_in_transit &&
 
				this->source_type == cp->source_type && this->source_id == cp->source_id;
 
	}
 

	
 
	static void InvalidateAllFrom(SourceType src_type, SourceID src);
 
};
 

	
 
/**
src/economy.cpp
Show inline comments
 
@@ -328,11 +328,13 @@ void ChangeOwnershipOfCompanyItems(Owner
 
		Company::Get(old_owner)->money = UINT64_MAX >> 2; // jackpot ;p
 
	}
 

	
 
	if (new_owner == INVALID_OWNER) {
 
		Subsidy *s;
 
		FOR_ALL_SUBSIDIES(s) {
 
			if (s->IsAwarded() && Station::Get(s->dst)->owner == old_owner) {
 
				s->cargo_type = CT_INVALID;
 
	Subsidy *s;
 
	FOR_ALL_SUBSIDIES(s) {
 
		if (s->awarded == old_owner) {
 
			if (new_owner == INVALID_OWNER) {
 
				DeleteSubsidy(s);
 
			} else {
 
				s->awarded = new_owner;
 
			}
 
		}
 
	}
 
@@ -916,45 +918,38 @@ static void DeliverGoodsToIndustry(const
 
/**
 
 * Delivers goods to industries/towns and calculates the payment
 
 * @param num_pieces amount of cargo delivered
 
 * @param source Originstation of the cargo
 
 * @param dest Station the cargo has been unloaded
 
 * @param source_tile The origin of the cargo for distance calculation
 
 * @param days_in_transit Travel time
 
 * @param company The company delivering the cargo
 
 * The cargo is just added to the stockpile of the industry. It is due to the caller to trigger the industry's production machinery
 
 * @param src_type Type of source of cargo (industry, town, headquarters)
 
 * @param src Index of source of cargo
 
 * @return Revenue for delivering cargo
 
 * @note The cargo is just added to the stockpile of the industry. It is due to the caller to trigger the industry's production machinery
 
 */
 
static Money DeliverGoods(int num_pieces, CargoID cargo_type, StationID source, StationID dest, TileIndex source_tile, byte days_in_transit, Company *company)
 
static Money DeliverGoods(int num_pieces, CargoID cargo_type, StationID dest, TileIndex source_tile, byte days_in_transit, Company *company, SourceType src_type, SourceID src)
 
{
 
	bool subsidised = false;
 

	
 
	assert(num_pieces > 0);
 

	
 
	/* Update company statistics */
 
	company->cur_economy.delivered_cargo += num_pieces;
 
	SetBit(company->cargo_types, cargo_type);
 

	
 
	const Station *s_to = Station::Get(dest);
 

	
 
	if (source != INVALID_STATION) {
 
		const Station *s_from = Station::Get(source);
 

	
 
		/* Check if a subsidy applies. */
 
		subsidised = CheckSubsidised(s_from, s_to, cargo_type, company->index);
 
	}
 
	const Station *st = Station::Get(dest);
 

	
 
	/* Increase town's counter for some special goods types */
 
	const CargoSpec *cs = CargoSpec::Get(cargo_type);
 
	if (cs->town_effect == TE_FOOD) s_to->town->new_act_food += num_pieces;
 
	if (cs->town_effect == TE_WATER) s_to->town->new_act_water += num_pieces;
 
	if (cs->town_effect == TE_FOOD) st->town->new_act_food += num_pieces;
 
	if (cs->town_effect == TE_WATER) st->town->new_act_water += num_pieces;
 

	
 
	/* Give the goods to the industry. */
 
	DeliverGoodsToIndustry(s_to, cargo_type, num_pieces);
 
	DeliverGoodsToIndustry(st, cargo_type, num_pieces);
 

	
 
	/* Determine profit */
 
	Money profit = GetTransportedGoodsIncome(num_pieces, DistanceManhattan(source_tile, s_to->xy), days_in_transit, cargo_type);
 
	Money profit = GetTransportedGoodsIncome(num_pieces, DistanceManhattan(source_tile, st->xy), days_in_transit, cargo_type);
 

	
 
	/* Modify profit if a subsidy is in effect */
 
	if (subsidised) {
 
	if (CheckSubsidised(cargo_type, company->index, src_type, src, st))  {
 
		switch (_settings_game.difficulty.subsidy_multiplier) {
 
			case 0:  profit += profit >> 1; break;
 
			case 1:  profit *= 2; break;
 
@@ -1051,7 +1046,7 @@ void CargoPayment::PayFinalDelivery(Carg
 
	}
 

	
 
	/* Handle end of route payment */
 
	Money profit = DeliverGoods(count, this->ct, cp->source, this->current_station, cp->source_xy, cp->days_in_transit, this->owner);
 
	Money profit = DeliverGoods(count, this->ct, this->current_station, cp->source_xy, cp->days_in_transit, this->owner, cp->source_type, cp->source_id);
 
	this->route_profit += profit;
 

	
 
	/* The vehicle's profit is whatever route profit there is minus feeder shares. */
src/economy_func.h
Show inline comments
 
@@ -32,7 +32,7 @@ int UpdateCompanyRatingAndValue(Company 
 
void StartupIndustryDailyChanges(bool init_counter);
 

	
 
Money GetTransportedGoodsIncome(uint num_pieces, uint dist, byte transit_days, CargoID cargo_type);
 
uint MoveGoodsToStation(TileIndex tile, int w, int h, CargoID type, uint amount);
 
uint MoveGoodsToStation(TileIndex tile, int w, int h, CargoID type, uint amount, SourceType source_type, SourceID source_id);
 

	
 
void PrepareUnload(Vehicle *front_v);
 
void LoadUnloadStation(Station *st);
src/industry.h
Show inline comments
 
@@ -19,6 +19,7 @@
 
#include "tile_type.h"
 
#include "company_type.h"
 
#include "strings_type.h"
 
#include "subsidy_type.h"
 

	
 
enum {
 
	INVALID_INDUSTRY       = 0xFFFF,
 
@@ -125,6 +126,8 @@ struct Industry : IndustryPool::PoolItem
 
	Year last_prod_year;                ///< last year of production
 
	byte was_cargo_delivered;           ///< flag that indicate this has been the closest industry chosen for cargo delivery by a station. see DeliverGoodsToIndustry
 

	
 
	PartOfSubsidyByte part_of_subsidy;  ///< NOSAVE: is this industry a source/destination of a subsidy?
 

	
 
	OwnerByte founder;                  ///< Founder of the industry
 
	Date construction_date;             ///< Date of the construction of the industry
 
	uint8 construction_type;            ///< Way the industry was constructed (@see IndustryConstructionType)
src/industry_cmd.cpp
Show inline comments
 
@@ -167,11 +167,12 @@ Industry::~Industry()
 

	
 
	DecIndustryTypeCount(this->type);
 

	
 
	DeleteSubsidyWith(ST_INDUSTRY, this->index);
 
	DeleteIndustryNews(this->index);
 
	DeleteWindowById(WC_INDUSTRY_VIEW, this->index);
 
	InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, 0);
 

	
 
	DeleteSubsidyWith(ST_INDUSTRY, this->index);
 
	CargoPacket::InvalidateAllFrom(ST_INDUSTRY, this->index);
 
	Station::RecomputeIndustriesNearForAll();
 
}
 

	
 
@@ -479,7 +480,7 @@ static void TransportIndustryGoods(TileI
 

	
 
			i->this_month_production[j] += cw;
 

	
 
			uint am = MoveGoodsToStation(i->xy, i->width, i->height, i->produced_cargo[j], cw);
 
			uint am = MoveGoodsToStation(i->xy, i->width, i->height, i->produced_cargo[j], cw, ST_INDUSTRY, i->index);
 
			i->this_month_transported[j] += am;
 

	
 
			moved_cargo |= (am != 0);
src/lang/english.txt
Show inline comments
 
@@ -797,12 +797,12 @@ STR_NEWS_STATION_NOW_ACCEPTS_CARGO      
 
STR_NEWS_STATION_NOW_ACCEPTS_CARGO_AND_CARGO                    :{WHITE}{STATION} now accepts {STRING} and {STRING}
 

	
 
STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED                               :{BIGFONT}{BLACK}Offer of subsidy expired:{}{}{STRING} from {STRING2} to {STRING2} will now not attract a subsidy.
 
STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE                              :{BIGFONT}{BLACK}Subsidy withdrawn:{}{}{STRING} service from {STATION} to {STATION} is no longer subsidised.
 
STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE                              :{BIGFONT}{BLACK}Subsidy withdrawn:{}{}{STRING} service from {STRING2} to {STRING2} is no longer subsidised.
 
STR_NEWS_SERVICE_SUBSIDY_OFFERED                                :{BIGFONT}{BLACK}Service subsidy offered:{}{}First {STRING} service from {STRING2} to {STRING2} will attract a year's subsidy from the local authority!
 
STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF                           :{BIGFONT}{BLACK}Service subsidy awarded to {RAW_STRING}!{}{}{STRING} service from {STATION} to {STATION} will pay 50% extra for the next year!
 
STR_NEWS_SERVICE_SUBSIDY_AWARDED_DOUBLE                         :{BIGFONT}{BLACK}Service subsidy awarded to {RAW_STRING}!{}{}{STRING} service from {STATION} to {STATION} will pay double rates for the next year!
 
STR_NEWS_SERVICE_SUBSIDY_AWARDED_TRIPLE                         :{BIGFONT}{BLACK}Service subsidy awarded to {RAW_STRING}!{}{}{STRING} service from {STATION} to {STATION} will pay triple rates for the next year!
 
STR_NEWS_SERVICE_SUBSIDY_AWARDED_QUADRUPLE                      :{BIGFONT}{BLACK}Service subsidy awarded to {RAW_STRING}!{}{}{STRING} service from {STATION} to {STATION} will pay quadruple rates for the next year!
 
STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF                           :{BIGFONT}{BLACK}Service subsidy awarded to {RAW_STRING}!{}{}{STRING} service from {STRING2} to {STRING2} will pay 50% extra for the next year!
 
STR_NEWS_SERVICE_SUBSIDY_AWARDED_DOUBLE                         :{BIGFONT}{BLACK}Service subsidy awarded to {RAW_STRING}!{}{}{STRING} service from {STRING2} to {STRING2} will pay double rates for the next year!
 
STR_NEWS_SERVICE_SUBSIDY_AWARDED_TRIPLE                         :{BIGFONT}{BLACK}Service subsidy awarded to {RAW_STRING}!{}{}{STRING} service from {STRING2} to {STRING2} will pay triple rates for the next year!
 
STR_NEWS_SERVICE_SUBSIDY_AWARDED_QUADRUPLE                      :{BIGFONT}{BLACK}Service subsidy awarded to {RAW_STRING}!{}{}{STRING} service from {STRING2} to {STRING2} will pay quadruple rates for the next year!
 

	
 
STR_NEWS_ROAD_REBUILDING                                        :{BIGFONT}{BLACK}Traffic chaos in {TOWN}!{}{}Road rebuilding programme funded by {RAW_STRING} brings 6 months of misery to motorists!
 

	
 
@@ -2397,7 +2397,7 @@ STR_SUBSIDIES_OFFERED_TITLE             
 
STR_SUBSIDIES_OFFERED_FROM_TO                                   :{ORANGE}{STRING} from {STRING2} to {STRING2}{YELLOW} (by {DATE_SHORT})
 
STR_SUBSIDIES_NONE                                              :{ORANGE}None
 
STR_SUBSIDIES_SUBSIDISED_TITLE                                  :{BLACK}Services already subsidised:
 
STR_SUBSIDIES_SUBSIDISED_FROM_TO                                :{ORANGE}{STRING} from {STATION} to {STATION}{YELLOW} ({COMPANY}{YELLOW}, until {DATE_SHORT})
 
STR_SUBSIDIES_SUBSIDISED_FROM_TO                                :{ORANGE}{STRING} from {STRING2} to {STRING2}{YELLOW} ({COMPANY}{YELLOW}, until {DATE_SHORT})
 
STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER                :{BLACK}Click on service to centre view on industry/town
 

	
 
# Station list window
src/saveload/afterload.cpp
Show inline comments
 
@@ -32,6 +32,7 @@
 
#include "../economy_base.h"
 
#include "../animated_tile_func.h"
 
#include "../subsidy_base.h"
 
#include "../subsidy_func.h"
 

	
 
#include "table/strings.h"
 

	
 
@@ -230,6 +231,7 @@ static bool InitializeWindowsAndCaches()
 
	SetCachedEngineCounts();
 

	
 
	Station::RecomputeIndustriesNearForAll();
 
	RebuildSubsidisedSourceAndDestinationCache();
 

	
 
	/* Towns have a noise controlled number of airports system
 
	 * So each airport's noise value must be added to the town->noise_reached value
 
@@ -1868,17 +1870,15 @@ bool AfterLoadGame()
 
		}
 
	}
 

	
 
	{
 
		/* Delete invalid subsidies possibly present in old versions (but converted to new savegame) */
 
	if (CheckSavegameVersion(125)) {
 
		/* Convert old subsidies */
 
		Subsidy *s;
 
		FOR_ALL_SUBSIDIES(s) {
 
			if (s->IsAwarded()) {
 
				/* Station -> Station */
 
				const Station *from = Station::GetIfValid(s->src);
 
				const Station *to = Station::GetIfValid(s->dst);
 
				s->src_type = s->dst_type = ST_STATION;
 
				if (from != NULL && to != NULL && from->owner == to->owner && Company::IsValidID(from->owner)) continue;
 
			} else {
 
			/* Convert only nonawarded subsidies. The original source and destination town/industry
 
			 * anymore for awarded subsidies, so invalidate them. */
 
			if (s->remaining < 12) {
 
				s->remaining = 12 - s->remaining; // convert "age" to "remaining"
 
				s->awarded = INVALID_COMPANY; // not awarded to anyone
 
				const CargoSpec *cs = CargoSpec::Get(s->cargo_type);
 
				switch (cs->town_effect) {
 
					case TE_PASSENGERS:
 
@@ -1901,6 +1901,7 @@ bool AfterLoadGame()
 
						break;
 
				}
 
			}
 
			/* Awarded subsidy or invalid source/destination, invalidate */
 
			s->cargo_type = CT_INVALID;
 
		}
 
	}
src/saveload/cargopacket_sl.cpp
Show inline comments
 
@@ -14,6 +14,8 @@ static const SaveLoad _cargopacket_desc[
 
	     SLE_VAR(CargoPacket, count,           SLE_UINT16),
 
	     SLE_VAR(CargoPacket, days_in_transit, SLE_UINT8),
 
	     SLE_VAR(CargoPacket, feeder_share,    SLE_INT64),
 
	 SLE_CONDVAR(CargoPacket, source_type,     SLE_UINT8,  125, SL_MAX_VERSION),
 
	 SLE_CONDVAR(CargoPacket, source_id,       SLE_UINT16, 125, SL_MAX_VERSION),
 

	
 
	/* Used to be paid_for, but that got changed. */
 
	SLE_CONDNULL(1, 0, 120),
src/saveload/oldloader_sl.cpp
Show inline comments
 
@@ -1468,7 +1468,7 @@ static bool LoadOldEngineName(LoadgameSt
 

	
 
static const OldChunks subsidy_chunk[] = {
 
	OCL_SVAR(  OC_UINT8, Subsidy, cargo_type ),
 
	OCL_SVAR(  OC_UINT8, Subsidy, age ),
 
	OCL_SVAR(  OC_UINT8, Subsidy, remaining ),
 
	OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Subsidy, src ),
 
	OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Subsidy, dst ),
 

	
src/saveload/saveload.cpp
Show inline comments
 
@@ -41,7 +41,7 @@
 

	
 
#include "saveload_internal.h"
 

	
 
extern const uint16 SAVEGAME_VERSION = 124;
 
extern const uint16 SAVEGAME_VERSION = 125;
 

	
 
SavegameType _savegame_type; ///< type of savegame we are loading
 

	
src/saveload/subsidy_sl.cpp
Show inline comments
 
@@ -9,11 +9,14 @@
 

	
 
static const SaveLoad _subsidies_desc[] = {
 
	    SLE_VAR(Subsidy, cargo_type, SLE_UINT8),
 
	    SLE_VAR(Subsidy, age,        SLE_UINT8),
 
	SLE_CONDVAR(Subsidy, src,        SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
 
	SLE_CONDVAR(Subsidy, src,        SLE_UINT16,                5, SL_MAX_VERSION),
 
	SLE_CONDVAR(Subsidy, dst,        SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
 
	SLE_CONDVAR(Subsidy, dst,        SLE_UINT16,                5, SL_MAX_VERSION),
 
	    SLE_VAR(Subsidy, remaining,  SLE_UINT8),
 
	SLE_CONDVAR(Subsidy, awarded,    SLE_UINT8,                 125, SL_MAX_VERSION),
 
	SLE_CONDVAR(Subsidy, src_type,   SLE_UINT8,                 125, SL_MAX_VERSION),
 
	SLE_CONDVAR(Subsidy, dst_type,   SLE_UINT8,                 125, SL_MAX_VERSION),
 
	SLE_CONDVAR(Subsidy, src,        SLE_FILE_U8 | SLE_VAR_U16,   0, 4),
 
	SLE_CONDVAR(Subsidy, src,        SLE_UINT16,                  5, SL_MAX_VERSION),
 
	SLE_CONDVAR(Subsidy, dst,        SLE_FILE_U8 | SLE_VAR_U16,   0, 4),
 
	SLE_CONDVAR(Subsidy, dst,        SLE_UINT16,                  5, SL_MAX_VERSION),
 
	SLE_END()
 
};
 

	
src/station.cpp
Show inline comments
 
@@ -90,9 +90,6 @@ Station::~Station()
 
	/* Now delete all orders that go to the station */
 
	RemoveOrderFromAllVehicles(OT_GOTO_STATION, this->index);
 

	
 
	/* Subsidies need removal as well */
 
	DeleteSubsidyWith(ST_STATION, this->index);
 

	
 
	/* Remove all news items */
 
	DeleteStationNews(this->index);
 

	
src/station_cmd.cpp
Show inline comments
 
@@ -2840,9 +2840,9 @@ void ModifyStationRatingAround(TileIndex
 
	}
 
}
 

	
 
static void UpdateStationWaiting(Station *st, CargoID type, uint amount)
 
static void UpdateStationWaiting(Station *st, CargoID type, uint amount, SourceType source_type, SourceID source_id)
 
{
 
	st->goods[type].cargo.Append(new CargoPacket(st->index, amount));
 
	st->goods[type].cargo.Append(new CargoPacket(st->index, amount, source_type, source_id));
 
	SetBit(st->goods[type].acceptance_pickup, GoodsEntry::PICKUP);
 

	
 
	StationAnimationTrigger(st, st->xy, STAT_ANIM_NEW_CARGO, type);
 
@@ -2926,7 +2926,7 @@ void FindStationsAroundTiles(TileIndex t
 
	}
 
}
 

	
 
uint MoveGoodsToStation(TileIndex tile, int w, int h, CargoID type, uint amount)
 
uint MoveGoodsToStation(TileIndex tile, int w, int h, CargoID type, uint amount, SourceType source_type, SourceID source_id)
 
{
 
	/* Return if nothing to do. Also the rounding below fails for 0. */
 
	if (amount == 0) return 0;
 
@@ -2968,7 +2968,7 @@ uint MoveGoodsToStation(TileIndex tile, 
 
	if (st2 == NULL) {
 
		/* only one station around */
 
		uint moved = amount * best_rating1 / 256 + 1;
 
		UpdateStationWaiting(st1, type, moved);
 
		UpdateStationWaiting(st1, type, moved, source_type, source_id);
 
		return moved;
 
	}
 

	
 
@@ -2987,13 +2987,13 @@ uint MoveGoodsToStation(TileIndex tile, 
 
	if (t != 0) {
 
		moved = t * best_rating1 / 256 + 1;
 
		amount -= t;
 
		UpdateStationWaiting(st1, type, moved);
 
		UpdateStationWaiting(st1, type, moved, source_type, source_id);
 
	}
 

	
 
	if (amount != 0) {
 
		amount = amount * best_rating2 / 256 + 1;
 
		moved += amount;
 
		UpdateStationWaiting(st2, type, amount);
 
		UpdateStationWaiting(st2, type, amount, source_type, source_id);
 
	}
 

	
 
	return moved;
src/subsidy.cpp
Show inline comments
 
@@ -22,27 +22,23 @@
 

	
 
/**
 
 * Marks subsidy as awarded, creates news and AI event
 
 * @param from source station
 
 * @param to destination station
 
 * @param company awarded company
 
 */
 
void Subsidy::AwardTo(StationID from, StationID to, CompanyID company)
 
void Subsidy::AwardTo(CompanyID company)
 
{
 
	assert(!this->IsAwarded());
 

	
 
	this->age = 12;
 
	this->src_type = this->dst_type = ST_STATION;
 
	this->src = from;
 
	this->dst = to;
 
	this->awarded = company;
 
	this->remaining = 12;
 

	
 
	char *company_name = MallocT<char>(MAX_LENGTH_COMPANY_NAME_BYTES);
 
	SetDParam(0, company);
 
	GetString(company_name, STR_COMPANY_NAME, company_name + MAX_LENGTH_COMPANY_NAME_BYTES - 1);
 

	
 
	/* Add a news item */
 
	Pair reftype = SetupSubsidyDecodeParam(this, 0);
 
	InjectDParam(1);
 

	
 
	char *company_name = MallocT<char>(MAX_LENGTH_COMPANY_NAME_BYTES);
 
	SetDParam(0, company);
 
	GetString(company_name, STR_COMPANY_NAME, company_name + MAX_LENGTH_COMPANY_NAME_BYTES - 1);
 

	
 
	SetDParamStr(0, company_name);
 
	AddNewsItem(
 
		STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF + _settings_game.difficulty.subsidy_multiplier,
 
@@ -62,7 +58,10 @@ void Subsidy::AwardTo(StationID from, St
 
/* static */ Subsidy *Subsidy::AllocateItem()
 
{
 
	for (Subsidy *s = Subsidy::array; s < endof(Subsidy::array); s++) {
 
		if (!s->IsValid()) return s;
 
		if (!s->IsValid()) {
 
			s->awarded = INVALID_COMPANY;
 
			return s;
 
		}
 
	}
 

	
 
	return NULL;
 
@@ -105,10 +104,6 @@ Pair SetupSubsidyDecodeParam(const Subsi
 
			reftype1 = NR_TOWN;
 
			SetDParam(1, STR_TOWN_NAME);
 
			break;
 
		case ST_STATION:
 
			reftype1 = NR_STATION;
 
			SetDParam(1, s->src);
 
			break;
 
		default: NOT_REACHED();
 
	}
 
	SetDParam(2, s->src);
 
@@ -122,10 +117,6 @@ Pair SetupSubsidyDecodeParam(const Subsi
 
			reftype2 = NR_TOWN;
 
			SetDParam(4, STR_TOWN_NAME);
 
			break;
 
		case ST_STATION:
 
			reftype2 = NR_STATION;
 
			SetDParam(2, s->dst);
 
			break;
 
		default: NOT_REACHED();
 
	}
 
	SetDParam(5, s->dst);
 
@@ -136,6 +127,42 @@ Pair SetupSubsidyDecodeParam(const Subsi
 
	return p;
 
}
 

	
 
/**
 
 * Sets a flag indicating that given town/industry is part of subsidised route.
 
 * @param type is it a town or an industry?
 
 * @param index index of town/industry
 
 * @param flag flag to set
 
 */
 
static inline void SetPartOfSubsidyFlag(SourceType type, SourceID index, PartOfSubsidy flag)
 
{
 
	switch (type) {
 
		case ST_INDUSTRY: Industry::Get(index)->part_of_subsidy |= flag; return;
 
		case ST_TOWN:         Town::Get(index)->part_of_subsidy |= flag; return;
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
void RebuildSubsidisedSourceAndDestinationCache()
 
{
 
	Town *t;
 
	FOR_ALL_TOWNS(t) t->part_of_subsidy = POS_NONE;
 

	
 
	Industry *i;
 
	FOR_ALL_INDUSTRIES(i) i->part_of_subsidy = POS_NONE;
 

	
 
	const Subsidy *s;
 
	FOR_ALL_SUBSIDIES(s) {
 
		SetPartOfSubsidyFlag(s->src_type, s->src, POS_SRC);
 
		SetPartOfSubsidyFlag(s->dst_type, s->dst, POS_DST);
 
	}
 
}
 

	
 
void DeleteSubsidy(Subsidy *s)
 
{
 
	s->cargo_type = CT_INVALID;
 
	RebuildSubsidisedSourceAndDestinationCache();
 
}
 

	
 
void DeleteSubsidyWith(SourceType type, SourceID index)
 
{
 
	bool dirty = false;
 
@@ -252,23 +279,20 @@ void SubsidyMonthlyLoop()
 

	
 
	Subsidy *s;
 
	FOR_ALL_SUBSIDIES(s) {
 
		if (s->age == 12 - 1) {
 
			Pair reftype = SetupSubsidyDecodeParam(s, 1);
 
			AddNewsItem(STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED, NS_SUBSIDIES, (NewsReferenceType)reftype.a, s->src, (NewsReferenceType)reftype.b, s->dst);
 
			s->cargo_type = CT_INVALID;
 
		if (--s->remaining == 0) {
 
			if (!s->IsAwarded()) {
 
				Pair reftype = SetupSubsidyDecodeParam(s, 1);
 
				AddNewsItem(STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED, NS_SUBSIDIES, (NewsReferenceType)reftype.a, s->src, (NewsReferenceType)reftype.b, s->dst);
 
				AI::BroadcastNewEvent(new AIEventSubsidyOfferExpired(s->Index()));
 
			} else {
 
				if (s->awarded == _local_company) {
 
					Pair reftype = SetupSubsidyDecodeParam(s, 1);
 
					AddNewsItem(STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE, NS_SUBSIDIES, (NewsReferenceType)reftype.a, s->src, (NewsReferenceType)reftype.b, s->dst);
 
				}
 
				AI::BroadcastNewEvent(new AIEventSubsidyExpired(s->Index()));
 
			}
 
			DeleteSubsidy(s);
 
			modified = true;
 
			AI::BroadcastNewEvent(new AIEventSubsidyOfferExpired(s->Index()));
 
		} else if (s->age == 2 * 12 - 1) {
 
			Station *st = Station::Get(s->dst);
 
			if (st->owner == _local_company) {
 
				Pair reftype = SetupSubsidyDecodeParam(s, 1);
 
				AddNewsItem(STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE, NS_SUBSIDIES, (NewsReferenceType)reftype.a, s->src, (NewsReferenceType)reftype.b, s->dst);
 
			}
 
			s->cargo_type = CT_INVALID;
 
			modified = true;
 
			AI::BroadcastNewEvent(new AIEventSubsidyExpired(s->Index()));
 
		} else {
 
			s->age++;
 
		}
 
	}
 

	
 
@@ -306,9 +330,11 @@ void SubsidyMonthlyLoop()
 
				}
 
	add_subsidy:
 
				if (!CheckSubsidyDuplicate(s)) {
 
					s->age = 0;
 
					s->remaining = 12;
 
					Pair reftype = SetupSubsidyDecodeParam(s, 0);
 
					AddNewsItem(STR_NEWS_SERVICE_SUBSIDY_OFFERED, NS_SUBSIDIES, (NewsReferenceType)reftype.a, s->src, (NewsReferenceType)reftype.b, s->dst);
 
					SetPartOfSubsidyFlag(s->src_type, s->src, POS_SRC);
 
					SetPartOfSubsidyFlag(s->dst_type, s->dst, POS_DST);
 
					AI::BroadcastNewEvent(new AIEventSubsidyOffer(s->Index()));
 
					modified = true;
 
					break;
 
@@ -321,51 +347,85 @@ no_add:;
 
		InvalidateWindow(WC_SUBSIDIES_LIST, 0);
 
}
 

	
 
bool CheckSubsidised(const Station *from, const Station *to, CargoID cargo_type, CompanyID company)
 
/**
 
 * Tests whether given delivery is subsidised and possibly awards the subsidy to delivering company
 
 * @param cargo_type type of cargo
 
 * @param company company delivering the cargo
 
 * @param src_type type of #src
 
 * @param src index of source
 
 * @param st station where the cargo is delivered to
 
 * @return is the delivery subsidised?
 
 */
 
bool CheckSubsidised(CargoID cargo_type, CompanyID company, SourceType src_type, SourceID src, const Station *st)
 
{
 
	Subsidy *s;
 
	TileIndex xy;
 
	/* If the source isn't subsidised, don't continue */
 
	if (src == INVALID_SOURCE) return false;
 
	switch (src_type) {
 
		case ST_INDUSTRY:
 
			if (!(Industry::Get(src)->part_of_subsidy & POS_SRC)) return false;
 
			break;
 
		case ST_TOWN:
 
			if (!(    Town::Get(src)->part_of_subsidy & POS_SRC)) return false;
 
			break;
 
		default: return false;
 
	}
 

	
 
	/* check if there is an already existing subsidy that applies to us */
 
	FOR_ALL_SUBSIDIES(s) {
 
		if (s->cargo_type == cargo_type &&
 
				s->IsAwarded() &&
 
				s->src == from->index &&
 
				s->dst == to->index) {
 
			return true;
 
	/* Remember all towns near this station (at least one house in its catchment radius)
 
	 * which are destination of subsidised path. Do that only if needed */
 
	SmallVector<const Town *, 2> towns_near;
 
	if (!st->rect.IsEmpty()) {
 
		Subsidy *s;
 
		FOR_ALL_SUBSIDIES(s) {
 
			/* Don't create the cache if there is no applicable subsidy with town as destination */
 
			if (s->dst_type != ST_TOWN) continue;
 
			if (s->cargo_type != cargo_type || s->src_type != src_type || s->src != src) continue;
 
			if (s->IsAwarded() && s->awarded != company) continue;
 

	
 
			Rect rect = st->GetCatchmentRect();
 

	
 
			for (int y = rect.top; y <= rect.bottom; y++) {
 
				for (int x = rect.left; x <= rect.right; x++) {
 
					TileIndex tile = TileXY(x, y);
 
					if (!IsTileType(tile, MP_HOUSE)) continue;
 
					const Town *t = Town::GetByTile(tile);
 
					if (t->part_of_subsidy & POS_DST) towns_near.Include(t);
 
				}
 
			}
 
			break;
 
		}
 
	}
 

	
 
	/* check if there's a new subsidy that applies.. */
 
	FOR_ALL_SUBSIDIES(s) {
 
		if (s->cargo_type == cargo_type && !s->IsAwarded()) {
 
			/* Check distance from source */
 
			const CargoSpec *cs = CargoSpec::Get(cargo_type);
 
			if (cs->town_effect == TE_PASSENGERS || cs->town_effect == TE_MAIL) {
 
				xy = Town::Get(s->src)->xy;
 
			} else {
 
				xy = Industry::Get(s->src)->xy;
 
			}
 
			if (DistanceMax(xy, from->xy) > 9) continue;
 
	bool subsidised = false;
 

	
 
			/* Check distance from dest */
 
			switch (cs->town_effect) {
 
				case TE_PASSENGERS:
 
				case TE_MAIL:
 
				case TE_GOODS:
 
				case TE_FOOD:
 
					xy = Town::Get(s->dst)->xy;
 
	/* Check if there's a (new) subsidy that applies. There can be more subsidies triggered by this delivery!
 
	 * Think about the case that subsidies are A->B and A->C and station has both B and C in its catchment area */
 
	Subsidy *s;
 
	FOR_ALL_SUBSIDIES(s) {
 
		if (s->cargo_type == cargo_type && s->src_type == src_type && s->src == src && (!s->IsAwarded() || s->awarded == company)) {
 
			switch (s->dst_type) {
 
				case ST_INDUSTRY:
 
					for (const Industry * const *ip = st->industries_near.Begin(); ip != st->industries_near.End(); ip++) {
 
						if (s->dst == (*ip)->index) {
 
							assert((*ip)->part_of_subsidy & POS_DST);
 
							subsidised = true;
 
							if (!s->IsAwarded()) s->AwardTo(company);
 
						}
 
					}
 
					break;
 

	
 
				case ST_TOWN:
 
					for (const Town * const *tp = towns_near.Begin(); tp != towns_near.End(); tp++) {
 
						if (s->dst == (*tp)->index) {
 
							assert((*tp)->part_of_subsidy & POS_DST);
 
							subsidised = true;
 
							if (!s->IsAwarded()) s->AwardTo(company);
 
						}
 
					}
 
					break;
 
				default:
 
					xy = Industry::Get(s->dst)->xy;
 
					break;
 
					NOT_REACHED();
 
			}
 
			if (DistanceMax(xy, to->xy) > 9) continue;
 

	
 
			s->AwardTo(from->index, to->index, company);
 
			return true;
 
		}
 
	}
 
	return false;
 

	
 
	return subsidised;
 
}
src/subsidy_base.h
Show inline comments
 
@@ -7,18 +7,17 @@
 

	
 
#include "cargo_type.h"
 
#include "company_type.h"
 
#include "station_type.h"
 

	
 
typedef uint16 SubsidyID; ///< ID of a subsidy
 
#include "subsidy_type.h"
 

	
 
/** Struct about subsidies, offered and awarded */
 
struct Subsidy {
 
	CargoID cargo_type;      ///< Cargo type involved in this subsidy, CT_INVALID for invalid subsidy
 
	byte age;                ///< Subsidy age; < 12 is unawarded, >= 12 is awarded
 
	SourceTypeByte src_type; ///< Source of subsidised path
 
	SourceTypeByte dst_type; ///< Destination of subsidised path
 
	uint16 src;              ///< Index of source. Either TownID, IndustryID or StationID, when awarded
 
	uint16 dst;              ///< Index of destination. Either TownID, IndustryID or StationID, when awarded
 
	byte remaining;          ///< Remaining months when this subsidy is valid
 
	CompanyByte awarded;     ///< Subsidy is awarded to this company; INVALID_COMPANY if it's not awarded to anyone
 
	SourceTypeByte src_type; ///< Source of subsidised path (ST_INDUSTRY or ST_TOWN)
 
	SourceTypeByte dst_type; ///< Destination of subsidised path (ST_INDUSTRY or ST_TOWN)
 
	SourceID src;            ///< Index of source. Either TownID or IndustryID
 
	SourceID dst;            ///< Index of destination. Either TownID or IndustryID
 

	
 
	/**
 
	 * Tests whether this subsidy has been awarded to someone
 
@@ -26,10 +25,10 @@ struct Subsidy {
 
	 */
 
	FORCEINLINE bool IsAwarded() const
 
	{
 
		return this->age >= 12;
 
		return this->awarded != INVALID_COMPANY;
 
	}
 

	
 
	void AwardTo(StationID from, StationID to, CompanyID company);
 
	void AwardTo(CompanyID company);
 

	
 
	/**
 
	 * Determines index of this subsidy
src/subsidy_func.h
Show inline comments
 
@@ -13,7 +13,9 @@
 

	
 
Pair SetupSubsidyDecodeParam(const struct Subsidy *s, bool mode);
 
void DeleteSubsidyWith(SourceType type, SourceID index);
 
bool CheckSubsidised(const Station *from, const Station *to, CargoID cargo_type, CompanyID company);
 
bool CheckSubsidised(CargoID cargo_type, CompanyID company, SourceType src_type, SourceID src, const Station *st);
 
void SubsidyMonthlyHandler();
 
void RebuildSubsidisedSourceAndDestinationCache();
 
void DeleteSubsidy(struct Subsidy *s);
 

	
 
#endif /* SUBSIDY_FUNC_H */
src/subsidy_gui.cpp
Show inline comments
 
@@ -83,7 +83,6 @@ struct SubsidyListWindow : Window {
 
		switch (s->src_type) {
 
			case ST_INDUSTRY: xy = Industry::Get(s->src)->xy; break;
 
			case ST_TOWN:     xy =     Town::Get(s->src)->xy; break;
 
			case ST_STATION:  xy =  Station::Get(s->src)->xy; break;
 
			default: NOT_REACHED();
 
		}
 

	
 
@@ -94,11 +93,9 @@ struct SubsidyListWindow : Window {
 
			switch (s->dst_type) {
 
				case ST_INDUSTRY: xy = Industry::Get(s->dst)->xy; break;
 
				case ST_TOWN:     xy =     Town::Get(s->dst)->xy; break;
 
				case ST_STATION:  xy =  Station::Get(s->dst)->xy; break;
 
				default: NOT_REACHED();
 
			}
 

	
 

	
 
			if (_ctrl_pressed) {
 
				ShowExtraViewPortWindow(xy);
 
			} else {
 
@@ -129,7 +126,7 @@ struct SubsidyListWindow : Window {
 
			if (!s->IsAwarded()) {
 
				/* Displays the two offered towns */
 
				SetupSubsidyDecodeParam(s, 1);
 
				SetDParam(7, _date - ymd.day + 384 - s->age * 32);
 
				SetDParam(7, _date - ymd.day + s->remaining * 32);
 
				DrawString(x + 2, right - 2, y, STR_SUBSIDIES_OFFERED_FROM_TO);
 

	
 
				y += FONT_HEIGHT_NORMAL;
 
@@ -150,8 +147,8 @@ struct SubsidyListWindow : Window {
 
		FOR_ALL_SUBSIDIES(s) {
 
			if (s->IsAwarded()) {
 
				SetupSubsidyDecodeParam(s, 1);
 
				SetDParam(3, Station::Get(s->dst)->owner);
 
				SetDParam(4, _date - ymd.day + 768 - s->age * 32);
 
				SetDParam(7, s->awarded);
 
				SetDParam(8, _date - ymd.day + s->remaining * 32);
 

	
 
				/* Displays the two connected stations */
 
				DrawString(x + 2, right - 2, y, STR_SUBSIDIES_SUBSIDISED_FROM_TO);
src/subsidy_type.h
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file subsidy_type.h basic types related to subsidies */
 

	
 
#ifndef SUBSIDY_TYPE_H
 
#define SUBSIDY_TYPE_H
 

	
 
#include "core/enum_type.hpp"
 

	
 
enum PartOfSubsidy {
 
	POS_NONE =     0,
 
	POS_SRC = 1 << 0, ///< bit 0 set -> town/industry is source of subsidised path
 
	POS_DST = 1 << 1, ///< bit 1 set -> town/industry is destination of subsidised path
 
};
 
typedef SimpleTinyEnumT<PartOfSubsidy, byte> PartOfSubsidyByte;
 

	
 
DECLARE_ENUM_AS_BIT_SET(PartOfSubsidy);
 

	
 
typedef uint16 SubsidyID; ///< ID of a subsidy
 
struct Subsidy;
 

	
 
#endif /* SUBSIDY_TYPE_H */
src/town.h
Show inline comments
 
@@ -20,6 +20,7 @@
 
#include "map_type.h"
 
#include "command_type.h"
 
#include "town_map.h"
 
#include "subsidy_type.h"
 

	
 
template <typename T>
 
struct BuildingCounts {
 
@@ -107,6 +108,8 @@ struct Town : TownPool::PoolItem<&_town_
 
	bool larger_town;
 
	TownLayoutByte layout; ///< town specific road layout
 

	
 
	PartOfSubsidyByte part_of_subsidy; ///< NOSAVE: is this town a source/destination of a subsidy?
 

	
 
	/* NOSAVE: UpdateTownRadius updates this given the house count. */
 
	uint32 squared_town_zone_radius[HZB_END];
 

	
src/town_cmd.cpp
Show inline comments
 
@@ -99,7 +99,7 @@ Town::~Town()
 
	}
 

	
 
	DeleteSubsidyWith(ST_TOWN, this->index);
 

	
 
	CargoPacket::InvalidateAllFrom(ST_TOWN, this->index);
 
	MarkWholeScreenDirty();
 
}
 

	
 
@@ -460,7 +460,7 @@ static void TileLoop_Town(TileIndex tile
 
			uint amt = GB(callback, 0, 8);
 
			if (amt == 0) continue;
 

	
 
			uint moved = MoveGoodsToStation(tile, 1, 1, cargo, amt);
 
			uint moved = MoveGoodsToStation(tile, 1, 1, cargo, amt, ST_TOWN, t->index);
 

	
 
			const CargoSpec *cs = CargoSpec::Get(cargo);
 
			switch (cs->town_effect) {
 
@@ -484,7 +484,7 @@ static void TileLoop_Town(TileIndex tile
 

	
 
			if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
 
			t->new_max_pass += amt;
 
			t->new_act_pass += MoveGoodsToStation(tile, 1, 1, CT_PASSENGERS, amt);
 
			t->new_act_pass += MoveGoodsToStation(tile, 1, 1, CT_PASSENGERS, amt, ST_TOWN, t->index);
 
		}
 

	
 
		if (GB(r, 8, 8) < hs->mail_generation) {
 
@@ -492,7 +492,7 @@ static void TileLoop_Town(TileIndex tile
 

	
 
			if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
 
			t->new_max_mail += amt;
 
			t->new_act_mail += MoveGoodsToStation(tile, 1, 1, CT_MAIL, amt);
 
			t->new_act_mail += MoveGoodsToStation(tile, 1, 1, CT_MAIL, amt, ST_TOWN, t->index);
 
		}
 
	}
 

	
src/unmovable_cmd.cpp
Show inline comments
 
@@ -23,6 +23,7 @@
 
#include "cheat_type.h"
 
#include "landscape_type.h"
 
#include "unmovable.h"
 
#include "cargopacket.h"
 

	
 
#include "table/strings.h"
 
#include "table/sprites.h"
 
@@ -62,6 +63,8 @@ static CommandCost DestroyCompanyHQ(Comp
 
		DoClearSquare(t + TileDiffXY(1, 1));
 
		c->location_of_HQ = INVALID_TILE; // reset HQ position
 
		InvalidateWindow(WC_COMPANY, cid);
 

	
 
		CargoPacket::InvalidateAllFrom(ST_HEADQUARTERS, cid);
 
	}
 

	
 
	/* cost of relocating company is 1% of company value */
 
@@ -335,7 +338,7 @@ static void TileLoop_Unmovable(TileIndex
 
	if (GB(r, 0, 8) < (256 / 4 / (6 - level))) {
 
		uint amt = GB(r, 0, 8) / 8 / 4 + 1;
 
		if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
 
		MoveGoodsToStation(tile, 2, 2, CT_PASSENGERS, amt);
 
		MoveGoodsToStation(tile, 2, 2, CT_PASSENGERS, amt, ST_HEADQUARTERS, GetTileOwner(tile));
 
	}
 

	
 
	/* Top town building generates 90, HQ can make up to 196. The
 
@@ -344,7 +347,7 @@ static void TileLoop_Unmovable(TileIndex
 
	if (GB(r, 8, 8) < (196 / 4 / (6 - level))) {
 
		uint amt = GB(r, 8, 8) / 8 / 4 + 1;
 
		if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
 
		MoveGoodsToStation(tile, 2, 2, CT_MAIL, amt);
 
		MoveGoodsToStation(tile, 2, 2, CT_MAIL, amt, ST_HEADQUARTERS, GetTileOwner(tile));
 
	}
 
}
 

	
0 comments (0 inline, 0 general)