mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-08 23:19:40 +00:00
Codechange: put SourceType and SourceID into Source struct
This commit is contained in:
parent
95bfd68341
commit
5f41bc0279
@ -141,4 +141,12 @@ enum class SourceType : uint8_t {
|
||||
typedef uint16_t SourceID; ///< Contains either industry ID, town ID or company ID (or INVALID_SOURCE)
|
||||
static const SourceID INVALID_SOURCE = 0xFFFF; ///< Invalid/unknown index of source
|
||||
|
||||
/** A location from where cargo can come from (or go to). Specifically industries, towns and headquarters. */
|
||||
struct Source {
|
||||
SourceID id; ///< Index of industry/town/HQ, INVALID_SOURCE if unknown/invalid.
|
||||
SourceType type; ///< Type of \c source_id.
|
||||
|
||||
auto operator<=>(const Source &source) const = default;
|
||||
};
|
||||
|
||||
#endif /* CARGO_TYPE_H */
|
||||
|
@ -110,26 +110,25 @@ int32_t GetPickupAmount(CargoMonitorID monitor, bool keep_monitoring)
|
||||
* @param cargo_type type of cargo.
|
||||
* @param company company delivering the cargo.
|
||||
* @param amount Amount of cargo delivered.
|
||||
* @param src_type type of \a src.
|
||||
* @param src index of source.
|
||||
* @param src source of cargo.
|
||||
* @param st station where the cargo is delivered to.
|
||||
* @param dest industry index where the cargo is delivered to.
|
||||
*/
|
||||
void AddCargoDelivery(CargoType cargo_type, CompanyID company, uint32_t amount, SourceType src_type, SourceID src, const Station *st, IndustryID dest)
|
||||
void AddCargoDelivery(CargoType cargo_type, CompanyID company, uint32_t amount, Source src, const Station *st, IndustryID dest)
|
||||
{
|
||||
if (amount == 0) return;
|
||||
|
||||
if (src != INVALID_SOURCE) {
|
||||
if (src.id != INVALID_SOURCE) {
|
||||
/* Handle pickup update. */
|
||||
switch (src_type) {
|
||||
switch (src.type) {
|
||||
case SourceType::Industry: {
|
||||
CargoMonitorID num = EncodeCargoIndustryMonitor(company, cargo_type, src);
|
||||
CargoMonitorID num = EncodeCargoIndustryMonitor(company, cargo_type, src.id);
|
||||
CargoMonitorMap::iterator iter = _cargo_pickups.find(num);
|
||||
if (iter != _cargo_pickups.end()) iter->second += amount;
|
||||
break;
|
||||
}
|
||||
case SourceType::Town: {
|
||||
CargoMonitorID num = EncodeCargoTownMonitor(company, cargo_type, src);
|
||||
CargoMonitorID num = EncodeCargoTownMonitor(company, cargo_type, src.id);
|
||||
CargoMonitorMap::iterator iter = _cargo_pickups.find(num);
|
||||
if (iter != _cargo_pickups.end()) iter->second += amount;
|
||||
break;
|
||||
|
@ -143,6 +143,6 @@ void ClearCargoPickupMonitoring(CompanyID company = INVALID_OWNER);
|
||||
void ClearCargoDeliveryMonitoring(CompanyID company = INVALID_OWNER);
|
||||
int32_t GetDeliveryAmount(CargoMonitorID monitor, bool keep_monitoring);
|
||||
int32_t GetPickupAmount(CargoMonitorID monitor, bool keep_monitoring);
|
||||
void AddCargoDelivery(CargoType cargo_type, CompanyID company, uint32_t amount, SourceType src_type, SourceID src, const Station *st, IndustryID dest = INVALID_INDUSTRY);
|
||||
void AddCargoDelivery(CargoType cargo_type, CompanyID company, uint32_t amount, Source src, const Station *st, IndustryID dest = INVALID_INDUSTRY);
|
||||
|
||||
#endif /* CARGOMONITOR_H */
|
||||
|
@ -26,8 +26,6 @@ INSTANTIATE_POOL_METHODS(CargoPacket)
|
||||
*/
|
||||
CargoPacket::CargoPacket()
|
||||
{
|
||||
this->source_type = SourceType::Industry;
|
||||
this->source_id = INVALID_SOURCE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -35,14 +33,12 @@ CargoPacket::CargoPacket()
|
||||
*
|
||||
* @param first_station Source station of the packet.
|
||||
* @param count Number of cargo entities to put in this packet.
|
||||
* @param source_type 'Type' of source the packet comes from (for subsidies).
|
||||
* @param source_id Actual source of the packet (for subsidies).
|
||||
* @param source Source of the packet (for subsidies).
|
||||
* @pre count != 0
|
||||
*/
|
||||
CargoPacket::CargoPacket(StationID first_station,uint16_t count, SourceType source_type, SourceID source_id) :
|
||||
CargoPacket::CargoPacket(StationID first_station,uint16_t count, Source source) :
|
||||
count(count),
|
||||
source_id(source_id),
|
||||
source_type(source_type),
|
||||
source(source),
|
||||
first_station(first_station)
|
||||
{
|
||||
assert(count != 0);
|
||||
@ -80,8 +76,7 @@ CargoPacket::CargoPacket(uint16_t count, Money feeder_share, CargoPacket &origin
|
||||
feeder_share(feeder_share),
|
||||
source_xy(original.source_xy),
|
||||
travelled(original.travelled),
|
||||
source_id(original.source_id),
|
||||
source_type(original.source_type),
|
||||
source(original.source),
|
||||
#ifdef WITH_ASSERT
|
||||
in_vehicle(original.in_vehicle),
|
||||
#endif /* WITH_ASSERT */
|
||||
@ -134,10 +129,10 @@ void CargoPacket::Reduce(uint count)
|
||||
* @param src_type Type of source.
|
||||
* @param src Index of source.
|
||||
*/
|
||||
/* static */ void CargoPacket::InvalidateAllFrom(SourceType src_type, SourceID src)
|
||||
/* static */ void CargoPacket::InvalidateAllFrom(Source src)
|
||||
{
|
||||
for (CargoPacket *cp : CargoPacket::Iterate()) {
|
||||
if (cp->source_type == src_type && cp->source_id == src) cp->source_id = INVALID_SOURCE;
|
||||
if (cp->source == src) cp->source.id = INVALID_SOURCE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,8 +53,7 @@ private:
|
||||
TileIndex source_xy = INVALID_TILE; ///< The origin of the cargo.
|
||||
Vector travelled{0, 0}; ///< If cargo is in station: the vector from the unload tile to the source tile. If in vehicle: an intermediate value.
|
||||
|
||||
SourceID source_id = INVALID_SOURCE; ///< Index of industry/town/HQ, INVALID_SOURCE if unknown/invalid.
|
||||
SourceType source_type = SourceType::Industry; ///< Type of \c source_id.
|
||||
Source source{INVALID_SOURCE, SourceType::Industry}; ///< Source of the cargo
|
||||
|
||||
#ifdef WITH_ASSERT
|
||||
bool in_vehicle = false; ///< NOSAVE: Whether this cargo is in a vehicle or not.
|
||||
@ -74,7 +73,7 @@ public:
|
||||
static const uint16_t MAX_COUNT = UINT16_MAX;
|
||||
|
||||
CargoPacket();
|
||||
CargoPacket(StationID first_station, uint16_t count, SourceType source_type, SourceID source_id);
|
||||
CargoPacket(StationID first_station, uint16_t count, Source source);
|
||||
CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID first_station, TileIndex source_xy, Money feeder_share);
|
||||
CargoPacket(uint16_t count, Money feeder_share, CargoPacket &original);
|
||||
|
||||
@ -194,21 +193,12 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of the cargo's source. industry, town or head quarter.
|
||||
* @return Source type.
|
||||
* Gets the source of the packet for subsidy purposes.
|
||||
* @return The source.
|
||||
*/
|
||||
inline SourceType GetSourceType() const
|
||||
inline Source GetSource() const
|
||||
{
|
||||
return this->source_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ID of the cargo's source. An IndustryID, TownID or CompanyID.
|
||||
* @return Source ID.
|
||||
*/
|
||||
inline SourceID GetSourceID() const
|
||||
{
|
||||
return this->source_id;
|
||||
return this->source;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -270,7 +260,7 @@ public:
|
||||
return this->next_hop;
|
||||
}
|
||||
|
||||
static void InvalidateAllFrom(SourceType src_type, SourceID src);
|
||||
static void InvalidateAllFrom(Source src);
|
||||
static void InvalidateAllFrom(StationID sid);
|
||||
static void AfterLoad();
|
||||
};
|
||||
@ -514,9 +504,9 @@ public:
|
||||
{
|
||||
return cp1->source_xy == cp2->source_xy &&
|
||||
cp1->periods_in_transit == cp2->periods_in_transit &&
|
||||
cp1->source_type == cp2->source_type &&
|
||||
cp1->source.type == cp2->source.type &&
|
||||
cp1->first_station == cp2->first_station &&
|
||||
cp1->source_id == cp2->source_id;
|
||||
cp1->source.id == cp2->source.id;
|
||||
}
|
||||
};
|
||||
|
||||
@ -547,7 +537,7 @@ public:
|
||||
friend class CargoReturn;
|
||||
friend class StationCargoReroute;
|
||||
|
||||
static void InvalidateAllFrom(SourceType src_type, SourceID src);
|
||||
static void InvalidateAllFrom(Source src);
|
||||
|
||||
template <class Taction>
|
||||
bool ShiftCargo(Taction &action, StationID next);
|
||||
@ -629,9 +619,8 @@ public:
|
||||
{
|
||||
return cp1->source_xy == cp2->source_xy &&
|
||||
cp1->periods_in_transit == cp2->periods_in_transit &&
|
||||
cp1->source_type == cp2->source_type &&
|
||||
cp1->first_station == cp2->first_station &&
|
||||
cp1->source_id == cp2->source_id;
|
||||
cp1->source == cp2->source;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1089,7 +1089,7 @@ static uint DeliverGoodsToIndustry(const Station *st, CargoType cargo_type, uint
|
||||
accepted += amount;
|
||||
|
||||
/* Update the cargo monitor. */
|
||||
AddCargoDelivery(cargo_type, company, amount, SourceType::Industry, source, st, ind->index);
|
||||
AddCargoDelivery(cargo_type, company, amount, {source, SourceType::Industry}, st, ind->index);
|
||||
}
|
||||
|
||||
return accepted;
|
||||
@ -1103,19 +1103,18 @@ static uint DeliverGoodsToIndustry(const Station *st, CargoType cargo_type, uint
|
||||
* @param distance The distance the cargo has traveled.
|
||||
* @param periods_in_transit Travel time in cargo aging periods
|
||||
* @param company The company delivering the cargo
|
||||
* @param src_type Type of source of cargo (industry, town, headquarters)
|
||||
* @param src Index of source of cargo
|
||||
* @param src 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, CargoType cargo_type, StationID dest, uint distance, uint16_t periods_in_transit, Company *company, SourceType src_type, SourceID src)
|
||||
static Money DeliverGoods(int num_pieces, CargoType cargo_type, StationID dest, uint distance, uint16_t periods_in_transit, Company *company, Source src)
|
||||
{
|
||||
assert(num_pieces > 0);
|
||||
|
||||
Station *st = Station::Get(dest);
|
||||
|
||||
/* Give the goods to the industry. */
|
||||
uint accepted_ind = DeliverGoodsToIndustry(st, cargo_type, num_pieces, src_type == SourceType::Industry ? src : INVALID_INDUSTRY, company->index);
|
||||
uint accepted_ind = DeliverGoodsToIndustry(st, cargo_type, num_pieces, src.type == SourceType::Industry ? src.id : INVALID_INDUSTRY, company->index);
|
||||
|
||||
/* If this cargo type is always accepted, accept all */
|
||||
uint accepted_total = HasBit(st->always_accepted, cargo_type) ? num_pieces : accepted_ind;
|
||||
@ -1138,10 +1137,10 @@ static Money DeliverGoods(int num_pieces, CargoType cargo_type, StationID dest,
|
||||
Money profit = GetTransportedGoodsIncome(accepted_total, distance, periods_in_transit, cargo_type);
|
||||
|
||||
/* Update the cargo monitor. */
|
||||
AddCargoDelivery(cargo_type, company->index, accepted_total - accepted_ind, src_type, src, st);
|
||||
AddCargoDelivery(cargo_type, company->index, accepted_total - accepted_ind, src, st);
|
||||
|
||||
/* Modify profit if a subsidy is in effect */
|
||||
if (CheckSubsidised(cargo_type, company->index, src_type, src, st)) {
|
||||
if (CheckSubsidised(cargo_type, company->index, src, st)) {
|
||||
switch (_settings_game.difficulty.subsidy_multiplier) {
|
||||
case 0: profit += profit >> 1; break;
|
||||
case 1: profit *= 2; break;
|
||||
@ -1240,7 +1239,7 @@ void CargoPayment::PayFinalDelivery(CargoType cargo, const CargoPacket *cp, uint
|
||||
}
|
||||
|
||||
/* Handle end of route payment */
|
||||
Money profit = DeliverGoods(count, cargo, this->current_station, cp->GetDistance(current_tile), cp->GetPeriodsInTransit(), this->owner, cp->GetSourceType(), cp->GetSourceID());
|
||||
Money profit = DeliverGoods(count, cargo, this->current_station, cp->GetDistance(current_tile), cp->GetPeriodsInTransit(), this->owner, cp->GetSource());
|
||||
this->route_profit += profit;
|
||||
|
||||
/* The vehicle's profit is whatever route profit there is minus feeder shares. */
|
||||
|
@ -31,7 +31,7 @@ int UpdateCompanyRatingAndValue(Company *c, bool update);
|
||||
void StartupIndustryDailyChanges(bool init_counter);
|
||||
|
||||
Money GetTransportedGoodsIncome(uint num_pieces, uint dist, uint16_t transit_periods, CargoType cargo_type);
|
||||
uint MoveGoodsToStation(CargoType type, uint amount, SourceType source_type, SourceID source_id, const StationList &all_stations, Owner exclusivity = INVALID_OWNER);
|
||||
uint MoveGoodsToStation(CargoType type, uint amount, Source source, const StationList &all_stations, Owner exclusivity = INVALID_OWNER);
|
||||
|
||||
void PrepareUnload(Vehicle *front_v);
|
||||
void LoadUnloadStation(Station *st);
|
||||
|
@ -197,8 +197,9 @@ Industry::~Industry()
|
||||
CloseWindowById(WC_INDUSTRY_VIEW, this->index);
|
||||
DeleteNewGRFInspectWindow(GSF_INDUSTRIES, this->index);
|
||||
|
||||
DeleteSubsidyWith(SourceType::Industry, this->index);
|
||||
CargoPacket::InvalidateAllFrom(SourceType::Industry, this->index);
|
||||
Source src{this->index, SourceType::Industry};
|
||||
DeleteSubsidyWith(src);
|
||||
CargoPacket::InvalidateAllFrom(src);
|
||||
|
||||
for (Station *st : this->stations_near) {
|
||||
st->RemoveIndustryToDeliver(this);
|
||||
@ -537,7 +538,7 @@ static bool TransportIndustryGoods(TileIndex tile)
|
||||
|
||||
p.history[THIS_MONTH].production += cw;
|
||||
|
||||
uint am = MoveGoodsToStation(p.cargo, cw, SourceType::Industry, i->index, i->stations_near, i->exclusive_consumer);
|
||||
uint am = MoveGoodsToStation(p.cargo, cw, {i->index, SourceType::Industry}, i->stations_near, i->exclusive_consumer);
|
||||
p.history[THIS_MONTH].transported += am;
|
||||
|
||||
moved_cargo |= (am != 0);
|
||||
|
@ -591,7 +591,7 @@ static CommandCost ClearTile_Object(TileIndex tile, DoCommandFlag flags)
|
||||
if (flags & DC_EXEC) {
|
||||
c->location_of_HQ = INVALID_TILE; // reset HQ position
|
||||
SetWindowDirty(WC_COMPANY, c->index);
|
||||
CargoPacket::InvalidateAllFrom(SourceType::Headquarters, c->index);
|
||||
CargoPacket::InvalidateAllFrom({c->index, SourceType::Headquarters});
|
||||
}
|
||||
|
||||
/* cost of relocating company is 1% of company value */
|
||||
@ -704,13 +704,13 @@ static void TileLoop_Object(TileIndex tile)
|
||||
/* Scale by cargo scale setting. */
|
||||
amt = ScaleByCargoScale(amt, true);
|
||||
|
||||
MoveGoodsToStation(pass, amt, SourceType::Headquarters, GetTileOwner(tile), stations.GetStations());
|
||||
MoveGoodsToStation(pass, amt, {GetTileOwner(tile), SourceType::Headquarters}, stations.GetStations());
|
||||
}
|
||||
|
||||
/* Top town building generates 90, HQ can make up to 196. The
|
||||
* proportion passengers:mail is about the same as in the acceptance
|
||||
* equations. */
|
||||
CargoType mail = GetCargoTypeByLabel(CT_MAIL);
|
||||
CargoType mail = GetCargoTypeByLabel(CT_MAIL);
|
||||
if (IsValidCargoType(mail) && GB(r, 8, 8) < (196 / 4 / (6 - level))) {
|
||||
uint amt = GB(r, 8, 8) / 8 / 4 + 1;
|
||||
|
||||
@ -720,7 +720,7 @@ static void TileLoop_Object(TileIndex tile)
|
||||
/* Scale by cargo scale setting. */
|
||||
amt = ScaleByCargoScale(amt, true);
|
||||
|
||||
MoveGoodsToStation(mail, amt, SourceType::Headquarters, GetTileOwner(tile), stations.GetStations());
|
||||
MoveGoodsToStation(mail, amt, {GetTileOwner(tile), SourceType::Headquarters}, stations.GetStations());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2279,20 +2279,20 @@ bool AfterLoadGame()
|
||||
case TAE_PASSENGERS:
|
||||
case TAE_MAIL:
|
||||
/* Town -> Town */
|
||||
s->src_type = s->dst_type = SourceType::Town;
|
||||
if (Town::IsValidID(s->src) && Town::IsValidID(s->dst)) continue;
|
||||
s->src.type = s->dst.type = SourceType::Town;
|
||||
if (Town::IsValidID(s->src.id) && Town::IsValidID(s->dst.id)) continue;
|
||||
break;
|
||||
case TAE_GOODS:
|
||||
case TAE_FOOD:
|
||||
/* Industry -> Town */
|
||||
s->src_type = SourceType::Industry;
|
||||
s->dst_type = SourceType::Town;
|
||||
if (Industry::IsValidID(s->src) && Town::IsValidID(s->dst)) continue;
|
||||
s->src.type = SourceType::Industry;
|
||||
s->dst.type = SourceType::Town;
|
||||
if (Industry::IsValidID(s->src.id) && Town::IsValidID(s->dst.id)) continue;
|
||||
break;
|
||||
default:
|
||||
/* Industry -> Industry */
|
||||
s->src_type = s->dst_type = SourceType::Industry;
|
||||
if (Industry::IsValidID(s->src) && Industry::IsValidID(s->dst)) continue;
|
||||
s->src.type = s->dst.type = SourceType::Industry;
|
||||
if (Industry::IsValidID(s->src.id) && Industry::IsValidID(s->dst.id)) continue;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@ -2305,13 +2305,13 @@ bool AfterLoadGame()
|
||||
case TAE_PASSENGERS:
|
||||
case TAE_MAIL: {
|
||||
/* Town -> Town */
|
||||
const Station *ss = Station::GetIfValid(s->src);
|
||||
const Station *sd = Station::GetIfValid(s->dst);
|
||||
const Station *ss = Station::GetIfValid(s->src.id);
|
||||
const Station *sd = Station::GetIfValid(s->dst.id);
|
||||
if (ss != nullptr && sd != nullptr && ss->owner == sd->owner &&
|
||||
Company::IsValidID(ss->owner)) {
|
||||
s->src_type = s->dst_type = SourceType::Town;
|
||||
s->src = ss->town->index;
|
||||
s->dst = sd->town->index;
|
||||
s->src.type = s->dst.type = SourceType::Town;
|
||||
s->src.id = ss->town->index;
|
||||
s->dst.id = sd->town->index;
|
||||
s->awarded = ss->owner;
|
||||
continue;
|
||||
}
|
||||
|
@ -134,8 +134,8 @@ SaveLoadTable GetCargoPacketDesc()
|
||||
SLE_CONDVARNAME(CargoPacket, periods_in_transit, "days_in_transit", SLE_UINT16, SLV_MORE_CARGO_AGE, SLV_PERIODS_IN_TRANSIT_RENAME),
|
||||
SLE_CONDVAR(CargoPacket, periods_in_transit, SLE_UINT16, SLV_PERIODS_IN_TRANSIT_RENAME, SL_MAX_VERSION),
|
||||
SLE_VAR(CargoPacket, feeder_share, SLE_INT64),
|
||||
SLE_CONDVAR(CargoPacket, source_type, SLE_UINT8, SLV_125, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(CargoPacket, source_id, SLE_UINT16, SLV_125, SL_MAX_VERSION),
|
||||
SLE_CONDVARNAME(CargoPacket, source.type, "source_type", SLE_UINT8, SLV_125, SL_MAX_VERSION),
|
||||
SLE_CONDVARNAME(CargoPacket, source.id, "source_id", SLE_UINT16, SLV_125, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(CargoPacket, travelled.x, SLE_INT16, SLV_CARGO_TRAVELLED, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(CargoPacket, travelled.y, SLE_INT16, SLV_CARGO_TRAVELLED, SL_MAX_VERSION),
|
||||
};
|
||||
|
@ -21,12 +21,12 @@ static const SaveLoad _subsidies_desc[] = {
|
||||
SLE_CONDVAR(Subsidy, remaining, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_CUSTOM_SUBSIDY_DURATION),
|
||||
SLE_CONDVAR(Subsidy, remaining, SLE_UINT16, SLV_CUSTOM_SUBSIDY_DURATION, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Subsidy, awarded, SLE_UINT8, SLV_125, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Subsidy, src_type, SLE_UINT8, SLV_125, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Subsidy, dst_type, SLE_UINT8, SLV_125, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Subsidy, src, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5),
|
||||
SLE_CONDVAR(Subsidy, src, SLE_UINT16, SLV_5, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Subsidy, dst, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5),
|
||||
SLE_CONDVAR(Subsidy, dst, SLE_UINT16, SLV_5, SL_MAX_VERSION),
|
||||
SLE_CONDVARNAME(Subsidy, src.type, "src_type", SLE_UINT8, SLV_125, SL_MAX_VERSION),
|
||||
SLE_CONDVARNAME(Subsidy, dst.type, "dst_type", SLE_UINT8, SLV_125, SL_MAX_VERSION),
|
||||
SLE_CONDVARNAME(Subsidy, src.id, "src", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5),
|
||||
SLE_CONDVARNAME(Subsidy, src.id, "src", SLE_UINT16, SLV_5, SL_MAX_VERSION),
|
||||
SLE_CONDVARNAME(Subsidy, dst.id, "dst", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5),
|
||||
SLE_CONDVARNAME(Subsidy, dst.id, "dst", SLE_UINT16, SLV_5, SL_MAX_VERSION),
|
||||
};
|
||||
|
||||
struct SUBSChunkHandler : ChunkHandler {
|
||||
|
@ -40,7 +40,10 @@
|
||||
EnforcePrecondition(false, (from_type == SPT_INDUSTRY && ScriptIndustry::IsValidIndustry(from_id)) || (from_type == SPT_TOWN && ScriptTown::IsValidTown(from_id)));
|
||||
EnforcePrecondition(false, (to_type == SPT_INDUSTRY && ScriptIndustry::IsValidIndustry(to_id)) || (to_type == SPT_TOWN && ScriptTown::IsValidTown(to_id)));
|
||||
|
||||
return ScriptObject::Command<CMD_CREATE_SUBSIDY>::Do(cargo_type, (::SourceType)from_type, from_id, (::SourceType)to_type, to_id);
|
||||
Source from{static_cast<SourceID>(from_id), static_cast<SourceType>(from_type)};
|
||||
Source to{static_cast<SourceID>(to_id), static_cast<SourceType>(to_type)};
|
||||
|
||||
return ScriptObject::Command<CMD_CREATE_SUBSIDY>::Do(cargo_type, from, to);
|
||||
}
|
||||
|
||||
/* static */ ScriptCompany::CompanyID ScriptSubsidy::GetAwardedTo(SubsidyID subsidy_id)
|
||||
@ -74,26 +77,26 @@
|
||||
{
|
||||
if (!IsValidSubsidy(subsidy_id)) return SPT_INVALID;
|
||||
|
||||
return (SubsidyParticipantType)(uint)::Subsidy::Get(subsidy_id)->src_type;
|
||||
return static_cast<SubsidyParticipantType>(::Subsidy::Get(subsidy_id)->src.type);
|
||||
}
|
||||
|
||||
/* static */ SQInteger ScriptSubsidy::GetSourceIndex(SubsidyID subsidy_id)
|
||||
{
|
||||
if (!IsValidSubsidy(subsidy_id)) return INVALID_SOURCE;
|
||||
|
||||
return ::Subsidy::Get(subsidy_id)->src;
|
||||
return ::Subsidy::Get(subsidy_id)->src.id;
|
||||
}
|
||||
|
||||
/* static */ ScriptSubsidy::SubsidyParticipantType ScriptSubsidy::GetDestinationType(SubsidyID subsidy_id)
|
||||
{
|
||||
if (!IsValidSubsidy(subsidy_id)) return SPT_INVALID;
|
||||
|
||||
return (SubsidyParticipantType)(uint)::Subsidy::Get(subsidy_id)->dst_type;
|
||||
return static_cast<SubsidyParticipantType>(::Subsidy::Get(subsidy_id)->dst.type);
|
||||
}
|
||||
|
||||
/* static */ SQInteger ScriptSubsidy::GetDestinationIndex(SubsidyID subsidy_id)
|
||||
{
|
||||
if (!IsValidSubsidy(subsidy_id)) return INVALID_SOURCE;
|
||||
|
||||
return ::Subsidy::Get(subsidy_id)->dst;
|
||||
return ::Subsidy::Get(subsidy_id)->dst.id;
|
||||
}
|
||||
|
@ -4246,7 +4246,7 @@ void ModifyStationRatingAround(TileIndex tile, Owner owner, int amount, uint rad
|
||||
});
|
||||
}
|
||||
|
||||
static uint UpdateStationWaiting(Station *st, CargoType type, uint amount, SourceType source_type, SourceID source_id)
|
||||
static uint UpdateStationWaiting(Station *st, CargoType type, uint amount, Source source)
|
||||
{
|
||||
/* We can't allocate a CargoPacket? Then don't do anything
|
||||
* at all; i.e. just discard the incoming cargo. */
|
||||
@ -4261,7 +4261,7 @@ static uint UpdateStationWaiting(Station *st, CargoType type, uint amount, Sourc
|
||||
if (amount == 0) return 0;
|
||||
|
||||
StationID next = ge.GetVia(st->index);
|
||||
ge.GetOrCreateData().cargo.Append(new CargoPacket(st->index, amount, source_type, source_id), next);
|
||||
ge.GetOrCreateData().cargo.Append(new CargoPacket(st->index, amount, source), next);
|
||||
LinkGraph *lg = nullptr;
|
||||
if (ge.link_graph == INVALID_LINK_GRAPH) {
|
||||
if (LinkGraph::CanAllocateItem()) {
|
||||
@ -4391,7 +4391,7 @@ static bool CanMoveGoodsToStation(const Station *st, CargoType type)
|
||||
return true;
|
||||
}
|
||||
|
||||
uint MoveGoodsToStation(CargoType type, uint amount, SourceType source_type, SourceID source_id, const StationList &all_stations, Owner exclusivity)
|
||||
uint MoveGoodsToStation(CargoType type, uint amount, Source source, const StationList &all_stations, Owner exclusivity)
|
||||
{
|
||||
/* Return if nothing to do. Also the rounding below fails for 0. */
|
||||
if (all_stations.empty()) return 0;
|
||||
@ -4424,7 +4424,7 @@ uint MoveGoodsToStation(CargoType type, uint amount, SourceType source_type, Sou
|
||||
if (used_stations.empty()) {
|
||||
/* only one station around */
|
||||
amount *= first_station->goods[type].rating + 1;
|
||||
return UpdateStationWaiting(first_station, type, amount, source_type, source_id);
|
||||
return UpdateStationWaiting(first_station, type, amount, source);
|
||||
}
|
||||
|
||||
uint company_best[OWNER_NONE + 1] = {}; // best rating for each company, including OWNER_NONE
|
||||
@ -4470,7 +4470,7 @@ uint MoveGoodsToStation(CargoType type, uint amount, SourceType source_type, Sou
|
||||
|
||||
uint moved = 0;
|
||||
for (auto &p : used_stations) {
|
||||
moved += UpdateStationWaiting(p.first, type, p.second, source_type, source_id);
|
||||
moved += UpdateStationWaiting(p.first, type, p.second, source);
|
||||
}
|
||||
|
||||
return moved;
|
||||
|
167
src/subsidy.cpp
167
src/subsidy.cpp
@ -57,7 +57,7 @@ void Subsidy::AwardTo(CompanyID company)
|
||||
AddNewsItem(
|
||||
STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF + _settings_game.difficulty.subsidy_multiplier,
|
||||
NewsType::Subsidies, NewsStyle::Normal, {},
|
||||
reftype.first, this->src, reftype.second, this->dst
|
||||
reftype.first, this->src.id, reftype.second, this->dst.id
|
||||
);
|
||||
AI::BroadcastNewEvent(new ScriptEventSubsidyAwarded(this->index));
|
||||
Game::NewEvent(new ScriptEventSubsidyAwarded(this->index));
|
||||
@ -81,7 +81,7 @@ std::pair<NewsReferenceType, NewsReferenceType> SetupSubsidyDecodeParam(const Su
|
||||
const CargoSpec *cs = CargoSpec::Get(s->cargo_type);
|
||||
SetDParam(parameter_offset, cs->name);
|
||||
|
||||
switch (s->src_type) {
|
||||
switch (s->src.type) {
|
||||
case SourceType::Industry:
|
||||
reftype1 = NewsReferenceType::Industry;
|
||||
SetDParam(parameter_offset + 1, STR_INDUSTRY_NAME);
|
||||
@ -92,9 +92,9 @@ std::pair<NewsReferenceType, NewsReferenceType> SetupSubsidyDecodeParam(const Su
|
||||
break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
SetDParam(parameter_offset + 2, s->src);
|
||||
SetDParam(parameter_offset + 2, s->src.id);
|
||||
|
||||
switch (s->dst_type) {
|
||||
switch (s->dst.type) {
|
||||
case SourceType::Industry:
|
||||
reftype2 = NewsReferenceType::Industry;
|
||||
SetDParam(parameter_offset + 4, STR_INDUSTRY_NAME);
|
||||
@ -105,7 +105,7 @@ std::pair<NewsReferenceType, NewsReferenceType> SetupSubsidyDecodeParam(const Su
|
||||
break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
SetDParam(parameter_offset + 5, s->dst);
|
||||
SetDParam(parameter_offset + 5, s->dst.id);
|
||||
|
||||
/* If the subsidy is being offered or awarded, the news item mentions the subsidy duration. */
|
||||
if (mode == SubsidyDecodeParamType::NewsOffered || mode == SubsidyDecodeParamType::NewsAwarded) {
|
||||
@ -117,15 +117,14 @@ std::pair<NewsReferenceType, NewsReferenceType> SetupSubsidyDecodeParam(const Su
|
||||
|
||||
/**
|
||||
* 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 source actual source
|
||||
* @param flag flag to set
|
||||
*/
|
||||
static inline void SetPartOfSubsidyFlag(SourceType type, SourceID index, PartOfSubsidy flag)
|
||||
static inline void SetPartOfSubsidyFlag(Source source, PartOfSubsidy flag)
|
||||
{
|
||||
switch (type) {
|
||||
case SourceType::Industry: Industry::Get(index)->part_of_subsidy |= flag; return;
|
||||
case SourceType::Town: Town::Get(index)->cache.part_of_subsidy |= flag; return;
|
||||
switch (source.type) {
|
||||
case SourceType::Industry: Industry::Get(source.id)->part_of_subsidy |= flag; return;
|
||||
case SourceType::Town: Town::Get(source.id)->cache.part_of_subsidy |= flag; return;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
}
|
||||
@ -138,22 +137,21 @@ void RebuildSubsidisedSourceAndDestinationCache()
|
||||
for (Industry *i : Industry::Iterate()) i->part_of_subsidy = POS_NONE;
|
||||
|
||||
for (const Subsidy *s : Subsidy::Iterate()) {
|
||||
SetPartOfSubsidyFlag(s->src_type, s->src, POS_SRC);
|
||||
SetPartOfSubsidyFlag(s->dst_type, s->dst, POS_DST);
|
||||
SetPartOfSubsidyFlag(s->src, POS_SRC);
|
||||
SetPartOfSubsidyFlag(s->dst, POS_DST);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the subsidies associated with a given cargo source type and id.
|
||||
* @param type Cargo source type of the id.
|
||||
* @param index Id to remove.
|
||||
* @param source The source to look for.
|
||||
*/
|
||||
void DeleteSubsidyWith(SourceType type, SourceID index)
|
||||
void DeleteSubsidyWith(Source source)
|
||||
{
|
||||
bool dirty = false;
|
||||
|
||||
for (Subsidy *s : Subsidy::Iterate()) {
|
||||
if ((s->src_type == type && s->src == index) || (s->dst_type == type && s->dst == index)) {
|
||||
if (s->src == source || s->dst == source) {
|
||||
delete s;
|
||||
dirty = true;
|
||||
}
|
||||
@ -168,18 +166,14 @@ void DeleteSubsidyWith(SourceType type, SourceID index)
|
||||
/**
|
||||
* Check whether a specific subsidy already exists.
|
||||
* @param cargo Cargo type.
|
||||
* @param src_type Type of source of the cargo, affects interpretation of \a src.
|
||||
* @param src Id of the source.
|
||||
* @param dst_type Type of the destination of the cargo, affects interpretation of \a dst.
|
||||
* @param dst Id of the destination.
|
||||
* @param src The source.
|
||||
* @param dst The destination.
|
||||
* @return \c true if the subsidy already exists, \c false if not.
|
||||
*/
|
||||
static bool CheckSubsidyDuplicate(CargoType cargo, SourceType src_type, SourceID src, SourceType dst_type, SourceID dst)
|
||||
static bool CheckSubsidyDuplicate(CargoType cargo, Source src, Source dst)
|
||||
{
|
||||
for (const Subsidy *s : Subsidy::Iterate()) {
|
||||
if (s->cargo_type == cargo &&
|
||||
s->src_type == src_type && s->src == src &&
|
||||
s->dst_type == dst_type && s->dst == dst) {
|
||||
if (s->cargo_type == cargo && s->src == src && s->dst == dst) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -188,43 +182,37 @@ static bool CheckSubsidyDuplicate(CargoType cargo, SourceType src_type, SourceID
|
||||
|
||||
/**
|
||||
* Checks if the source and destination of a subsidy are inside the distance limit.
|
||||
* @param src_type Type of \a src.
|
||||
* @param src Index of source.
|
||||
* @param dst_type Type of \a dst.
|
||||
* @param dst Index of destination.
|
||||
* @param src Source of cargo.
|
||||
* @param dst Destination of cargo.
|
||||
* @return True if they are inside the distance limit.
|
||||
*/
|
||||
static bool CheckSubsidyDistance(SourceType src_type, SourceID src, SourceType dst_type, SourceID dst)
|
||||
static bool CheckSubsidyDistance(Source src, Source dst)
|
||||
{
|
||||
TileIndex tile_src = (src_type == SourceType::Town) ? Town::Get(src)->xy : Industry::Get(src)->location.tile;
|
||||
TileIndex tile_dst = (dst_type == SourceType::Town) ? Town::Get(dst)->xy : Industry::Get(dst)->location.tile;
|
||||
TileIndex tile_src = (src.type == SourceType::Town) ? Town::Get(src.id)->xy : Industry::Get(src.id)->location.tile;
|
||||
TileIndex tile_dst = (dst.type == SourceType::Town) ? Town::Get(dst.id)->xy : Industry::Get(dst.id)->location.tile;
|
||||
|
||||
return (DistanceManhattan(tile_src, tile_dst) <= SUBSIDY_MAX_DISTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a subsidy with the given parameters.
|
||||
* @param cargo_type Subsidised cargo.
|
||||
* @param src_type Type of \a src.
|
||||
* @param src Index of source.
|
||||
* @param dst_type Type of \a dst.
|
||||
* @param dst Index of destination.
|
||||
* @param cargo_type Subsidised cargo.
|
||||
* @param src Source of cargo.
|
||||
* @param dst Destination of cargo.
|
||||
*/
|
||||
void CreateSubsidy(CargoType cargo_type, SourceType src_type, SourceID src, SourceType dst_type, SourceID dst)
|
||||
void CreateSubsidy(CargoType cargo_type, Source src, Source dst)
|
||||
{
|
||||
Subsidy *s = new Subsidy();
|
||||
s->cargo_type = cargo_type;
|
||||
s->src_type = src_type;
|
||||
s->src = src;
|
||||
s->dst_type = dst_type;
|
||||
s->dst = dst;
|
||||
s->remaining = SUBSIDY_OFFER_MONTHS;
|
||||
s->awarded = INVALID_COMPANY;
|
||||
|
||||
std::pair<NewsReferenceType, NewsReferenceType> reftype = SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::NewsOffered);
|
||||
AddNewsItem(STR_NEWS_SERVICE_SUBSIDY_OFFERED, NewsType::Subsidies, NewsStyle::Normal, {}, reftype.first, s->src, reftype.second, s->dst);
|
||||
SetPartOfSubsidyFlag(s->src_type, s->src, POS_SRC);
|
||||
SetPartOfSubsidyFlag(s->dst_type, s->dst, POS_DST);
|
||||
AddNewsItem(STR_NEWS_SERVICE_SUBSIDY_OFFERED, NewsType::Subsidies, NewsStyle::Normal, {}, reftype.first, s->src.id, reftype.second, s->dst.id);
|
||||
SetPartOfSubsidyFlag(s->src, POS_SRC);
|
||||
SetPartOfSubsidyFlag(s->dst, POS_DST);
|
||||
AI::BroadcastNewEvent(new ScriptEventSubsidyOffer(s->index));
|
||||
Game::NewEvent(new ScriptEventSubsidyOffer(s->index));
|
||||
|
||||
@ -235,13 +223,11 @@ void CreateSubsidy(CargoType cargo_type, SourceType src_type, SourceID src, Sour
|
||||
* Create a new subsidy.
|
||||
* @param flags type of operation
|
||||
* @param cargo_type CargoType of subsidy.
|
||||
* @param src_type SourceType of source.
|
||||
* @param src SourceID of source.
|
||||
* @param dst_type SourceType of destination.
|
||||
* @param dst SourceID of destination.
|
||||
* @param src Source.
|
||||
* @param dst Destination.
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdCreateSubsidy(DoCommandFlag flags, CargoType cargo_type, SourceType src_type, SourceID src, SourceType dst_type, SourceID dst)
|
||||
CommandCost CmdCreateSubsidy(DoCommandFlag flags, CargoType cargo_type, Source src, Source dst)
|
||||
{
|
||||
if (!Subsidy::CanAllocateItem()) return CMD_ERROR;
|
||||
|
||||
@ -249,29 +235,29 @@ CommandCost CmdCreateSubsidy(DoCommandFlag flags, CargoType cargo_type, SourceTy
|
||||
|
||||
if (cargo_type >= NUM_CARGO || !::CargoSpec::Get(cargo_type)->IsValid()) return CMD_ERROR;
|
||||
|
||||
switch (src_type) {
|
||||
switch (src.type) {
|
||||
case SourceType::Town:
|
||||
if (!Town::IsValidID(src)) return CMD_ERROR;
|
||||
if (!Town::IsValidID(src.id)) return CMD_ERROR;
|
||||
break;
|
||||
case SourceType::Industry:
|
||||
if (!Industry::IsValidID(src)) return CMD_ERROR;
|
||||
if (!Industry::IsValidID(src.id)) return CMD_ERROR;
|
||||
break;
|
||||
default:
|
||||
return CMD_ERROR;
|
||||
}
|
||||
switch (dst_type) {
|
||||
switch (dst.type) {
|
||||
case SourceType::Town:
|
||||
if (!Town::IsValidID(dst)) return CMD_ERROR;
|
||||
if (!Town::IsValidID(dst.id)) return CMD_ERROR;
|
||||
break;
|
||||
case SourceType::Industry:
|
||||
if (!Industry::IsValidID(dst)) return CMD_ERROR;
|
||||
if (!Industry::IsValidID(dst.id)) return CMD_ERROR;
|
||||
break;
|
||||
default:
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
CreateSubsidy(cargo_type, src_type, src, dst_type, dst);
|
||||
CreateSubsidy(cargo_type, src, dst);
|
||||
}
|
||||
|
||||
return CommandCost();
|
||||
@ -301,14 +287,14 @@ bool FindSubsidyPassengerRoute()
|
||||
}
|
||||
|
||||
if (DistanceManhattan(src->xy, dst->xy) > SUBSIDY_MAX_DISTANCE) return false;
|
||||
if (CheckSubsidyDuplicate(cargo_type, SourceType::Town, src->index, SourceType::Town, dst->index)) return false;
|
||||
if (CheckSubsidyDuplicate(cargo_type, {src->index, SourceType::Town}, {dst->index, SourceType::Town})) return false;
|
||||
|
||||
CreateSubsidy(cargo_type, SourceType::Town, src->index, SourceType::Town, dst->index);
|
||||
CreateSubsidy(cargo_type, {src->index, SourceType::Town}, {dst->index, SourceType::Town});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FindSubsidyCargoDestination(CargoType cargo_type, SourceType src_type, SourceID src);
|
||||
bool FindSubsidyCargoDestination(CargoType cargo_type, Source src);
|
||||
|
||||
|
||||
/**
|
||||
@ -319,8 +305,6 @@ bool FindSubsidyTownCargoRoute()
|
||||
{
|
||||
if (!Subsidy::CanAllocateItem()) return false;
|
||||
|
||||
SourceType src_type = SourceType::Town;
|
||||
|
||||
/* Select a random town. */
|
||||
const Town *src_town = Town::GetRandom();
|
||||
if (src_town->cache.population < SUBSIDY_CARGO_MIN_POPULATION) return false;
|
||||
@ -363,9 +347,7 @@ bool FindSubsidyTownCargoRoute()
|
||||
/* Quit if the percentage transported is large enough. */
|
||||
if (src_town->GetPercentTransported(cargo_type) > SUBSIDY_MAX_PCT_TRANSPORTED) return false;
|
||||
|
||||
SourceID src = src_town->index;
|
||||
|
||||
return FindSubsidyCargoDestination(cargo_type, src_type, src);
|
||||
return FindSubsidyCargoDestination(cargo_type, {src_town->index, SourceType::Town});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -376,8 +358,6 @@ bool FindSubsidyIndustryCargoRoute()
|
||||
{
|
||||
if (!Subsidy::CanAllocateItem()) return false;
|
||||
|
||||
SourceType src_type = SourceType::Industry;
|
||||
|
||||
/* Select a random industry. */
|
||||
const Industry *src_ind = Industry::GetRandom();
|
||||
if (src_ind == nullptr) return false;
|
||||
@ -411,25 +391,21 @@ bool FindSubsidyIndustryCargoRoute()
|
||||
return false;
|
||||
}
|
||||
|
||||
SourceID src = src_ind->index;
|
||||
|
||||
return FindSubsidyCargoDestination(cargo_type, src_type, src);
|
||||
return FindSubsidyCargoDestination(cargo_type, {src_ind->index, SourceType::Industry});
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to find a suitable destination for the given source and cargo.
|
||||
* @param cargo_type Subsidized cargo.
|
||||
* @param src_type Type of \a src.
|
||||
* @param src Index of source.
|
||||
* @param cargo_type Subsidized cargo.
|
||||
* @param src Source of cargo.
|
||||
* @return True iff the subsidy was created.
|
||||
*/
|
||||
bool FindSubsidyCargoDestination(CargoType cargo_type, SourceType src_type, SourceID src)
|
||||
bool FindSubsidyCargoDestination(CargoType cargo_type, Source src)
|
||||
{
|
||||
/* Choose a random destination. */
|
||||
SourceType dst_type = Chance16(1, 2) ? SourceType::Town : SourceType::Industry;
|
||||
Source dst{INVALID_SOURCE, Chance16(1, 2) ? SourceType::Town : SourceType::Industry};
|
||||
|
||||
SourceID dst;
|
||||
switch (dst_type) {
|
||||
switch (dst.type) {
|
||||
case SourceType::Town: {
|
||||
/* Select a random town. */
|
||||
const Town *dst_town = Town::GetRandom();
|
||||
@ -446,7 +422,7 @@ bool FindSubsidyCargoDestination(CargoType cargo_type, SourceType src_type, Sour
|
||||
/* Check if the town can accept this cargo. */
|
||||
if (town_cargo_accepted[cargo_type] < 8) return false;
|
||||
|
||||
dst = dst_town->index;
|
||||
dst.id = dst_town->index;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -458,7 +434,7 @@ bool FindSubsidyCargoDestination(CargoType cargo_type, SourceType src_type, Sour
|
||||
/* The industry must accept the cargo */
|
||||
if (!dst_ind->IsCargoAccepted(cargo_type)) return false;
|
||||
|
||||
dst = dst_ind->index;
|
||||
dst.id = dst_ind->index;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -466,15 +442,15 @@ bool FindSubsidyCargoDestination(CargoType cargo_type, SourceType src_type, Sour
|
||||
}
|
||||
|
||||
/* Check that the source and the destination are not the same. */
|
||||
if (src_type == dst_type && src == dst) return false;
|
||||
if (src == dst) return false;
|
||||
|
||||
/* Check distance between source and destination. */
|
||||
if (!CheckSubsidyDistance(src_type, src, dst_type, dst)) return false;
|
||||
if (!CheckSubsidyDistance(src, dst)) return false;
|
||||
|
||||
/* Avoid duplicate subsidies. */
|
||||
if (CheckSubsidyDuplicate(cargo_type, src_type, src, dst_type, dst)) return false;
|
||||
if (CheckSubsidyDuplicate(cargo_type, src, dst)) return false;
|
||||
|
||||
CreateSubsidy(cargo_type, src_type, src, dst_type, dst);
|
||||
CreateSubsidy(cargo_type, src, dst);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -488,13 +464,13 @@ static IntervalTimer<TimerGameEconomy> _economy_subsidies_monthly({TimerGameEcon
|
||||
if (--s->remaining == 0) {
|
||||
if (!s->IsAwarded()) {
|
||||
std::pair<NewsReferenceType, NewsReferenceType> reftype = SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::NewsWithdrawn);
|
||||
AddNewsItem(STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED, NewsType::Subsidies, NewsStyle::Normal, {}, reftype.first, s->src, reftype.second, s->dst);
|
||||
AddNewsItem(STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED, NewsType::Subsidies, NewsStyle::Normal, {}, reftype.first, s->src.id, reftype.second, s->dst.id);
|
||||
AI::BroadcastNewEvent(new ScriptEventSubsidyOfferExpired(s->index));
|
||||
Game::NewEvent(new ScriptEventSubsidyOfferExpired(s->index));
|
||||
} else {
|
||||
if (s->awarded == _local_company) {
|
||||
std::pair<NewsReferenceType, NewsReferenceType> reftype = SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::NewsWithdrawn);
|
||||
AddNewsItem(STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE, NewsType::Subsidies, NewsStyle::Normal, {}, reftype.first, s->src, reftype.second, s->dst);
|
||||
AddNewsItem(STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE, NewsType::Subsidies, NewsStyle::Normal, {}, reftype.first, s->src.id, reftype.second, s->dst.id);
|
||||
}
|
||||
AI::BroadcastNewEvent(new ScriptEventSubsidyExpired(s->index));
|
||||
Game::NewEvent(new ScriptEventSubsidyExpired(s->index));
|
||||
@ -556,21 +532,20 @@ static IntervalTimer<TimerGameEconomy> _economy_subsidies_monthly({TimerGameEcon
|
||||
* 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 \a src
|
||||
* @param src index of source
|
||||
* @param src source of cargo
|
||||
* @param st station where the cargo is delivered to
|
||||
* @return is the delivery subsidised?
|
||||
*/
|
||||
bool CheckSubsidised(CargoType cargo_type, CompanyID company, SourceType src_type, SourceID src, const Station *st)
|
||||
bool CheckSubsidised(CargoType cargo_type, CompanyID company, Source src, const Station *st)
|
||||
{
|
||||
/* If the source isn't subsidised, don't continue */
|
||||
if (src == INVALID_SOURCE) return false;
|
||||
switch (src_type) {
|
||||
if (src.id == INVALID_SOURCE) return false;
|
||||
switch (src.type) {
|
||||
case SourceType::Industry:
|
||||
if (!(Industry::Get(src)->part_of_subsidy & POS_SRC)) return false;
|
||||
if (!(Industry::Get(src.id)->part_of_subsidy & POS_SRC)) return false;
|
||||
break;
|
||||
case SourceType::Town:
|
||||
if (!(Town::Get(src)->cache.part_of_subsidy & POS_SRC)) return false;
|
||||
if (!(Town::Get(src.id)->cache.part_of_subsidy & POS_SRC)) return false;
|
||||
break;
|
||||
default: return false;
|
||||
}
|
||||
@ -581,8 +556,8 @@ bool CheckSubsidised(CargoType cargo_type, CompanyID company, SourceType src_typ
|
||||
if (!st->rect.IsEmpty()) {
|
||||
for (const Subsidy *s : Subsidy::Iterate()) {
|
||||
/* Don't create the cache if there is no applicable subsidy with town as destination */
|
||||
if (s->dst_type != SourceType::Town) continue;
|
||||
if (s->cargo_type != cargo_type || s->src_type != src_type || s->src != src) continue;
|
||||
if (s->dst.type != SourceType::Town) continue;
|
||||
if (s->cargo_type != cargo_type || s->src != src) continue;
|
||||
if (s->IsAwarded() && s->awarded != company) continue;
|
||||
|
||||
BitmapTileIterator it(st->catchment_tiles);
|
||||
@ -600,11 +575,11 @@ bool CheckSubsidised(CargoType cargo_type, CompanyID company, SourceType src_typ
|
||||
/* 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 */
|
||||
for (Subsidy *s : Subsidy::Iterate()) {
|
||||
if (s->cargo_type == cargo_type && s->src_type == src_type && s->src == src && (!s->IsAwarded() || s->awarded == company)) {
|
||||
switch (s->dst_type) {
|
||||
if (s->cargo_type == cargo_type && s->src == src && (!s->IsAwarded() || s->awarded == company)) {
|
||||
switch (s->dst.type) {
|
||||
case SourceType::Industry:
|
||||
for (const auto &i : st->industries_near) {
|
||||
if (s->dst == i.industry->index) {
|
||||
if (s->dst.id == i.industry->index) {
|
||||
assert(i.industry->part_of_subsidy & POS_DST);
|
||||
subsidised = true;
|
||||
if (!s->IsAwarded()) s->AwardTo(company);
|
||||
@ -613,7 +588,7 @@ bool CheckSubsidised(CargoType cargo_type, CompanyID company, SourceType src_typ
|
||||
break;
|
||||
case SourceType::Town:
|
||||
for (const Town *tp : towns_near) {
|
||||
if (s->dst == tp->index) {
|
||||
if (s->dst.id == tp->index) {
|
||||
assert(tp->cache.part_of_subsidy & POS_DST);
|
||||
subsidised = true;
|
||||
if (!s->IsAwarded()) s->AwardTo(company);
|
||||
|
@ -23,10 +23,8 @@ struct Subsidy : SubsidyPool::PoolItem<&_subsidy_pool> {
|
||||
CargoType cargo_type; ///< Cargo type involved in this subsidy, INVALID_CARGO for invalid subsidy
|
||||
uint16_t remaining; ///< Remaining months when this subsidy is valid
|
||||
CompanyID awarded; ///< Subsidy is awarded to this company; INVALID_COMPANY if it's not awarded to anyone
|
||||
SourceType src_type; ///< Source of subsidised path (SourceType::Industry or SourceType::Town)
|
||||
SourceType dst_type; ///< Destination of subsidised path (SourceType::Industry or SourceType::Town)
|
||||
SourceID src; ///< Index of source. Either TownID or IndustryID
|
||||
SourceID dst; ///< Index of destination. Either TownID or IndustryID
|
||||
Source src; ///< Source of subsidised path
|
||||
Source dst; ///< Destination of subsidised path
|
||||
|
||||
/**
|
||||
* We need an (empty) constructor so struct isn't zeroed (as C++ standard states)
|
||||
|
@ -12,9 +12,22 @@
|
||||
|
||||
#include "command_type.h"
|
||||
#include "cargo_type.h"
|
||||
#include "misc/endian_buffer.hpp"
|
||||
|
||||
CommandCost CmdCreateSubsidy(DoCommandFlag flags, CargoType cargo_type, SourceType src_type, SourceID src, SourceType dst_type, SourceID dst);
|
||||
CommandCost CmdCreateSubsidy(DoCommandFlag flags, CargoType cargo_type, Source src, Source dst);
|
||||
|
||||
DEF_CMD_TRAIT(CMD_CREATE_SUBSIDY, CmdCreateSubsidy, CMD_DEITY, CMDT_OTHER_MANAGEMENT)
|
||||
|
||||
|
||||
template <typename Tcont, typename Titer>
|
||||
inline EndianBufferWriter<Tcont, Titer> &operator <<(EndianBufferWriter<Tcont, Titer> &buffer, const Source &source)
|
||||
{
|
||||
return buffer << source.id << source.type;
|
||||
}
|
||||
|
||||
inline EndianBufferReader &operator >>(EndianBufferReader &buffer, Source &source)
|
||||
{
|
||||
return buffer >> source.id >> source.type;
|
||||
}
|
||||
|
||||
#endif /* SUBSIDY_CMD_H */
|
||||
|
@ -18,8 +18,8 @@
|
||||
#include "subsidy_base.h"
|
||||
|
||||
std::pair<NewsReferenceType, NewsReferenceType> SetupSubsidyDecodeParam(const struct Subsidy *s, SubsidyDecodeParamType mode, uint parameter_offset = 0);
|
||||
void DeleteSubsidyWith(SourceType type, SourceID index);
|
||||
bool CheckSubsidised(CargoType cargo_type, CompanyID company, SourceType src_type, SourceID src, const Station *st);
|
||||
void DeleteSubsidyWith(Source src);
|
||||
bool CheckSubsidised(CargoType cargo_type, CompanyID company, Source src, const Station *st);
|
||||
void RebuildSubsidisedSourceAndDestinationCache();
|
||||
|
||||
#endif /* SUBSIDY_FUNC_H */
|
||||
|
@ -82,9 +82,9 @@ struct SubsidyListWindow : Window {
|
||||
{
|
||||
/* determine src coordinate for subsidy and try to scroll to it */
|
||||
TileIndex xy;
|
||||
switch (s->src_type) {
|
||||
case SourceType::Industry: xy = Industry::Get(s->src)->location.tile; break;
|
||||
case SourceType::Town: xy = Town::Get(s->src)->xy; break;
|
||||
switch (s->src.type) {
|
||||
case SourceType::Industry: xy = Industry::Get(s->src.id)->location.tile; break;
|
||||
case SourceType::Town: xy = Town::Get(s->src.id)->xy; break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
|
||||
@ -92,9 +92,9 @@ struct SubsidyListWindow : Window {
|
||||
if (_ctrl_pressed) ShowExtraViewportWindow(xy);
|
||||
|
||||
/* otherwise determine dst coordinate for subsidy and scroll to it */
|
||||
switch (s->dst_type) {
|
||||
case SourceType::Industry: xy = Industry::Get(s->dst)->location.tile; break;
|
||||
case SourceType::Town: xy = Town::Get(s->dst)->xy; break;
|
||||
switch (s->dst.type) {
|
||||
case SourceType::Industry: xy = Industry::Get(s->dst.id)->location.tile; break;
|
||||
case SourceType::Town: xy = Town::Get(s->dst.id)->xy; break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
|
||||
|
@ -153,9 +153,10 @@ Town::~Town()
|
||||
}
|
||||
this->psa_list.clear();
|
||||
|
||||
DeleteSubsidyWith(SourceType::Town, this->index);
|
||||
Source src{this->index, SourceType::Town};
|
||||
DeleteSubsidyWith(src);
|
||||
DeleteNewGRFInspectWindow(GSF_FAKE_TOWNS, this->index);
|
||||
CargoPacket::InvalidateAllFrom(SourceType::Town, this->index);
|
||||
CargoPacket::InvalidateAllFrom(src);
|
||||
MarkWholeScreenDirty();
|
||||
}
|
||||
|
||||
@ -548,7 +549,7 @@ static void TownGenerateCargo(Town *t, CargoType ct, uint amount, StationFinder
|
||||
|
||||
/* Actually generate cargo and update town statistics. */
|
||||
t->supplied[ct].new_max += amount;
|
||||
t->supplied[ct].new_act += MoveGoodsToStation(ct, amount, SourceType::Town, t->index, stations.GetStations());;
|
||||
t->supplied[ct].new_act += MoveGoodsToStation(ct, amount, {t->index, SourceType::Town}, stations.GetStations());;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user