diff options
Diffstat (limited to 'src/economy.cpp')
-rw-r--r-- | src/economy.cpp | 339 |
1 files changed, 1 insertions, 338 deletions
diff --git a/src/economy.cpp b/src/economy.cpp index 0f90b8bdc..90732b78b 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -33,6 +33,7 @@ #include "autoreplace_func.h" #include "company_gui.h" #include "signs_base.h" +#include "subsidy_func.h" #include "table/strings.h" #include "table/sprites.h" @@ -87,7 +88,6 @@ const ScoreInfo _score_info[] = { int _score_part[MAX_COMPANIES][SCORE_END]; Economy _economy; -Subsidy _subsidies[MAX_COMPANIES]; Prices _price; uint16 _price_frac[NUM_PRICES]; Money _cargo_payment_rates[NUM_CARGO]; @@ -857,274 +857,6 @@ Money GetPriceByIndex(uint8 index) return ((Money*)&_price)[index]; } - -Pair SetupSubsidyDecodeParam(const Subsidy *s, bool mode) -{ - TileIndex tile; - TileIndex tile2; - Pair tp; - - /* if mode is false, use the singular form */ - const CargoSpec *cs = GetCargo(s->cargo_type); - SetDParam(0, mode ? cs->name : cs->name_single); - - if (s->age < 12) { - if (cs->town_effect != TE_PASSENGERS && cs->town_effect != TE_MAIL) { - SetDParam(1, STR_INDUSTRY); - SetDParam(2, s->from); - tile = Industry::Get(s->from)->xy; - - if (cs->town_effect != TE_GOODS && cs->town_effect != TE_FOOD) { - SetDParam(4, STR_INDUSTRY); - SetDParam(5, s->to); - tile2 = Industry::Get(s->to)->xy; - } else { - SetDParam(4, STR_TOWN); - SetDParam(5, s->to); - tile2 = Town::Get(s->to)->xy; - } - } else { - SetDParam(1, STR_TOWN); - SetDParam(2, s->from); - tile = Town::Get(s->from)->xy; - - SetDParam(4, STR_TOWN); - SetDParam(5, s->to); - tile2 = Town::Get(s->to)->xy; - } - } else { - SetDParam(1, s->from); - tile = Station::Get(s->from)->xy; - - SetDParam(2, s->to); - tile2 = Station::Get(s->to)->xy; - } - - tp.a = tile; - tp.b = tile2; - - return tp; -} - -void DeleteSubsidyWithTown(TownID index) -{ - Subsidy *s; - - for (s = _subsidies; s != endof(_subsidies); s++) { - if (s->cargo_type != CT_INVALID && s->age < 12) { - const CargoSpec *cs = GetCargo(s->cargo_type); - if (((cs->town_effect == TE_PASSENGERS || cs->town_effect == TE_MAIL) && (index == s->from || index == s->to)) || - ((cs->town_effect == TE_GOODS || cs->town_effect == TE_FOOD) && index == s->to)) { - s->cargo_type = CT_INVALID; - } - } - } -} - -void DeleteSubsidyWithIndustry(IndustryID index) -{ - Subsidy *s; - - for (s = _subsidies; s != endof(_subsidies); s++) { - if (s->cargo_type != CT_INVALID && s->age < 12) { - const CargoSpec *cs = GetCargo(s->cargo_type); - if (cs->town_effect != TE_PASSENGERS && cs->town_effect != TE_MAIL && - (index == s->from || (cs->town_effect != TE_GOODS && cs->town_effect != TE_FOOD && index == s->to))) { - s->cargo_type = CT_INVALID; - } - } - } -} - -void DeleteSubsidyWithStation(StationID index) -{ - Subsidy *s; - bool dirty = false; - - for (s = _subsidies; s != endof(_subsidies); s++) { - if (s->cargo_type != CT_INVALID && s->age >= 12 && - (s->from == index || s->to == index)) { - s->cargo_type = CT_INVALID; - dirty = true; - } - } - - if (dirty) - InvalidateWindow(WC_SUBSIDIES_LIST, 0); -} - -struct FoundRoute { - uint distance; - CargoID cargo; - void *from; - void *to; -}; - -static void FindSubsidyPassengerRoute(FoundRoute *fr) -{ - Town *from, *to; - - fr->distance = UINT_MAX; - - fr->from = from = GetRandomTown(); - if (from == NULL || from->population < 400) return; - - fr->to = to = GetRandomTown(); - if (from == to || to == NULL || to->population < 400 || to->pct_pass_transported > 42) - return; - - fr->distance = DistanceManhattan(from->xy, to->xy); -} - -static void FindSubsidyCargoRoute(FoundRoute *fr) -{ - Industry *i; - int trans, total; - CargoID cargo; - - fr->distance = UINT_MAX; - - fr->from = i = GetRandomIndustry(); - if (i == NULL) return; - - /* Randomize cargo type */ - if (HasBit(Random(), 0) && i->produced_cargo[1] != CT_INVALID) { - cargo = i->produced_cargo[1]; - trans = i->last_month_pct_transported[1]; - total = i->last_month_production[1]; - } else { - cargo = i->produced_cargo[0]; - trans = i->last_month_pct_transported[0]; - total = i->last_month_production[0]; - } - - /* Quit if no production in this industry - * or if the cargo type is passengers - * or if the pct transported is already large enough */ - if (total == 0 || trans > 42 || cargo == CT_INVALID) return; - - const CargoSpec *cs = GetCargo(cargo); - if (cs->town_effect == TE_PASSENGERS) return; - - fr->cargo = cargo; - - if (cs->town_effect == TE_GOODS || cs->town_effect == TE_FOOD) { - /* The destination is a town */ - Town *t = GetRandomTown(); - - /* Only want big towns */ - if (t == NULL || t->population < 900) return; - - fr->distance = DistanceManhattan(i->xy, t->xy); - fr->to = t; - } else { - /* The destination is an industry */ - Industry *i2 = GetRandomIndustry(); - - /* The industry must accept the cargo */ - if (i2 == NULL || i == i2 || - (cargo != i2->accepts_cargo[0] && - cargo != i2->accepts_cargo[1] && - cargo != i2->accepts_cargo[2])) { - return; - } - fr->distance = DistanceManhattan(i->xy, i2->xy); - fr->to = i2; - } -} - -static bool CheckSubsidyDuplicate(Subsidy *s) -{ - const Subsidy *ss; - - for (ss = _subsidies; ss != endof(_subsidies); ss++) { - if (s != ss && - ss->from == s->from && - ss->to == s->to && - ss->cargo_type == s->cargo_type) { - s->cargo_type = CT_INVALID; - return true; - } - } - return false; -} - - -static void SubsidyMonthlyHandler() -{ - Subsidy *s; - Pair pair; - Station *st; - uint n; - FoundRoute fr; - bool modified = false; - - for (s = _subsidies; s != endof(_subsidies); s++) { - if (s->cargo_type == CT_INVALID) continue; - - if (s->age == 12 - 1) { - pair = SetupSubsidyDecodeParam(s, 1); - AddNewsItem(STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED, NS_SUBSIDIES, pair.a, pair.b); - s->cargo_type = CT_INVALID; - modified = true; - AI::BroadcastNewEvent(new AIEventSubsidyOfferExpired(s - _subsidies)); - } else if (s->age == 2 * 12 - 1) { - st = Station::Get(s->to); - if (st->owner == _local_company) { - pair = SetupSubsidyDecodeParam(s, 1); - AddNewsItem(STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE, NS_SUBSIDIES, pair.a, pair.b); - } - s->cargo_type = CT_INVALID; - modified = true; - AI::BroadcastNewEvent(new AIEventSubsidyExpired(s - _subsidies)); - } else { - s->age++; - } - } - - /* 25% chance to go on */ - if (Chance16(1, 4)) { - /* Find a free slot*/ - s = _subsidies; - while (s->cargo_type != CT_INVALID) { - if (++s == endof(_subsidies)) - goto no_add; - } - - n = 1000; - do { - FindSubsidyPassengerRoute(&fr); - if (fr.distance <= 70) { - s->cargo_type = CT_PASSENGERS; - s->from = ((Town*)fr.from)->index; - s->to = ((Town*)fr.to)->index; - goto add_subsidy; - } - FindSubsidyCargoRoute(&fr); - if (fr.distance <= 70) { - s->cargo_type = fr.cargo; - s->from = ((Industry*)fr.from)->index; - { - const CargoSpec *cs = GetCargo(fr.cargo); - s->to = (cs->town_effect == TE_GOODS || cs->town_effect == TE_FOOD) ? ((Town*)fr.to)->index : ((Industry*)fr.to)->index; - } - add_subsidy: - if (!CheckSubsidyDuplicate(s)) { - s->age = 0; - pair = SetupSubsidyDecodeParam(s, 0); - AddNewsItem(STR_NEWS_SERVICE_SUBSIDY_OFFERED, NS_SUBSIDIES, pair.a, pair.b); - AI::BroadcastNewEvent(new AIEventSubsidyOffer(s - _subsidies)); - modified = true; - break; - } - } - } while (n--); - } -no_add:; - if (modified) - InvalidateWindow(WC_SUBSIDIES_LIST, 0); -} - Money GetTransportedGoodsIncome(uint num_pieces, uint dist, byte transit_days, CargoID cargo_type) { const CargoSpec *cs = GetCargo(cargo_type); @@ -1173,7 +905,6 @@ Money GetTransportedGoodsIncome(uint num_pieces, uint dist, byte transit_days, C return BigMulS(dist * time_factor * num_pieces, _cargo_payment_rates[cargo_type], 21); } - struct FindIndustryToDeliverData { const Rect *rect; ///< Station acceptance rectangle CargoID cargo_type; ///< Cargo type that was delivered @@ -1273,73 +1004,6 @@ static void DeliverGoodsToIndustry(const Station *st, CargoID cargo_type, int nu } } -static bool CheckSubsidised(Station *from, Station *to, CargoID cargo_type) -{ - Subsidy *s; - TileIndex xy; - Pair pair; - - /* check if there is an already existing subsidy that applies to us */ - for (s = _subsidies; s != endof(_subsidies); s++) { - if (s->cargo_type == cargo_type && - s->age >= 12 && - s->from == from->index && - s->to == to->index) { - return true; - } - } - - /* check if there's a new subsidy that applies.. */ - for (s = _subsidies; s != endof(_subsidies); s++) { - if (s->cargo_type == cargo_type && s->age < 12) { - /* Check distance from source */ - const CargoSpec *cs = GetCargo(cargo_type); - if (cs->town_effect == TE_PASSENGERS || cs->town_effect == TE_MAIL) { - xy = Town::Get(s->from)->xy; - } else { - xy = Industry::Get(s->from)->xy; - } - if (DistanceMax(xy, from->xy) > 9) continue; - - /* Check distance from dest */ - switch (cs->town_effect) { - case TE_PASSENGERS: - case TE_MAIL: - case TE_GOODS: - case TE_FOOD: - xy = Town::Get(s->to)->xy; - break; - - default: - xy = Industry::Get(s->to)->xy; - break; - } - if (DistanceMax(xy, to->xy) > 9) continue; - - /* Found a subsidy, change the values to indicate that it's in use */ - s->age = 12; - s->from = from->index; - s->to = to->index; - - /* Add a news item */ - pair = SetupSubsidyDecodeParam(s, 0); - InjectDParam(1); - - SetDParam(0, _current_company); - AddNewsItem( - STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF + _settings_game.difficulty.subsidy_multiplier, - NS_SUBSIDIES, - pair.a, pair.b - ); - AI::BroadcastNewEvent(new AIEventSubsidyAwarded(s - _subsidies)); - - InvalidateWindow(WC_SUBSIDIES_LIST, 0); - return true; - } - } - return false; -} - /** * Delivers goods to industries/towns and calculates the payment * @param num_pieces amount of cargo delivered @@ -1826,7 +1490,6 @@ void CompaniesMonthlyLoop() /* Reset the _current_company flag */ _current_company = OWNER_NONE; HandleEconomyFluctuations(); - SubsidyMonthlyHandler(); } static void DoAcquireCompany(Company *c) |