OpenTTD Source 20260731-master-g77ba2b244a
economy.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#include "stdafx.h"
11#include <ranges>
12#include "company_func.h"
13#include "command_func.h"
14#include "industry.h"
15#include "town.h"
16#include "news_func.h"
17#include "network/network.h"
19#include "ai/ai.hpp"
20#include "aircraft.h"
21#include "train.h"
22#include "newgrf_engine.h"
23#include "engine_base.h"
24#include "ground_vehicle.hpp"
25#include "newgrf_cargo.h"
26#include "newgrf_sound.h"
28#include "newgrf_station.h"
29#include "newgrf_airporttiles.h"
30#include "newgrf_roadstop.h"
31#include "object.h"
32#include "strings_func.h"
33#include "vehicle_func.h"
34#include "sound_func.h"
35#include "autoreplace_func.h"
36#include "company_gui.h"
37#include "signs_base.h"
38#include "subsidy_base.h"
39#include "subsidy_func.h"
40#include "station_base.h"
41#include "waypoint_base.h"
42#include "economy_base.h"
43#include "core/pool_func.hpp"
44#include "core/backup_type.hpp"
46#include "cargo_type.h"
47#include "water.h"
48#include "game/game.hpp"
49#include "cargomonitor.h"
50#include "goal_base.h"
51#include "story_base.h"
52#include "linkgraph/refresh.h"
53#include "company_cmd.h"
54#include "economy_cmd.h"
55#include "vehicle_cmd.h"
56#include "script/api/script_event_types.hpp"
57#include "timer/timer.h"
60
61#include "table/strings.h"
62#include "table/pricebase.h"
63
64#include "safeguards.h"
65
66
67/* Initialize the cargo payment-pool */
70
71
82static inline int32_t BigMulS(const int32_t a, const int32_t b, const uint8_t shift)
83{
84 return (int32_t)((int64_t)a * (int64_t)b >> shift);
85}
86
87typedef std::vector<Industry *> SmallIndustryList;
88
93 ScoreInfo(100, 120), // ScoreID::Vehicles
94 ScoreInfo(100, 80), // ScoreID::Stations
95 ScoreInfo(100, 10000), // ScoreID::MinProfit
96 ScoreInfo(50, 50000), // ScoreID::MinIncome
97 ScoreInfo(100, 100000), // ScoreID::MaxIncome
98 ScoreInfo(400, 40000), // ScoreID::Delivered
99 ScoreInfo(50, 8), // ScoreID::Cargo
100 ScoreInfo(50, 10000000), // ScoreID::Money
101 ScoreInfo(50, 250000), // ScoreID::Loan
102 ScoreInfo(0, 0), // ScoreID::Total
103};
104
106Economy _economy;
108static PriceMultipliers _price_base_multiplier;
109
117{
118 Owner owner = c->index;
119
120 uint num = 0;
121
122 for (const Station *st : Station::Iterate()) {
123 if (st->owner == owner) num += st->facilities.Count();
124 }
125
126 Money value = num * _price[Price::StationValue] * 25;
127
128 for (const Vehicle *v : Vehicle::Iterate()) {
129 if (v->owner != owner) continue;
130
131 if (v->type == VehicleType::Train ||
132 v->type == VehicleType::Road ||
133 (v->type == VehicleType::Aircraft && Aircraft::From(v)->IsNormalAircraft()) ||
134 v->type == VehicleType::Ship) {
135 value += v->value * 3 >> 1;
136 }
137 }
138
139 return value;
140}
141
151Money CalculateCompanyValue(const Company *c, bool including_loan)
152{
153 Money value = CalculateCompanyAssetValue(c);
154
155 /* Add real money value */
156 if (including_loan) value -= c->current_loan;
157 value += c->money;
158
159 return std::max<Money>(value, 1);
160}
161
179{
180 Money value = CalculateCompanyAssetValue(c);
181
182 value += c->current_loan;
183 /* Negative balance is basically a loan. */
184 if (c->money < 0) {
185 value += -c->money;
186 }
187
188 for (int quarter = 0; quarter < 4; quarter++) {
189 value += std::max<Money>(c->old_economy[quarter].income + c->old_economy[quarter].expenses, 0) * 2;
190 }
191
192 return std::max<Money>(value, 1);
193}
194
204{
205 Owner owner = c->index;
206 int score = 0;
207
208 _score_part[owner].fill(0);
209
210 /* Count vehicles */
211 {
212 Money min_profit = 0;
213 bool min_profit_first = true;
214 uint num = 0;
215
216 for (const Vehicle *v : Vehicle::Iterate()) {
217 if (v->owner != owner) continue;
218 if (IsCompanyBuildableVehicleType(v->type) && v->IsPrimaryVehicle()) {
219 if (v->profit_last_year > 0) num++; // For the vehicle score only count profitable vehicles
220 if (v->economy_age > VEHICLE_PROFIT_MIN_AGE) {
221 /* Find the vehicle with the lowest amount of profit */
222 if (min_profit_first || min_profit > v->profit_last_year) {
223 min_profit = v->profit_last_year;
224 min_profit_first = false;
225 }
226 }
227 }
228 }
229
230 min_profit >>= 8; // remove the fract part
231
232 _score_part[owner][ScoreID::Vehicles] = num;
233 /* Don't allow negative min_profit to show */
234 if (min_profit > 0) {
235 _score_part[owner][ScoreID::MinProfit] = min_profit;
236 }
237 }
238
239 /* Count stations */
240 {
241 uint num = 0;
242 for (const Station *st : Station::Iterate()) {
243 /* Only count stations that are actually serviced */
244 if (st->owner == owner && (st->time_since_load <= 20 || st->time_since_unload <= 20)) num += st->facilities.Count();
245 }
246 _score_part[owner][ScoreID::Stations] = num;
247 }
248
249 /* Generate statistics depending on recent income statistics */
250 {
251 int numec = std::min<uint>(c->num_valid_stat_ent, 12u);
252 if (numec != 0) {
253 auto [min_income, max_income] = std::ranges::minmax(c->old_economy | std::views::take(numec) | std::views::transform([](const auto &ce) { return ce.income + ce.expenses; }));
254
255 if (min_income > 0) _score_part[owner][ScoreID::MinIncome] = min_income;
256 _score_part[owner][ScoreID::MaxIncome] = max_income;
257 }
258 }
259
260 /* Generate score depending on amount of transported cargo */
261 {
262 int numec = std::min<uint>(c->num_valid_stat_ent, 4u);
263 if (numec != 0) {
264 OverflowSafeInt64 total_delivered = 0;
265 for (auto &ce : c->old_economy | std::views::take(numec)) total_delivered += ce.delivered_cargo.GetSum<OverflowSafeInt64>();
266
267 _score_part[owner][ScoreID::Delivered] = total_delivered;
268 }
269 }
270
271 /* Generate score for variety of cargo */
272 {
273 _score_part[owner][ScoreID::Cargo] = c->old_economy[0].delivered_cargo.GetCount();
274 }
275
276 /* Generate score for company's money */
277 {
278 if (c->money > 0) {
279 _score_part[owner][ScoreID::Money] = c->money;
280 }
281 }
282
283 /* Generate score for loan */
284 {
285 _score_part[owner][ScoreID::Loan] = _score_info[ScoreID::Loan].needed - c->current_loan;
286 }
287
288 /* Now we calculate the score for each item.. */
289 {
290 int total_score = 0;
291 int s;
292 score = 0;
293 for (ScoreID i : EnumRange(ScoreID::End)) {
294 /* Skip the total */
295 if (i == ScoreID::Total) continue;
296 /* Check the score */
297 s = Clamp<int64_t>(_score_part[owner][i], 0, _score_info[i].needed) * _score_info[i].score / _score_info[i].needed;
298 score += s;
299 total_score += _score_info[i].score;
300 }
301
302 _score_part[owner][ScoreID::Total] = score;
303
304 /* We always want the score scaled to SCORE_MAX (1000) */
305 if (total_score != SCORE_MAX) score = score * SCORE_MAX / total_score;
306 }
307
308 if (update) {
309 c->old_economy[0].performance_history = score;
311 c->old_economy[0].company_value = CalculateCompanyValue(c);
312 }
313
314 SetWindowDirty(WindowClass::PerformanceDetail, 0);
315 return score;
316}
317
323void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
324{
325 /* We need to set _current_company to old_owner before we try to move
326 * the client. This is needed as it needs to know whether "you" really
327 * are the current local company. */
328 AutoRestoreBackup cur_company(_current_company, old_owner);
329 /* In all cases, make spectators of clients connected to that company */
331 if (old_owner == _local_company) {
332 /* Single player cheated to AI company.
333 * There are no spectators in singleplayer mode, so we must pick some other company. */
334 assert(!_networking);
336 for (const Company *c : Company::Iterate()) {
337 if (c->index != old_owner) {
338 SetLocalCompany(c->index);
339 break;
340 }
341 }
342 cur_company2.Restore();
343 assert(old_owner != _local_company);
344 }
345
346 assert(old_owner != new_owner);
347
348 /* Temporarily increase the company's money, to be sure that
349 * removing their property doesn't fail because of lack of money.
350 * Not too drastically though, because it could overflow */
351 if (new_owner == INVALID_OWNER) {
352 Company::Get(old_owner)->money = UINT64_MAX >> 2; // jackpot ;p
353 }
354
355 for (Subsidy *s : Subsidy::Iterate()) {
356 if (s->awarded == old_owner) {
357 if (new_owner == INVALID_OWNER) {
358 delete s;
359 } else {
360 s->awarded = new_owner;
361 }
362 }
363 }
365
366 /* Take care of rating and transport rights in towns */
367 for (Town *t : Town::Iterate()) {
368 /* If a company takes over, give the ratings to that company. */
369 if (new_owner != INVALID_OWNER) {
370 if (t->have_ratings.Test(old_owner)) {
371 if (t->have_ratings.Test(new_owner)) {
372 /* use max of the two ratings. */
373 t->ratings[new_owner] = std::max(t->ratings[new_owner], t->ratings[old_owner]);
374 } else {
375 t->have_ratings.Set(new_owner);
376 t->ratings[new_owner] = t->ratings[old_owner];
377 }
378 }
379 }
380
381 /* Reset the ratings for the old owner */
382 t->ratings[old_owner] = RATING_INITIAL;
383 t->have_ratings.Reset(old_owner);
384
385 /* Transfer exclusive rights */
386 if (t->exclusive_counter > 0 && t->exclusivity == old_owner) {
387 if (new_owner != INVALID_OWNER) {
388 t->exclusivity = new_owner;
389 } else {
390 t->exclusive_counter = 0;
391 t->exclusivity = CompanyID::Invalid();
392 }
393 }
394 }
395
396 {
397 for (Vehicle *v : Vehicle::Iterate()) {
398 if (v->owner == old_owner && IsCompanyBuildableVehicleType(v->type)) {
399 if (new_owner == INVALID_OWNER) {
400 if (v->Previous() == nullptr) delete v;
401 } else {
402 if (v->IsEngineCountable()) GroupStatistics::CountEngine(v, -1);
403 if (v->IsPrimaryVehicle()) GroupStatistics::CountVehicle(v, -1);
404 }
405 }
406 }
407 }
408
409 /* In all cases clear replace engine rules.
410 * Even if it was copied, it could interfere with new owner's rules */
412
413 if (new_owner == INVALID_OWNER) {
414 RemoveAllGroupsForCompany(old_owner);
415 } else {
416 Company *c = Company::Get(new_owner);
417 for (Group *g : Group::Iterate()) {
418 if (g->owner == old_owner) {
419 g->owner = new_owner;
420 g->number = c->freegroups.UseID(c->freegroups.NextID());
421 }
422 }
423 }
424
425 {
426 Company *new_company = new_owner == INVALID_OWNER ? nullptr : Company::Get(new_owner);
427
428 /* Override company settings to new company defaults in case we need to convert them.
429 * This is required as the CmdChangeServiceInt doesn't copy the supplied value when it is non-custom
430 */
431 if (new_owner != INVALID_OWNER) {
432 Company *old_company = Company::Get(old_owner);
433
435 old_company->settings.vehicle.servint_trains = new_company->settings.vehicle.servint_trains;
437 old_company->settings.vehicle.servint_ships = new_company->settings.vehicle.servint_ships;
439 }
440
441 for (Vehicle *v : Vehicle::Iterate()) {
442 if (v->owner == old_owner && IsCompanyBuildableVehicleType(v->type)) {
443 assert(new_owner != INVALID_OWNER);
444
445 /* Correct default values of interval settings while maintaining custom set ones.
446 * This prevents invalid values on mismatching company defaults being accepted.
447 */
448 if (!v->ServiceIntervalIsCustom()) {
449 /* Technically, passing the interval is not needed as the command will query the default value itself.
450 * However, do not rely on that behaviour.
451 */
452 int interval = CompanyServiceInterval(new_company, v->type);
453 Command<Commands::ChangeServiceInterval>::Do({DoCommandFlag::Execute, DoCommandFlag::Bankrupt}, v->index, interval, false, new_company->settings.vehicle.servint_ispercent);
454 }
455
456 v->owner = new_owner;
457
458 /* Owner changes, clear cache */
459 v->colourmap = PAL_NONE;
460 v->InvalidateNewGRFCache();
461
462 if (v->IsEngineCountable()) {
464 }
465 if (v->IsPrimaryVehicle()) {
467 auto &unitidgen = new_company->freeunits[v->type];
468 v->unitnumber = unitidgen.UseID(unitidgen.NextID());
469 }
470 }
471 }
472
473 if (new_owner != INVALID_OWNER) GroupStatistics::UpdateAutoreplace(new_owner);
474 }
475
476 /* Change ownership of tiles */
477 {
478 for (const auto tile : Map::Iterate()) {
479 ChangeTileOwner(tile, old_owner, new_owner);
480 }
481
482 if (new_owner != INVALID_OWNER) {
483 /* Update all signals because there can be new segment that was owned by two companies
484 * and signals were not propagated
485 * Similar with crossings - it is needed to bar crossings that weren't before
486 * because of different owner of crossing and approaching train */
487 for (const auto tile : Map::Iterate()) {
488 if (IsTileType(tile, TileType::Railway) && IsTileOwner(tile, new_owner) && HasSignals(tile)) {
489 for (Track track : GetTrackBits(tile)) {
490 if (IsSignalPresent(tile, SignalOnTrack(track))) AddTrackToSignalBuffer(tile, track, new_owner);
491 }
492 } else if (IsLevelCrossingTile(tile) && IsTileOwner(tile, new_owner)) {
494 }
495 }
496 }
497
498 /* update signals in buffer */
500 }
501
502 /* Add airport infrastructure count of the old company to the new one. */
503 if (new_owner != INVALID_OWNER) Company::Get(new_owner)->infrastructure.airport += Company::Get(old_owner)->infrastructure.airport;
504
505 /* convert owner of stations (including deleted ones, but excluding buoys) */
506 for (Station *st : Station::Iterate()) {
507 if (st->owner == old_owner) {
508 /* if a company goes bankrupt, set owner to OWNER_NONE so the sign doesn't disappear immediately
509 * also, drawing station window would cause reading invalid company's colour */
510 st->owner = new_owner == INVALID_OWNER ? OWNER_NONE : new_owner;
511 }
512 }
513
514 /* do the same for waypoints (we need to do this here so deleted waypoints are converted too) */
515 for (Waypoint *wp : Waypoint::Iterate()) {
516 if (wp->owner == old_owner) {
517 wp->owner = new_owner == INVALID_OWNER ? OWNER_NONE : new_owner;
518 }
519 }
520
521 for (Sign *si : Sign::Iterate()) {
522 if (si->owner == old_owner) si->owner = new_owner == INVALID_OWNER ? OWNER_NONE : new_owner;
523 }
524
525 /* Remove Game Script created Goals, CargoMonitors and Story pages. */
526 for (Goal *g : Goal::Iterate()) {
527 if (g->company == old_owner) delete g;
528 }
529
532
533 for (StoryPage *sp : StoryPage::Iterate()) {
534 if (sp->company == old_owner) delete sp;
535 }
536
537 /* Change colour of existing windows */
538 if (new_owner != INVALID_OWNER) ChangeWindowOwner(old_owner, new_owner);
539
541}
542
548{
549 /* If "Infinite money" setting is on, companies should not go bankrupt. */
550 if (_settings_game.difficulty.infinite_money) return;
551
552 /* If the company has money again, it does not go bankrupt */
553 if (c->money - c->current_loan >= -c->GetMaxLoan()) {
554 int previous_months_of_bankruptcy = CeilDiv(c->months_of_bankruptcy, 3);
557 if (previous_months_of_bankruptcy != 0) CompanyAdminUpdate(c);
558 return;
559 }
560
562
563 switch (c->months_of_bankruptcy) {
564 /* All the boring cases (months) with a bad balance where no action is taken */
565 case 0:
566 case 1:
567 case 2:
568 case 3:
569
570 case 5:
571 case 6:
572
573 case 8:
574 case 9:
575 break;
576
577 /* Warn about bankruptcy after 3 months */
578 case 4: {
579 auto cni = std::make_unique<CompanyNewsInformation>(STR_NEWS_COMPANY_IN_TROUBLE_TITLE, c);
580 EncodedString headline = GetEncodedString(STR_NEWS_COMPANY_IN_TROUBLE_DESCRIPTION, cni->company_name);
581 AddCompanyNewsItem(std::move(headline), std::move(cni));
582 AI::BroadcastNewEvent(new ScriptEventCompanyInTrouble(c->index));
583 Game::NewEvent(new ScriptEventCompanyInTrouble(c->index));
584 break;
585 }
586
587 /* Offer company for sale after 6 months */
588 case 7: {
589 /* Don't consider the loan */
590 Money val = CalculateCompanyValue(c, false);
591
592 c->bankrupt_value = val;
593 c->bankrupt_asked = CompanyMask{}.Set(c->index); // Don't ask the owner
594 c->bankrupt_timeout = 0;
595
596 /* The company assets should always have some value */
597 assert(c->bankrupt_value > 0);
598 break;
599 }
600
601 /* Bankrupt company after 6 months (if the company has no value) or latest
602 * after 9 months (if it still had value after 6 months) */
603 default:
604 case 10: {
605 if (!_networking && _local_company == c->index) {
606 /* If we are in singleplayer mode, leave the company playing. Eg. there
607 * is no THE-END, otherwise mark the client as spectator to make sure
608 * they are no longer in control of this company. However... when you
609 * join another company (cheat) the "unowned" company can bankrupt. */
610 c->bankrupt_asked.Set();
611 break;
612 }
613
614 /* Actually remove the company, but not when we're a network client.
615 * In case of network clients we will be getting a command from the
616 * server. It is done in this way as we are called from the
617 * StateGameLoop which can't change the current company, and thus
618 * updating the local company triggers an assert later on. In the
619 * case of a network game the command will be processed at a time
620 * that changing the current company is okay. In case of single
621 * player we are sure (the above check) that we are not the local
622 * company and thus we won't be moved. */
624 Command<Commands::CompanyControl>::Post(CompanyCtrlAction::Delete, c->index, CompanyRemoveReason::Bankrupt, ClientID::Invalid);
625 return;
626 }
627 break;
628 }
629 }
630
632}
633
639{
640 /* Check for bankruptcy each month */
641 for (Company *c : Company::Iterate()) {
643 }
644
645 /* Pay Infrastructure Maintenance, if enabled */
646 if (_settings_game.economy.infrastructure_maintenance) {
647 /* Improved monthly infrastructure costs. */
648 for (const Company *c : Company::Iterate()) {
650 uint32_t rail_total = c->infrastructure.GetRailTotal();
651 for (RailType rt : EnumRange(RAILTYPE_END)) {
652 if (c->infrastructure.rail[rt] != 0) cost.AddCost(RailMaintenanceCost(rt, c->infrastructure.rail[rt], rail_total));
653 }
654 cost.AddCost(SignalMaintenanceCost(c->infrastructure.signal));
655 uint32_t road_total = c->infrastructure.GetRoadTotal();
656 uint32_t tram_total = c->infrastructure.GetTramTotal();
657 for (RoadType rt : EnumRange(ROADTYPE_END)) {
658 if (c->infrastructure.road[rt] != 0) cost.AddCost(RoadMaintenanceCost(rt, c->infrastructure.road[rt], RoadTypeIsRoad(rt) ? road_total : tram_total));
659 }
660 cost.AddCost(CanalMaintenanceCost(c->infrastructure.water));
661 cost.AddCost(StationMaintenanceCost(c->infrastructure.station));
662 cost.AddCost(AirportMaintenanceCost(c->index));
663
664 SubtractMoneyFromCompany(c->index, cost);
665 }
666 }
667
668 /* Only run the economic statistics and update company stats every 3rd economy month (1st of quarter). */
669 if (!HasBit(1 << 0 | 1 << 3 | 1 << 6 | 1 << 9, TimerGameEconomy::month)) return;
670
671 for (Company *c : Company::Iterate()) {
672 /* Drop the oldest history off the end */
673 std::copy_backward(c->old_economy.data(), c->old_economy.data() + MAX_HISTORY_QUARTERS - 1, c->old_economy.data() + MAX_HISTORY_QUARTERS);
674 c->old_economy[0] = c->cur_economy;
675 c->cur_economy = {};
676
677 if (c->num_valid_stat_ent != MAX_HISTORY_QUARTERS) c->num_valid_stat_ent++;
678
680 if (c->block_preview != 0) c->block_preview--;
681 }
682
683 SetWindowDirty(WindowClass::IncomeGraph, 0);
684 SetWindowDirty(WindowClass::OperatingProfitGraph, 0);
685 SetWindowDirty(WindowClass::DeliveredCargoGraph, 0);
686 SetWindowDirty(WindowClass::PerformanceGraph, 0);
687 SetWindowDirty(WindowClass::CompanyValueGraph, 0);
688 SetWindowDirty(WindowClass::CompanyLeague, 0);
689}
690
696bool AddInflation(bool check_year)
697{
698 /* The cargo payment inflation differs from the normal inflation, so the
699 * relative amount of money you make with a transport decreases slowly over
700 * the 170 years. After a few hundred years we reach a level in which the
701 * games will become unplayable as the maximum income will be less than
702 * the minimum running cost.
703 *
704 * Furthermore there are a lot of inflation related overflows all over the
705 * place. Solving them is hardly possible because inflation will always
706 * reach the overflow threshold some day. So we'll just perform the
707 * inflation mechanism during the first 170 years (the amount of years that
708 * one had in the original TTD) and stop doing the inflation after that
709 * because it only causes problems that can't be solved nicely and the
710 * inflation doesn't add anything after that either; it even makes playing
711 * it impossible due to the diverging cost and income rates.
712 */
714
715 if (_economy.inflation_prices == MAX_INFLATION || _economy.inflation_payment == MAX_INFLATION) return true;
716
717 /* Approximation for (100 + infl_amount)% ** (1 / 12) - 100%
718 * scaled by 65536
719 * 12 -> months per year
720 * This is only a good approximation for small values
721 */
722 _economy.inflation_prices += (_economy.inflation_prices * _economy.infl_amount * 54) >> 16;
723 _economy.inflation_payment += (_economy.inflation_payment * _economy.infl_amount_pr * 54) >> 16;
724
725 if (_economy.inflation_prices > MAX_INFLATION) _economy.inflation_prices = MAX_INFLATION;
726 if (_economy.inflation_payment > MAX_INFLATION) _economy.inflation_payment = MAX_INFLATION;
727
728 return false;
729}
730
735{
736 /* Setup maximum loan as a rounded down multiple of LOAN_INTERVAL. */
737 _economy.max_loan = ((uint64_t)_settings_game.difficulty.max_loan * _economy.inflation_prices >> 16) / LOAN_INTERVAL * LOAN_INTERVAL;
738
739 /* Setup price bases */
740 for (Price i : EnumRange(Price::End)) {
741 Money price = _price_base_specs[i].start_price;
742
743 /* Apply difficulty settings */
744 uint mod = 1;
745 switch (_price_base_specs[i].category) {
747 mod = _settings_game.difficulty.vehicle_costs;
748 break;
749
751 mod = _settings_game.difficulty.construction_cost;
752 break;
753
754 default: break;
755 }
756 switch (mod) {
757 case 0: price *= 6; break;
758 case 1: price *= 8; break; // normalised to 1 below
759 case 2: price *= 9; break;
760 default: NOT_REACHED();
761 }
762
763 /* Apply inflation */
764 price = (int64_t)price * _economy.inflation_prices;
765
766 /* Apply newgrf modifiers, remove fractional part of inflation, and normalise on medium difficulty. */
767 int shift = _price_base_multiplier[i] - 16 - 3;
768 if (shift >= 0) {
769 price <<= shift;
770 } else {
771 price >>= -shift;
772 }
773
774 /* Make sure the price does not get reduced to zero.
775 * Zero breaks quite a few commands that use a zero
776 * cost to see whether something got changed or not
777 * and based on that cause an error. When the price
778 * is zero that fails even when things are done. */
779 if (price == 0) {
780 price = Clamp(_price_base_specs[i].start_price, -1, 1);
781 /* No base price should be zero, but be sure. */
782 assert(price != 0);
783 }
784 /* Store value */
785 _price[i] = price;
786 }
787
788 /* Setup cargo payment */
789 for (CargoSpec *cs : CargoSpec::Iterate()) {
790 cs->current_payment = (cs->initial_payment * (int64_t)_economy.inflation_payment) >> 16;
791 }
792
793 SetWindowClassesDirty(WindowClass::BuildVehicle);
794 SetWindowClassesDirty(WindowClass::ReplaceVehicle);
795 SetWindowClassesDirty(WindowClass::VehicleDetails);
796 SetWindowClassesDirty(WindowClass::CompanyInfrastructure);
797 InvalidateWindowData(WindowClass::CargoPaymentRatesGraph, 0);
798}
799
802{
803 for (const Company *c : Company::Iterate()) {
804 /* Over a year the paid interest should be "loan * interest percentage",
805 * but... as that number is likely not dividable by 12 (pay each month),
806 * one needs to account for that in the monthly fee calculations.
807 *
808 * To easily calculate what one should pay "this" month, you calculate
809 * what (total) should have been paid up to this month and you subtract
810 * whatever has been paid in the previous months. This will mean one month
811 * it'll be a bit more and the other it'll be a bit less than the average
812 * monthly fee, but on average it will be exact.
813 *
814 * In order to prevent cheating or abuse (just not paying interest by not
815 * taking a loan) we make companies pay interest on negative cash as well,
816 * except if infinite money is enabled.
817 */
818 Money yearly_fee = c->current_loan * _economy.interest_rate / 100;
819 Money available_money = GetAvailableMoney(c->index);
820 if (available_money < 0) {
821 yearly_fee += -available_money * _economy.interest_rate / 100;
822 }
823 Money up_to_previous_month = yearly_fee * TimerGameEconomy::month / 12;
824 Money up_to_this_month = yearly_fee * (TimerGameEconomy::month + 1) / 12;
825
826 SubtractMoneyFromCompany(c->index, CommandCost(ExpensesType::LoanInterest, up_to_this_month - up_to_previous_month));
827
829 }
830}
831
832static void HandleEconomyFluctuations()
833{
834 if (_settings_game.difficulty.economy != 0) {
835 /* When economy is Fluctuating, decrease counter */
836 _economy.fluct--;
837 } else if (EconomyIsInRecession()) {
838 /* When it's Steady and we are in recession, end it now */
839 _economy.fluct = -12;
840 } else {
841 /* No need to do anything else in other cases */
842 return;
843 }
844
845 if (_economy.fluct == 0) {
846 _economy.fluct = -(int)GB(Random(), 0, 2);
847 AddNewsItem(GetEncodedString(STR_NEWS_BEGIN_OF_RECESSION), NewsType::Economy, NewsStyle::Normal, {});
848 } else if (_economy.fluct == -12) {
849 _economy.fluct = GB(Random(), 0, 8) + 312;
850 AddNewsItem(GetEncodedString(STR_NEWS_END_OF_RECESSION), NewsType::Economy, NewsStyle::Normal, {});
851 }
852}
853
854
859{
860 _price_base_multiplier.fill(0);
861}
862
870void SetPriceBaseMultiplier(Price price, int factor)
871{
872 assert(price < Price::End);
873 _price_base_multiplier[price] = Clamp(factor, MIN_PRICE_MODIFIER, MAX_PRICE_MODIFIER);
874}
875
880void StartupIndustryDailyChanges(bool init_counter)
881{
882 uint map_size = Map::LogX() + Map::LogY();
883 /* After getting map size, it needs to be scaled appropriately and divided by 31,
884 * which stands for the days in a month.
885 * Using just 31 will make it so that a monthly reset (based on the real number of days of that month)
886 * would not be needed.
887 * Since it is based on "fractional parts", the leftover days will not make much of a difference
888 * on the overall total number of changes performed */
889 _economy.industry_daily_increment = (1 << map_size) / 31;
890
891 if (init_counter) {
892 /* A new game or a savegame from an older version will require the counter to be initialized */
893 _economy.industry_daily_change_counter = 0;
894 }
895}
896
897void StartupEconomy()
898{
899 _economy.interest_rate = _settings_game.difficulty.initial_interest;
900 _economy.infl_amount = _settings_game.difficulty.initial_interest;
901 _economy.infl_amount_pr = std::max(0, _settings_game.difficulty.initial_interest - 1);
902 _economy.fluct = GB(Random(), 0, 8) + 168;
903
904 if (_settings_game.economy.inflation) {
905 /* Apply inflation that happened before our game start year. */
907 for (int i = 0; i < months; i++) {
908 AddInflation(false);
909 }
910 }
911
912 /* Set up prices */
914
915 StartupIndustryDailyChanges(true); // As we are starting a new game, initialize the counter too
916
917}
918
923{
924 _economy.inflation_prices = _economy.inflation_payment = 1 << 16;
927}
928
937Money GetPrice(Price index, uint cost_factor, const GRFFile *grf_file, int shift)
938{
939 if (index >= Price::End) return 0;
940
941 Money cost = _price[index] * cost_factor;
942 if (grf_file != nullptr) shift += grf_file->price_base_multipliers[index];
943
944 if (shift >= 0) {
945 cost <<= shift;
946 } else {
947 cost >>= -shift;
948 }
949
950 return cost;
951}
952
953Money GetTransportedGoodsIncome(uint num_pieces, uint dist, uint16_t transit_periods, CargoType cargo_type)
954{
955 const CargoSpec *cs = CargoSpec::Get(cargo_type);
956 if (!cs->IsValid()) {
957 /* User changed newgrfs and some vehicle still carries some cargo which is no longer available. */
958 return 0;
959 }
960
961 /* Scale transit periods according to the game setting. We also pass this scaled value to the NewGRF callback. */
962 transit_periods = ScaleByPercentage<uint16_t, uint32_t>(transit_periods, _settings_game.economy.cargo_aging_rate);
963
964 /* Use callback to calculate cargo profit, if available */
966 uint32_t var18 = ClampTo<uint16_t>(dist) | (ClampTo<uint8_t>(num_pieces) << 16) | (ClampTo<uint8_t>(transit_periods) << 24);
967 uint16_t callback = GetCargoCallback(CBID_CARGO_PROFIT_CALC, 0, var18, cs);
968 if (callback != CALLBACK_FAILED) {
969 int result = GB(callback, 0, 14);
970
971 /* Simulate a 15 bit signed value */
972 if (HasBit(callback, 14)) result -= 0x4000;
973
974 /* "The result should be a signed multiplier that gets multiplied
975 * by the amount of cargo moved and the price factor, then gets
976 * divided by 8192." */
977 return result * num_pieces * cs->current_payment / 8192;
978 }
979 }
980
981 static const int MIN_TIME_FACTOR = 31;
982 static const int MAX_TIME_FACTOR = 255;
983 static const int TIME_FACTOR_FRAC_BITS = 4;
984 static const int TIME_FACTOR_FRAC = 1 << TIME_FACTOR_FRAC_BITS;
985
986 const int periods1 = cs->transit_periods[0];
987 const int periods2 = cs->transit_periods[1];
988 const int periods_over_periods1 = std::max(transit_periods - periods1, 0);
989 const int periods_over_periods2 = std::max(periods_over_periods1 - periods2, 0);
990 int periods_over_max = MIN_TIME_FACTOR - MAX_TIME_FACTOR;
991 if (periods2 > -periods_over_max) {
992 periods_over_max += transit_periods - periods1;
993 } else {
994 periods_over_max += 2 * (transit_periods - periods1) - periods2;
995 }
996
997 /*
998 * The time factor is calculated based on the time it took
999 * (transit_periods) compared two cargo-depending values. The
1000 * range is divided into four parts:
1001 *
1002 * - constant for fast transits
1003 * - linear decreasing with time with a slope of -1 for medium transports
1004 * - linear decreasing with time with a slope of -2 for slow transports
1005 * - after hitting MIN_TIME_FACTOR, the time factor will be asymptotically decreased to a limit of 1 with a scaled 1/(x+1) function.
1006 *
1007 */
1008 if (periods_over_max > 0) {
1009 const int time_factor = std::max(2 * MIN_TIME_FACTOR * TIME_FACTOR_FRAC * TIME_FACTOR_FRAC / (periods_over_max + 2 * TIME_FACTOR_FRAC), 1); // MIN_TIME_FACTOR / (x/(2 * TIME_FACTOR_FRAC) + 1) + 1, expressed as fixed point with TIME_FACTOR_FRAC_BITS.
1010 return BigMulS(dist * time_factor * num_pieces, cs->current_payment, 21 + TIME_FACTOR_FRAC_BITS);
1011 } else {
1012 const int time_factor = std::max(MAX_TIME_FACTOR - periods_over_periods1 - periods_over_periods2, MIN_TIME_FACTOR);
1013 return BigMulS(dist * time_factor * num_pieces, cs->current_payment, 21);
1014 }
1015}
1016
1018static SmallIndustryList _cargo_delivery_destinations;
1019
1030static uint DeliverGoodsToIndustry(const Station *st, CargoType cargo_type, uint num_pieces, IndustryID source, CompanyID company)
1031{
1032 /* Find the nearest industrytile to the station sign inside the catchment area, whose industry accepts the cargo.
1033 * This fails in three cases:
1034 * 1) The station accepts the cargo because there are enough houses around it accepting the cargo.
1035 * 2) The industries in the catchment area temporarily reject the cargo, and the daily station loop has not yet updated station acceptance.
1036 * 3) The results of callbacks CBID_INDUSTRY_REFUSE_CARGO and CBID_INDTILE_CARGO_ACCEPTANCE are inconsistent. (documented behaviour)
1037 */
1038
1039 uint accepted = 0;
1040
1041 for (const auto &i : st->industries_near) {
1042 if (num_pieces == 0) break;
1043
1044 Industry *ind = i.industry;
1045 if (ind->index == source) continue;
1046
1047 auto it = ind->GetCargoAccepted(cargo_type);
1048 /* Check if matching cargo has been found */
1049 if (it == std::end(ind->accepted)) continue;
1050
1051 /* Check if industry temporarily refuses acceptance */
1052 if (IndustryTemporarilyRefusesCargo(ind, cargo_type)) continue;
1053
1054 if (ind->exclusive_supplier != INVALID_OWNER && ind->exclusive_supplier != st->owner) continue;
1055
1056 /* Insert the industry into _cargo_delivery_destinations, if not yet contained */
1058
1059 uint amount = std::min(num_pieces, 0xFFFFu - it->waiting);
1060 it->waiting += amount;
1061 it->GetOrCreateHistory()[THIS_MONTH].accepted += amount;
1062 it->last_accepted = TimerGameEconomy::date;
1063 num_pieces -= amount;
1064 accepted += amount;
1065
1066 /* Update the cargo monitor. */
1067 AddCargoDelivery(cargo_type, company, amount, {source, SourceType::Industry}, st, ind->index);
1068 }
1069
1070 return accepted;
1071}
1072
1085static Money DeliverGoods(int num_pieces, CargoType cargo_type, StationID dest, uint distance, uint16_t periods_in_transit, Company *company, Source src)
1086{
1087 assert(num_pieces > 0);
1088
1089 Station *st = Station::Get(dest);
1090
1091 /* Give the goods to the industry. */
1092 uint accepted_ind = DeliverGoodsToIndustry(st, cargo_type, num_pieces, src.type == SourceType::Industry ? src.ToIndustryID() : IndustryID::Invalid(), company->index);
1093
1094 /* If this cargo type is always accepted, accept all */
1095 uint accepted_total = st->always_accepted.Test(cargo_type) ? num_pieces : accepted_ind;
1096
1097 /* Update station statistics */
1098 if (accepted_total > 0) {
1100 }
1101
1102 /* Update company statistics */
1103 company->cur_economy.delivered_cargo[cargo_type] += accepted_total;
1104
1105 /* Increase town's counter for town effects */
1106 const CargoSpec *cs = CargoSpec::Get(cargo_type);
1107 st->town->received[cs->town_acceptance_effect].new_act += accepted_total;
1108 if (accepted_total - accepted_ind > 0) {
1109 /* Cargo not delivered to an industry must go to the town. */
1110 st->town->GetOrCreateCargoAccepted(cargo_type).history[THIS_MONTH].accepted += accepted_total - accepted_ind;
1111 }
1112
1113 /* Determine profit */
1114 Money profit = GetTransportedGoodsIncome(accepted_total, distance, periods_in_transit, cargo_type);
1115
1116 /* Update the cargo monitor. */
1117 AddCargoDelivery(cargo_type, company->index, accepted_total - accepted_ind, src, st);
1118
1119 /* Modify profit if a subsidy is in effect */
1120 if (CheckSubsidised(cargo_type, company->index, src, st)) {
1121 switch (_settings_game.difficulty.subsidy_multiplier) {
1122 case 0: profit += profit >> 1; break;
1123 case 1: profit *= 2; break;
1124 case 2: profit *= 3; break;
1125 default: profit *= 4; break;
1126 }
1127 }
1128
1129 return profit;
1130}
1131
1138{
1139 const IndustrySpec *indspec = GetIndustrySpec(i->type);
1140 IndustryCallbackMasks cbm = indspec->callback_mask;
1141
1142 i->was_cargo_delivered = true;
1143
1147 } else {
1148 SetWindowDirty(WindowClass::IndustryView, i->index);
1149 }
1150 } else {
1151 for (auto ita = std::begin(i->accepted); ita != std::end(i->accepted); ++ita) {
1152 if (ita->waiting == 0 || !IsValidCargoType(ita->cargo)) continue;
1153
1154 for (auto itp = std::begin(i->produced); itp != std::end(i->produced); ++itp) {
1155 if (!IsValidCargoType(itp->cargo)) continue;
1156 itp->waiting = ClampTo<uint16_t>(itp->waiting + (ita->waiting * indspec->input_cargo_multiplier[ita - std::begin(i->accepted)][itp - std::begin(i->produced)] / 256));
1157 }
1158
1159 ita->waiting = 0;
1160 }
1161 }
1162
1164 TriggerIndustryAnimation(i, IndustryAnimationTrigger::CargoReceived);
1165}
1166
1172CargoPayment::CargoPayment(CargoPaymentID index, Vehicle *front) :
1174 current_station(front->last_station_visited),
1175 front(front)
1176{
1177}
1178
1181{
1182 if (CleaningPool()) return;
1183
1184 this->front->cargo_payment = nullptr;
1185
1186 if (this->visual_profit == 0 && this->visual_transfer == 0) return;
1187
1188 AutoRestoreBackup cur_company(_current_company, this->front->owner);
1189
1190 SubtractMoneyFromCompany(_current_company, CommandCost(this->front->GetExpenseType(true), -this->route_profit));
1191 this->front->profit_this_year += (this->visual_profit + this->visual_transfer) << 8;
1192
1193 const Vehicle *moving_front = this->front->GetMovingFront();
1194 if (this->route_profit != 0 && IsLocalCompany() && !PlayVehicleSound(this->front, VSE_LOAD_UNLOAD)) {
1195 SndPlayVehicleFx(SND_14_CASHTILL, this->front);
1196 }
1197
1198 if (this->visual_transfer != 0) {
1199 ShowFeederIncomeAnimation(moving_front->x_pos, moving_front->y_pos,
1200 moving_front->z_pos, this->visual_transfer, -this->visual_profit);
1201 } else {
1202 ShowCostOrIncomeAnimation(moving_front->x_pos, moving_front->y_pos,
1203 moving_front->z_pos, -this->visual_profit);
1204 }
1205}
1206
1214void CargoPayment::PayFinalDelivery(CargoType cargo, const CargoPacket *cp, uint count, TileIndex current_tile)
1215{
1216 /* Handle end of route payment */
1217 Money profit = DeliverGoods(count, cargo, this->current_station, cp->GetDistance(current_tile), cp->GetPeriodsInTransit(), Company::Get(this->front->owner), cp->GetSource());
1218 this->route_profit += profit;
1219
1220 /* The vehicle's profit is whatever route profit there is minus feeder shares. */
1221 this->visual_profit += profit - cp->GetFeederShare(count);
1222}
1223
1232Money CargoPayment::PayTransfer(CargoType cargo, const CargoPacket *cp, uint count, TileIndex current_tile)
1233{
1234 /* Pay transfer vehicle the difference between the payment for the journey from
1235 * the source to the current point, and the sum of the previous transfer payments */
1236 Money profit = -cp->GetFeederShare(count) + GetTransportedGoodsIncome(
1237 count,
1238 cp->GetDistance(current_tile),
1239 cp->GetPeriodsInTransit(),
1240 cargo);
1241
1242 profit = profit * _settings_game.economy.feeder_payment_share / 100;
1243
1244 this->visual_transfer += profit; // accumulate transfer profits for whole vehicle
1245 return profit; // account for the (virtual) profit already made for the cargo packet
1246}
1247
1253{
1254 Station *curr_station = Station::Get(front_v->last_station_visited);
1255 curr_station->loading_vehicles.push_back(front_v);
1256
1257 /* At this moment loading cannot be finished */
1259
1260 /* Start unloading at the first possible moment */
1261 front_v->load_unload_ticks = 1;
1262
1263 assert(front_v->cargo_payment == nullptr);
1264 /* One CargoPayment per vehicle and the vehicle limit equals the
1265 * limit in number of CargoPayments. Can't go wrong. */
1268 front_v->cargo_payment = CargoPayment::Create(front_v);
1269
1270 std::vector<StationID> next_station;
1271 front_v->GetNextStoppingStation(next_station);
1272 if (front_v->orders == nullptr || front_v->current_order.GetUnloadType() != OrderUnloadType::NoUnload) {
1274 for (Vehicle *v = front_v; v != nullptr; v = v->Next()) {
1275 const GoodsEntry *ge = &st->goods[v->cargo_type];
1276 if (v->cargo_cap > 0 && v->cargo.TotalCount() > 0) {
1277 v->cargo.Stage(
1279 front_v->last_station_visited, next_station,
1280 front_v->current_order.GetUnloadType(), ge,
1281 v->cargo_type, front_v->cargo_payment,
1282 v->GetMovingFront()->GetCargoTile());
1283 if (v->cargo.UnloadCount() > 0) v->vehicle_flags.Set(VehicleFlag::CargoUnloading);
1284 }
1285 }
1286 }
1287}
1288
1295static uint GetLoadAmount(Vehicle *v)
1296{
1297 const Engine *e = v->GetEngine();
1298 uint load_amount = e->info.load_amount;
1299
1300 /* The default loadamount for mail is 1/4 of the load amount for passengers */
1301 bool air_mail = v->type == VehicleType::Aircraft && !Aircraft::From(v)->IsNormalAircraft();
1302 if (air_mail) load_amount = CeilDiv(load_amount, 4);
1303
1304 if (_settings_game.order.gradual_loading) {
1305 uint16_t cb_load_amount = CALLBACK_FAILED;
1306 if (e->GetGRF() != nullptr && e->GetGRF()->grf_version >= 8) {
1307 /* Use callback 36 */
1308 cb_load_amount = GetVehicleProperty(v, PROP_VEHICLE_LOAD_AMOUNT, CALLBACK_FAILED);
1310 /* Use callback 12 */
1311 cb_load_amount = GetVehicleCallback(CBID_VEHICLE_LOAD_AMOUNT, 0, 0, v->engine_type, v);
1312 }
1313 if (cb_load_amount != CALLBACK_FAILED) {
1314 if (e->GetGRF()->grf_version < 8) cb_load_amount = GB(cb_load_amount, 0, 8);
1315 if (cb_load_amount >= 0x100) {
1317 } else if (cb_load_amount != 0) {
1318 load_amount = cb_load_amount;
1319 }
1320 }
1321 }
1322
1323 /* Scale load amount the same as capacity */
1324 if (e->info.misc_flags.Test(EngineMiscFlag::NoDefaultCargoMultiplier) && !air_mail) load_amount = CeilDiv(load_amount * CargoSpec::Get(v->cargo_type)->multiplier, 0x100);
1325
1326 /* Zero load amount breaks a lot of things. */
1327 return std::max(1u, load_amount);
1328}
1329
1339template <class Taction>
1340bool IterateVehicleParts(Vehicle *v, Taction action)
1341{
1342 for (Vehicle *w = v; w != nullptr;
1343 w = w->HasArticulatedPart() ? w->GetNextArticulatedPart() : nullptr) {
1344 if (!action(w)) return false;
1345 if (w->type == VehicleType::Train) {
1346 Train *train = Train::From(w);
1347 if (train->IsMultiheaded() && !action(train->other_multiheaded_part)) return false;
1348 }
1349 }
1350 if (v->type == VehicleType::Aircraft && Aircraft::From(v)->IsNormalAircraft()) return action(v->Next());
1351 return true;
1352}
1353
1358{
1364 bool operator()(const Vehicle *v)
1365 {
1366 return v->cargo.StoredCount() == 0;
1367 }
1368};
1369
1374{
1377
1385
1392 bool operator()(const Vehicle *v)
1393 {
1394 this->consist_capleft[v->cargo_type] -= v->cargo_cap - v->cargo.ReservedCount();
1395 this->refit_mask.Set(EngInfo(v->engine_type)->refit_mask);
1396 return true;
1397 }
1398};
1399
1404{
1406 StationID next_hop;
1407
1413 ReturnCargoAction(Station *st, StationID next_one) : st(st), next_hop(next_one) {}
1414
1421 {
1422 v->cargo.Return(UINT_MAX, &this->st->goods[v->cargo_type].GetOrCreateData().cargo, this->next_hop, v->GetCargoTile());
1423 return true;
1424 }
1425};
1426
1431{
1434 std::span<const StationID> next_station;
1436
1446
1454 {
1455 if (this->do_reserve) {
1456 this->st->goods[v->cargo_type].GetOrCreateData().cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(),
1457 &v->cargo, this->next_station, v->GetCargoTile());
1458 }
1459 this->consist_capleft[v->cargo_type] += v->cargo_cap - v->cargo.RemainingCount();
1460 return true;
1461 }
1462};
1463
1472static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station *st, std::span<const StationID> next_station, CargoType new_cargo_type)
1473{
1474 Vehicle *v_start = v->GetFirstEnginePart();
1475 if (!IterateVehicleParts(v_start, IsEmptyAction())) return;
1476
1477 AutoRestoreBackup cur_company(_current_company, v->owner);
1478
1479 CargoTypes refit_mask = v->GetEngine()->info.refit_mask;
1480
1481 /* Remove old capacity from consist capacity and collect refit mask. */
1482 IterateVehicleParts(v_start, PrepareRefitAction(consist_capleft, refit_mask));
1483
1484 bool is_auto_refit = new_cargo_type == CARGO_AUTO_REFIT;
1485 if (is_auto_refit) {
1486 /* Get a refittable cargo type with waiting cargo for next_station or StationID::Invalid(). */
1487 new_cargo_type = v_start->cargo_type;
1488 for (CargoType cargo_type : refit_mask) {
1489 if (st->goods[cargo_type].HasData() && st->goods[cargo_type].GetData().cargo.HasCargoFor(next_station)) {
1490 /* Try to find out if auto-refitting would succeed. In case the refit is allowed,
1491 * the returned refit capacity will be greater than zero. */
1492 auto [cc, refit_capacity, mail_capacity, cargo_capacities] = Command<Commands::RefitVehicle>::Do(DoCommandFlag::QueryCost, v_start->index, cargo_type, 0xFF, true, false, 1); // Auto-refit and only this vehicle including artic parts.
1493 /* Try to balance different loadable cargoes between parts of the consist, so that
1494 * all of them can be loaded. Avoid a situation where all vehicles suddenly switch
1495 * to the first loadable cargo for which there is only one packet. If the capacities
1496 * are equal refit to the cargo of which most is available. This is important for
1497 * consists of only a single vehicle as those will generally have a consist_capleft
1498 * of 0 for all cargoes. */
1499 if (refit_capacity > 0 && (consist_capleft[cargo_type] < consist_capleft[new_cargo_type] ||
1500 (consist_capleft[cargo_type] == consist_capleft[new_cargo_type] &&
1501 st->goods[cargo_type].AvailableCount() > st->goods[new_cargo_type].AvailableCount()))) {
1502 new_cargo_type = cargo_type;
1503 }
1504 }
1505 }
1506 }
1507
1508 /* Refit if given a valid cargo. */
1509 if (new_cargo_type < NUM_CARGO && new_cargo_type != v_start->cargo_type) {
1510 /* StationID::Invalid() because in the DistributionType::Manual case that's correct and in the DT_(A)SYMMETRIC
1511 * cases the next hop of the vehicle doesn't really tell us anything if the cargo had been
1512 * "via any station" before reserving. We rather produce some more "any station" cargo than
1513 * misrouting it. */
1514 IterateVehicleParts(v_start, ReturnCargoAction(st, StationID::Invalid()));
1515 CommandCost cost = ExtractCommandCost(Command<Commands::RefitVehicle>::Do(DoCommandFlag::Execute, v_start->index, new_cargo_type, 0xFF, true, false, 1)); // Auto-refit and only this vehicle including artic parts.
1516 if (cost.Succeeded()) v->First()->profit_this_year -= cost.GetCost() << 8;
1517 }
1518
1519 /* Add new capacity to consist capacity and reserve cargo */
1520 IterateVehicleParts(v_start, FinalizeRefitAction(consist_capleft, st, next_station,
1521 is_auto_refit || v->First()->current_order.IsFullLoadOrder()));
1522}
1523
1530static bool MayLoadUnderExclusiveRights(const Station *st, const Vehicle *v)
1531{
1532 return st->owner != OWNER_NONE || st->town->exclusive_counter == 0 || st->town->exclusivity == v->owner;
1533}
1534
1535struct ReserveCargoAction {
1536 Station *st;
1537 std::span<const StationID> next_station;
1538
1539 ReserveCargoAction(Station *st, std::span<const StationID> next_station) :
1540 st(st), next_station(next_station) {}
1541
1542 bool operator()(Vehicle *v)
1543 {
1545 st->goods[v->cargo_type].GetOrCreateData().cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(),
1546 &v->cargo, next_station, v->GetCargoTile());
1547 }
1548
1549 return true;
1550 }
1551
1552};
1553
1562static void ReserveConsist(Station *st, Vehicle *u, CargoArray *consist_capleft, std::span<const StationID> next_station)
1563{
1564 /* If there is a cargo payment not all vehicles of the consist have tried to do the refit.
1565 * In that case, only reserve if it's a fixed refit and the equivalent of "articulated chain"
1566 * a vehicle belongs to already has the right cargo. */
1567 bool must_reserve = !u->current_order.IsRefit() || u->cargo_payment == nullptr;
1568 for (Vehicle *v = u; v != nullptr; v = v->Next()) {
1569 assert(v->cargo_cap >= v->cargo.RemainingCount());
1570
1571 /* Exclude various ways in which the vehicle might not be the head of an equivalent of
1572 * "articulated chain". Also don't do the reservation if the vehicle is going to refit
1573 * to a different cargo and hasn't tried to do so, yet. */
1574 if (!v->IsArticulatedPart() &&
1575 (v->type != VehicleType::Train || !Train::From(v)->IsRearDualheaded()) &&
1576 (v->type != VehicleType::Aircraft || Aircraft::From(v)->IsNormalAircraft()) &&
1577 (must_reserve || u->current_order.GetRefitCargo() == v->cargo_type)) {
1578 IterateVehicleParts(v, ReserveCargoAction(st, next_station));
1579 }
1580 if (consist_capleft == nullptr || v->cargo_cap == 0) continue;
1581 (*consist_capleft)[v->cargo_type] += v->cargo_cap - v->cargo.RemainingCount();
1582 }
1583}
1584
1592static void UpdateLoadUnloadTicks(Vehicle *front, const Station *st, int ticks)
1593{
1594 if (front->type == VehicleType::Train && _settings_game.order.station_length_loading_penalty) {
1595 /* Each platform tile is worth 2 rail vehicles. */
1596 int overhang = front->GetGroundVehicleCache()->cached_total_length - st->GetPlatformLength(front->GetMovingFront()->tile) * TILE_SIZE;
1597 if (overhang > 0) {
1598 ticks <<= 1;
1599 ticks += (overhang * ticks) / 8;
1600 }
1601 }
1602 /* Always wait at least 1, otherwise we'll wait 'infinitively' long. */
1603 front->load_unload_ticks = std::max(1, ticks);
1604}
1605
1610static void LoadUnloadVehicle(Vehicle *front)
1611{
1612 assert(front->current_order.IsType(OT_LOADING));
1613
1614 StationID last_visited = front->last_station_visited;
1615 Station *st = Station::Get(last_visited);
1616
1617 std::vector<StationID> next_station;
1618 front->GetNextStoppingStation(next_station);
1619 bool use_autorefit = front->current_order.IsRefit() && front->current_order.GetRefitCargo() == CARGO_AUTO_REFIT;
1620 CargoArray consist_capleft{};
1621 if (_settings_game.order.improved_load && use_autorefit ?
1622 front->cargo_payment == nullptr : (front->current_order.IsFullLoadOrder())) {
1623 ReserveConsist(st, front,
1624 (use_autorefit && front->load_unload_ticks != 0) ? &consist_capleft : nullptr,
1625 next_station);
1626 }
1627
1628 /* We have not waited enough time till the next round of loading/unloading */
1629 if (front->load_unload_ticks != 0) return;
1630
1631 const Vehicle *moving_front = front->GetMovingFront();
1632 if (front->type == VehicleType::Train && (!IsTileType(moving_front->tile, TileType::Station) || GetStationIndex(moving_front->tile) != st->index)) {
1633 /* The train reversed in the station. Take the "easy" way
1634 * out and let the train just leave as it always did. */
1636 front->load_unload_ticks = 1;
1637 return;
1638 }
1639
1640 int new_load_unload_ticks = 0;
1641 bool dirty_vehicle = false;
1642 bool dirty_station = false;
1643
1644 bool completely_emptied = true;
1645 bool anything_unloaded = false;
1646 bool anything_loaded = false;
1647 CargoTypes full_load_amount{};
1648 CargoTypes cargo_not_full{};
1649 CargoTypes cargo_full{};
1650 CargoTypes reservation_left{};
1651
1652 front->cur_speed = 0;
1653
1654 CargoPayment *payment = front->cargo_payment;
1655
1656 uint artic_part = 0; // Articulated part we are currently trying to load. (not counting parts without capacity)
1657 for (Vehicle *v = front; v != nullptr; v = v->Next()) {
1658 if (v == front || !v->Previous()->HasArticulatedPart()) artic_part = 0;
1659 if (v->cargo_cap == 0) continue;
1660 artic_part++;
1661
1662 GoodsEntry *ge = &st->goods[v->cargo_type];
1663
1664 if (v->vehicle_flags.Test(VehicleFlag::CargoUnloading) && front->current_order.GetUnloadType() != OrderUnloadType::NoUnload) {
1665 uint cargo_count = v->cargo.UnloadCount();
1666 uint amount_unloaded = _settings_game.order.gradual_loading ? std::min(cargo_count, GetLoadAmount(v)) : cargo_count;
1667 bool remaining = false; // Are there cargo entities in this vehicle that can still be unloaded here?
1668
1669 if (!ge->status.Test(GoodsEntry::State::Acceptance) && v->cargo.ActionCount(VehicleCargoList::MoveToAction::Deliver) > 0) {
1670 /* The station does not accept our goods anymore. */
1672 /* Transfer instead of delivering. */
1673 v->cargo.Reassign<VehicleCargoList::MoveToAction::Deliver, VehicleCargoList::MoveToAction::Transfer>(
1674 v->cargo.ActionCount(VehicleCargoList::MoveToAction::Deliver));
1675 } else {
1676 uint new_remaining = v->cargo.RemainingCount() + v->cargo.ActionCount(VehicleCargoList::MoveToAction::Deliver);
1677 if (v->cargo_cap < new_remaining) {
1678 /* Return some of the reserved cargo to not overload the vehicle. */
1679 v->cargo.Return(new_remaining - v->cargo_cap, &ge->GetOrCreateData().cargo, StationID::Invalid(), v->GetCargoTile());
1680 }
1681
1682 /* Keep instead of delivering. This may lead to no cargo being unloaded, so ...*/
1683 v->cargo.Reassign<VehicleCargoList::MoveToAction::Deliver, VehicleCargoList::MoveToAction::Keep>(
1684 v->cargo.ActionCount(VehicleCargoList::MoveToAction::Deliver));
1685
1686 /* ... say we unloaded something, otherwise we'll think we didn't unload
1687 * something and we didn't load something, so we must be finished
1688 * at this station. Setting the unloaded means that we will get a
1689 * retry for loading in the next cycle. */
1690 anything_unloaded = true;
1691 }
1692 }
1693
1694 if (v->cargo.ActionCount(VehicleCargoList::MoveToAction::Transfer) > 0) {
1695 /* Mark the station dirty if we transfer, but not if we only deliver. */
1696 dirty_station = true;
1697
1698 if (!ge->HasRating()) {
1699 /* Upon transferring cargo, make sure the station has a rating. Fake a pickup for the
1700 * first unload to prevent the cargo from quickly decaying after the initial drop. */
1701 ge->time_since_pickup = 0;
1703 }
1704 }
1705
1706 assert(payment != nullptr);
1707 amount_unloaded = v->cargo.Unload(amount_unloaded, &ge->GetOrCreateData().cargo, v->cargo_type, payment, v->GetCargoTile());
1708 remaining = v->cargo.UnloadCount() > 0;
1709 if (amount_unloaded > 0) {
1710 dirty_vehicle = true;
1711 anything_unloaded = true;
1712 new_load_unload_ticks += amount_unloaded;
1713
1714 /* Deliver goods to the station */
1715 st->time_since_unload = 0;
1716 }
1717
1718 if (_settings_game.order.gradual_loading && remaining) {
1719 completely_emptied = false;
1720 } else {
1721 /* We have finished unloading (cargo count == 0) */
1722 v->vehicle_flags.Reset(VehicleFlag::CargoUnloading);
1723 }
1724
1725 continue;
1726 }
1727
1728 /* Do not pick up goods when we have no-load set or loading is stopped. */
1730
1731 /* This order has a refit, if this is the first vehicle part carrying cargo and the whole vehicle is empty, try refitting. */
1732 if (front->current_order.IsRefit() && artic_part == 1) {
1733 HandleStationRefit(v, consist_capleft, st, next_station, front->current_order.GetRefitCargo());
1734 ge = &st->goods[v->cargo_type];
1735 }
1736
1737 /* As we're loading here the following link can carry the full capacity of the vehicle. */
1738 v->refit_cap = v->cargo_cap;
1739
1740 /* update stats */
1741 int t;
1742 switch (front->type) {
1743 case VehicleType::Train:
1744 case VehicleType::Ship:
1745 t = front->vcache.cached_max_speed;
1746 break;
1747
1748 case VehicleType::Road:
1749 t = front->vcache.cached_max_speed / 2;
1750 break;
1751
1753 t = Aircraft::From(front)->GetSpeedOldUnits(); // Convert to old units.
1754 break;
1755
1756 default: NOT_REACHED();
1757 }
1758
1759 /* if last speed is 0, we treat that as if no vehicle has ever visited the station. */
1762
1763 assert(v->cargo_cap >= v->cargo.StoredCount());
1764 /* Capacity available for loading more cargo. */
1765 uint cap_left = v->cargo_cap - v->cargo.StoredCount();
1766
1767 if (cap_left > 0) {
1768 /* If vehicle can load cargo, reset time_since_pickup. */
1769 ge->time_since_pickup = 0;
1770
1771 /* If there's goods waiting at the station, and the vehicle
1772 * has capacity for it, load it on the vehicle. */
1773 if ((v->cargo.ActionCount(VehicleCargoList::MoveToAction::Load) > 0 || ge->AvailableCount() > 0) && MayLoadUnderExclusiveRights(st, v)) {
1774 if (v->cargo.StoredCount() == 0) TriggerVehicleRandomisation(v, VehicleRandomTrigger::NewCargo);
1775 if (_settings_game.order.gradual_loading) cap_left = std::min(cap_left, GetLoadAmount(v));
1776
1777 uint loaded = ge->GetOrCreateData().cargo.Load(cap_left, &v->cargo, next_station, v->GetCargoTile());
1778 if (v->cargo.ActionCount(VehicleCargoList::MoveToAction::Load) > 0) {
1779 /* Remember if there are reservations left so that we don't stop
1780 * loading before they're loaded. */
1781 reservation_left.Set(v->cargo_type);
1782 }
1783
1784 /* Store whether the maximum possible load amount was loaded or not.*/
1785 if (loaded == cap_left) {
1786 full_load_amount.Set(v->cargo_type);
1787 } else {
1788 full_load_amount.Reset(v->cargo_type);
1789 }
1790
1791 /* TODO: Regarding this, when we do gradual loading, we
1792 * should first unload all vehicles and then start
1793 * loading them. Since this will cause
1794 * VEHICLE_TRIGGER_EMPTY to be called at the time when
1795 * the whole vehicle chain is really totally empty, the
1796 * completely_emptied assignment can then be safely
1797 * removed; that's how TTDPatch behaves too. --pasky */
1798 if (loaded > 0) {
1799 completely_emptied = false;
1800 anything_loaded = true;
1801
1802 st->time_since_load = 0;
1803 st->last_vehicle_type = v->type;
1804
1805 if (ge->GetData().cargo.TotalCount() == 0) {
1807 TriggerStationAnimation(st, st->xy, StationAnimationTrigger::CargoTaken, v->cargo_type);
1808 TriggerAirportAnimation(st, AirportAnimationTrigger::CargoTaken, v->cargo_type);
1810 TriggerRoadStopAnimation(st, st->xy, StationAnimationTrigger::CargoTaken, v->cargo_type);
1811 }
1812
1813 new_load_unload_ticks += loaded;
1814
1815 dirty_vehicle = dirty_station = true;
1816 }
1817 }
1818 }
1819
1820 if (v->cargo.StoredCount() >= v->cargo_cap) {
1821 cargo_full.Set(v->cargo_type);
1822 } else {
1823 cargo_not_full.Set(v->cargo_type);
1824 }
1825 }
1826
1827 if (anything_loaded || anything_unloaded) {
1828 if (front->type == VehicleType::Train) {
1830 TriggerStationAnimation(st, moving_front->tile, StationAnimationTrigger::VehicleLoads);
1831 } else if (front->type == VehicleType::Road) {
1833 TriggerRoadStopAnimation(st, front->tile, StationAnimationTrigger::VehicleLoads);
1834 }
1835 }
1836
1837 /* Only set completely_emptied, if we just unloaded all remaining cargo */
1838 completely_emptied &= anything_unloaded;
1839
1840 if (!anything_unloaded) delete payment;
1841
1843 if (anything_loaded || anything_unloaded) {
1844 if (_settings_game.order.gradual_loading) {
1845 /* The time it takes to load one 'slice' of cargo or passengers depends
1846 * on the vehicle type - the values here are those found in TTDPatch */
1847 constexpr VehicleTypeIndexArray<const uint> gradual_loading_wait_time = { 40, 20, 10, 20 };
1848
1849 new_load_unload_ticks = gradual_loading_wait_time[front->type];
1850 }
1851 /* We loaded less cargo than possible for all cargo types and it's not full
1852 * load and we're not supposed to wait any longer: stop loading. */
1853 if (!anything_unloaded && full_load_amount.None() && reservation_left.None() && !front->current_order.IsFullLoadOrder() &&
1854 front->current_order_time >= std::max(front->current_order.GetTimetabledWait() - front->lateness_counter, 0)) {
1856 }
1857
1858 UpdateLoadUnloadTicks(front, st, new_load_unload_ticks);
1859 } else {
1860 UpdateLoadUnloadTicks(front, st, 20); // We need the ticks for link refreshing.
1861 bool finished_loading = true;
1862 if (front->current_order.IsFullLoadOrder()) {
1864 /* if the aircraft carries passengers and is NOT full, then
1865 * continue loading, no matter how much mail is in */
1866 if ((front->type == VehicleType::Aircraft && IsCargoInClass(front->cargo_type, CargoClass::Passengers) && front->cargo_cap > front->cargo.StoredCount()) ||
1867 (cargo_not_full.Any() && cargo_full.Reset(cargo_not_full).None())) { // There are still non-full cargoes
1868 finished_loading = false;
1869 }
1870 } else if (cargo_not_full.Any()) {
1871 finished_loading = false;
1872 }
1873
1874 /* Refresh next hop stats if we're full loading to make the links
1875 * known to the distribution algorithm and allow cargo to be sent
1876 * along them. Otherwise the vehicle could wait for cargo
1877 * indefinitely if it hasn't visited the other links yet, or if the
1878 * links die while it's loading. */
1879 if (!finished_loading) LinkRefresher::Run(front, true, true);
1880 }
1881
1882 front->vehicle_flags.Set(VehicleFlag::LoadingFinished, finished_loading);
1883 }
1884
1885 /* Calculate the loading indicator fill percent and display
1886 * In the Game Menu do not display indicators
1887 * If _settings_client.gui.loading_indicators == 2, show indicators (bool can be promoted to int as 0 or 1 - results in 2 > 0,1 )
1888 * if _settings_client.gui.loading_indicators == 1, _local_company must be the owner or must be a spectator to show ind., so 1 > 0
1889 * if _settings_client.gui.loading_indicators == 0, do not display indicators ... 0 is never greater than anything
1890 */
1891 if (_game_mode != GameMode::Menu && (_settings_client.gui.loading_indicators > (uint)(front->owner != _local_company && _local_company != COMPANY_SPECTATOR))) {
1892 StringID percent_up_down = STR_NULL;
1893 int percent = CalcPercentVehicleFilled(front, &percent_up_down);
1894 if (front->fill_percent_te_id == INVALID_TE_ID) {
1895 front->fill_percent_te_id = ShowFillingPercent(moving_front->x_pos, moving_front->y_pos, moving_front->z_pos + 20, percent, percent_up_down);
1896 } else {
1897 UpdateFillingPercent(front->fill_percent_te_id, percent, percent_up_down);
1898 }
1899 }
1900
1901 if (completely_emptied) {
1902 /* Make sure the vehicle is marked dirty, since we need to update the NewGRF
1903 * properties such as weight, power and TE whenever the trigger runs. */
1904 dirty_vehicle = true;
1905 TriggerVehicleRandomisation(front, VehicleRandomTrigger::Empty);
1906 }
1907
1908 if (dirty_vehicle) {
1910 SetWindowDirty(WindowClass::VehicleDetails, front->index);
1911 front->MarkDirty();
1912 }
1913 if (dirty_station) {
1914 st->MarkTilesDirty(true);
1915 SetWindowDirty(WindowClass::StationView, st->index);
1916 SetWindowDirty(WindowClass::StationList, st->owner);
1917 }
1918}
1919
1926{
1927 /* No vehicle is here... */
1928 if (st->loading_vehicles.empty()) return;
1929
1930 Vehicle *last_loading = nullptr;
1931
1932 /* Check if anything will be loaded at all. Otherwise we don't need to reserve either. */
1933 for (Vehicle *v : st->loading_vehicles) {
1934 if (v->vehstatus.Any({VehState::Stopped, VehState::Crashed})) continue;
1935
1936 assert(v->load_unload_ticks != 0);
1937 if (--v->load_unload_ticks == 0) last_loading = v;
1938 }
1939
1940 /* We only need to reserve and load/unload up to the last loading vehicle.
1941 * Anything else will be forgotten anyway after returning from this function.
1942 *
1943 * Especially this means we do _not_ need to reserve cargo for a single
1944 * consist in a station which is not allowed to load yet because its
1945 * load_unload_ticks is still not 0.
1946 */
1947 if (last_loading == nullptr) return;
1948
1949 for (Vehicle *v : st->loading_vehicles) {
1950 if (!v->vehstatus.Any({VehState::Stopped, VehState::Crashed})) LoadUnloadVehicle(v);
1951 if (v == last_loading) break;
1952 }
1953
1954 /* Call the production machinery of industries */
1957 }
1959}
1960
1964static const IntervalTimer<TimerGameCalendar> _calendar_inflation_monthly({TimerGameCalendar::Trigger::Month, TimerGameCalendar::Priority::Company}, [](auto)
1965{
1966 if (_settings_game.economy.inflation) {
1967 AddInflation();
1969 }
1970});
1971
1975static const IntervalTimer<TimerGameEconomy> _economy_companies_monthly({ TimerGameEconomy::Trigger::Month, TimerGameEconomy::Priority::Company }, [](auto)
1976{
1979 HandleEconomyFluctuations();
1980});
1981
1982static void DoAcquireCompany(Company *c, bool hostile_takeover)
1983{
1984 CompanyID ci = c->index;
1985
1986 auto cni = std::make_unique<CompanyNewsInformation>(STR_NEWS_COMPANY_MERGER_TITLE, c, Company::Get(_current_company));
1987 EncodedString headline = hostile_takeover
1988 ? GetEncodedString(STR_NEWS_MERGER_TAKEOVER_TITLE, cni->company_name, cni->other_company_name)
1989 : GetEncodedString(STR_NEWS_COMPANY_MERGER_DESCRIPTION, cni->company_name, cni->other_company_name, c->bankrupt_value);
1990 AddCompanyNewsItem(std::move(headline), std::move(cni));
1991 AI::BroadcastNewEvent(new ScriptEventCompanyMerger(ci, _current_company));
1992 Game::NewEvent(new ScriptEventCompanyMerger(ci, _current_company));
1993
1995
1996 if (c->is_ai) AI::Stop(c->index);
1997
1999 InvalidateWindowClassesData(WindowClass::TrainList, 0);
2000 InvalidateWindowClassesData(WindowClass::ShipList, 0);
2001 InvalidateWindowClassesData(WindowClass::RoadVehicleList, 0);
2002 InvalidateWindowClassesData(WindowClass::AircraftList, 0);
2003 InvalidateWindowData(WindowClass::NetworkClientList, 0);
2004
2005 delete c;
2006}
2007
2018CommandCost CmdBuyCompany(DoCommandFlags flags, CompanyID target_company, bool hostile_takeover)
2019{
2020 Company *c = Company::GetIfValid(target_company);
2021 if (c == nullptr) return CMD_ERROR;
2022
2023 /* If you do a hostile takeover but the company went bankrupt, buy it via bankruptcy rules. */
2024 if (hostile_takeover && c->bankrupt_asked.Test(_current_company)) hostile_takeover = false;
2025
2026 /* Disable takeovers when not asked */
2027 if (!hostile_takeover && !c->bankrupt_asked.Test(_current_company)) return CMD_ERROR;
2028
2029 /* Only allow hostile takeover of AI companies and when in single player */
2030 if (hostile_takeover && !c->is_ai) return CMD_ERROR;
2031 if (hostile_takeover && _networking) return CMD_ERROR;
2032
2033 /* Disable taking over the local company in singleplayer mode */
2034 if (!_networking && _local_company == c->index) return CMD_ERROR;
2035
2036 /* Do not allow companies to take over themselves */
2037 if (target_company == _current_company) return CMD_ERROR;
2038
2039 /* Do not allow takeover if the resulting company would have too many vehicles. */
2040 if (!CheckTakeoverVehicleLimit(_current_company, target_company)) return CommandCost(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME);
2041
2042 /* Get the cost here as the company is deleted in DoAcquireCompany.
2043 * For bankruptcy this amount is calculated when the offer was made;
2044 * for hostile takeover you pay the current price. */
2045 CommandCost cost(ExpensesType::Other, hostile_takeover ? CalculateHostileTakeoverValue(c) : c->bankrupt_value);
2046
2047 if (flags.Test(DoCommandFlag::Execute)) {
2048 DoAcquireCompany(c, hostile_takeover);
2049 }
2050 return cost;
2051}
Base functions for all AIs.
Base for aircraft.
Functions related to autoreplacing.
void RemoveAllEngineReplacementForCompany(Company *c)
Remove all engine replacement settings for the given company.
Class for backupping variables and making sure they are restored later.
@ StopLoading
Don't load anymore during the next load cycle.
@ LoadingFinished
Vehicle has finished loading.
@ CargoUnloading
Vehicle is unloading cargo.
static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
Types related to cargoes...
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:110
static constexpr CargoType CARGO_AUTO_REFIT
Automatically choose cargo type when doing auto refitting.
Definition cargo_type.h:78
EnumBitSet< CargoType, uint64_t > CargoTypes
Bitset of CargoType elements.
Definition cargo_type.h:113
CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:22
void ClearCargoDeliveryMonitoring(CompanyID company)
Clear all delivery cargo monitors.
void ClearCargoPickupMonitoring(CompanyID company)
Clear all pick-up cargo monitors.
void AddCargoDelivery(CargoType cargo_type, CompanyID company, uint32_t amount, Source src, const Station *st, IndustryID dest)
Cargo was delivered to its final destination, update the pickup and delivery maps.
Cargo transport monitoring declarations.
@ Passengers
Passengers.
Definition cargotype.h:51
bool IsCargoInClass(CargoType cargo, CargoClasses cc)
Does cargo c have cargo class cc?
Definition cargotype.h:238
static void BroadcastNewEvent(ScriptEvent *event, CompanyID skip_company=CompanyID::Invalid())
Broadcast a new event to all active AIs.
Definition ai_core.cpp:250
static void Stop(CompanyID company)
Stop a company to be controlled by an AI.
Definition ai_core.cpp:113
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr bool None() const
Test if none of the values are set.
constexpr Timpl & Reset()
Reset all bits.
constexpr Timpl & Set()
Set all bits.
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
Common return value for all commands.
bool Succeeded() const
Did this command succeed?
void AddCost(const Money &cost)
Adds the given cost to the cost of the command.
Money GetCost() const
The costs as made up to this moment.
Container for an encoded string, created by GetEncodedString.
const GRFFile * GetGRF() const
Retrieve the NewGRF the engine is tied to.
GrfID GetGRFID() const
Retrieve the GRF ID of the NewGRF the engine is tied to.
Definition engine.cpp:183
Iterate a range of enum values.
UnitID UseID(UnitID index)
Use a unit number.
Definition vehicle.cpp:1889
UnitID NextID() const
Find first unused unit number.
Definition vehicle.cpp:1874
static void NewEvent(class ScriptEvent *event)
Queue a new event for the game script.
An interval timer will fire every interval, and will continue to fire until it is deleted.
Definition timer.h:76
static void Run(Vehicle *v, bool allow_merge=true, bool is_full_loading=false)
Refresh all links the given vehicle will visit.
Definition refresh.cpp:26
uint TotalCount() const
Returns total count of cargo at the station, including cargo which is already reserved for loading.
uint Load(uint max_move, VehicleCargoList *dest, std::span< const StationID > next, TileIndex current_tile)
Loads cargo onto a vehicle.
static Year year
Current year, starting at 0.
static constexpr TimerGame< struct Calendar >::Year ORIGINAL_MAX_YEAR
static constexpr TimerGame< struct Calendar >::Year ORIGINAL_BASE_YEAR
static Date date
Current date in days (day counter).
static Month month
Current month (0..11).
A sort-of mixin that implements 'at(pos)' and 'operator[](pos)' only for a specific type.
uint Return(uint max_move, StationCargoList *dest, StationID next_station, TileIndex current_tile)
Returns reserved cargo to the station and removes it from the cache.
uint ReservedCount() const
Returns sum of reserved cargo.
uint RemainingCount() const
Returns the sum of cargo to be kept in the vehicle at the current station.
uint StoredCount() const
Returns sum of cargo on board the vehicle (ie not only reserved).
Functions related to commands.
CommandCost & ExtractCommandCost(Tret &ret)
Extract the CommandCost from a command proc result.
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
@ QueryCost
query cost only, don't build.
@ Execute
execute the given command
@ Bankrupt
company bankrupts, skip money check, skip vehicle on tile check in some cases
EnumBitSet< DoCommandFlag, uint16_t > DoCommandFlags
Bitset of DoCommandFlag elements.
int CompanyServiceInterval(const Company *c, VehicleType type)
Get the service interval for the given company and vehicle type.
static void SubtractMoneyFromCompany(Company *c, const CommandCost &cost)
Deduct costs of a command from the money of a company.
void SetLocalCompany(CompanyID new_company, bool switching_game)
Sets the local company and updates the settings that are set on a per-company basis to reflect the co...
void CompanyAdminUpdate(const Company *company)
Called whenever company related information changes in order to notify admins.
Money GetAvailableMoney(CompanyID company)
Get the amount of money that a company has available, or INT64_MAX if there is no such valid company.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
bool CheckTakeoverVehicleLimit(CompanyID cbig, CompanyID csmall)
Can company cbig buy company csmall without exceeding vehicle limits?
CompanyID _current_company
Company currently doing an action.
Command definitions related to companies.
Functions related to companies.
bool IsLocalCompany()
Is the current company the local company?
GUI Functions related to companies.
void CloseCompanyWindows(CompanyID company)
Close all windows of a company.
Definition window.cpp:1233
@ Delete
Delete a company.
static constexpr CompanyID COMPANY_SPECTATOR
The client is spectating.
static const uint MAX_HISTORY_QUARTERS
The maximum number of quarters kept as performance's history.
static constexpr Owner OWNER_NONE
The tile has no ownership.
static constexpr Owner INVALID_OWNER
An invalid owner.
@ Bankrupt
The company went belly-up.
Some simple functions to help with accessing containers.
bool include(Container &container, typename Container::const_reference &item)
Helper function to append an item to a container if it is not already contained.
static bool MayLoadUnderExclusiveRights(const Station *st, const Vehicle *v)
Test whether a vehicle can load cargo at a station even if exclusive transport rights are present.
Definition economy.cpp:1530
static void UpdateLoadUnloadTicks(Vehicle *front, const Station *st, int ticks)
Update the vehicle's load_unload_ticks, the time it will wait until it tries to load or unload again.
Definition economy.cpp:1592
int UpdateCompanyRatingAndValue(Company *c, bool update)
if update is set to true, the economy is updated with this score (also the house is updated,...
Definition economy.cpp:203
static void ReserveConsist(Station *st, Vehicle *u, CargoArray *consist_capleft, std::span< const StationID > next_station)
Reserves cargo if the full load order and improved_load is set or if the current order allows autoref...
Definition economy.cpp:1562
void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
Change the ownership of all the items of a company.
Definition economy.cpp:323
static void CompaniesPayInterest()
Let all companies pay the monthly interest on their loan.
Definition economy.cpp:801
static const IntervalTimer< TimerGameEconomy > _economy_companies_monthly({ TimerGameEconomy::Trigger::Month, TimerGameEconomy::Priority::Company }, [](auto) { CompaniesGenStatistics();CompaniesPayInterest();HandleEconomyFluctuations();})
Every economy month update of company economic data, plus economy fluctuations.
static const IntervalTimer< TimerGameCalendar > _calendar_inflation_monthly({TimerGameCalendar::Trigger::Month, TimerGameCalendar::Priority::Company}, [](auto) { if(_settings_game.economy.inflation) { AddInflation();RecomputePrices();} })
Every calendar month update of inflation.
void LoadUnloadStation(Station *st)
Load/unload the vehicles in this station according to the order they entered.
Definition economy.cpp:1925
void RecomputePrices()
Computes all prices, payments and maximum loan.
Definition economy.cpp:734
static uint DeliverGoodsToIndustry(const Station *st, CargoType cargo_type, uint num_pieces, IndustryID source, CompanyID company)
Transfer goods from station to industry.
Definition economy.cpp:1030
static void LoadUnloadVehicle(Vehicle *front)
Loads/unload the vehicle if possible.
Definition economy.cpp:1610
Money CalculateHostileTakeoverValue(const Company *c)
Calculate what you have to pay to take over a company.
Definition economy.cpp:178
static Money CalculateCompanyAssetValue(const Company *c)
Calculate the value of the assets of a company.
Definition economy.cpp:116
static SmallIndustryList _cargo_delivery_destinations
The industries we've currently brought cargo to.
Definition economy.cpp:1018
void PrepareUnload(Vehicle *front_v)
Prepare the vehicle to be unloaded.
Definition economy.cpp:1252
static uint GetLoadAmount(Vehicle *v)
Gets the amount of cargo the given vehicle can load in the current tick.
Definition economy.cpp:1295
static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station *st, std::span< const StationID > next_station, CargoType new_cargo_type)
Refit a vehicle in a station.
Definition economy.cpp:1472
void SetPriceBaseMultiplier(Price price, int factor)
Change a price base by the given factor.
Definition economy.cpp:870
Money GetPrice(Price index, uint cost_factor, const GRFFile *grf_file, int shift)
Determine a certain price.
Definition economy.cpp:937
static void TriggerIndustryProduction(Industry *i)
Inform the industry about just delivered cargo DeliverGoodsToIndustry() silently incremented incoming...
Definition economy.cpp:1137
bool IterateVehicleParts(Vehicle *v, Taction action)
Iterate the articulated parts of a vehicle, also considering the special cases of "normal" aircraft a...
Definition economy.cpp:1340
static Money DeliverGoods(int num_pieces, CargoType cargo_type, StationID dest, uint distance, uint16_t periods_in_transit, Company *company, Source src)
Delivers goods to industries/towns and calculates the payment.
Definition economy.cpp:1085
Prices _price
Prices and also the fractional part.
Definition economy.cpp:107
static int32_t BigMulS(const int32_t a, const int32_t b, const uint8_t shift)
Multiply two integer values and shift the results to right.
Definition economy.cpp:82
void InitializeEconomy()
Resets economy to initial values.
Definition economy.cpp:922
static void CompanyCheckBankrupt(Company *c)
Check for bankruptcy of a company.
Definition economy.cpp:547
void ResetPriceBaseMultipliers()
Reset changes to the price base multipliers.
Definition economy.cpp:858
static void CompaniesGenStatistics()
Update the finances of all companies.
Definition economy.cpp:638
bool AddInflation(bool check_year)
Add monthly inflation.
Definition economy.cpp:696
CommandCost CmdBuyCompany(DoCommandFlags flags, CompanyID target_company, bool hostile_takeover)
Buy up another company.
Definition economy.cpp:2018
const EnumIndexArray< ScoreInfo, ScoreID, ScoreID::End > _score_info
Score info, values used for computing the detailed performance rating.
Definition economy.cpp:92
Money CalculateCompanyValue(const Company *c, bool including_loan)
Calculate the value of the company.
Definition economy.cpp:151
void StartupIndustryDailyChanges(bool init_counter)
Initialize the variables that will maintain the daily industry change system.
Definition economy.cpp:880
Base classes related to the economy.
Pool< CargoPayment, CargoPaymentID, 512 > CargoPaymentPool
Type of pool to store cargo payments in; little over 1 million.
CargoPaymentPool _cargo_payment_pool
The actual pool to store cargo payments in.
Command definitions related to the economy.
bool EconomyIsInRecession()
Is the economy in recession?
ScoreID
Score categories in the detailed performance rating.
@ Delivered
Units of cargo delivered in the last four quarter.
@ MinIncome
Income in the quarter with the lowest profit of the last 12 quarters.
@ Vehicles
Number of vehicles that turned profit last year.
@ End
Score ID end marker.
@ Stations
Number of recently-serviced stations.
@ Total
Total points out of possible points ,must always be the last entry.
@ Loan
The amount of money company can take as a loan.
@ MaxIncome
Income in the quarter with the highest profit of the last 12 quarters.
@ MinProfit
The profit of the vehicle with the lowest income.
@ Money
Amount of money company has in the bank.
@ Cargo
Number of types of cargo delivered in the last four quarter.
static const int MIN_PRICE_MODIFIER
Maximum NewGRF price modifiers.
EnumIndexArray< Money, Price, Price::End > Prices
Prices of everything.
@ LoanInterest
Interest payments over the loan.
@ Property
Property costs.
@ Other
Other expenses.
@ Construction
Price is affected by "construction cost" difficulty setting.
@ Running
Price is affected by "vehicle running cost" difficulty setting.
static const int LOAN_INTERVAL
The "steps" in loan size, in British Pounds!
static const uint64_t MAX_INFLATION
Maximum inflation (including fractional part) without causing overflows in int64_t price computations...
Price
Enumeration of all base prices for use with Prices.
@ End
Price base end marker.
@ StationValue
Stations value and additional constant company running fee.
static constexpr int SCORE_MAX
The max score that can be in the performance history.
Base class for engines.
@ NoDefaultCargoMultiplier
Use the new capacity algorithm. The default cargotype of the vehicle does not affect capacity multipl...
EnumClassIndexContainer< std::array< T, to_underlying(N)>, Index > EnumIndexArray
A typedef for EnumClassIndexContainer using std::array as the backing container type.
Base functions for all Games.
Goal base class.
Base class and functions for all vehicles that move through ground.
void MarkTilesDirty(bool cargo_change) const
Marks the tiles of the station as dirty.
Definition station.cpp:250
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1553
virtual void MarkDirty()
Marks the vehicles to be redrawn and updates cached variables.
Base of all industries.
const IndustrySpec * GetIndustrySpec(IndustryType thistype)
Accessor for array _industry_specs.
@ CargoReceived
Cargo has been delivered.
@ CargoReceived
Trigger when cargo is received .
void ChangeTileOwner(TileIndex tile, Owner old_owner, Owner new_owner)
Change the owner of a tile.
constexpr T ScaleByPercentage(U num, uint16_t percentage)
Scale a number by the required percentage.
constexpr uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
constexpr To ClampTo(From value)
Clamp the given value down to lie within the requested type.
void ShowCostOrIncomeAnimation(int x, int y, int z, Money cost)
Display animated income or costs on the map.
Definition misc_gui.cpp:508
void ShowFeederIncomeAnimation(int x, int y, int z, Money transfer, Money income)
Display animated feeder income.
Definition misc_gui.cpp:531
void UpdateFillingPercent(TextEffectID te_id, uint8_t percent, StringID string)
Update vehicle loading indicators.
Definition misc_gui.cpp:571
TextEffectID ShowFillingPercent(int x, int y, int z, uint8_t percent, StringID string)
Display vehicle loading indicators.
Definition misc_gui.cpp:556
bool _networking
are we in networking mode?
Definition network.cpp:67
bool _network_server
network-server is active
Definition network.cpp:68
Basic functions/variables used all over the place.
void NetworkClientsToSpectators(CompanyID cid)
Move the clients of a company to the spectators.
Network functions used by other parts of OpenTTD.
@ Invalid
Client is not part of anything.
NewGRF handling of airport tiles.
@ ProfitCalc
custom profit calculation
@ Production256Ticks
call production callback every 256 ticks
@ ProductionCargoArrival
call production callback when cargo arrives at the industry
@ CBID_CARGO_PROFIT_CALC
Called to calculate the income of delivered cargo.
@ CBID_VEHICLE_LOAD_AMOUNT
Determine the amount of cargo to load per unit of time when using gradual loading.
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
EnumBitSet< IndustryCallbackMask, uint16_t > IndustryCallbackMasks
Bitset of IndustryCallbackMask elements.
Cargo support for NewGRFs.
void ErrorUnknownCallbackResult(GrfID grfid, uint16_t cbid, uint16_t cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
uint16_t GetVehicleCallback(CallbackID callback, uint32_t param1, uint32_t param2, EngineID engine, const Vehicle *v, std::span< int32_t > regs100)
Evaluate a newgrf callback for vehicles.
Functions for NewGRF engines.
void IndustryProductionCallback(Industry *ind, int reason)
Get the industry production callback and apply it to the industry.
bool IndustryTemporarilyRefusesCargo(Industry *ind, CargoType cargo_type)
Check whether an industry temporarily refuses to accept a certain cargo.
void TriggerIndustryRandomisation(Industry *ind, IndustryRandomTrigger trigger)
Trigger a random trigger for all industry tiles.
NewGRF handling of industry tiles.
@ PROP_VEHICLE_LOAD_AMOUNT
Loading speed.
void TriggerRoadStopRandomisation(BaseStation *st, TileIndex tile, StationRandomTrigger trigger, CargoType cargo_type)
Trigger road stop randomisation.
NewGRF definitions and structures for road stops.
bool PlayVehicleSound(const Vehicle *v, VehicleSoundEvent event, bool force)
Checks whether a NewGRF wants to play a different vehicle sound effect.
Functions related to NewGRF provided sounds.
@ VSE_LOAD_UNLOAD
Whenever cargo payment is made for a vehicle.
void TriggerStationRandomisation(BaseStation *st, TileIndex trigger_tile, StationRandomTrigger trigger, CargoType cargo_type)
Trigger station randomisation.
Header file for NewGRF stations.
Functions related to news.
void AddNewsItem(EncodedString &&headline, NewsType type, NewsStyle style, NewsFlags flags, NewsReference ref1={}, NewsReference ref2={}, std::unique_ptr< NewsAllocatedData > &&data=nullptr, AdviceType advice_type=AdviceType::Invalid)
Add a new newsitem to be shown.
Definition news_gui.cpp:917
@ Economy
Economic changes (recession, industry up/dowm).
Definition news_type.h:37
@ Normal
Normal news item. (Newspaper with text only).
Definition news_type.h:80
Functions related to objects.
void UpdateCompanyHQ(TileIndex tile, uint score)
Update the CompanyHQ to the state associated with the given score.
@ Menu
In the main menu.
Definition openttd.h:19
@ Transfer
Transfer all cargo onto the platform.
Definition order_type.h:70
@ NoUnload
Totally no unloading will be done.
Definition order_type.h:71
@ Unload
Force unloading all cargo onto the platform, possibly not getting paid.
Definition order_type.h:69
@ NoLoad
Do not load anything.
Definition order_type.h:81
@ FullLoadAny
Full load a single cargo of the consist.
Definition order_type.h:80
Some methods of Pool are placed here in order to reduce compilation time and binary size.
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
Table of all default price bases.
Money RailMaintenanceCost(RailType railtype, uint32_t num, uint32_t total_num)
Calculates the maintenance cost of a number of track bits.
Definition rail.h:486
Money SignalMaintenanceCost(uint32_t num)
Calculates the maintenance cost of a number of signals.
Definition rail.h:497
TrackBits GetTrackBits(Tile tile)
Gets the track bits of the given tile.
Definition rail_map.h:136
bool IsSignalPresent(Tile t, uint8_t signalbit)
Checks whether the given signals is present.
Definition rail_map.h:462
bool HasSignals(Tile t)
Checks if a rail tile has signals.
Definition rail_map.h:72
RailType
Enumeration for all possible railtypes.
Definition rail_type.h:26
@ RAILTYPE_END
Used for iterations.
Definition rail_type.h:32
Declaration of link refreshing utility.
Money RoadMaintenanceCost(RoadType roadtype, uint32_t num, uint32_t total_num)
Calculates the maintenance cost of a number of road bits.
Definition road_func.h:107
void UpdateLevelCrossing(TileIndex tile, bool sound=true, bool force_bar=false)
Update a level crossing to barred or open (crossing may include multiple adjacent tiles).
bool IsLevelCrossingTile(Tile t)
Return whether a tile is a level crossing tile.
Definition road_map.h:79
RoadType
The different roadtypes we support.
Definition road_type.h:24
@ ROADTYPE_END
Used for iterations.
Definition road_type.h:28
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
void AddTrackToSignalBuffer(TileIndex tile, Track track, Owner owner)
Add track to signal update buffer.
Definition signal.cpp:598
void UpdateSignalsInBuffer()
Update signals in buffer Called from 'outside'.
Definition signal.cpp:582
uint8_t SignalOnTrack(Track track)
Maps a Track to the bits that store the status of the two signals that can be present on the given tr...
Definition signal_func.h:48
Base class for signs.
Functions related to sound.
@ SND_14_CASHTILL
18 == 0x12 Income from cargo delivery
Definition sound_type.h:66
@ Industry
Source/destination is an industry.
Definition source_type.h:21
Money AirportMaintenanceCost(Owner owner)
Calculates the maintenance cost of all airports of a company.
Definition station.cpp:716
Base classes/functions for stations.
Money StationMaintenanceCost(uint32_t num)
Calculates the maintenance cost of a number of station tiles.
StationID GetStationIndex(Tile t)
Get StationID from a tile.
Definition station_map.h:28
@ CargoTaken
Trigger station when cargo is completely taken.
@ VehicleLoads
Trigger platform when train loads/unloads.
@ CargoTaken
Trigger station when cargo is completely taken.
@ VehicleLoads
Trigger platform when train loads/unloads.
@ CargoTaken
Triggered when a cargo type is completely removed from the station (for all tiles at the same time).
Definition of base types and functions in a cross-platform compatible way.
StoryPage base class.
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:90
Functions related to OTTD's strings.
StrongType::Typedef< uint32_t, struct StringIDTag, StrongType::Compare, StrongType::Integer > StringID
Numeric value that represents a string, independent of the selected language.
bool IsNormalAircraft() const
Check if the aircraft type is a normal flying device; eg not a rotor or a shadow.
Definition aircraft.h:123
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
Class to backup a specific variable and restore it later.
void Restore()
Restore the variable.
TimerGameTick::Ticks current_order_time
How many ticks have passed since this order started.
VehicleFlags vehicle_flags
Used for gradual loading and other miscellaneous things (.
TimerGameTick::Ticks lateness_counter
How many ticks late (or early if negative) this vehicle is.
TileIndex xy
Base tile of the station.
Owner owner
The owner of this station.
Town * town
The town this station is associated with.
VehicleType type
Type of vehicle.
Class for storing amounts of cargo.
Definition cargo_type.h:118
Container for cargo from the same location and time.
Definition cargopacket.h:41
Money GetFeederShare() const
Gets the amount of money already paid to earlier vehicles in the feeder chain.
uint GetDistance(TileIndex current_tile) const
Get the current distance the cargo has traveled.
uint16_t GetPeriodsInTransit() const
Gets the number of cargo aging periods this cargo has been in transit.
Source GetSource() const
Gets the source of the packet for subsidy purposes.
Helper class to perform the cargo payment.
void PayFinalDelivery(CargoType cargo, const CargoPacket *cp, uint count, TileIndex current_tile)
Handle payment for final delivery of the given cargo packet.
Definition economy.cpp:1214
~CargoPayment()
Execute the actual payment to the coffers of the company.
Definition economy.cpp:1180
StationID current_station
NOSAVE: The current station.
Money PayTransfer(CargoType cargo, const CargoPacket *cp, uint count, TileIndex current_tile)
Handle payment for transfer of the given cargo packet.
Definition economy.cpp:1232
Vehicle * front
The front vehicle to do the payment of.
Money visual_transfer
The transfer credits to be shown.
Money visual_profit
The visual profit to show.
Money route_profit
The amount of money to add/remove from the bank account.
Specification of a cargo type.
Definition cargotype.h:77
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo type.
Definition cargotype.h:141
static IterateWrapper Iterate(size_t from=0)
Returns an iterable ensemble of all valid CargoSpec.
Definition cargotype.h:194
TownAcceptanceEffect town_acceptance_effect
The effect that delivering this cargo type has on towns. Also affects destination of subsidies.
Definition cargotype.h:89
CargoCallbackMasks callback_mask
Bitmask of cargo callbacks that have to be called.
Definition cargotype.h:92
bool IsValid() const
Tests for validity of this cargospec.
Definition cargotype.h:121
CargoArray delivered_cargo
The amount of delivered cargo.
TileIndex location_of_HQ
Northern tile of HQ; INVALID_TILE when there is none.
uint8_t months_of_bankruptcy
Number of months that the company is unable to pay its debts.
CompanyMask bankrupt_asked
which companies were asked about buying it?
int16_t bankrupt_timeout
If bigger than 0, amount of time to wait for an answer on an offer to buy this company.
CompanySettings settings
settings specific for each company
bool is_ai
If true, the company is (also) controlled by the computer (a NoAI program).
Money current_loan
Amount of money borrowed from the bank.
CompanyEconomyEntry cur_economy
Economic data of the company of this quarter.
std::array< CompanyEconomyEntry, MAX_HISTORY_QUARTERS > old_economy
Economic data of the company of the last MAX_HISTORY_QUARTERS quarters.
Money money
Money owned by the company.
uint8_t num_valid_stat_ent
Number of valid statistical entries in old_economy.
VehicleDefaultSettings vehicle
default settings for vehicles
Money GetMaxLoan() const
Calculate the max allowed loan for this company.
Data of the economy.
EngineMiscFlags misc_flags
Miscellaneous flags.
VehicleCallbackMasks callback_mask
Bitmask of vehicle callbacks that have to be called.
Action for finalizing a refit.
Definition economy.cpp:1431
std::span< const StationID > next_station
Next hops to reserve cargo for.
Definition economy.cpp:1434
CargoArray & consist_capleft
Capacities left in the consist.
Definition economy.cpp:1432
bool do_reserve
If the vehicle should reserve.
Definition economy.cpp:1435
FinalizeRefitAction(CargoArray &consist_capleft, Station *st, std::span< const StationID > next_station, bool do_reserve)
Create a finalizing action.
Definition economy.cpp:1444
bool operator()(Vehicle *v)
Reserve cargo from the station and update the remaining consist capacities with the vehicle's remaini...
Definition economy.cpp:1453
Station * st
Station to reserve cargo from.
Definition economy.cpp:1433
Dynamic data of a loaded NewGRF.
Definition newgrf.h:124
PriceMultipliers price_base_multipliers
Price base multipliers as set by the grf.
Definition newgrf.h:169
Struct about goals, current and completed.
Definition goal_base.h:22
StationCargoList cargo
The cargo packets of cargo waiting in this station.
Stores station stats for a single cargo.
bool HasRating() const
Does this cargo have a rating at this station?
uint8_t last_speed
Maximum speed (up to 255) of the last vehicle that tried to load this cargo.
uint8_t last_age
Age in years (up to 255) of the last vehicle that tried to load this cargo.
uint8_t time_since_pickup
Number of rating-intervals (up to 255) since the last vehicle tried to load this cargo.
States status
Status of this cargo, see State.
@ Acceptance
Set when the station accepts the cargo currently for final deliveries.
@ EverAccepted
Set when a vehicle ever delivered cargo to the station for final delivery.
@ Rating
This indicates whether a cargo has a rating at the station.
@ AcceptedBigtick
Set when cargo was delivered for final delivery during the current STATION_ACCEPTANCE_TICKS interval.
@ CurrentMonth
Set when cargo was delivered for final delivery this month.
const GoodsEntryData & GetData() const
Get optional cargo packet/flow data.
GoodsEntryData & GetOrCreateData()
Get optional cargo packet/flow data.
uint AvailableCount() const
Returns sum of cargo still available for loading at the station.
uint16_t cached_total_length
Length of the whole vehicle (valid only for the first engine).
bool IsMultiheaded() const
Check if the vehicle is a multiheaded engine.
static void CountVehicle(const Vehicle *v, int delta)
Update num_vehicle when adding or removing a vehicle.
static void CountEngine(const Vehicle *v, int delta)
Update num_engines when adding/removing an engine.
static void UpdateAutoreplace(CompanyID company)
Update autoreplace_defined and autoreplace_finished of all statistics of a company.
Group data.
Definition group.h:76
Defines the data structure for constructing industry.
IndustryCallbackMasks callback_mask
Bitmask of industry callbacks that have to be called.
uint16_t input_cargo_multiplier[INDUSTRY_NUM_INPUTS][INDUSTRY_NUM_OUTPUTS]
Input cargo multipliers (multiply amount of incoming cargo for the produced cargoes).
Defines the internal data of a functional industry.
Definition industry.h:64
IndustryType type
type of industry.
Definition industry.h:117
Owner exclusive_supplier
Which company has exclusive rights to deliver cargo (INVALID_OWNER = anyone).
Definition industry.h:132
ProducedCargoes produced
produced cargo slots
Definition industry.h:112
AcceptedCargoes accepted
accepted cargo slots
Definition industry.h:113
uint8_t was_cargo_delivered
flag that indicate this has been the closest industry chosen for cargo delivery by a station....
Definition industry.h:121
AcceptedCargoes::iterator GetCargoAccepted(CargoType cargo)
Get accepted cargo slot for a specific cargo type.
Definition industry.h:204
Action to check if a vehicle has no stored cargo.
Definition economy.cpp:1358
bool operator()(const Vehicle *v)
Checks if the vehicle has stored cargo.
Definition economy.cpp:1364
static IterateWrapper Iterate()
Returns an iterable ensemble of all Tiles.
Definition map_func.h:366
static uint LogX()
Logarithm of the map size along the X side.
Definition map_func.h:243
static uint LogY()
Logarithm of the map size along the y side.
Definition map_func.h:253
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition order_base.h:67
CargoType GetRefitCargo() const
Get the cargo to to refit to.
Definition order_base.h:128
bool IsFullLoadOrder() const
Is this order a OrderLoadType::FullLoad or OrderLoadType::FullLoadAny?
Definition order_base.h:136
OrderUnloadType GetUnloadType() const
How must the consist be unloaded?
Definition order_base.h:152
OrderLoadType GetLoadType() const
How must the consist be loaded?
Definition order_base.h:146
uint16_t GetTimetabledWait() const
Get the time in ticks a vehicle should wait at the destination or 0 if it's not timetabled.
Definition order_base.h:283
bool IsRefit() const
Is this order a refit order.
Definition order_base.h:114
static Pool::IterateWrapper< Vehicle > Iterate(size_t from=0)
static Company * Get(auto index)
static Company * GetIfValid(auto index)
Refit preparation action.
Definition economy.cpp:1374
CargoTypes & refit_mask
Bitmask of possible refit cargoes.
Definition economy.cpp:1376
PrepareRefitAction(CargoArray &consist_capleft, CargoTypes &refit_mask)
Create a refit preparation action.
Definition economy.cpp:1383
CargoArray & consist_capleft
Capacities left in the consist.
Definition economy.cpp:1375
bool operator()(const Vehicle *v)
Prepares for refitting of a vehicle, subtracting its free capacity from consist_capleft and adding th...
Definition economy.cpp:1392
Action for returning reserved cargo.
Definition economy.cpp:1404
Station * st
Station to give the returned cargo to.
Definition economy.cpp:1405
bool operator()(Vehicle *v)
Return all reserved cargo from a vehicle.
Definition economy.cpp:1420
ReturnCargoAction(Station *st, StationID next_one)
Construct a cargo return action.
Definition economy.cpp:1413
StationID next_hop
Next hop the cargo should be assigned to.
Definition economy.cpp:1406
Data structure for storing how the score is computed for a single score id.
A location from where cargo can come from (or go to).
Definition source_type.h:32
SourceType type
Type of source_id.
Definition source_type.h:37
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
static Station * Get(auto index)
Station data structure.
uint GetPlatformLength(TileIndex tile, DiagDirection dir) const override
Determines the REMAINING length of a platform, starting at (and including) the given tile.
Definition station.cpp:292
IndustryList industries_near
Cached list of industries near the station that can accept cargo,.
CargoTypes always_accepted
Bitmask of always accepted cargo types (by houses, HQs, industry tiles when industry doesn't accept c...
std::array< GoodsEntry, NUM_CARGO > goods
Goods at this station.
Struct about stories, current and completed.
Definition story_base.h:162
Struct about subsidies, offered and awarded.
HistoryData< AcceptedHistory > history
Histor data of accepted cargo.
Definition town.h:118
Town data structure.
Definition town.h:64
AcceptedCargo & GetOrCreateCargoAccepted(CargoType cargo)
Get or create the storage for an accepted cargo.
Definition town.h:160
CompanyID exclusivity
which company has exclusivity
Definition town.h:87
uint8_t exclusive_counter
months till the exclusivity expires
Definition town.h:88
EnumIndexArray< TransportedCargoStat< uint16_t >, TownAcceptanceEffect, TownAcceptanceEffect::End > received
Cargo statistics about received cargotypes.
Definition town.h:133
'Train' is either a loco or a wagon.
Definition train.h:97
Train * other_multiheaded_part
Link between the two ends of a multiheaded engine.
Definition train.h:105
uint16_t cached_max_speed
Maximum speed of the consist (minimum of the max speed of all vehicles in the consist).
uint16_t servint_aircraft
service interval for aircraft
uint16_t servint_roadveh
service interval for road vehicles
uint16_t servint_ships
service interval for ships
bool servint_ispercent
service intervals are in percents
uint16_t servint_trains
service interval for trains
Vehicle data structure.
CargoPayment * cargo_payment
The cargo payment we're currently in.
EngineID engine_type
The type of engine used for this vehicle.
int32_t z_pos
z coordinate.
const Engine * GetEngine() const
Retrieves the engine of the vehicle.
Definition vehicle.cpp:749
virtual TileIndex GetCargoTile() const
Tile to use for economic calculations when moving cargo into or out of this vehicle.
VehicleCargoList cargo
The cargo this vehicle is carrying.
uint16_t cargo_cap
total capacity
Vehicle * GetFirstEnginePart()
Get the first part of an articulated engine.
Money profit_this_year
Profit this year << 8, low 8 bits are fract.
bool HasArticulatedPart() const
Check if an engine has an articulated part.
VehStates vehstatus
Status.
void GetNextStoppingStation(std::vector< StationID > &next_station) const
Get the next station the vehicle will stop at.
CargoType cargo_type
type of cargo this vehicle is carrying
Vehicle * First() const
Get the first vehicle of this vehicle chain.
Order current_order
The current order (+ status, like: loading).
Vehicle * Next() const
Get the next vehicle of this vehicle.
int32_t y_pos
y coordinate.
int32_t x_pos
x coordinate.
OrderList * orders
Pointer to the order list for this vehicle.
Vehicle * GetMovingFront() const
Get the moving front of the vehicle chain.
VehicleCache vcache
Cache of often used vehicle values.
GroundVehicleCache * GetGroundVehicleCache()
Access the ground vehicle cache of the vehicle.
Definition vehicle.cpp:3209
uint16_t load_unload_ticks
Ticks to wait before starting next cycle.
uint16_t cur_speed
current speed
TextEffectID fill_percent_te_id
a text-effect id to a loading indicator object
Vehicle * Previous() const
Get the previous vehicle of this vehicle.
TileIndex tile
Current tile index.
StationID last_station_visited
The last station we stopped at.
TimerGameCalendar::Year build_year
Year the vehicle has been built.
Owner owner
Which company owns the vehicle?
Representation of a waypoint.
void RebuildSubsidisedSourceAndDestinationCache()
Perform a full rebuild of the subsidies cache.
Definition subsidy.cpp:104
bool CheckSubsidised(CargoType cargo_type, CompanyID company, Source src, const Station *st)
Tests whether given delivery is subsidised and possibly awards the subsidy to delivering company.
Definition subsidy.cpp:494
Subsidy base class.
Functions related to subsidies.
static bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
bool IsTileOwner(Tile tile, Owner owner)
Checks if a tile belongs to the given owner.
Definition tile_map.h:214
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
Definition tile_type.h:92
static constexpr uint TILE_SIZE
Tile size in world coordinates.
Definition tile_type.h:15
@ Station
A tile of a station or airport.
Definition tile_type.h:54
@ Railway
A tile with railway.
Definition tile_type.h:50
Definition of Interval and OneShot timers.
Definition of the game-calendar-timer.
Definition of the game-economy-timer.
Base of the town class.
static constexpr int RATING_INITIAL
initial rating
Definition town_type.h:44
Track
These are used to specify a single track.
Definition track_type.h:19
Base for the train class.
uint8_t CalcPercentVehicleFilled(const Vehicle *front, StringID *colour)
Calculates how full a vehicle is.
Definition vehicle.cpp:1504
Command definitions for vehicles.
Functions related to vehicles.
static const TimerGameEconomy::Date VEHICLE_PROFIT_MIN_AGE
Only vehicles older than this have a meaningful profit.
bool IsCompanyBuildableVehicleType(VehicleType type)
Is the given vehicle type buildable by a company?
WindowClass GetWindowClassForVehicleType(VehicleType vt)
Get WindowClass for vehicle list of given vehicle type.
Definition vehicle_gui.h:97
@ Ship
Ship vehicle type.
@ Aircraft
Aircraft vehicle type.
@ Road
Road vehicle type.
@ Train
Train vehicle type.
@ NewCargo
Affected vehicle only: Vehicle is loaded with cargo, after it was empty.
@ Empty
Front vehicle only: Entire consist is empty.
EnumIndexArray< T, VehicleType, Tend > VehicleTypeIndexArray
Array with VehicleType as index.
Functions related to water management.
Money CanalMaintenanceCost(uint32_t num)
Calculates the maintenance cost of a number of canal tiles.
Definition water.h:53
Base of waypoints.
void ChangeWindowOwner(Owner old_owner, Owner new_owner)
Change the owner of all the windows one company can take over from another company in the case of a c...
Definition window.cpp:1253
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting).
Definition window.cpp:3226
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
Definition window.cpp:3318
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting).
Definition window.cpp:3196
void InvalidateWindowClassesData(WindowClass cls, int data, bool gui_scope)
Mark window data of all windows of a given class as invalid (in need of re-computing) Note that by de...
Definition window.cpp:3336