OpenTTD Source 20250529-master-g10c159a79f
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 <http://www.gnu.org/licenses/>.
6 */
7
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 "timer/timer.h"
59
60#include "table/strings.h"
61#include "table/pricebase.h"
62
63#include "safeguards.h"
64
65
66/* Initialize the cargo payment-pool */
67CargoPaymentPool _cargo_payment_pool("CargoPayment");
69
70
81static inline int32_t BigMulS(const int32_t a, const int32_t b, const uint8_t shift)
82{
83 return (int32_t)((int64_t)a * (int64_t)b >> shift);
84}
85
86typedef std::vector<Industry *> SmallIndustryList;
87
92 { 120, 100}, // SCORE_VEHICLES
93 { 80, 100}, // SCORE_STATIONS
94 { 10000, 100}, // SCORE_MIN_PROFIT
95 { 50000, 50}, // SCORE_MIN_INCOME
96 { 100000, 100}, // SCORE_MAX_INCOME
97 { 40000, 400}, // SCORE_DELIVERED
98 { 8, 50}, // SCORE_CARGO
99 {10000000, 50}, // SCORE_MONEY
100 { 250000, 50}, // SCORE_LOAN
101 { 0, 0} // SCORE_TOTAL
102};
103
105Economy _economy;
106Prices _price;
107static PriceMultipliers _price_base_multiplier;
108
116{
117 Owner owner = c->index;
118
119 uint num = 0;
120
121 for (const Station *st : Station::Iterate()) {
122 if (st->owner == owner) num += st->facilities.Count();
123 }
124
125 Money value = num * _price[PR_STATION_VALUE] * 25;
126
127 for (const Vehicle *v : Vehicle::Iterate()) {
128 if (v->owner != owner) continue;
129
130 if (v->type == VEH_TRAIN ||
131 v->type == VEH_ROAD ||
132 (v->type == VEH_AIRCRAFT && Aircraft::From(v)->IsNormalAircraft()) ||
133 v->type == VEH_SHIP) {
134 value += v->value * 3 >> 1;
135 }
136 }
137
138 return value;
139}
140
150Money CalculateCompanyValue(const Company *c, bool including_loan)
151{
153
154 /* Add real money value */
155 if (including_loan) value -= c->current_loan;
156 value += c->money;
157
158 return std::max<Money>(value, 1);
159}
160
178{
180
181 value += c->current_loan;
182 /* Negative balance is basically a loan. */
183 if (c->money < 0) {
184 value += -c->money;
185 }
186
187 for (int quarter = 0; quarter < 4; quarter++) {
188 value += std::max<Money>(c->old_economy[quarter].income + c->old_economy[quarter].expenses, 0) * 2;
189 }
190
191 return std::max<Money>(value, 1);
192}
193
203{
204 Owner owner = c->index;
205 int score = 0;
206
207 _score_part[owner].fill(0);
208
209 /* Count vehicles */
210 {
211 Money min_profit = 0;
212 bool min_profit_first = true;
213 uint num = 0;
214
215 for (const Vehicle *v : Vehicle::Iterate()) {
216 if (v->owner != owner) continue;
217 if (IsCompanyBuildableVehicleType(v->type) && v->IsPrimaryVehicle()) {
218 if (v->profit_last_year > 0) num++; // For the vehicle score only count profitable vehicles
219 if (v->economy_age > VEHICLE_PROFIT_MIN_AGE) {
220 /* Find the vehicle with the lowest amount of profit */
221 if (min_profit_first || min_profit > v->profit_last_year) {
222 min_profit = v->profit_last_year;
223 min_profit_first = false;
224 }
225 }
226 }
227 }
228
229 min_profit >>= 8; // remove the fract part
230
231 _score_part[owner][SCORE_VEHICLES] = num;
232 /* Don't allow negative min_profit to show */
233 if (min_profit > 0) {
234 _score_part[owner][SCORE_MIN_PROFIT] = min_profit;
235 }
236 }
237
238 /* Count stations */
239 {
240 uint num = 0;
241 for (const Station *st : Station::Iterate()) {
242 /* Only count stations that are actually serviced */
243 if (st->owner == owner && (st->time_since_load <= 20 || st->time_since_unload <= 20)) num += st->facilities.Count();
244 }
245 _score_part[owner][SCORE_STATIONS] = num;
246 }
247
248 /* Generate statistics depending on recent income statistics */
249 {
250 int numec = std::min<uint>(c->num_valid_stat_ent, 12u);
251 if (numec != 0) {
252 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; }));
253
254 if (min_income > 0) _score_part[owner][SCORE_MIN_INCOME] = min_income;
255 _score_part[owner][SCORE_MAX_INCOME] = max_income;
256 }
257 }
258
259 /* Generate score depending on amount of transported cargo */
260 {
261 int numec = std::min<uint>(c->num_valid_stat_ent, 4u);
262 if (numec != 0) {
263 OverflowSafeInt64 total_delivered = 0;
264 for (auto &ce : c->old_economy | std::views::take(numec)) total_delivered += ce.delivered_cargo.GetSum<OverflowSafeInt64>();
265
266 _score_part[owner][SCORE_DELIVERED] = total_delivered;
267 }
268 }
269
270 /* Generate score for variety of cargo */
271 {
272 _score_part[owner][SCORE_CARGO] = c->old_economy[0].delivered_cargo.GetCount();
273 }
274
275 /* Generate score for company's money */
276 {
277 if (c->money > 0) {
278 _score_part[owner][SCORE_MONEY] = c->money;
279 }
280 }
281
282 /* Generate score for loan */
283 {
284 _score_part[owner][SCORE_LOAN] = _score_info[SCORE_LOAN].needed - c->current_loan;
285 }
286
287 /* Now we calculate the score for each item.. */
288 {
289 int total_score = 0;
290 int s;
291 score = 0;
292 for (ScoreID i = SCORE_BEGIN; i < SCORE_END; i++) {
293 /* Skip the total */
294 if (i == SCORE_TOTAL) continue;
295 /* Check the score */
296 s = Clamp<int64_t>(_score_part[owner][i], 0, _score_info[i].needed) * _score_info[i].score / _score_info[i].needed;
297 score += s;
298 total_score += _score_info[i].score;
299 }
300
301 _score_part[owner][SCORE_TOTAL] = score;
302
303 /* We always want the score scaled to SCORE_MAX (1000) */
304 if (total_score != SCORE_MAX) score = score * SCORE_MAX / total_score;
305 }
306
307 if (update) {
308 c->old_economy[0].performance_history = score;
310 c->old_economy[0].company_value = CalculateCompanyValue(c);
311 }
312
314 return score;
315}
316
322void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
323{
324 /* We need to set _current_company to old_owner before we try to move
325 * the client. This is needed as it needs to know whether "you" really
326 * are the current local company. */
327 Backup<CompanyID> cur_company(_current_company, old_owner);
328 /* In all cases, make spectators of clients connected to that company */
330 if (old_owner == _local_company) {
331 /* Single player cheated to AI company.
332 * There are no spectators in singleplayer mode, so we must pick some other company. */
333 assert(!_networking);
335 for (const Company *c : Company::Iterate()) {
336 if (c->index != old_owner) {
337 SetLocalCompany(c->index);
338 break;
339 }
340 }
341 cur_company2.Restore();
342 assert(old_owner != _local_company);
343 }
344
345 assert(old_owner != new_owner);
346
347 /* Temporarily increase the company's money, to be sure that
348 * removing their property doesn't fail because of lack of money.
349 * Not too drastically though, because it could overflow */
350 if (new_owner == INVALID_OWNER) {
351 Company::Get(old_owner)->money = UINT64_MAX >> 2; // jackpot ;p
352 }
353
354 for (Subsidy *s : Subsidy::Iterate()) {
355 if (s->awarded == old_owner) {
356 if (new_owner == INVALID_OWNER) {
357 delete s;
358 } else {
359 s->awarded = new_owner;
360 }
361 }
362 }
364
365 /* Take care of rating and transport rights in towns */
366 for (Town *t : Town::Iterate()) {
367 /* If a company takes over, give the ratings to that company. */
368 if (new_owner != INVALID_OWNER) {
369 if (t->have_ratings.Test(old_owner)) {
370 if (t->have_ratings.Test(new_owner)) {
371 /* use max of the two ratings. */
372 t->ratings[new_owner] = std::max(t->ratings[new_owner], t->ratings[old_owner]);
373 } else {
374 t->have_ratings.Set(new_owner);
375 t->ratings[new_owner] = t->ratings[old_owner];
376 }
377 }
378 }
379
380 /* Reset the ratings for the old owner */
381 t->ratings[old_owner] = RATING_INITIAL;
382 t->have_ratings.Reset(old_owner);
383
384 /* Transfer exclusive rights */
385 if (t->exclusive_counter > 0 && t->exclusivity == old_owner) {
386 if (new_owner != INVALID_OWNER) {
387 t->exclusivity = new_owner;
388 } else {
389 t->exclusive_counter = 0;
390 t->exclusivity = CompanyID::Invalid();
391 }
392 }
393 }
394
395 {
396 for (Vehicle *v : Vehicle::Iterate()) {
397 if (v->owner == old_owner && IsCompanyBuildableVehicleType(v->type)) {
398 if (new_owner == INVALID_OWNER) {
399 if (v->Previous() == nullptr) delete v;
400 } else {
401 if (v->IsEngineCountable()) GroupStatistics::CountEngine(v, -1);
402 if (v->IsPrimaryVehicle()) GroupStatistics::CountVehicle(v, -1);
403 }
404 }
405 }
406 }
407
408 /* In all cases clear replace engine rules.
409 * Even if it was copied, it could interfere with new owner's rules */
411
412 if (new_owner == INVALID_OWNER) {
413 RemoveAllGroupsForCompany(old_owner);
414 } else {
415 Company *c = Company::Get(old_owner);
416 for (Group *g : Group::Iterate()) {
417 if (g->owner == old_owner) {
418 g->owner = new_owner;
419 g->number = c->freegroups.UseID(c->freegroups.NextID());
420 }
421 }
422 }
423
424 {
425 Company *new_company = new_owner == INVALID_OWNER ? nullptr : Company::Get(new_owner);
426
427 /* Override company settings to new company defaults in case we need to convert them.
428 * This is required as the CmdChangeServiceInt doesn't copy the supplied value when it is non-custom
429 */
430 if (new_owner != INVALID_OWNER) {
431 Company *old_company = Company::Get(old_owner);
432
434 old_company->settings.vehicle.servint_trains = new_company->settings.vehicle.servint_trains;
436 old_company->settings.vehicle.servint_ships = new_company->settings.vehicle.servint_ships;
438 }
439
440 for (Vehicle *v : Vehicle::Iterate()) {
441 if (v->owner == old_owner && IsCompanyBuildableVehicleType(v->type)) {
442 assert(new_owner != INVALID_OWNER);
443
444 /* Correct default values of interval settings while maintaining custom set ones.
445 * This prevents invalid values on mismatching company defaults being accepted.
446 */
447 if (!v->ServiceIntervalIsCustom()) {
448 /* Technically, passing the interval is not needed as the command will query the default value itself.
449 * However, do not rely on that behaviour.
450 */
451 int interval = CompanyServiceInterval(new_company, v->type);
453 }
454
455 v->owner = new_owner;
456
457 /* Owner changes, clear cache */
458 v->colourmap = PAL_NONE;
459 v->InvalidateNewGRFCache();
460
461 if (v->IsEngineCountable()) {
463 }
464 if (v->IsPrimaryVehicle()) {
466 auto &unitidgen = new_company->freeunits[v->type];
467 v->unitnumber = unitidgen.UseID(unitidgen.NextID());
468 }
469
470 /* Invalidate the vehicle's cargo payment "owner cache". */
471 if (v->cargo_payment != nullptr) v->cargo_payment->owner = nullptr;
472 }
473 }
474
475 if (new_owner != INVALID_OWNER) GroupStatistics::UpdateAutoreplace(new_owner);
476 }
477
478 /* Change ownership of tiles */
479 {
480 for (const auto tile : Map::Iterate()) {
481 ChangeTileOwner(tile, old_owner, new_owner);
482 }
483
484 if (new_owner != INVALID_OWNER) {
485 /* Update all signals because there can be new segment that was owned by two companies
486 * and signals were not propagated
487 * Similar with crossings - it is needed to bar crossings that weren't before
488 * because of different owner of crossing and approaching train */
489 for (const auto tile : Map::Iterate()) {
490 if (IsTileType(tile, MP_RAILWAY) && IsTileOwner(tile, new_owner) && HasSignals(tile)) {
491 TrackBits tracks = GetTrackBits(tile);
492 do { // there may be two tracks with signals for TRACK_BIT_HORZ and TRACK_BIT_VERT
493 Track track = RemoveFirstTrack(&tracks);
494 if (HasSignalOnTrack(tile, track)) AddTrackToSignalBuffer(tile, track, new_owner);
495 } while (tracks != TRACK_BIT_NONE);
496 } else if (IsLevelCrossingTile(tile) && IsTileOwner(tile, new_owner)) {
498 }
499 }
500 }
501
502 /* update signals in buffer */
504 }
505
506 /* Add airport infrastructure count of the old company to the new one. */
507 if (new_owner != INVALID_OWNER) Company::Get(new_owner)->infrastructure.airport += Company::Get(old_owner)->infrastructure.airport;
508
509 /* convert owner of stations (including deleted ones, but excluding buoys) */
510 for (Station *st : Station::Iterate()) {
511 if (st->owner == old_owner) {
512 /* if a company goes bankrupt, set owner to OWNER_NONE so the sign doesn't disappear immediately
513 * also, drawing station window would cause reading invalid company's colour */
514 st->owner = new_owner == INVALID_OWNER ? OWNER_NONE : new_owner;
515 }
516 }
517
518 /* do the same for waypoints (we need to do this here so deleted waypoints are converted too) */
519 for (Waypoint *wp : Waypoint::Iterate()) {
520 if (wp->owner == old_owner) {
521 wp->owner = new_owner == INVALID_OWNER ? OWNER_NONE : new_owner;
522 }
523 }
524
525 for (Sign *si : Sign::Iterate()) {
526 if (si->owner == old_owner) si->owner = new_owner == INVALID_OWNER ? OWNER_NONE : new_owner;
527 }
528
529 /* Remove Game Script created Goals, CargoMonitors and Story pages. */
530 for (Goal *g : Goal::Iterate()) {
531 if (g->company == old_owner) delete g;
532 }
533
536
537 for (StoryPage *sp : StoryPage::Iterate()) {
538 if (sp->company == old_owner) delete sp;
539 }
540
541 /* Change colour of existing windows */
542 if (new_owner != INVALID_OWNER) ChangeWindowOwner(old_owner, new_owner);
543
544 cur_company.Restore();
545
547}
548
554{
555 /* If "Infinite money" setting is on, companies should not go bankrupt. */
557
558 /* If the company has money again, it does not go bankrupt */
559 if (c->money - c->current_loan >= -c->GetMaxLoan()) {
560 int previous_months_of_bankruptcy = CeilDiv(c->months_of_bankruptcy, 3);
563 if (previous_months_of_bankruptcy != 0) CompanyAdminUpdate(c);
564 return;
565 }
566
568
569 switch (c->months_of_bankruptcy) {
570 /* All the boring cases (months) with a bad balance where no action is taken */
571 case 0:
572 case 1:
573 case 2:
574 case 3:
575
576 case 5:
577 case 6:
578
579 case 8:
580 case 9:
581 break;
582
583 /* Warn about bankruptcy after 3 months */
584 case 4: {
585 auto cni = std::make_unique<CompanyNewsInformation>(STR_NEWS_COMPANY_IN_TROUBLE_TITLE, c);
586 EncodedString headline = GetEncodedString(STR_NEWS_COMPANY_IN_TROUBLE_DESCRIPTION, cni->company_name);
587 AddCompanyNewsItem(std::move(headline), std::move(cni));
588 AI::BroadcastNewEvent(new ScriptEventCompanyInTrouble(c->index));
589 Game::NewEvent(new ScriptEventCompanyInTrouble(c->index));
590 break;
591 }
592
593 /* Offer company for sale after 6 months */
594 case 7: {
595 /* Don't consider the loan */
596 Money val = CalculateCompanyValue(c, false);
597
598 c->bankrupt_value = val;
599 c->bankrupt_asked = CompanyMask{}.Set(c->index); // Don't ask the owner
600 c->bankrupt_timeout = 0;
601
602 /* The company assets should always have some value */
603 assert(c->bankrupt_value > 0);
604 break;
605 }
606
607 /* Bankrupt company after 6 months (if the company has no value) or latest
608 * after 9 months (if it still had value after 6 months) */
609 default:
610 case 10: {
611 if (!_networking && _local_company == c->index) {
612 /* If we are in singleplayer mode, leave the company playing. Eg. there
613 * is no THE-END, otherwise mark the client as spectator to make sure
614 * they are no longer in control of this company. However... when you
615 * join another company (cheat) the "unowned" company can bankrupt. */
616 c->bankrupt_asked.Set();
617 break;
618 }
619
620 /* Actually remove the company, but not when we're a network client.
621 * In case of network clients we will be getting a command from the
622 * server. It is done in this way as we are called from the
623 * StateGameLoop which can't change the current company, and thus
624 * updating the local company triggers an assert later on. In the
625 * case of a network game the command will be processed at a time
626 * that changing the current company is okay. In case of single
627 * player we are sure (the above check) that we are not the local
628 * company and thus we won't be moved. */
631 return;
632 }
633 break;
634 }
635 }
636
638}
639
645{
646 /* Check for bankruptcy each month */
647 for (Company *c : Company::Iterate()) {
649 }
650
652
653 /* Pay Infrastructure Maintenance, if enabled */
655 /* Improved monthly infrastructure costs. */
656 for (const Company *c : Company::Iterate()) {
657 cur_company.Change(c->index);
658
660 uint32_t rail_total = c->infrastructure.GetRailTotal();
661 for (RailType rt = RAILTYPE_BEGIN; rt < RAILTYPE_END; rt++) {
662 if (c->infrastructure.rail[rt] != 0) cost.AddCost(RailMaintenanceCost(rt, c->infrastructure.rail[rt], rail_total));
663 }
664 cost.AddCost(SignalMaintenanceCost(c->infrastructure.signal));
665 uint32_t road_total = c->infrastructure.GetRoadTotal();
666 uint32_t tram_total = c->infrastructure.GetTramTotal();
667 for (RoadType rt = ROADTYPE_BEGIN; rt < ROADTYPE_END; rt++) {
668 if (c->infrastructure.road[rt] != 0) cost.AddCost(RoadMaintenanceCost(rt, c->infrastructure.road[rt], RoadTypeIsRoad(rt) ? road_total : tram_total));
669 }
670 cost.AddCost(CanalMaintenanceCost(c->infrastructure.water));
671 cost.AddCost(StationMaintenanceCost(c->infrastructure.station));
672 cost.AddCost(AirportMaintenanceCost(c->index));
673
675 }
676 }
677 cur_company.Restore();
678
679 /* Only run the economic statistics and update company stats every 3rd economy month (1st of quarter). */
680 if (!HasBit(1 << 0 | 1 << 3 | 1 << 6 | 1 << 9, TimerGameEconomy::month)) return;
681
682 for (Company *c : Company::Iterate()) {
683 /* Drop the oldest history off the end */
684 std::copy_backward(c->old_economy.data(), c->old_economy.data() + MAX_HISTORY_QUARTERS - 1, c->old_economy.data() + MAX_HISTORY_QUARTERS);
685 c->old_economy[0] = c->cur_economy;
686 c->cur_economy = {};
687
688 if (c->num_valid_stat_ent != MAX_HISTORY_QUARTERS) c->num_valid_stat_ent++;
689
691 if (c->block_preview != 0) c->block_preview--;
692 }
693
700}
701
707bool AddInflation(bool check_year)
708{
709 /* The cargo payment inflation differs from the normal inflation, so the
710 * relative amount of money you make with a transport decreases slowly over
711 * the 170 years. After a few hundred years we reach a level in which the
712 * games will become unplayable as the maximum income will be less than
713 * the minimum running cost.
714 *
715 * Furthermore there are a lot of inflation related overflows all over the
716 * place. Solving them is hardly possible because inflation will always
717 * reach the overflow threshold some day. So we'll just perform the
718 * inflation mechanism during the first 170 years (the amount of years that
719 * one had in the original TTD) and stop doing the inflation after that
720 * because it only causes problems that can't be solved nicely and the
721 * inflation doesn't add anything after that either; it even makes playing
722 * it impossible due to the diverging cost and income rates.
723 */
724 if (check_year && (TimerGameCalendar::year < CalendarTime::ORIGINAL_BASE_YEAR || TimerGameCalendar::year >= CalendarTime::ORIGINAL_MAX_YEAR)) return true;
725
726 if (_economy.inflation_prices == MAX_INFLATION || _economy.inflation_payment == MAX_INFLATION) return true;
727
728 /* Approximation for (100 + infl_amount)% ** (1 / 12) - 100%
729 * scaled by 65536
730 * 12 -> months per year
731 * This is only a good approximation for small values
732 */
733 _economy.inflation_prices += (_economy.inflation_prices * _economy.infl_amount * 54) >> 16;
734 _economy.inflation_payment += (_economy.inflation_payment * _economy.infl_amount_pr * 54) >> 16;
735
738
739 return false;
740}
741
746{
747 /* Setup maximum loan as a rounded down multiple of LOAN_INTERVAL. */
748 _economy.max_loan = ((uint64_t)_settings_game.difficulty.max_loan * _economy.inflation_prices >> 16) / LOAN_INTERVAL * LOAN_INTERVAL;
749
750 /* Setup price bases */
751 for (Price i = PR_BEGIN; i < PR_END; i++) {
752 Money price = _price_base_specs[i].start_price;
753
754 /* Apply difficulty settings */
755 uint mod = 1;
756 switch (_price_base_specs[i].category) {
757 case PCAT_RUNNING:
759 break;
760
763 break;
764
765 default: break;
766 }
767 switch (mod) {
768 case 0: price *= 6; break;
769 case 1: price *= 8; break; // normalised to 1 below
770 case 2: price *= 9; break;
771 default: NOT_REACHED();
772 }
773
774 /* Apply inflation */
775 price = (int64_t)price * _economy.inflation_prices;
776
777 /* Apply newgrf modifiers, remove fractional part of inflation, and normalise on medium difficulty. */
778 int shift = _price_base_multiplier[i] - 16 - 3;
779 if (shift >= 0) {
780 price <<= shift;
781 } else {
782 price >>= -shift;
783 }
784
785 /* Make sure the price does not get reduced to zero.
786 * Zero breaks quite a few commands that use a zero
787 * cost to see whether something got changed or not
788 * and based on that cause an error. When the price
789 * is zero that fails even when things are done. */
790 if (price == 0) {
791 price = Clamp(_price_base_specs[i].start_price, -1, 1);
792 /* No base price should be zero, but be sure. */
793 assert(price != 0);
794 }
795 /* Store value */
796 _price[i] = price;
797 }
798
799 /* Setup cargo payment */
800 for (CargoSpec *cs : CargoSpec::Iterate()) {
801 cs->current_payment = (cs->initial_payment * (int64_t)_economy.inflation_payment) >> 16;
802 }
803
809}
810
813{
815 for (const Company *c : Company::Iterate()) {
816 cur_company.Change(c->index);
817
818 /* Over a year the paid interest should be "loan * interest percentage",
819 * but... as that number is likely not dividable by 12 (pay each month),
820 * one needs to account for that in the monthly fee calculations.
821 *
822 * To easily calculate what one should pay "this" month, you calculate
823 * what (total) should have been paid up to this month and you subtract
824 * whatever has been paid in the previous months. This will mean one month
825 * it'll be a bit more and the other it'll be a bit less than the average
826 * monthly fee, but on average it will be exact.
827 *
828 * In order to prevent cheating or abuse (just not paying interest by not
829 * taking a loan) we make companies pay interest on negative cash as well,
830 * except if infinite money is enabled.
831 */
832 Money yearly_fee = c->current_loan * _economy.interest_rate / 100;
833 Money available_money = GetAvailableMoney(c->index);
834 if (available_money < 0) {
835 yearly_fee += -available_money * _economy.interest_rate / 100;
836 }
837 Money up_to_previous_month = yearly_fee * TimerGameEconomy::month / 12;
838 Money up_to_this_month = yearly_fee * (TimerGameEconomy::month + 1) / 12;
839
840 SubtractMoneyFromCompany(CommandCost(EXPENSES_LOAN_INTEREST, up_to_this_month - up_to_previous_month));
841
842 SubtractMoneyFromCompany(CommandCost(EXPENSES_OTHER, _price[PR_STATION_VALUE] >> 2));
843 }
844 cur_company.Restore();
845}
846
847static void HandleEconomyFluctuations()
848{
850 /* When economy is Fluctuating, decrease counter */
851 _economy.fluct--;
852 } else if (EconomyIsInRecession()) {
853 /* When it's Steady and we are in recession, end it now */
854 _economy.fluct = -12;
855 } else {
856 /* No need to do anything else in other cases */
857 return;
858 }
859
860 if (_economy.fluct == 0) {
861 _economy.fluct = -(int)GB(Random(), 0, 2);
862 AddNewsItem(GetEncodedString(STR_NEWS_BEGIN_OF_RECESSION), NewsType::Economy, NewsStyle::Normal, {});
863 } else if (_economy.fluct == -12) {
864 _economy.fluct = GB(Random(), 0, 8) + 312;
865 AddNewsItem(GetEncodedString(STR_NEWS_END_OF_RECESSION), NewsType::Economy, NewsStyle::Normal, {});
866 }
867}
868
869
874{
875 _price_base_multiplier.fill(0);
876}
877
885void SetPriceBaseMultiplier(Price price, int factor)
886{
887 assert(price < PR_END);
888 _price_base_multiplier[price] = Clamp(factor, MIN_PRICE_MODIFIER, MAX_PRICE_MODIFIER);
889}
890
895void StartupIndustryDailyChanges(bool init_counter)
896{
897 uint map_size = Map::LogX() + Map::LogY();
898 /* After getting map size, it needs to be scaled appropriately and divided by 31,
899 * which stands for the days in a month.
900 * Using just 31 will make it so that a monthly reset (based on the real number of days of that month)
901 * would not be needed.
902 * Since it is based on "fractional parts", the leftover days will not make much of a difference
903 * on the overall total number of changes performed */
904 _economy.industry_daily_increment = (1 << map_size) / 31;
905
906 if (init_counter) {
907 /* A new game or a savegame from an older version will require the counter to be initialized */
909 }
910}
911
912void StartupEconomy()
913{
916 _economy.infl_amount_pr = std::max(0, _settings_game.difficulty.initial_interest - 1);
917 _economy.fluct = GB(Random(), 0, 8) + 168;
918
920 /* Apply inflation that happened before our game start year. */
922 for (int i = 0; i < months; i++) {
923 AddInflation(false);
924 }
925 }
926
927 /* Set up prices */
929
930 StartupIndustryDailyChanges(true); // As we are starting a new game, initialize the counter too
931
932}
933
943
952Money GetPrice(Price index, uint cost_factor, const GRFFile *grf_file, int shift)
953{
954 if (index >= PR_END) return 0;
955
956 Money cost = _price[index] * cost_factor;
957 if (grf_file != nullptr) shift += grf_file->price_base_multipliers[index];
958
959 if (shift >= 0) {
960 cost <<= shift;
961 } else {
962 cost >>= -shift;
963 }
964
965 return cost;
966}
967
968Money GetTransportedGoodsIncome(uint num_pieces, uint dist, uint16_t transit_periods, CargoType cargo_type)
969{
970 const CargoSpec *cs = CargoSpec::Get(cargo_type);
971 if (!cs->IsValid()) {
972 /* User changed newgrfs and some vehicle still carries some cargo which is no longer available. */
973 return 0;
974 }
975
976 /* Use callback to calculate cargo profit, if available */
978 uint32_t var18 = ClampTo<uint16_t>(dist) | (ClampTo<uint8_t>(num_pieces) << 16) | (ClampTo<uint8_t>(transit_periods) << 24);
979 uint16_t callback = GetCargoCallback(CBID_CARGO_PROFIT_CALC, 0, var18, cs);
980 if (callback != CALLBACK_FAILED) {
981 int result = GB(callback, 0, 14);
982
983 /* Simulate a 15 bit signed value */
984 if (HasBit(callback, 14)) result -= 0x4000;
985
986 /* "The result should be a signed multiplier that gets multiplied
987 * by the amount of cargo moved and the price factor, then gets
988 * divided by 8192." */
989 return result * num_pieces * cs->current_payment / 8192;
990 }
991 }
992
993 static const int MIN_TIME_FACTOR = 31;
994 static const int MAX_TIME_FACTOR = 255;
995 static const int TIME_FACTOR_FRAC_BITS = 4;
996 static const int TIME_FACTOR_FRAC = 1 << TIME_FACTOR_FRAC_BITS;
997
998 const int periods1 = cs->transit_periods[0];
999 const int periods2 = cs->transit_periods[1];
1000 const int periods_over_periods1 = std::max(transit_periods - periods1, 0);
1001 const int periods_over_periods2 = std::max(periods_over_periods1 - periods2, 0);
1002 int periods_over_max = MIN_TIME_FACTOR - MAX_TIME_FACTOR;
1003 if (periods2 > -periods_over_max) {
1004 periods_over_max += transit_periods - periods1;
1005 } else {
1006 periods_over_max += 2 * (transit_periods - periods1) - periods2;
1007 }
1008
1009 /*
1010 * The time factor is calculated based on the time it took
1011 * (transit_periods) compared two cargo-depending values. The
1012 * range is divided into four parts:
1013 *
1014 * - constant for fast transits
1015 * - linear decreasing with time with a slope of -1 for medium transports
1016 * - linear decreasing with time with a slope of -2 for slow transports
1017 * - after hitting MIN_TIME_FACTOR, the time factor will be asymptotically decreased to a limit of 1 with a scaled 1/(x+1) function.
1018 *
1019 */
1020 if (periods_over_max > 0) {
1021 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.
1022 return BigMulS(dist * time_factor * num_pieces, cs->current_payment, 21 + TIME_FACTOR_FRAC_BITS);
1023 } else {
1024 const int time_factor = std::max(MAX_TIME_FACTOR - periods_over_periods1 - periods_over_periods2, MIN_TIME_FACTOR);
1025 return BigMulS(dist * time_factor * num_pieces, cs->current_payment, 21);
1026 }
1027}
1028
1030static SmallIndustryList _cargo_delivery_destinations;
1031
1042static uint DeliverGoodsToIndustry(const Station *st, CargoType cargo_type, uint num_pieces, IndustryID source, CompanyID company)
1043{
1044 /* Find the nearest industrytile to the station sign inside the catchment area, whose industry accepts the cargo.
1045 * This fails in three cases:
1046 * 1) The station accepts the cargo because there are enough houses around it accepting the cargo.
1047 * 2) The industries in the catchment area temporarily reject the cargo, and the daily station loop has not yet updated station acceptance.
1048 * 3) The results of callbacks CBID_INDUSTRY_REFUSE_CARGO and CBID_INDTILE_CARGO_ACCEPTANCE are inconsistent. (documented behaviour)
1049 */
1050
1051 uint accepted = 0;
1052
1053 for (const auto &i : st->industries_near) {
1054 if (num_pieces == 0) break;
1055
1056 Industry *ind = i.industry;
1057 if (ind->index == source) continue;
1058
1059 auto it = ind->GetCargoAccepted(cargo_type);
1060 /* Check if matching cargo has been found */
1061 if (it == std::end(ind->accepted)) continue;
1062
1063 /* Check if industry temporarily refuses acceptance */
1064 if (IndustryTemporarilyRefusesCargo(ind, cargo_type)) continue;
1065
1066 if (ind->exclusive_supplier != INVALID_OWNER && ind->exclusive_supplier != st->owner) continue;
1067
1068 /* Insert the industry into _cargo_delivery_destinations, if not yet contained */
1070
1071 uint amount = std::min(num_pieces, 0xFFFFu - it->waiting);
1072 it->waiting += amount;
1073 it->last_accepted = TimerGameEconomy::date;
1074 num_pieces -= amount;
1075 accepted += amount;
1076
1077 /* Update the cargo monitor. */
1078 AddCargoDelivery(cargo_type, company, amount, {source, SourceType::Industry}, st, ind->index);
1079 }
1080
1081 return accepted;
1082}
1083
1096static Money DeliverGoods(int num_pieces, CargoType cargo_type, StationID dest, uint distance, uint16_t periods_in_transit, Company *company, Source src)
1097{
1098 assert(num_pieces > 0);
1099
1100 Station *st = Station::Get(dest);
1101
1102 /* Give the goods to the industry. */
1103 uint accepted_ind = DeliverGoodsToIndustry(st, cargo_type, num_pieces, src.type == SourceType::Industry ? src.ToIndustryID() : IndustryID::Invalid(), company->index);
1104
1105 /* If this cargo type is always accepted, accept all */
1106 uint accepted_total = HasBit(st->always_accepted, cargo_type) ? num_pieces : accepted_ind;
1107
1108 /* Update station statistics */
1109 if (accepted_total > 0) {
1111 }
1112
1113 /* Update company statistics */
1114 company->cur_economy.delivered_cargo[cargo_type] += accepted_total;
1115
1116 /* Increase town's counter for town effects */
1117 const CargoSpec *cs = CargoSpec::Get(cargo_type);
1118 st->town->received[cs->town_acceptance_effect].new_act += accepted_total;
1119
1120 /* Determine profit */
1121 Money profit = GetTransportedGoodsIncome(accepted_total, distance, periods_in_transit, cargo_type);
1122
1123 /* Update the cargo monitor. */
1124 AddCargoDelivery(cargo_type, company->index, accepted_total - accepted_ind, src, st);
1125
1126 /* Modify profit if a subsidy is in effect */
1127 if (CheckSubsidised(cargo_type, company->index, src, st)) {
1129 case 0: profit += profit >> 1; break;
1130 case 1: profit *= 2; break;
1131 case 2: profit *= 3; break;
1132 default: profit *= 4; break;
1133 }
1134 }
1135
1136 return profit;
1137}
1138
1145{
1146 const IndustrySpec *indspec = GetIndustrySpec(i->type);
1147 IndustryCallbackMasks cbm = indspec->callback_mask;
1148
1149 i->was_cargo_delivered = true;
1150
1154 } else {
1156 }
1157 } else {
1158 for (auto ita = std::begin(i->accepted); ita != std::end(i->accepted); ++ita) {
1159 if (ita->waiting == 0 || !IsValidCargoType(ita->cargo)) continue;
1160
1161 for (auto itp = std::begin(i->produced); itp != std::end(i->produced); ++itp) {
1162 if (!IsValidCargoType(itp->cargo)) continue;
1163 itp->waiting = ClampTo<uint16_t>(itp->waiting + (ita->waiting * indspec->input_cargo_multiplier[ita - std::begin(i->accepted)][itp - std::begin(i->produced)] / 256));
1164 }
1165
1166 ita->waiting = 0;
1167 }
1168 }
1169
1171 TriggerIndustryAnimation(i, IndustryAnimationTrigger::CargoReceived);
1172}
1173
1179 current_station(front->last_station_visited),
1180 front(front)
1181{
1182}
1183
1184CargoPayment::~CargoPayment()
1185{
1186 if (this->CleaningPool()) return;
1187
1188 this->front->cargo_payment = nullptr;
1189
1190 if (this->visual_profit == 0 && this->visual_transfer == 0) return;
1191
1192 Backup<CompanyID> cur_company(_current_company, this->front->owner);
1193
1194 SubtractMoneyFromCompany(CommandCost(this->front->GetExpenseType(true), -this->route_profit));
1195 this->front->profit_this_year += (this->visual_profit + this->visual_transfer) << 8;
1196
1197 if (this->route_profit != 0 && IsLocalCompany() && !PlayVehicleSound(this->front, VSE_LOAD_UNLOAD)) {
1198 SndPlayVehicleFx(SND_14_CASHTILL, this->front);
1199 }
1200
1201 if (this->visual_transfer != 0) {
1202 ShowFeederIncomeAnimation(this->front->x_pos, this->front->y_pos,
1203 this->front->z_pos, this->visual_transfer, -this->visual_profit);
1204 } else {
1205 ShowCostOrIncomeAnimation(this->front->x_pos, this->front->y_pos,
1206 this->front->z_pos, -this->visual_profit);
1207 }
1208
1209 cur_company.Restore();
1210}
1211
1219void CargoPayment::PayFinalDelivery(CargoType cargo, const CargoPacket *cp, uint count, TileIndex current_tile)
1220{
1221 if (this->owner == nullptr) {
1222 this->owner = Company::Get(this->front->owner);
1223 }
1224
1225 /* Handle end of route payment */
1226 Money profit = DeliverGoods(count, cargo, this->current_station, cp->GetDistance(current_tile), cp->GetPeriodsInTransit(), this->owner, cp->GetSource());
1227 this->route_profit += profit;
1228
1229 /* The vehicle's profit is whatever route profit there is minus feeder shares. */
1230 this->visual_profit += profit - cp->GetFeederShare(count);
1231}
1232
1241Money CargoPayment::PayTransfer(CargoType cargo, const CargoPacket *cp, uint count, TileIndex current_tile)
1242{
1243 /* Pay transfer vehicle the difference between the payment for the journey from
1244 * the source to the current point, and the sum of the previous transfer payments */
1245 Money profit = -cp->GetFeederShare(count) + GetTransportedGoodsIncome(
1246 count,
1247 cp->GetDistance(current_tile),
1248 cp->GetPeriodsInTransit(),
1249 cargo);
1250
1251 profit = profit * _settings_game.economy.feeder_payment_share / 100;
1252
1253 this->visual_transfer += profit; // accumulate transfer profits for whole vehicle
1254 return profit; // account for the (virtual) profit already made for the cargo packet
1255}
1256
1262{
1263 Station *curr_station = Station::Get(front_v->last_station_visited);
1264 curr_station->loading_vehicles.push_back(front_v);
1265
1266 /* At this moment loading cannot be finished */
1268
1269 /* Start unloading at the first possible moment */
1270 front_v->load_unload_ticks = 1;
1271
1272 assert(front_v->cargo_payment == nullptr);
1273 /* One CargoPayment per vehicle and the vehicle limit equals the
1274 * limit in number of CargoPayments. Can't go wrong. */
1277 front_v->cargo_payment = new CargoPayment(front_v);
1278
1279 StationIDStack next_station = front_v->GetNextStoppingStation();
1280 if (front_v->orders == nullptr || (front_v->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0) {
1282 for (Vehicle *v = front_v; v != nullptr; v = v->Next()) {
1283 const GoodsEntry *ge = &st->goods[v->cargo_type];
1284 if (v->cargo_cap > 0 && v->cargo.TotalCount() > 0) {
1285 v->cargo.Stage(
1287 front_v->last_station_visited, next_station,
1288 front_v->current_order.GetUnloadType(), ge,
1289 v->cargo_type, front_v->cargo_payment,
1290 v->GetCargoTile());
1291 if (v->cargo.UnloadCount() > 0) v->vehicle_flags.Set(VehicleFlag::CargoUnloading);
1292 }
1293 }
1294 }
1295}
1296
1303static uint GetLoadAmount(Vehicle *v)
1304{
1305 const Engine *e = v->GetEngine();
1306 uint load_amount = e->info.load_amount;
1307
1308 /* The default loadamount for mail is 1/4 of the load amount for passengers */
1309 bool air_mail = v->type == VEH_AIRCRAFT && !Aircraft::From(v)->IsNormalAircraft();
1310 if (air_mail) load_amount = CeilDiv(load_amount, 4);
1311
1313 uint16_t cb_load_amount = CALLBACK_FAILED;
1314 if (e->GetGRF() != nullptr && e->GetGRF()->grf_version >= 8) {
1315 /* Use callback 36 */
1316 cb_load_amount = GetVehicleProperty(v, PROP_VEHICLE_LOAD_AMOUNT, CALLBACK_FAILED);
1318 /* Use callback 12 */
1319 cb_load_amount = GetVehicleCallback(CBID_VEHICLE_LOAD_AMOUNT, 0, 0, v->engine_type, v);
1320 }
1321 if (cb_load_amount != CALLBACK_FAILED) {
1322 if (e->GetGRF()->grf_version < 8) cb_load_amount = GB(cb_load_amount, 0, 8);
1323 if (cb_load_amount >= 0x100) {
1325 } else if (cb_load_amount != 0) {
1326 load_amount = cb_load_amount;
1327 }
1328 }
1329 }
1330
1331 /* Scale load amount the same as capacity */
1332 if (e->info.misc_flags.Test(EngineMiscFlag::NoDefaultCargoMultiplier) && !air_mail) load_amount = CeilDiv(load_amount * CargoSpec::Get(v->cargo_type)->multiplier, 0x100);
1333
1334 /* Zero load amount breaks a lot of things. */
1335 return std::max(1u, load_amount);
1336}
1337
1347template <class Taction>
1348bool IterateVehicleParts(Vehicle *v, Taction action)
1349{
1350 for (Vehicle *w = v; w != nullptr;
1351 w = w->HasArticulatedPart() ? w->GetNextArticulatedPart() : nullptr) {
1352 if (!action(w)) return false;
1353 if (w->type == VEH_TRAIN) {
1354 Train *train = Train::From(w);
1355 if (train->IsMultiheaded() && !action(train->other_multiheaded_part)) return false;
1356 }
1357 }
1358 if (v->type == VEH_AIRCRAFT && Aircraft::From(v)->IsNormalAircraft()) return action(v->Next());
1359 return true;
1360}
1361
1366{
1372 bool operator()(const Vehicle *v)
1373 {
1374 return v->cargo.StoredCount() == 0;
1375 }
1376};
1377
1382{
1384 CargoTypes &refit_mask;
1385
1393
1400 bool operator()(const Vehicle *v)
1401 {
1402 this->consist_capleft[v->cargo_type] -= v->cargo_cap - v->cargo.ReservedCount();
1403 this->refit_mask |= EngInfo(v->engine_type)->refit_mask;
1404 return true;
1405 }
1406};
1407
1412{
1415
1421 ReturnCargoAction(Station *st, StationID next_one) : st(st), next_hop(next_one) {}
1422
1429 {
1430 v->cargo.Return(UINT_MAX, &this->st->goods[v->cargo_type].GetOrCreateData().cargo, this->next_hop, v->GetCargoTile());
1431 return true;
1432 }
1433};
1434
1439{
1444
1454
1462 {
1463 if (this->do_reserve) {
1464 this->st->goods[v->cargo_type].GetOrCreateData().cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(),
1465 &v->cargo, this->next_station, v->GetCargoTile());
1466 }
1467 this->consist_capleft[v->cargo_type] += v->cargo_cap - v->cargo.RemainingCount();
1468 return true;
1469 }
1470};
1471
1480static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station *st, StationIDStack next_station, CargoType new_cargo_type)
1481{
1482 Vehicle *v_start = v->GetFirstEnginePart();
1483 if (!IterateVehicleParts(v_start, IsEmptyAction())) return;
1484
1485 Backup<CompanyID> cur_company(_current_company, v->owner);
1486
1487 CargoTypes refit_mask = v->GetEngine()->info.refit_mask;
1488
1489 /* Remove old capacity from consist capacity and collect refit mask. */
1490 IterateVehicleParts(v_start, PrepareRefitAction(consist_capleft, refit_mask));
1491
1492 bool is_auto_refit = new_cargo_type == CARGO_AUTO_REFIT;
1493 if (is_auto_refit) {
1494 /* Get a refittable cargo type with waiting cargo for next_station or StationID::Invalid(). */
1495 new_cargo_type = v_start->cargo_type;
1496 for (CargoType cargo_type : SetCargoBitIterator(refit_mask)) {
1497 if (st->goods[cargo_type].HasData() && st->goods[cargo_type].GetData().cargo.HasCargoFor(next_station)) {
1498 /* Try to find out if auto-refitting would succeed. In case the refit is allowed,
1499 * the returned refit capacity will be greater than zero. */
1500 auto [cc, refit_capacity, mail_capacity, cargo_capacities] = Command<CMD_REFIT_VEHICLE>::Do(DoCommandFlag::QueryCost, v_start->index, cargo_type, 0xFF, true, false, 1); // Auto-refit and only this vehicle including artic parts.
1501 /* Try to balance different loadable cargoes between parts of the consist, so that
1502 * all of them can be loaded. Avoid a situation where all vehicles suddenly switch
1503 * to the first loadable cargo for which there is only one packet. If the capacities
1504 * are equal refit to the cargo of which most is available. This is important for
1505 * consists of only a single vehicle as those will generally have a consist_capleft
1506 * of 0 for all cargoes. */
1507 if (refit_capacity > 0 && (consist_capleft[cargo_type] < consist_capleft[new_cargo_type] ||
1508 (consist_capleft[cargo_type] == consist_capleft[new_cargo_type] &&
1509 st->goods[cargo_type].GetData().cargo.AvailableCount() > st->goods[new_cargo_type].GetData().cargo.AvailableCount()))) {
1510 new_cargo_type = cargo_type;
1511 }
1512 }
1513 }
1514 }
1515
1516 /* Refit if given a valid cargo. */
1517 if (new_cargo_type < NUM_CARGO && new_cargo_type != v_start->cargo_type) {
1518 /* StationID::Invalid() because in the DT_MANUAL case that's correct and in the DT_(A)SYMMETRIC
1519 * cases the next hop of the vehicle doesn't really tell us anything if the cargo had been
1520 * "via any station" before reserving. We rather produce some more "any station" cargo than
1521 * misrouting it. */
1522 IterateVehicleParts(v_start, ReturnCargoAction(st, StationID::Invalid()));
1523 CommandCost cost = std::get<0>(Command<CMD_REFIT_VEHICLE>::Do(DoCommandFlag::Execute, v_start->index, new_cargo_type, 0xFF, true, false, 1)); // Auto-refit and only this vehicle including artic parts.
1524 if (cost.Succeeded()) v->First()->profit_this_year -= cost.GetCost() << 8;
1525 }
1526
1527 /* Add new capacity to consist capacity and reserve cargo */
1528 IterateVehicleParts(v_start, FinalizeRefitAction(consist_capleft, st, next_station,
1529 is_auto_refit || (v->First()->current_order.GetLoadType() & OLFB_FULL_LOAD) != 0));
1530
1531 cur_company.Restore();
1532}
1533
1540static bool MayLoadUnderExclusiveRights(const Station *st, const Vehicle *v)
1541{
1542 return st->owner != OWNER_NONE || st->town->exclusive_counter == 0 || st->town->exclusivity == v->owner;
1543}
1544
1546 Station *st;
1547 StationIDStack *next_station;
1548
1549 ReserveCargoAction(Station *st, StationIDStack *next_station) :
1550 st(st), next_station(next_station) {}
1551
1552 bool operator()(Vehicle *v)
1553 {
1555 st->goods[v->cargo_type].GetOrCreateData().cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(),
1556 &v->cargo, *next_station, v->GetCargoTile());
1557 }
1558
1559 return true;
1560 }
1561
1562};
1563
1572static void ReserveConsist(Station *st, Vehicle *u, CargoArray *consist_capleft, StationIDStack *next_station)
1573{
1574 /* If there is a cargo payment not all vehicles of the consist have tried to do the refit.
1575 * In that case, only reserve if it's a fixed refit and the equivalent of "articulated chain"
1576 * a vehicle belongs to already has the right cargo. */
1577 bool must_reserve = !u->current_order.IsRefit() || u->cargo_payment == nullptr;
1578 for (Vehicle *v = u; v != nullptr; v = v->Next()) {
1579 assert(v->cargo_cap >= v->cargo.RemainingCount());
1580
1581 /* Exclude various ways in which the vehicle might not be the head of an equivalent of
1582 * "articulated chain". Also don't do the reservation if the vehicle is going to refit
1583 * to a different cargo and hasn't tried to do so, yet. */
1584 if (!v->IsArticulatedPart() &&
1585 (v->type != VEH_TRAIN || !Train::From(v)->IsRearDualheaded()) &&
1586 (v->type != VEH_AIRCRAFT || Aircraft::From(v)->IsNormalAircraft()) &&
1587 (must_reserve || u->current_order.GetRefitCargo() == v->cargo_type)) {
1588 IterateVehicleParts(v, ReserveCargoAction(st, next_station));
1589 }
1590 if (consist_capleft == nullptr || v->cargo_cap == 0) continue;
1591 (*consist_capleft)[v->cargo_type] += v->cargo_cap - v->cargo.RemainingCount();
1592 }
1593}
1594
1602static void UpdateLoadUnloadTicks(Vehicle *front, const Station *st, int ticks)
1603{
1605 /* Each platform tile is worth 2 rail vehicles. */
1606 int overhang = front->GetGroundVehicleCache()->cached_total_length - st->GetPlatformLength(front->tile) * TILE_SIZE;
1607 if (overhang > 0) {
1608 ticks <<= 1;
1609 ticks += (overhang * ticks) / 8;
1610 }
1611 }
1612 /* Always wait at least 1, otherwise we'll wait 'infinitively' long. */
1613 front->load_unload_ticks = std::max(1, ticks);
1614}
1615
1620static void LoadUnloadVehicle(Vehicle *front)
1621{
1622 assert(front->current_order.IsType(OT_LOADING));
1623
1624 StationID last_visited = front->last_station_visited;
1625 Station *st = Station::Get(last_visited);
1626
1627 StationIDStack next_station = front->GetNextStoppingStation();
1628 bool use_autorefit = front->current_order.IsRefit() && front->current_order.GetRefitCargo() == CARGO_AUTO_REFIT;
1629 CargoArray consist_capleft{};
1630 if (_settings_game.order.improved_load && use_autorefit ?
1631 front->cargo_payment == nullptr : (front->current_order.GetLoadType() & OLFB_FULL_LOAD) != 0) {
1632 ReserveConsist(st, front,
1633 (use_autorefit && front->load_unload_ticks != 0) ? &consist_capleft : nullptr,
1634 &next_station);
1635 }
1636
1637 /* We have not waited enough time till the next round of loading/unloading */
1638 if (front->load_unload_ticks != 0) return;
1639
1640 if (front->type == VEH_TRAIN && (!IsTileType(front->tile, MP_STATION) || GetStationIndex(front->tile) != st->index)) {
1641 /* The train reversed in the station. Take the "easy" way
1642 * out and let the train just leave as it always did. */
1644 front->load_unload_ticks = 1;
1645 return;
1646 }
1647
1648 int new_load_unload_ticks = 0;
1649 bool dirty_vehicle = false;
1650 bool dirty_station = false;
1651
1652 bool completely_emptied = true;
1653 bool anything_unloaded = false;
1654 bool anything_loaded = false;
1655 CargoTypes full_load_amount = 0;
1656 CargoTypes cargo_not_full = 0;
1657 CargoTypes cargo_full = 0;
1658 CargoTypes reservation_left = 0;
1659
1660 front->cur_speed = 0;
1661
1662 CargoPayment *payment = front->cargo_payment;
1663
1664 uint artic_part = 0; // Articulated part we are currently trying to load. (not counting parts without capacity)
1665 for (Vehicle *v = front; v != nullptr; v = v->Next()) {
1666 if (v == front || !v->Previous()->HasArticulatedPart()) artic_part = 0;
1667 if (v->cargo_cap == 0) continue;
1668 artic_part++;
1669
1670 GoodsEntry *ge = &st->goods[v->cargo_type];
1671
1672 if (v->vehicle_flags.Test(VehicleFlag::CargoUnloading) && (front->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0) {
1673 uint cargo_count = v->cargo.UnloadCount();
1674 uint amount_unloaded = _settings_game.order.gradual_loading ? std::min(cargo_count, GetLoadAmount(v)) : cargo_count;
1675 bool remaining = false; // Are there cargo entities in this vehicle that can still be unloaded here?
1676
1677 if (!ge->status.Test(GoodsEntry::State::Acceptance) && v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER) > 0) {
1678 /* The station does not accept our goods anymore. */
1680 /* Transfer instead of delivering. */
1682 v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER));
1683 } else {
1684 uint new_remaining = v->cargo.RemainingCount() + v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER);
1685 if (v->cargo_cap < new_remaining) {
1686 /* Return some of the reserved cargo to not overload the vehicle. */
1687 v->cargo.Return(new_remaining - v->cargo_cap, &ge->GetOrCreateData().cargo, StationID::Invalid(), v->GetCargoTile());
1688 }
1689
1690 /* Keep instead of delivering. This may lead to no cargo being unloaded, so ...*/
1692 v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER));
1693
1694 /* ... say we unloaded something, otherwise we'll think we didn't unload
1695 * something and we didn't load something, so we must be finished
1696 * at this station. Setting the unloaded means that we will get a
1697 * retry for loading in the next cycle. */
1698 anything_unloaded = true;
1699 }
1700 }
1701
1702 if (v->cargo.ActionCount(VehicleCargoList::MTA_TRANSFER) > 0) {
1703 /* Mark the station dirty if we transfer, but not if we only deliver. */
1704 dirty_station = true;
1705
1706 if (!ge->HasRating()) {
1707 /* Upon transferring cargo, make sure the station has a rating. Fake a pickup for the
1708 * first unload to prevent the cargo from quickly decaying after the initial drop. */
1709 ge->time_since_pickup = 0;
1711 }
1712 }
1713
1714 assert(payment != nullptr);
1715 amount_unloaded = v->cargo.Unload(amount_unloaded, &ge->GetOrCreateData().cargo, v->cargo_type, payment, v->GetCargoTile());
1716 remaining = v->cargo.UnloadCount() > 0;
1717 if (amount_unloaded > 0) {
1718 dirty_vehicle = true;
1719 anything_unloaded = true;
1720 new_load_unload_ticks += amount_unloaded;
1721
1722 /* Deliver goods to the station */
1723 st->time_since_unload = 0;
1724 }
1725
1726 if (_settings_game.order.gradual_loading && remaining) {
1727 completely_emptied = false;
1728 } else {
1729 /* We have finished unloading (cargo count == 0) */
1730 v->vehicle_flags.Reset(VehicleFlag::CargoUnloading);
1731 }
1732
1733 continue;
1734 }
1735
1736 /* Do not pick up goods when we have no-load set or loading is stopped. */
1738
1739 /* This order has a refit, if this is the first vehicle part carrying cargo and the whole vehicle is empty, try refitting. */
1740 if (front->current_order.IsRefit() && artic_part == 1) {
1741 HandleStationRefit(v, consist_capleft, st, next_station, front->current_order.GetRefitCargo());
1742 ge = &st->goods[v->cargo_type];
1743 }
1744
1745 /* As we're loading here the following link can carry the full capacity of the vehicle. */
1746 v->refit_cap = v->cargo_cap;
1747
1748 /* update stats */
1749 int t;
1750 switch (front->type) {
1751 case VEH_TRAIN:
1752 case VEH_SHIP:
1753 t = front->vcache.cached_max_speed;
1754 break;
1755
1756 case VEH_ROAD:
1757 t = front->vcache.cached_max_speed / 2;
1758 break;
1759
1760 case VEH_AIRCRAFT:
1761 t = Aircraft::From(front)->GetSpeedOldUnits(); // Convert to old units.
1762 break;
1763
1764 default: NOT_REACHED();
1765 }
1766
1767 /* if last speed is 0, we treat that as if no vehicle has ever visited the station. */
1768 ge->last_speed = ClampTo<uint8_t>(t);
1769 ge->last_age = ClampTo<uint8_t>(TimerGameCalendar::year - front->build_year);
1770
1771 assert(v->cargo_cap >= v->cargo.StoredCount());
1772 /* Capacity available for loading more cargo. */
1773 uint cap_left = v->cargo_cap - v->cargo.StoredCount();
1774
1775 if (cap_left > 0) {
1776 /* If vehicle can load cargo, reset time_since_pickup. */
1777 ge->time_since_pickup = 0;
1778
1779 /* If there's goods waiting at the station, and the vehicle
1780 * has capacity for it, load it on the vehicle. */
1781 if ((v->cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0 || (ge->HasData() && ge->GetData().cargo.AvailableCount() > 0)) && MayLoadUnderExclusiveRights(st, v)) {
1782 if (v->cargo.StoredCount() == 0) TriggerVehicleRandomisation(v, VehicleRandomTrigger::NewCargo);
1783 if (_settings_game.order.gradual_loading) cap_left = std::min(cap_left, GetLoadAmount(v));
1784
1785 uint loaded = ge->GetOrCreateData().cargo.Load(cap_left, &v->cargo, next_station, v->GetCargoTile());
1786 if (v->cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) {
1787 /* Remember if there are reservations left so that we don't stop
1788 * loading before they're loaded. */
1789 SetBit(reservation_left, v->cargo_type);
1790 }
1791
1792 /* Store whether the maximum possible load amount was loaded or not.*/
1793 if (loaded == cap_left) {
1794 SetBit(full_load_amount, v->cargo_type);
1795 } else {
1796 ClrBit(full_load_amount, v->cargo_type);
1797 }
1798
1799 /* TODO: Regarding this, when we do gradual loading, we
1800 * should first unload all vehicles and then start
1801 * loading them. Since this will cause
1802 * VEHICLE_TRIGGER_EMPTY to be called at the time when
1803 * the whole vehicle chain is really totally empty, the
1804 * completely_emptied assignment can then be safely
1805 * removed; that's how TTDPatch behaves too. --pasky */
1806 if (loaded > 0) {
1807 completely_emptied = false;
1808 anything_loaded = true;
1809
1810 st->time_since_load = 0;
1811 st->last_vehicle_type = v->type;
1812
1813 if (ge->GetData().cargo.TotalCount() == 0) {
1815 TriggerStationAnimation(st, st->xy, StationAnimationTrigger::CargoTaken, v->cargo_type);
1816 TriggerAirportAnimation(st, AirportAnimationTrigger::CargoTaken, v->cargo_type);
1817 TriggerRoadStopRandomisation(st, st->xy, StationRandomTrigger::CargoTaken, v->cargo_type);
1818 TriggerRoadStopAnimation(st, st->xy, StationAnimationTrigger::CargoTaken, v->cargo_type);
1819 }
1820
1821 new_load_unload_ticks += loaded;
1822
1823 dirty_vehicle = dirty_station = true;
1824 }
1825 }
1826 }
1827
1828 if (v->cargo.StoredCount() >= v->cargo_cap) {
1829 SetBit(cargo_full, v->cargo_type);
1830 } else {
1831 SetBit(cargo_not_full, v->cargo_type);
1832 }
1833 }
1834
1835 if (anything_loaded || anything_unloaded) {
1836 if (front->type == VEH_TRAIN) {
1838 TriggerStationAnimation(st, front->tile, StationAnimationTrigger::VehicleLoads);
1839 } else if (front->type == VEH_ROAD) {
1840 TriggerRoadStopRandomisation(st, front->tile, StationRandomTrigger::VehicleLoads);
1841 TriggerRoadStopAnimation(st, front->tile, StationAnimationTrigger::VehicleLoads);
1842 }
1843 }
1844
1845 /* Only set completely_emptied, if we just unloaded all remaining cargo */
1846 completely_emptied &= anything_unloaded;
1847
1848 if (!anything_unloaded) delete payment;
1849
1851 if (anything_loaded || anything_unloaded) {
1853 /* The time it takes to load one 'slice' of cargo or passengers depends
1854 * on the vehicle type - the values here are those found in TTDPatch */
1855 const uint gradual_loading_wait_time[] = { 40, 20, 10, 20 };
1856
1857 new_load_unload_ticks = gradual_loading_wait_time[front->type];
1858 }
1859 /* We loaded less cargo than possible for all cargo types and it's not full
1860 * load and we're not supposed to wait any longer: stop loading. */
1861 if (!anything_unloaded && full_load_amount == 0 && reservation_left == 0 && !(front->current_order.GetLoadType() & OLFB_FULL_LOAD) &&
1862 front->current_order_time >= std::max(front->current_order.GetTimetabledWait() - front->lateness_counter, 0)) {
1864 }
1865
1866 UpdateLoadUnloadTicks(front, st, new_load_unload_ticks);
1867 } else {
1868 UpdateLoadUnloadTicks(front, st, 20); // We need the ticks for link refreshing.
1869 bool finished_loading = true;
1870 if (front->current_order.GetLoadType() & OLFB_FULL_LOAD) {
1872 /* if the aircraft carries passengers and is NOT full, then
1873 * continue loading, no matter how much mail is in */
1874 if ((front->type == VEH_AIRCRAFT && IsCargoInClass(front->cargo_type, CargoClass::Passengers) && front->cargo_cap > front->cargo.StoredCount()) ||
1875 (cargo_not_full != 0 && (cargo_full & ~cargo_not_full) == 0)) { // There are still non-full cargoes
1876 finished_loading = false;
1877 }
1878 } else if (cargo_not_full != 0) {
1879 finished_loading = false;
1880 }
1881
1882 /* Refresh next hop stats if we're full loading to make the links
1883 * known to the distribution algorithm and allow cargo to be sent
1884 * along them. Otherwise the vehicle could wait for cargo
1885 * indefinitely if it hasn't visited the other links yet, or if the
1886 * links die while it's loading. */
1887 if (!finished_loading) LinkRefresher::Run(front, true, true);
1888 }
1889
1890 front->vehicle_flags.Set(VehicleFlag::LoadingFinished, finished_loading);
1891 }
1892
1893 /* Calculate the loading indicator fill percent and display
1894 * In the Game Menu do not display indicators
1895 * If _settings_client.gui.loading_indicators == 2, show indicators (bool can be promoted to int as 0 or 1 - results in 2 > 0,1 )
1896 * if _settings_client.gui.loading_indicators == 1, _local_company must be the owner or must be a spectator to show ind., so 1 > 0
1897 * if _settings_client.gui.loading_indicators == 0, do not display indicators ... 0 is never greater than anything
1898 */
1899 if (_game_mode != GM_MENU && (_settings_client.gui.loading_indicators > (uint)(front->owner != _local_company && _local_company != COMPANY_SPECTATOR))) {
1900 StringID percent_up_down = STR_NULL;
1901 int percent = CalcPercentVehicleFilled(front, &percent_up_down);
1902 if (front->fill_percent_te_id == INVALID_TE_ID) {
1903 front->fill_percent_te_id = ShowFillingPercent(front->x_pos, front->y_pos, front->z_pos + 20, percent, percent_up_down);
1904 } else {
1905 UpdateFillingPercent(front->fill_percent_te_id, percent, percent_up_down);
1906 }
1907 }
1908
1909 if (completely_emptied) {
1910 /* Make sure the vehicle is marked dirty, since we need to update the NewGRF
1911 * properties such as weight, power and TE whenever the trigger runs. */
1912 dirty_vehicle = true;
1913 TriggerVehicleRandomisation(front, VehicleRandomTrigger::Empty);
1914 }
1915
1916 if (dirty_vehicle) {
1919 front->MarkDirty();
1920 }
1921 if (dirty_station) {
1922 st->MarkTilesDirty(true);
1925 }
1926}
1927
1934{
1935 /* No vehicle is here... */
1936 if (st->loading_vehicles.empty()) return;
1937
1938 Vehicle *last_loading = nullptr;
1939
1940 /* Check if anything will be loaded at all. Otherwise we don't need to reserve either. */
1941 for (Vehicle *v : st->loading_vehicles) {
1942 if (v->vehstatus.Any({VehState::Stopped, VehState::Crashed})) continue;
1943
1944 assert(v->load_unload_ticks != 0);
1945 if (--v->load_unload_ticks == 0) last_loading = v;
1946 }
1947
1948 /* We only need to reserve and load/unload up to the last loading vehicle.
1949 * Anything else will be forgotten anyway after returning from this function.
1950 *
1951 * Especially this means we do _not_ need to reserve cargo for a single
1952 * consist in a station which is not allowed to load yet because its
1953 * load_unload_ticks is still not 0.
1954 */
1955 if (last_loading == nullptr) return;
1956
1957 for (Vehicle *v : st->loading_vehicles) {
1958 if (!v->vehstatus.Any({VehState::Stopped, VehState::Crashed})) LoadUnloadVehicle(v);
1959 if (v == last_loading) break;
1960 }
1961
1962 /* Call the production machinery of industries */
1965 }
1967}
1968
1972static const IntervalTimer<TimerGameCalendar> _calendar_inflation_monthly({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::COMPANY}, [](auto)
1973{
1975 AddInflation();
1977 }
1978});
1979
1983static const IntervalTimer<TimerGameEconomy> _economy_companies_monthly({ TimerGameEconomy::MONTH, TimerGameEconomy::Priority::COMPANY }, [](auto)
1984{
1987 HandleEconomyFluctuations();
1988});
1989
1990static void DoAcquireCompany(Company *c, bool hostile_takeover)
1991{
1992 CompanyID ci = c->index;
1993
1994 auto cni = std::make_unique<CompanyNewsInformation>(STR_NEWS_COMPANY_MERGER_TITLE, c, Company::Get(_current_company));
1995 EncodedString headline = hostile_takeover
1996 ? GetEncodedString(STR_NEWS_MERGER_TAKEOVER_TITLE, cni->company_name, cni->other_company_name)
1997 : GetEncodedString(STR_NEWS_COMPANY_MERGER_DESCRIPTION, cni->company_name, cni->other_company_name, c->bankrupt_value);
1998 AddCompanyNewsItem(std::move(headline), std::move(cni));
1999 AI::BroadcastNewEvent(new ScriptEventCompanyMerger(ci, _current_company));
2000 Game::NewEvent(new ScriptEventCompanyMerger(ci, _current_company));
2001
2003
2004 if (c->is_ai) AI::Stop(c->index);
2005
2011
2012 delete c;
2013}
2014
2025CommandCost CmdBuyCompany(DoCommandFlags flags, CompanyID target_company, bool hostile_takeover)
2026{
2027 Company *c = Company::GetIfValid(target_company);
2028 if (c == nullptr) return CMD_ERROR;
2029
2030 /* If you do a hostile takeover but the company went bankrupt, buy it via bankruptcy rules. */
2031 if (hostile_takeover && c->bankrupt_asked.Test(_current_company)) hostile_takeover = false;
2032
2033 /* Disable takeovers when not asked */
2034 if (!hostile_takeover && !c->bankrupt_asked.Test(_current_company)) return CMD_ERROR;
2035
2036 /* Only allow hostile takeover of AI companies and when in single player */
2037 if (hostile_takeover && !c->is_ai) return CMD_ERROR;
2038 if (hostile_takeover && _networking) return CMD_ERROR;
2039
2040 /* Disable taking over the local company in singleplayer mode */
2041 if (!_networking && _local_company == c->index) return CMD_ERROR;
2042
2043 /* Do not allow companies to take over themselves */
2044 if (target_company == _current_company) return CMD_ERROR;
2045
2046 /* Do not allow takeover if the resulting company would have too many vehicles. */
2047 if (!CheckTakeoverVehicleLimit(_current_company, target_company)) return CommandCost(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME);
2048
2049 /* Get the cost here as the company is deleted in DoAcquireCompany.
2050 * For bankruptcy this amount is calculated when the offer was made;
2051 * for hostile takeover you pay the current price. */
2052 CommandCost cost(EXPENSES_OTHER, hostile_takeover ? CalculateHostileTakeoverValue(c) : c->bankrupt_value);
2053
2054 if (flags.Test(DoCommandFlag::Execute)) {
2055 DoAcquireCompany(c, hostile_takeover);
2056 }
2057 return cost;
2058}
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.
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
debug_inline 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 T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
Types related to cargoes...
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:23
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:106
static const CargoType CARGO_AUTO_REFIT
Automatically choose cargo type when doing auto refitting.
Definition cargo_type.h:78
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.
bool IsCargoInClass(CargoType cargo, CargoClasses cc)
Does cargo c have cargo class cc?
Definition cargotype.h:236
static void BroadcastNewEvent(ScriptEvent *event, CompanyID skip_company=CompanyID::Invalid())
Broadcast a new event to all active AIs.
Definition ai_core.cpp:255
static void Stop(CompanyID company)
Stop a company to be controlled by an AI.
Definition ai_core.cpp:107
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr Timpl & Reset()
Reset all bits.
constexpr Timpl & Set()
Set all bits.
@ MTA_KEEP
Keep the cargo in the vehicle.
@ MTA_DELIVER
Deliver the cargo to some town or industry.
@ MTA_LOAD
Load the cargo from the station.
@ MTA_TRANSFER
Transfer the cargo to the station.
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.
UnitID UseID(UnitID index)
Use a unit number.
Definition vehicle.cpp:1833
UnitID NextID() const
Find first unused unit number.
Definition vehicle.cpp:1818
static void NewEvent(class ScriptEvent *event)
Queue a new event for a 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
A sort-of mixin that adds 'at(pos)' and 'operator[](pos)' implementations for 'ConvertibleThroughBase...
Minimal stack that uses a pool to avoid pointers.
uint TotalCount() const
Returns total count of cargo at the station, including cargo which is already reserved for loading.
uint AvailableCount() const
Returns sum of cargo still available for loading at the sation.
uint Load(uint max_move, VehicleCargoList *dest, StationIDStack 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
The maximum year of the original TTD.
static constexpr TimerGame< struct Calendar >::Year ORIGINAL_BASE_YEAR
The minimum starting year/base year of the original TTD.
static Date date
Current date in days (day counter).
static Month month
Current month (0..11).
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.
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
@ Execute
execute the given command
@ QueryCost
query cost only, don't build.
@ Bankrupt
company bankrupts, skip money check, skip vehicle on tile check in some cases
int CompanyServiceInterval(const Company *c, VehicleType type)
Get the service interval for the given company and vehicle type.
void CompanyAdminUpdate(const Company *company)
Called whenever company related information changes in order to notify admins.
void SubtractMoneyFromCompany(const CommandCost &cost)
Subtract money from the _current_company, if the company is valid.
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?
void SetLocalCompany(CompanyID new_company)
Sets the local company and updates the settings that are set on a per-company basis to reflect the co...
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:1210
@ CCA_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.
@ CRR_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:1540
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:1602
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:202
const ScoreInfo _score_info[]
Score info, values used for computing the detailed performance rating.
Definition economy.cpp:91
void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
Change the ownership of all the items of a company.
Definition economy.cpp:322
static void CompaniesPayInterest()
Let all companies pay the monthly interest on their loan.
Definition economy.cpp:812
void LoadUnloadStation(Station *st)
Load/unload the vehicles in this station according to the order they entered.
Definition economy.cpp:1933
void RecomputePrices()
Computes all prices, payments and maximum loan.
Definition economy.cpp:745
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:1042
static void LoadUnloadVehicle(Vehicle *front)
Loads/unload the vehicle if possible.
Definition economy.cpp:1620
Money CalculateHostileTakeoverValue(const Company *c)
Calculate what you have to pay to take over a company.
Definition economy.cpp:177
static Money CalculateCompanyAssetValue(const Company *c)
Calculate the value of the assets of a company.
Definition economy.cpp:115
static SmallIndustryList _cargo_delivery_destinations
The industries we've currently brought cargo to.
Definition economy.cpp:1030
void PrepareUnload(Vehicle *front_v)
Prepare the vehicle to be unloaded.
Definition economy.cpp:1261
static uint GetLoadAmount(Vehicle *v)
Gets the amount of cargo the given vehicle can load in the current tick.
Definition economy.cpp:1303
static void ReserveConsist(Station *st, Vehicle *u, CargoArray *consist_capleft, StationIDStack *next_station)
Reserves cargo if the full load order and improved_load is set or if the current order allows autoref...
Definition economy.cpp:1572
void SetPriceBaseMultiplier(Price price, int factor)
Change a price base by the given factor.
Definition economy.cpp:885
Money GetPrice(Price index, uint cost_factor, const GRFFile *grf_file, int shift)
Determine a certain price.
Definition economy.cpp:952
static const IntervalTimer< TimerGameCalendar > _calendar_inflation_monthly({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::COMPANY}, [](auto) { if(_settings_game.economy.inflation) { AddInflation();RecomputePrices();} })
Every calendar month update of inflation.
static void TriggerIndustryProduction(Industry *i)
Inform the industry about just delivered cargo DeliverGoodsToIndustry() silently incremented incoming...
Definition economy.cpp:1144
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:1348
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:1096
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:81
void InitializeEconomy()
Resets economy to initial values.
Definition economy.cpp:937
static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station *st, StationIDStack next_station, CargoType new_cargo_type)
Refit a vehicle in a station.
Definition economy.cpp:1480
static void CompanyCheckBankrupt(Company *c)
Check for bankruptcy of a company.
Definition economy.cpp:553
void ResetPriceBaseMultipliers()
Reset changes to the price base multipliers.
Definition economy.cpp:873
static void CompaniesGenStatistics()
Update the finances of all companies.
Definition economy.cpp:644
bool AddInflation(bool check_year)
Add monthly inflation.
Definition economy.cpp:707
CommandCost CmdBuyCompany(DoCommandFlags flags, CompanyID target_company, bool hostile_takeover)
Buy up another company.
Definition economy.cpp:2025
static const IntervalTimer< TimerGameEconomy > _economy_companies_monthly({ TimerGameEconomy::MONTH, TimerGameEconomy::Priority::COMPANY }, [](auto) { CompaniesGenStatistics();CompaniesPayInterest();HandleEconomyFluctuations();})
Every economy month update of company economic data, plus economy fluctuations.
Money CalculateCompanyValue(const Company *c, bool including_loan)
Calculate the value of the company.
Definition economy.cpp:150
void StartupIndustryDailyChanges(bool init_counter)
Initialize the variables that will maintain the daily industry change system.
Definition economy.cpp:895
Base classes related to the economy.
Command definitions related to the economy.
bool EconomyIsInRecession()
Is the economy in recession?
ScoreID
Score categories in the detailed performance rating.
@ SCORE_END
How many scores are there..
@ SCORE_TOTAL
This must always be the last entry.
static const int MIN_PRICE_MODIFIER
Maximum NewGRF price modifiers.
@ EXPENSES_PROPERTY
Property costs.
@ EXPENSES_OTHER
Other expenses.
@ EXPENSES_LOAN_INTEREST
Interest payments over the loan.
Money Prices[PR_END]
Prices of everything.
@ PCAT_RUNNING
Price is affected by "vehicle running cost" difficulty setting.
@ PCAT_CONSTRUCTION
Price is affected by "construction 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.
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...
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:247
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1535
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.
@ Random
Randomise borders.
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
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:570
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_ID
Client is not part of anything.
NewGRF handling of airport tiles.
@ LoadAmount
Load amount.
@ 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.
Cargo support for NewGRFs.
void ErrorUnknownCallbackResult(uint32_t 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.
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:902
@ Economy
Economic changes (recession, industry up/dowm)
@ Normal
Normal news item. (Newspaper with text only)
Functions related to objects.
void UpdateCompanyHQ(TileIndex tile, uint score)
Update the CompanyHQ to the state associated with the given score.
@ OUFB_TRANSFER
Transfer all cargo onto the platform.
Definition order_type.h:70
@ OUFB_NO_UNLOAD
Totally no unloading will be done.
Definition order_type.h:71
@ OUFB_UNLOAD
Force unloading all cargo onto the platform, possibly not getting paid.
Definition order_type.h:69
@ OLFB_FULL_LOAD
Full load all cargoes of the consist.
Definition order_type.h:79
@ OLFB_NO_LOAD
Do not load anything.
Definition order_type.h:81
@ OLF_FULL_LOAD_ANY
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.
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:436
Money SignalMaintenanceCost(uint32_t num)
Calculates the maintenance cost of a number of signals.
Definition rail.h:447
TrackBits GetTrackBits(Tile tile)
Gets the track bits of the given tile.
Definition rail_map.h:136
bool HasSignalOnTrack(Tile tile, Track track)
Checks for the presence of signals (either way) on the given track on the given rail tile.
Definition rail_map.h:412
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:25
@ RAILTYPE_BEGIN
Used for iterations.
Definition rail_type.h:26
@ RAILTYPE_END
Used for iterations.
Definition rail_type.h:31
Definition 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:125
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:23
@ ROADTYPE_END
Used for iterations.
Definition road_type.h:27
@ ROADTYPE_BEGIN
Used for iterations.
Definition road_type.h:24
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:587
void UpdateSignalsInBuffer()
Update signals in buffer Called from 'outside'.
Definition signal.cpp:571
Base class for signs.
Functions related to sound.
@ SND_14_CASHTILL
18 == 0x12 Income from cargo delivery
Definition sound_type.h:65
@ Industry
Source/destination is an industry.
Money AirportMaintenanceCost(Owner owner)
Calculates the maintenance cost of all airports of a company.
Definition station.cpp:713
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:91
Functions related to OTTD's strings.
uint32_t 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:121
Class to backup a specific variable and restore it later.
void Change(const U &new_value)
Change the value of the variable.
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:113
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:1219
CargoPayment()
Constructor for pool saveload.
Company * owner
NOSAVE: The owner of the vehicle.
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:1241
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:74
uint16_t multiplier
Capacity multiplier for vehicles. (8 fractional bits)
Definition cargotype.h:80
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo type.
Definition cargotype.h:137
static IterateWrapper Iterate(size_t from=0)
Returns an iterable ensemble of all valid CargoSpec.
Definition cargotype.h:192
TownAcceptanceEffect town_acceptance_effect
The effect that delivering this cargo type has on towns. Also affects destination of subsidies.
Definition cargotype.h:86
CargoCallbackMasks callback_mask
Bitmask of cargo callbacks that have to be called.
Definition cargotype.h:89
bool IsValid() const
Tests for validity of this cargospec.
Definition cargotype.h:118
GUISettings gui
settings related to the GUI
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.
uint8_t initial_interest
amount of interest (to pay over the loan)
bool infinite_money
whether spending money despite negative balance is allowed
uint32_t max_loan
the maximum initial loan
uint8_t construction_cost
how expensive is building
uint8_t subsidy_multiplier
payment multiplier for subsidized deliveries
uint8_t vehicle_costs
amount of money spent on vehicle running cost
bool economy
how volatile is the economy
bool inflation
disable inflation
bool infrastructure_maintenance
enable monthly maintenance fee for owner infrastructure
uint8_t feeder_payment_share
percentage of leg payment to virtually pay in feeder systems
Data of the economy.
uint64_t inflation_payment
Cumulated inflation of cargo payment since game start; 16 bit fractional part.
uint8_t infl_amount
inflation amount
uint64_t inflation_prices
Cumulated inflation of prices since game start; 16 bit fractional part.
int16_t fluct
Economy fluctuation status.
uint8_t infl_amount_pr
inflation rate for payment rates
uint32_t industry_daily_change_counter
Bits 31-16 are number of industry to be performed, 15-0 are fractional collected daily.
uint32_t industry_daily_increment
The value which will increment industry_daily_change_counter. Computed value. NOSAVE.
Money max_loan
NOSAVE: Maximum possible loan.
uint8_t interest_rate
Interest.
EngineMiscFlags misc_flags
Miscellaneous flags.
VehicleCallbackMasks callback_mask
Bitmask of vehicle callbacks that have to be called.
uint32_t GetGRFID() const
Retrieve the GRF ID of the NewGRF the engine is tied to.
Definition engine.cpp:157
const GRFFile * GetGRF() const
Retrieve the NewGRF the engine is tied to.
Action for finalizing a refit.
Definition economy.cpp:1439
CargoArray & consist_capleft
Capacities left in the consist.
Definition economy.cpp:1440
bool do_reserve
If the vehicle should reserve.
Definition economy.cpp:1443
StationIDStack & next_station
Next hops to reserve cargo for.
Definition economy.cpp:1442
bool operator()(Vehicle *v)
Reserve cargo from the station and update the remaining consist capacities with the vehicle's remaini...
Definition economy.cpp:1461
Station * st
Station to reserve cargo from.
Definition economy.cpp:1441
FinalizeRefitAction(CargoArray &consist_capleft, Station *st, StationIDStack &next_station, bool do_reserve)
Create a finalizing action.
Definition economy.cpp:1452
Dynamic data of a loaded NewGRF.
Definition newgrf.h:115
PriceMultipliers price_base_multipliers
Price base multipliers as set by the grf.
Definition newgrf.h:159
uint8_t loading_indicators
show loading indicators
EconomySettings economy
settings to change the economy
DifficultySettings difficulty
settings related to the difficulty
OrderSettings order
settings related to orders
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.
debug_inline const GoodsEntryData & GetData() const
Get optional cargo packet/flow data.
@ 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.
GoodsEntryData & GetOrCreateData()
Get optional cargo packet/flow data.
debug_inline bool HasData() const
Test if this goods entry has optional cargo packet/flow data.
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:73
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:100
Owner exclusive_supplier
Which company has exclusive rights to deliver cargo (INVALID_OWNER = anyone)
Definition industry.h:115
ProducedCargoes produced
produced cargo slots
Definition industry.h:95
AcceptedCargoes accepted
accepted cargo slots
Definition industry.h:96
uint8_t was_cargo_delivered
flag that indicate this has been the closest industry chosen for cargo delivery by a station....
Definition industry.h:104
AcceptedCargoes::iterator GetCargoAccepted(CargoType cargo)
Get accepted cargo slot for a specific cargo type.
Definition industry.h:187
Action to check if a vehicle has no stored cargo.
Definition economy.cpp:1366
bool operator()(const Vehicle *v)
Checks if the vehicle has stored cargo.
Definition economy.cpp:1372
static IterateWrapper Iterate()
Returns an iterable ensemble of all Tiles.
Definition map_func.h:362
static debug_inline uint LogX()
Logarithm of the map size along the X side.
Definition map_func.h:250
static uint LogY()
Logarithm of the map size along the y side.
Definition map_func.h:260
bool station_length_loading_penalty
make trains longer than the station load more slowly
bool improved_load
improved loading algorithm
bool gradual_loading
load vehicles gradually
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition order_base.h:66
CargoType GetRefitCargo() const
Get the cargo to to refit to.
Definition order_base.h:127
OrderLoadFlags GetLoadType() const
How must the consist be loaded?
Definition order_base.h:132
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:184
OrderUnloadFlags GetUnloadType() const
How must the consist be unloaded?
Definition order_base.h:134
bool IsRefit() const
Is this order a refit order.
Definition order_base.h:113
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
static Titem * Get(auto index)
Returns Titem with given index.
Tindex index
Index of this pool item.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
static bool CleaningPool()
Returns current state of pool cleaning - yes or no.
static Titem * GetIfValid(auto index)
Returns Titem with given index.
Base class for all pools.
static constexpr size_t MAX_SIZE
Make template parameter accessible from outside.
Refit preparation action.
Definition economy.cpp:1382
CargoTypes & refit_mask
Bitmask of possible refit cargoes.
Definition economy.cpp:1384
PrepareRefitAction(CargoArray &consist_capleft, CargoTypes &refit_mask)
Create a refit preparation action.
Definition economy.cpp:1391
CargoArray & consist_capleft
Capacities left in the consist.
Definition economy.cpp:1383
bool operator()(const Vehicle *v)
Prepares for refitting of a vehicle, subtracting its free capacity from consist_capleft and adding th...
Definition economy.cpp:1400
Money start_price
Default value at game start, before adding multipliers.
Definition newgrf.h:199
Action for returning reserved cargo.
Definition economy.cpp:1412
Station * st
Station to give the returned cargo to.
Definition economy.cpp:1413
bool operator()(Vehicle *v)
Return all reserved cargo from a vehicle.
Definition economy.cpp:1428
ReturnCargoAction(Station *st, StationID next_one)
Construct a cargo return action.
Definition economy.cpp:1421
StationID next_hop
Next hop the cargo should be assigned to.
Definition economy.cpp:1414
Data structure for storing how the score is computed for a single score id.
int needed
How much you need to get the perfect score.
int score
How much score it will give.
Iterable ensemble of each set bit in a value.
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)
Returns an iterable ensemble of all valid stations of type T.
static Station * Get(auto index)
Gets station with given index.
static Aircraft * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
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:289
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:167
Struct about subsidies, offered and awarded.
Town data structure.
Definition town.h:52
CompanyID exclusivity
which company has exclusivity
Definition town.h:73
uint8_t exclusive_counter
months till the exclusivity expires
Definition town.h:74
std::array< TransportedCargoStat< uint16_t >, NUM_TAE > received
Cargo statistics about received cargotypes.
Definition town.h:78
'Train' is either a loco or a wagon.
Definition train.h:91
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.
StationIDStack GetNextStoppingStation() const
Get the next station the vehicle will stop at.
const Engine * GetEngine() const
Retrieves the engine of the vehicle.
Definition vehicle.cpp:718
virtual ExpensesType GetExpenseType(bool income) const
Sets the expense type associated to this vehicle type.
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.
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.
VehicleCache vcache
Cache of often used vehicle values.
GroundVehicleCache * GetGroundVehicleCache()
Access the ground vehicle cache of the vehicle.
Definition vehicle.cpp:3116
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:103
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:507
Subsidy base class.
Functions related to subsidies.
bool IsTileOwner(Tile tile, Owner owner)
Checks if a tile belongs to the given owner.
Definition tile_map.h:214
static debug_inline bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
static const uint TILE_SIZE
Tile size in world coordinates.
Definition tile_type.h:15
@ MP_STATION
A tile of a station.
Definition tile_type.h:53
@ MP_RAILWAY
A railway.
Definition tile_type.h:49
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:45
Track RemoveFirstTrack(TrackBits *tracks)
Removes first Track from TrackBits and returns it.
Definition track_func.h:131
TrackBits
Allow incrementing of Track variables.
Definition track_type.h:35
@ TRACK_BIT_NONE
No track.
Definition track_type.h:36
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:1462
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
@ VEH_ROAD
Road vehicle type.
@ VEH_AIRCRAFT
Aircraft vehicle type.
@ VEH_SHIP
Ship vehicle type.
@ VEH_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.
Functions related to water (management)
Money CanalMaintenanceCost(uint32_t num)
Calculates the maintenance cost of a number of canal tiles.
Definition water.h:51
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:1230
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition window.cpp:3173
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:3265
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition window.cpp:3147
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:3282
@ WC_PERFORMANCE_HISTORY
Performance history graph; Window numbers:
@ WC_COMPANY_LEAGUE
Company league window; Window numbers:
@ WC_COMPANY_INFRASTRUCTURE
Company infrastructure overview; Window numbers:
@ WC_PERFORMANCE_DETAIL
Performance detail window; Window numbers:
@ WC_PAYMENT_RATES
Payment rates graph; Window numbers:
@ WC_STATION_LIST
Station list; Window numbers:
@ WC_ROADVEH_LIST
Road vehicle list; Window numbers:
@ WC_REPLACE_VEHICLE
Replace vehicle window; Window numbers:
@ WC_SHIPS_LIST
Ships list; Window numbers:
@ WC_STATION_VIEW
Station view; Window numbers:
@ WC_OPERATING_PROFIT
Operating profit graph; Window numbers:
@ WC_TRAINS_LIST
Trains list; Window numbers:
@ WC_INDUSTRY_VIEW
Industry view; Window numbers:
@ WC_INCOME_GRAPH
Income graph; Window numbers:
@ WC_DELIVERED_CARGO
Delivered cargo graph; Window numbers:
@ WC_COMPANY_VALUE
Company value graph; Window numbers:
@ WC_VEHICLE_DETAILS
Vehicle details; Window numbers:
@ WC_BUILD_VEHICLE
Build vehicle; Window numbers:
@ WC_AIRCRAFT_LIST
Aircraft list; Window numbers: