OpenTTD Source 20241222-master-gc72542431a
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 "company_func.h"
12#include "command_func.h"
13#include "industry.h"
14#include "town.h"
15#include "news_func.h"
16#include "network/network.h"
18#include "ai/ai.hpp"
19#include "aircraft.h"
20#include "train.h"
21#include "newgrf_engine.h"
22#include "engine_base.h"
23#include "ground_vehicle.hpp"
24#include "newgrf_cargo.h"
25#include "newgrf_sound.h"
27#include "newgrf_station.h"
28#include "newgrf_airporttiles.h"
29#include "newgrf_roadstop.h"
30#include "object.h"
31#include "strings_func.h"
32#include "vehicle_func.h"
33#include "sound_func.h"
34#include "autoreplace_func.h"
35#include "company_gui.h"
36#include "signs_base.h"
37#include "subsidy_base.h"
38#include "subsidy_func.h"
39#include "station_base.h"
40#include "waypoint_base.h"
41#include "economy_base.h"
42#include "core/pool_func.hpp"
43#include "core/backup_type.hpp"
45#include "cargo_type.h"
46#include "water.h"
47#include "game/game.hpp"
48#include "cargomonitor.h"
49#include "goal_base.h"
50#include "story_base.h"
51#include "linkgraph/refresh.h"
52#include "company_cmd.h"
53#include "economy_cmd.h"
54#include "vehicle_cmd.h"
55#include "timer/timer.h"
58
59#include "table/strings.h"
60#include "table/pricebase.h"
61
62#include "safeguards.h"
63
64
65/* Initialize the cargo payment-pool */
66CargoPaymentPool _cargo_payment_pool("CargoPayment");
68
69
80static inline int32_t BigMulS(const int32_t a, const int32_t b, const uint8_t shift)
81{
82 return (int32_t)((int64_t)a * (int64_t)b >> shift);
83}
84
85typedef std::vector<Industry *> SmallIndustryList;
86
91 { 120, 100}, // SCORE_VEHICLES
92 { 80, 100}, // SCORE_STATIONS
93 { 10000, 100}, // SCORE_MIN_PROFIT
94 { 50000, 50}, // SCORE_MIN_INCOME
95 { 100000, 100}, // SCORE_MAX_INCOME
96 { 40000, 400}, // SCORE_DELIVERED
97 { 8, 50}, // SCORE_CARGO
98 {10000000, 50}, // SCORE_MONEY
99 { 250000, 50}, // SCORE_LOAN
100 { 0, 0} // SCORE_TOTAL
101};
102
103int64_t _score_part[MAX_COMPANIES][SCORE_END];
104Economy _economy;
105Prices _price;
106static PriceMultipliers _price_base_multiplier;
107
115{
116 Owner owner = c->index;
117
118 uint num = 0;
119
120 for (const Station *st : Station::Iterate()) {
121 if (st->owner == owner) num += CountBits((uint8_t)st->facilities);
122 }
123
124 Money value = num * _price[PR_STATION_VALUE] * 25;
125
126 for (const Vehicle *v : Vehicle::Iterate()) {
127 if (v->owner != owner) continue;
128
129 if (v->type == VEH_TRAIN ||
130 v->type == VEH_ROAD ||
131 (v->type == VEH_AIRCRAFT && Aircraft::From(v)->IsNormalAircraft()) ||
132 v->type == VEH_SHIP) {
133 value += v->value * 3 >> 1;
134 }
135 }
136
137 return value;
138}
139
149Money CalculateCompanyValue(const Company *c, bool including_loan)
150{
152
153 /* Add real money value */
154 if (including_loan) value -= c->current_loan;
155 value += c->money;
156
157 return std::max<Money>(value, 1);
158}
159
177{
179
180 value += c->current_loan;
181 /* Negative balance is basically a loan. */
182 if (c->money < 0) {
183 value += -c->money;
184 }
185
186 for (int quarter = 0; quarter < 4; quarter++) {
187 value += std::max<Money>(c->old_economy[quarter].income + c->old_economy[quarter].expenses, 0) * 2;
188 }
189
190 return std::max<Money>(value, 1);
191}
192
202{
203 Owner owner = c->index;
204 int score = 0;
205
206 memset(_score_part[owner], 0, sizeof(_score_part[owner]));
207
208 /* Count vehicles */
209 {
210 Money min_profit = 0;
211 bool min_profit_first = true;
212 uint num = 0;
213
214 for (const Vehicle *v : Vehicle::Iterate()) {
215 if (v->owner != owner) continue;
216 if (IsCompanyBuildableVehicleType(v->type) && v->IsPrimaryVehicle()) {
217 if (v->profit_last_year > 0) num++; // For the vehicle score only count profitable vehicles
218 if (v->economy_age > VEHICLE_PROFIT_MIN_AGE) {
219 /* Find the vehicle with the lowest amount of profit */
220 if (min_profit_first || min_profit > v->profit_last_year) {
221 min_profit = v->profit_last_year;
222 min_profit_first = false;
223 }
224 }
225 }
226 }
227
228 min_profit >>= 8; // remove the fract part
229
230 _score_part[owner][SCORE_VEHICLES] = num;
231 /* Don't allow negative min_profit to show */
232 if (min_profit > 0) {
233 _score_part[owner][SCORE_MIN_PROFIT] = min_profit;
234 }
235 }
236
237 /* Count stations */
238 {
239 uint num = 0;
240 for (const Station *st : Station::Iterate()) {
241 /* Only count stations that are actually serviced */
242 if (st->owner == owner && (st->time_since_load <= 20 || st->time_since_unload <= 20)) num += CountBits((uint8_t)st->facilities);
243 }
244 _score_part[owner][SCORE_STATIONS] = num;
245 }
246
247 /* Generate statistics depending on recent income statistics */
248 {
249 int numec = std::min<uint>(c->num_valid_stat_ent, 12u);
250 if (numec != 0) {
251 const CompanyEconomyEntry *cee = c->old_economy;
252 Money min_income = cee->income + cee->expenses;
253 Money max_income = cee->income + cee->expenses;
254
255 do {
256 min_income = std::min(min_income, cee->income + cee->expenses);
257 max_income = std::max(max_income, cee->income + cee->expenses);
258 } while (++cee, --numec);
259
260 if (min_income > 0) {
261 _score_part[owner][SCORE_MIN_INCOME] = min_income;
262 }
263
264 _score_part[owner][SCORE_MAX_INCOME] = max_income;
265 }
266 }
267
268 /* Generate score depending on amount of transported cargo */
269 {
270 int numec = std::min<uint>(c->num_valid_stat_ent, 4u);
271 if (numec != 0) {
272 const CompanyEconomyEntry *cee = c->old_economy;
273 OverflowSafeInt64 total_delivered = 0;
274 do {
275 total_delivered += cee->delivered_cargo.GetSum<OverflowSafeInt64>();
276 } while (++cee, --numec);
277
278 _score_part[owner][SCORE_DELIVERED] = total_delivered;
279 }
280 }
281
282 /* Generate score for variety of cargo */
283 {
284 _score_part[owner][SCORE_CARGO] = c->old_economy->delivered_cargo.GetCount();
285 }
286
287 /* Generate score for company's money */
288 {
289 if (c->money > 0) {
290 _score_part[owner][SCORE_MONEY] = c->money;
291 }
292 }
293
294 /* Generate score for loan */
295 {
296 _score_part[owner][SCORE_LOAN] = _score_info[SCORE_LOAN].needed - c->current_loan;
297 }
298
299 /* Now we calculate the score for each item.. */
300 {
301 int total_score = 0;
302 int s;
303 score = 0;
304 for (ScoreID i = SCORE_BEGIN; i < SCORE_END; i++) {
305 /* Skip the total */
306 if (i == SCORE_TOTAL) continue;
307 /* Check the score */
308 s = Clamp<int64_t>(_score_part[owner][i], 0, _score_info[i].needed) * _score_info[i].score / _score_info[i].needed;
309 score += s;
310 total_score += _score_info[i].score;
311 }
312
313 _score_part[owner][SCORE_TOTAL] = score;
314
315 /* We always want the score scaled to SCORE_MAX (1000) */
316 if (total_score != SCORE_MAX) score = score * SCORE_MAX / total_score;
317 }
318
319 if (update) {
320 c->old_economy[0].performance_history = score;
323 }
324
326 return score;
327}
328
334void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
335{
336 /* We need to set _current_company to old_owner before we try to move
337 * the client. This is needed as it needs to know whether "you" really
338 * are the current local company. */
339 Backup<CompanyID> cur_company(_current_company, old_owner);
340 /* In all cases, make spectators of clients connected to that company */
342 if (old_owner == _local_company) {
343 /* Single player cheated to AI company.
344 * There are no spectators in singleplayer mode, so we must pick some other company. */
345 assert(!_networking);
347 for (const Company *c : Company::Iterate()) {
348 if (c->index != old_owner) {
349 SetLocalCompany(c->index);
350 break;
351 }
352 }
353 cur_company2.Restore();
354 assert(old_owner != _local_company);
355 }
356
357 assert(old_owner != new_owner);
358
359 /* Temporarily increase the company's money, to be sure that
360 * removing their property doesn't fail because of lack of money.
361 * Not too drastically though, because it could overflow */
362 if (new_owner == INVALID_OWNER) {
363 Company::Get(old_owner)->money = UINT64_MAX >> 2; // jackpot ;p
364 }
365
366 for (Subsidy *s : Subsidy::Iterate()) {
367 if (s->awarded == old_owner) {
368 if (new_owner == INVALID_OWNER) {
369 delete s;
370 } else {
371 s->awarded = new_owner;
372 }
373 }
374 }
376
377 /* Take care of rating and transport rights in towns */
378 for (Town *t : Town::Iterate()) {
379 /* If a company takes over, give the ratings to that company. */
380 if (new_owner != INVALID_OWNER) {
381 if (HasBit(t->have_ratings, old_owner)) {
382 if (HasBit(t->have_ratings, new_owner)) {
383 /* use max of the two ratings. */
384 t->ratings[new_owner] = std::max(t->ratings[new_owner], t->ratings[old_owner]);
385 } else {
386 SetBit(t->have_ratings, new_owner);
387 t->ratings[new_owner] = t->ratings[old_owner];
388 }
389 }
390 }
391
392 /* Reset the ratings for the old owner */
393 t->ratings[old_owner] = RATING_INITIAL;
394 ClrBit(t->have_ratings, old_owner);
395
396 /* Transfer exclusive rights */
397 if (t->exclusive_counter > 0 && t->exclusivity == old_owner) {
398 if (new_owner != INVALID_OWNER) {
399 t->exclusivity = new_owner;
400 } else {
401 t->exclusive_counter = 0;
402 t->exclusivity = INVALID_COMPANY;
403 }
404 }
405 }
406
407 {
408 for (Vehicle *v : Vehicle::Iterate()) {
409 if (v->owner == old_owner && IsCompanyBuildableVehicleType(v->type)) {
410 if (new_owner == INVALID_OWNER) {
411 if (v->Previous() == nullptr) delete v;
412 } else {
413 if (v->IsEngineCountable()) GroupStatistics::CountEngine(v, -1);
414 if (v->IsPrimaryVehicle()) GroupStatistics::CountVehicle(v, -1);
415 }
416 }
417 }
418 }
419
420 /* In all cases clear replace engine rules.
421 * Even if it was copied, it could interfere with new owner's rules */
423
424 if (new_owner == INVALID_OWNER) {
425 RemoveAllGroupsForCompany(old_owner);
426 } else {
427 Company *c = Company::Get(old_owner);
428 for (Group *g : Group::Iterate()) {
429 if (g->owner == old_owner) {
430 g->owner = new_owner;
431 g->number = c->freegroups.UseID(c->freegroups.NextID());
432 }
433 }
434 }
435
436 {
437 Company *new_company = new_owner == INVALID_OWNER ? nullptr : Company::Get(new_owner);
438
439 /* Override company settings to new company defaults in case we need to convert them.
440 * This is required as the CmdChangeServiceInt doesn't copy the supplied value when it is non-custom
441 */
442 if (new_owner != INVALID_OWNER) {
443 Company *old_company = Company::Get(old_owner);
444
446 old_company->settings.vehicle.servint_trains = new_company->settings.vehicle.servint_trains;
448 old_company->settings.vehicle.servint_ships = new_company->settings.vehicle.servint_ships;
450 }
451
452 for (Vehicle *v : Vehicle::Iterate()) {
453 if (v->owner == old_owner && IsCompanyBuildableVehicleType(v->type)) {
454 assert(new_owner != INVALID_OWNER);
455
456 /* Correct default values of interval settings while maintaining custom set ones.
457 * This prevents invalid values on mismatching company defaults being accepted.
458 */
459 if (!v->ServiceIntervalIsCustom()) {
460 /* Technically, passing the interval is not needed as the command will query the default value itself.
461 * However, do not rely on that behaviour.
462 */
463 int interval = CompanyServiceInterval(new_company, v->type);
465 }
466
467 v->owner = new_owner;
468
469 /* Owner changes, clear cache */
470 v->colourmap = PAL_NONE;
471 v->InvalidateNewGRFCache();
472
473 if (v->IsEngineCountable()) {
475 }
476 if (v->IsPrimaryVehicle()) {
478 auto &unitidgen = new_company->freeunits[v->type];
479 v->unitnumber = unitidgen.UseID(unitidgen.NextID());
480 }
481
482 /* Invalidate the vehicle's cargo payment "owner cache". */
483 if (v->cargo_payment != nullptr) v->cargo_payment->owner = nullptr;
484 }
485 }
486
487 if (new_owner != INVALID_OWNER) GroupStatistics::UpdateAutoreplace(new_owner);
488 }
489
490 /* Change ownership of tiles */
491 {
492 for (const auto tile : Map::Iterate()) {
493 ChangeTileOwner(tile, old_owner, new_owner);
494 }
495
496 if (new_owner != INVALID_OWNER) {
497 /* Update all signals because there can be new segment that was owned by two companies
498 * and signals were not propagated
499 * Similar with crossings - it is needed to bar crossings that weren't before
500 * because of different owner of crossing and approaching train */
501 for (const auto tile : Map::Iterate()) {
502 if (IsTileType(tile, MP_RAILWAY) && IsTileOwner(tile, new_owner) && HasSignals(tile)) {
503 TrackBits tracks = GetTrackBits(tile);
504 do { // there may be two tracks with signals for TRACK_BIT_HORZ and TRACK_BIT_VERT
505 Track track = RemoveFirstTrack(&tracks);
506 if (HasSignalOnTrack(tile, track)) AddTrackToSignalBuffer(tile, track, new_owner);
507 } while (tracks != TRACK_BIT_NONE);
508 } else if (IsLevelCrossingTile(tile) && IsTileOwner(tile, new_owner)) {
510 }
511 }
512 }
513
514 /* update signals in buffer */
516 }
517
518 /* Add airport infrastructure count of the old company to the new one. */
519 if (new_owner != INVALID_OWNER) Company::Get(new_owner)->infrastructure.airport += Company::Get(old_owner)->infrastructure.airport;
520
521 /* convert owner of stations (including deleted ones, but excluding buoys) */
522 for (Station *st : Station::Iterate()) {
523 if (st->owner == old_owner) {
524 /* if a company goes bankrupt, set owner to OWNER_NONE so the sign doesn't disappear immediately
525 * also, drawing station window would cause reading invalid company's colour */
526 st->owner = new_owner == INVALID_OWNER ? OWNER_NONE : new_owner;
527 }
528 }
529
530 /* do the same for waypoints (we need to do this here so deleted waypoints are converted too) */
531 for (Waypoint *wp : Waypoint::Iterate()) {
532 if (wp->owner == old_owner) {
533 wp->owner = new_owner == INVALID_OWNER ? OWNER_NONE : new_owner;
534 }
535 }
536
537 for (Sign *si : Sign::Iterate()) {
538 if (si->owner == old_owner) si->owner = new_owner == INVALID_OWNER ? OWNER_NONE : new_owner;
539 }
540
541 /* Remove Game Script created Goals, CargoMonitors and Story pages. */
542 for (Goal *g : Goal::Iterate()) {
543 if (g->company == old_owner) delete g;
544 }
545
548
549 for (StoryPage *sp : StoryPage::Iterate()) {
550 if (sp->company == old_owner) delete sp;
551 }
552
553 /* Change colour of existing windows */
554 if (new_owner != INVALID_OWNER) ChangeWindowOwner(old_owner, new_owner);
555
556 cur_company.Restore();
557
559}
560
566{
567 /* If "Infinite money" setting is on, companies should not go bankrupt. */
569
570 /* If the company has money again, it does not go bankrupt */
571 if (c->money - c->current_loan >= -c->GetMaxLoan()) {
572 int previous_months_of_bankruptcy = CeilDiv(c->months_of_bankruptcy, 3);
574 c->bankrupt_asked = 0;
575 if (previous_months_of_bankruptcy != 0) CompanyAdminUpdate(c);
576 return;
577 }
578
580
581 switch (c->months_of_bankruptcy) {
582 /* All the boring cases (months) with a bad balance where no action is taken */
583 case 0:
584 case 1:
585 case 2:
586 case 3:
587
588 case 5:
589 case 6:
590
591 case 8:
592 case 9:
593 break;
594
595 /* Warn about bankruptcy after 3 months */
596 case 4: {
597 auto cni = std::make_unique<CompanyNewsInformation>(c);
598 SetDParam(0, STR_NEWS_COMPANY_IN_TROUBLE_TITLE);
599 SetDParam(1, STR_NEWS_COMPANY_IN_TROUBLE_DESCRIPTION);
600 SetDParamStr(2, cni->company_name);
601 AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, std::move(cni));
602 AI::BroadcastNewEvent(new ScriptEventCompanyInTrouble(c->index));
603 Game::NewEvent(new ScriptEventCompanyInTrouble(c->index));
604 break;
605 }
606
607 /* Offer company for sale after 6 months */
608 case 7: {
609 /* Don't consider the loan */
610 Money val = CalculateCompanyValue(c, false);
611
612 c->bankrupt_value = val;
613 c->bankrupt_asked = 1 << c->index; // Don't ask the owner
614 c->bankrupt_timeout = 0;
615
616 /* The company assets should always have some value */
617 assert(c->bankrupt_value > 0);
618 break;
619 }
620
621 /* Bankrupt company after 6 months (if the company has no value) or latest
622 * after 9 months (if it still had value after 6 months) */
623 default:
624 case 10: {
625 if (!_networking && _local_company == c->index) {
626 /* If we are in singleplayer mode, leave the company playing. Eg. there
627 * is no THE-END, otherwise mark the client as spectator to make sure
628 * they are no longer in control of this company. However... when you
629 * join another company (cheat) the "unowned" company can bankrupt. */
630 c->bankrupt_asked = MAX_UVALUE(CompanyMask);
631 break;
632 }
633
634 /* Actually remove the company, but not when we're a network client.
635 * In case of network clients we will be getting a command from the
636 * server. It is done in this way as we are called from the
637 * StateGameLoop which can't change the current company, and thus
638 * updating the local company triggers an assert later on. In the
639 * case of a network game the command will be processed at a time
640 * that changing the current company is okay. In case of single
641 * player we are sure (the above check) that we are not the local
642 * company and thus we won't be moved. */
645 return;
646 }
647 break;
648 }
649 }
650
652}
653
659{
660 /* Check for bankruptcy each month */
661 for (Company *c : Company::Iterate()) {
663 }
664
666
667 /* Pay Infrastructure Maintenance, if enabled */
669 /* Improved monthly infrastructure costs. */
670 for (const Company *c : Company::Iterate()) {
671 cur_company.Change(c->index);
672
674 uint32_t rail_total = c->infrastructure.GetRailTotal();
675 for (RailType rt = RAILTYPE_BEGIN; rt < RAILTYPE_END; rt++) {
676 if (c->infrastructure.rail[rt] != 0) cost.AddCost(RailMaintenanceCost(rt, c->infrastructure.rail[rt], rail_total));
677 }
678 cost.AddCost(SignalMaintenanceCost(c->infrastructure.signal));
679 uint32_t road_total = c->infrastructure.GetRoadTotal();
680 uint32_t tram_total = c->infrastructure.GetTramTotal();
681 for (RoadType rt = ROADTYPE_BEGIN; rt < ROADTYPE_END; rt++) {
682 if (c->infrastructure.road[rt] != 0) cost.AddCost(RoadMaintenanceCost(rt, c->infrastructure.road[rt], RoadTypeIsRoad(rt) ? road_total : tram_total));
683 }
684 cost.AddCost(CanalMaintenanceCost(c->infrastructure.water));
685 cost.AddCost(StationMaintenanceCost(c->infrastructure.station));
686 cost.AddCost(AirportMaintenanceCost(c->index));
687
689 }
690 }
691 cur_company.Restore();
692
693 /* Only run the economic statics and update company stats every 3rd economy month (1st of quarter). */
694 if (!HasBit(1 << 0 | 1 << 3 | 1 << 6 | 1 << 9, TimerGameEconomy::month)) return;
695
696 for (Company *c : Company::Iterate()) {
697 /* Drop the oldest history off the end */
698 std::copy_backward(c->old_economy, c->old_economy + MAX_HISTORY_QUARTERS - 1, c->old_economy + MAX_HISTORY_QUARTERS);
699 c->old_economy[0] = c->cur_economy;
700 c->cur_economy = {};
701
702 if (c->num_valid_stat_ent != MAX_HISTORY_QUARTERS) c->num_valid_stat_ent++;
703
705 if (c->block_preview != 0) c->block_preview--;
706 }
707
714}
715
721bool AddInflation(bool check_year)
722{
723 /* The cargo payment inflation differs from the normal inflation, so the
724 * relative amount of money you make with a transport decreases slowly over
725 * the 170 years. After a few hundred years we reach a level in which the
726 * games will become unplayable as the maximum income will be less than
727 * the minimum running cost.
728 *
729 * Furthermore there are a lot of inflation related overflows all over the
730 * place. Solving them is hardly possible because inflation will always
731 * reach the overflow threshold some day. So we'll just perform the
732 * inflation mechanism during the first 170 years (the amount of years that
733 * one had in the original TTD) and stop doing the inflation after that
734 * because it only causes problems that can't be solved nicely and the
735 * inflation doesn't add anything after that either; it even makes playing
736 * it impossible due to the diverging cost and income rates.
737 */
738 if (check_year && (TimerGameCalendar::year < CalendarTime::ORIGINAL_BASE_YEAR || TimerGameCalendar::year >= CalendarTime::ORIGINAL_MAX_YEAR)) return true;
739
740 if (_economy.inflation_prices == MAX_INFLATION || _economy.inflation_payment == MAX_INFLATION) return true;
741
742 /* Approximation for (100 + infl_amount)% ** (1 / 12) - 100%
743 * scaled by 65536
744 * 12 -> months per year
745 * This is only a good approximation for small values
746 */
747 _economy.inflation_prices += (_economy.inflation_prices * _economy.infl_amount * 54) >> 16;
748 _economy.inflation_payment += (_economy.inflation_payment * _economy.infl_amount_pr * 54) >> 16;
749
752
753 return false;
754}
755
760{
761 /* Setup maximum loan as a rounded down multiple of LOAN_INTERVAL. */
762 _economy.max_loan = ((uint64_t)_settings_game.difficulty.max_loan * _economy.inflation_prices >> 16) / LOAN_INTERVAL * LOAN_INTERVAL;
763
764 /* Setup price bases */
765 for (Price i = PR_BEGIN; i < PR_END; i++) {
766 Money price = _price_base_specs[i].start_price;
767
768 /* Apply difficulty settings */
769 uint mod = 1;
770 switch (_price_base_specs[i].category) {
771 case PCAT_RUNNING:
773 break;
774
777 break;
778
779 default: break;
780 }
781 switch (mod) {
782 case 0: price *= 6; break;
783 case 1: price *= 8; break; // normalised to 1 below
784 case 2: price *= 9; break;
785 default: NOT_REACHED();
786 }
787
788 /* Apply inflation */
789 price = (int64_t)price * _economy.inflation_prices;
790
791 /* Apply newgrf modifiers, remove fractional part of inflation, and normalise on medium difficulty. */
792 int shift = _price_base_multiplier[i] - 16 - 3;
793 if (shift >= 0) {
794 price <<= shift;
795 } else {
796 price >>= -shift;
797 }
798
799 /* Make sure the price does not get reduced to zero.
800 * Zero breaks quite a few commands that use a zero
801 * cost to see whether something got changed or not
802 * and based on that cause an error. When the price
803 * is zero that fails even when things are done. */
804 if (price == 0) {
805 price = Clamp(_price_base_specs[i].start_price, -1, 1);
806 /* No base price should be zero, but be sure. */
807 assert(price != 0);
808 }
809 /* Store value */
810 _price[i] = price;
811 }
812
813 /* Setup cargo payment */
814 for (CargoSpec *cs : CargoSpec::Iterate()) {
815 cs->current_payment = (cs->initial_payment * (int64_t)_economy.inflation_payment) >> 16;
816 }
817
823}
824
827{
829 for (const Company *c : Company::Iterate()) {
830 cur_company.Change(c->index);
831
832 /* Over a year the paid interest should be "loan * interest percentage",
833 * but... as that number is likely not dividable by 12 (pay each month),
834 * one needs to account for that in the monthly fee calculations.
835 *
836 * To easily calculate what one should pay "this" month, you calculate
837 * what (total) should have been paid up to this month and you subtract
838 * whatever has been paid in the previous months. This will mean one month
839 * it'll be a bit more and the other it'll be a bit less than the average
840 * monthly fee, but on average it will be exact.
841 *
842 * In order to prevent cheating or abuse (just not paying interest by not
843 * taking a loan) we make companies pay interest on negative cash as well,
844 * except if infinite money is enabled.
845 */
846 Money yearly_fee = c->current_loan * _economy.interest_rate / 100;
847 Money available_money = GetAvailableMoney(c->index);
848 if (available_money < 0) {
849 yearly_fee += -available_money * _economy.interest_rate / 100;
850 }
851 Money up_to_previous_month = yearly_fee * TimerGameEconomy::month / 12;
852 Money up_to_this_month = yearly_fee * (TimerGameEconomy::month + 1) / 12;
853
854 SubtractMoneyFromCompany(CommandCost(EXPENSES_LOAN_INTEREST, up_to_this_month - up_to_previous_month));
855
856 SubtractMoneyFromCompany(CommandCost(EXPENSES_OTHER, _price[PR_STATION_VALUE] >> 2));
857 }
858 cur_company.Restore();
859}
860
861static void HandleEconomyFluctuations()
862{
864 /* When economy is Fluctuating, decrease counter */
865 _economy.fluct--;
866 } else if (EconomyIsInRecession()) {
867 /* When it's Steady and we are in recession, end it now */
868 _economy.fluct = -12;
869 } else {
870 /* No need to do anything else in other cases */
871 return;
872 }
873
874 if (_economy.fluct == 0) {
875 _economy.fluct = -(int)GB(Random(), 0, 2);
876 AddNewsItem(STR_NEWS_BEGIN_OF_RECESSION, NT_ECONOMY, NF_NORMAL);
877 } else if (_economy.fluct == -12) {
878 _economy.fluct = GB(Random(), 0, 8) + 312;
879 AddNewsItem(STR_NEWS_END_OF_RECESSION, NT_ECONOMY, NF_NORMAL);
880 }
881}
882
883
888{
889 memset(_price_base_multiplier, 0, sizeof(_price_base_multiplier));
890}
891
899void SetPriceBaseMultiplier(Price price, int factor)
900{
901 assert(price < PR_END);
902 _price_base_multiplier[price] = Clamp(factor, MIN_PRICE_MODIFIER, MAX_PRICE_MODIFIER);
903}
904
909void StartupIndustryDailyChanges(bool init_counter)
910{
911 uint map_size = Map::LogX() + Map::LogY();
912 /* After getting map size, it needs to be scaled appropriately and divided by 31,
913 * which stands for the days in a month.
914 * Using just 31 will make it so that a monthly reset (based on the real number of days of that month)
915 * would not be needed.
916 * Since it is based on "fractional parts", the leftover days will not make much of a difference
917 * on the overall total number of changes performed */
918 _economy.industry_daily_increment = (1 << map_size) / 31;
919
920 if (init_counter) {
921 /* A new game or a savegame from an older version will require the counter to be initialized */
923 }
924}
925
926void StartupEconomy()
927{
930 _economy.infl_amount_pr = std::max(0, _settings_game.difficulty.initial_interest - 1);
931 _economy.fluct = GB(Random(), 0, 8) + 168;
932
934 /* Apply inflation that happened before our game start year. */
936 for (int i = 0; i < months; i++) {
937 AddInflation(false);
938 }
939 }
940
941 /* Set up prices */
943
944 StartupIndustryDailyChanges(true); // As we are starting a new game, initialize the counter too
945
946}
947
957
966Money GetPrice(Price index, uint cost_factor, const GRFFile *grf_file, int shift)
967{
968 if (index >= PR_END) return 0;
969
970 Money cost = _price[index] * cost_factor;
971 if (grf_file != nullptr) shift += grf_file->price_base_multipliers[index];
972
973 if (shift >= 0) {
974 cost <<= shift;
975 } else {
976 cost >>= -shift;
977 }
978
979 return cost;
980}
981
982Money GetTransportedGoodsIncome(uint num_pieces, uint dist, uint16_t transit_periods, CargoID cargo_type)
983{
984 const CargoSpec *cs = CargoSpec::Get(cargo_type);
985 if (!cs->IsValid()) {
986 /* User changed newgrfs and some vehicle still carries some cargo which is no longer available. */
987 return 0;
988 }
989
990 /* Use callback to calculate cargo profit, if available */
992 uint32_t var18 = ClampTo<uint16_t>(dist) | (ClampTo<uint8_t>(num_pieces) << 16) | (ClampTo<uint8_t>(transit_periods) << 24);
993 uint16_t callback = GetCargoCallback(CBID_CARGO_PROFIT_CALC, 0, var18, cs);
994 if (callback != CALLBACK_FAILED) {
995 int result = GB(callback, 0, 14);
996
997 /* Simulate a 15 bit signed value */
998 if (HasBit(callback, 14)) result -= 0x4000;
999
1000 /* "The result should be a signed multiplier that gets multiplied
1001 * by the amount of cargo moved and the price factor, then gets
1002 * divided by 8192." */
1003 return result * num_pieces * cs->current_payment / 8192;
1004 }
1005 }
1006
1007 static const int MIN_TIME_FACTOR = 31;
1008 static const int MAX_TIME_FACTOR = 255;
1009 static const int TIME_FACTOR_FRAC_BITS = 4;
1010 static const int TIME_FACTOR_FRAC = 1 << TIME_FACTOR_FRAC_BITS;
1011
1012 const int periods1 = cs->transit_periods[0];
1013 const int periods2 = cs->transit_periods[1];
1014 const int periods_over_periods1 = std::max(transit_periods - periods1, 0);
1015 const int periods_over_periods2 = std::max(periods_over_periods1 - periods2, 0);
1016 int periods_over_max = MIN_TIME_FACTOR - MAX_TIME_FACTOR;
1017 if (periods2 > -periods_over_max) {
1018 periods_over_max += transit_periods - periods1;
1019 } else {
1020 periods_over_max += 2 * (transit_periods - periods1) - periods2;
1021 }
1022
1023 /*
1024 * The time factor is calculated based on the time it took
1025 * (transit_periods) compared two cargo-depending values. The
1026 * range is divided into four parts:
1027 *
1028 * - constant for fast transits
1029 * - linear decreasing with time with a slope of -1 for medium transports
1030 * - linear decreasing with time with a slope of -2 for slow transports
1031 * - after hitting MIN_TIME_FACTOR, the time factor will be asymptotically decreased to a limit of 1 with a scaled 1/(x+1) function.
1032 *
1033 */
1034 if (periods_over_max > 0) {
1035 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.
1036 return BigMulS(dist * time_factor * num_pieces, cs->current_payment, 21 + TIME_FACTOR_FRAC_BITS);
1037 } else {
1038 const int time_factor = std::max(MAX_TIME_FACTOR - periods_over_periods1 - periods_over_periods2, MIN_TIME_FACTOR);
1039 return BigMulS(dist * time_factor * num_pieces, cs->current_payment, 21);
1040 }
1041}
1042
1044static SmallIndustryList _cargo_delivery_destinations;
1045
1056static uint DeliverGoodsToIndustry(const Station *st, CargoID cargo_type, uint num_pieces, IndustryID source, CompanyID company)
1057{
1058 /* Find the nearest industrytile to the station sign inside the catchment area, whose industry accepts the cargo.
1059 * This fails in three cases:
1060 * 1) The station accepts the cargo because there are enough houses around it accepting the cargo.
1061 * 2) The industries in the catchment area temporarily reject the cargo, and the daily station loop has not yet updated station acceptance.
1062 * 3) The results of callbacks CBID_INDUSTRY_REFUSE_CARGO and CBID_INDTILE_CARGO_ACCEPTANCE are inconsistent. (documented behaviour)
1063 */
1064
1065 uint accepted = 0;
1066
1067 for (const auto &i : st->industries_near) {
1068 if (num_pieces == 0) break;
1069
1070 Industry *ind = i.industry;
1071 if (ind->index == source) continue;
1072
1073 auto it = ind->GetCargoAccepted(cargo_type);
1074 /* Check if matching cargo has been found */
1075 if (it == std::end(ind->accepted)) continue;
1076
1077 /* Check if industry temporarily refuses acceptance */
1078 if (IndustryTemporarilyRefusesCargo(ind, cargo_type)) continue;
1079
1080 if (ind->exclusive_supplier != INVALID_OWNER && ind->exclusive_supplier != st->owner) continue;
1081
1082 /* Insert the industry into _cargo_delivery_destinations, if not yet contained */
1084
1085 uint amount = std::min(num_pieces, 0xFFFFu - it->waiting);
1086 it->waiting += amount;
1087 it->last_accepted = TimerGameEconomy::date;
1088 num_pieces -= amount;
1089 accepted += amount;
1090
1091 /* Update the cargo monitor. */
1092 AddCargoDelivery(cargo_type, company, amount, SourceType::Industry, source, st, ind->index);
1093 }
1094
1095 return accepted;
1096}
1097
1111static Money DeliverGoods(int num_pieces, CargoID cargo_type, StationID dest, uint distance, uint16_t periods_in_transit, Company *company, SourceType src_type, SourceID src)
1112{
1113 assert(num_pieces > 0);
1114
1115 Station *st = Station::Get(dest);
1116
1117 /* Give the goods to the industry. */
1118 uint accepted_ind = DeliverGoodsToIndustry(st, cargo_type, num_pieces, src_type == SourceType::Industry ? src : INVALID_INDUSTRY, company->index);
1119
1120 /* If this cargo type is always accepted, accept all */
1121 uint accepted_total = HasBit(st->always_accepted, cargo_type) ? num_pieces : accepted_ind;
1122
1123 /* Update station statistics */
1124 if (accepted_total > 0) {
1128 }
1129
1130 /* Update company statistics */
1131 company->cur_economy.delivered_cargo[cargo_type] += accepted_total;
1132
1133 /* Increase town's counter for town effects */
1134 const CargoSpec *cs = CargoSpec::Get(cargo_type);
1135 st->town->received[cs->town_acceptance_effect].new_act += accepted_total;
1136
1137 /* Determine profit */
1138 Money profit = GetTransportedGoodsIncome(accepted_total, distance, periods_in_transit, cargo_type);
1139
1140 /* Update the cargo monitor. */
1141 AddCargoDelivery(cargo_type, company->index, accepted_total - accepted_ind, src_type, src, st);
1142
1143 /* Modify profit if a subsidy is in effect */
1144 if (CheckSubsidised(cargo_type, company->index, src_type, src, st)) {
1146 case 0: profit += profit >> 1; break;
1147 case 1: profit *= 2; break;
1148 case 2: profit *= 3; break;
1149 default: profit *= 4; break;
1150 }
1151 }
1152
1153 return profit;
1154}
1155
1162{
1163 const IndustrySpec *indspec = GetIndustrySpec(i->type);
1164 uint16_t callback = indspec->callback_mask;
1165
1166 i->was_cargo_delivered = true;
1167
1171 } else {
1173 }
1174 } else {
1175 for (auto ita = std::begin(i->accepted); ita != std::end(i->accepted); ++ita) {
1176 if (ita->waiting == 0 || !IsValidCargoID(ita->cargo)) continue;
1177
1178 for (auto itp = std::begin(i->produced); itp != std::end(i->produced); ++itp) {
1179 if (!IsValidCargoID(itp->cargo)) continue;
1180 itp->waiting = ClampTo<uint16_t>(itp->waiting + (ita->waiting * indspec->input_cargo_multiplier[ita - std::begin(i->accepted)][itp - std::begin(i->produced)] / 256));
1181 }
1182
1183 ita->waiting = 0;
1184 }
1185 }
1186
1188 StartStopIndustryTileAnimation(i, IAT_INDUSTRY_RECEIVED_CARGO);
1189}
1190
1196 current_station(front->last_station_visited),
1197 front(front)
1198{
1199}
1200
1201CargoPayment::~CargoPayment()
1202{
1203 if (this->CleaningPool()) return;
1204
1205 this->front->cargo_payment = nullptr;
1206
1207 if (this->visual_profit == 0 && this->visual_transfer == 0) return;
1208
1209 Backup<CompanyID> cur_company(_current_company, this->front->owner);
1210
1211 SubtractMoneyFromCompany(CommandCost(this->front->GetExpenseType(true), -this->route_profit));
1212 this->front->profit_this_year += (this->visual_profit + this->visual_transfer) << 8;
1213
1214 if (this->route_profit != 0 && IsLocalCompany() && !PlayVehicleSound(this->front, VSE_LOAD_UNLOAD)) {
1215 SndPlayVehicleFx(SND_14_CASHTILL, this->front);
1216 }
1217
1218 if (this->visual_transfer != 0) {
1219 ShowFeederIncomeAnimation(this->front->x_pos, this->front->y_pos,
1220 this->front->z_pos, this->visual_transfer, -this->visual_profit);
1221 } else {
1222 ShowCostOrIncomeAnimation(this->front->x_pos, this->front->y_pos,
1223 this->front->z_pos, -this->visual_profit);
1224 }
1225
1226 cur_company.Restore();
1227}
1228
1236void CargoPayment::PayFinalDelivery(CargoID cargo, const CargoPacket *cp, uint count, TileIndex current_tile)
1237{
1238 if (this->owner == nullptr) {
1239 this->owner = Company::Get(this->front->owner);
1240 }
1241
1242 /* Handle end of route payment */
1243 Money profit = DeliverGoods(count, cargo, this->current_station, cp->GetDistance(current_tile), cp->GetPeriodsInTransit(), this->owner, cp->GetSourceType(), cp->GetSourceID());
1244 this->route_profit += profit;
1245
1246 /* The vehicle's profit is whatever route profit there is minus feeder shares. */
1247 this->visual_profit += profit - cp->GetFeederShare(count);
1248}
1249
1258Money CargoPayment::PayTransfer(CargoID cargo, const CargoPacket *cp, uint count, TileIndex current_tile)
1259{
1260 /* Pay transfer vehicle the difference between the payment for the journey from
1261 * the source to the current point, and the sum of the previous transfer payments */
1262 Money profit = -cp->GetFeederShare(count) + GetTransportedGoodsIncome(
1263 count,
1264 cp->GetDistance(current_tile),
1265 cp->GetPeriodsInTransit(),
1266 cargo);
1267
1268 profit = profit * _settings_game.economy.feeder_payment_share / 100;
1269
1270 this->visual_transfer += profit; // accumulate transfer profits for whole vehicle
1271 return profit; // account for the (virtual) profit already made for the cargo packet
1272}
1273
1279{
1280 Station *curr_station = Station::Get(front_v->last_station_visited);
1281 curr_station->loading_vehicles.push_back(front_v);
1282
1283 /* At this moment loading cannot be finished */
1285
1286 /* Start unloading at the first possible moment */
1287 front_v->load_unload_ticks = 1;
1288
1289 assert(front_v->cargo_payment == nullptr);
1290 /* One CargoPayment per vehicle and the vehicle limit equals the
1291 * limit in number of CargoPayments. Can't go wrong. */
1294 front_v->cargo_payment = new CargoPayment(front_v);
1295
1296 StationIDStack next_station = front_v->GetNextStoppingStation();
1297 if (front_v->orders == nullptr || (front_v->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0) {
1299 for (Vehicle *v = front_v; v != nullptr; v = v->Next()) {
1300 const GoodsEntry *ge = &st->goods[v->cargo_type];
1301 if (v->cargo_cap > 0 && v->cargo.TotalCount() > 0) {
1302 v->cargo.Stage(
1304 front_v->last_station_visited, next_station,
1305 front_v->current_order.GetUnloadType(), ge,
1306 v->cargo_type, front_v->cargo_payment,
1307 v->GetCargoTile());
1308 if (v->cargo.UnloadCount() > 0) SetBit(v->vehicle_flags, VF_CARGO_UNLOADING);
1309 }
1310 }
1311 }
1312}
1313
1320static uint GetLoadAmount(Vehicle *v)
1321{
1322 const Engine *e = v->GetEngine();
1323 uint load_amount = e->info.load_amount;
1324
1325 /* The default loadamount for mail is 1/4 of the load amount for passengers */
1326 bool air_mail = v->type == VEH_AIRCRAFT && !Aircraft::From(v)->IsNormalAircraft();
1327 if (air_mail) load_amount = CeilDiv(load_amount, 4);
1328
1330 uint16_t cb_load_amount = CALLBACK_FAILED;
1331 if (e->GetGRF() != nullptr && e->GetGRF()->grf_version >= 8) {
1332 /* Use callback 36 */
1333 cb_load_amount = GetVehicleProperty(v, PROP_VEHICLE_LOAD_AMOUNT, CALLBACK_FAILED);
1334 } else if (HasBit(e->info.callback_mask, CBM_VEHICLE_LOAD_AMOUNT)) {
1335 /* Use callback 12 */
1336 cb_load_amount = GetVehicleCallback(CBID_VEHICLE_LOAD_AMOUNT, 0, 0, v->engine_type, v);
1337 }
1338 if (cb_load_amount != CALLBACK_FAILED) {
1339 if (e->GetGRF()->grf_version < 8) cb_load_amount = GB(cb_load_amount, 0, 8);
1340 if (cb_load_amount >= 0x100) {
1342 } else if (cb_load_amount != 0) {
1343 load_amount = cb_load_amount;
1344 }
1345 }
1346 }
1347
1348 /* Scale load amount the same as capacity */
1349 if (HasBit(e->info.misc_flags, EF_NO_DEFAULT_CARGO_MULTIPLIER) && !air_mail) load_amount = CeilDiv(load_amount * CargoSpec::Get(v->cargo_type)->multiplier, 0x100);
1350
1351 /* Zero load amount breaks a lot of things. */
1352 return std::max(1u, load_amount);
1353}
1354
1364template<class Taction>
1365bool IterateVehicleParts(Vehicle *v, Taction action)
1366{
1367 for (Vehicle *w = v; w != nullptr;
1368 w = w->HasArticulatedPart() ? w->GetNextArticulatedPart() : nullptr) {
1369 if (!action(w)) return false;
1370 if (w->type == VEH_TRAIN) {
1371 Train *train = Train::From(w);
1372 if (train->IsMultiheaded() && !action(train->other_multiheaded_part)) return false;
1373 }
1374 }
1375 if (v->type == VEH_AIRCRAFT && Aircraft::From(v)->IsNormalAircraft()) return action(v->Next());
1376 return true;
1377}
1378
1383{
1389 bool operator()(const Vehicle *v)
1390 {
1391 return v->cargo.StoredCount() == 0;
1392 }
1393};
1394
1399{
1401 CargoTypes &refit_mask;
1402
1410
1417 bool operator()(const Vehicle *v)
1418 {
1419 this->consist_capleft[v->cargo_type] -= v->cargo_cap - v->cargo.ReservedCount();
1420 this->refit_mask |= EngInfo(v->engine_type)->refit_mask;
1421 return true;
1422 }
1423};
1424
1429{
1431 StationID next_hop;
1432
1438 ReturnCargoAction(Station *st, StationID next_one) : st(st), next_hop(next_one) {}
1439
1446 {
1447 v->cargo.Return(UINT_MAX, &this->st->goods[v->cargo_type].cargo, this->next_hop, v->GetCargoTile());
1448 return true;
1449 }
1450};
1451
1456{
1461
1471
1479 {
1480 if (this->do_reserve) {
1481 this->st->goods[v->cargo_type].cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(),
1482 &v->cargo, this->next_station, v->GetCargoTile());
1483 }
1484 this->consist_capleft[v->cargo_type] += v->cargo_cap - v->cargo.RemainingCount();
1485 return true;
1486 }
1487};
1488
1497static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station *st, StationIDStack next_station, CargoID new_cid)
1498{
1499 Vehicle *v_start = v->GetFirstEnginePart();
1500 if (!IterateVehicleParts(v_start, IsEmptyAction())) return;
1501
1502 Backup<CompanyID> cur_company(_current_company, v->owner);
1503
1504 CargoTypes refit_mask = v->GetEngine()->info.refit_mask;
1505
1506 /* Remove old capacity from consist capacity and collect refit mask. */
1507 IterateVehicleParts(v_start, PrepareRefitAction(consist_capleft, refit_mask));
1508
1509 bool is_auto_refit = new_cid == CARGO_AUTO_REFIT;
1510 if (is_auto_refit) {
1511 /* Get a refittable cargo type with waiting cargo for next_station or INVALID_STATION. */
1512 new_cid = v_start->cargo_type;
1513 for (CargoID cid : SetCargoBitIterator(refit_mask)) {
1514 if (st->goods[cid].cargo.HasCargoFor(next_station)) {
1515 /* Try to find out if auto-refitting would succeed. In case the refit is allowed,
1516 * the returned refit capacity will be greater than zero. */
1517 auto [cc, refit_capacity, mail_capacity, cargo_capacities] = Command<CMD_REFIT_VEHICLE>::Do(DC_QUERY_COST, v_start->index, cid, 0xFF, true, false, 1); // Auto-refit and only this vehicle including artic parts.
1518 /* Try to balance different loadable cargoes between parts of the consist, so that
1519 * all of them can be loaded. Avoid a situation where all vehicles suddenly switch
1520 * to the first loadable cargo for which there is only one packet. If the capacities
1521 * are equal refit to the cargo of which most is available. This is important for
1522 * consists of only a single vehicle as those will generally have a consist_capleft
1523 * of 0 for all cargoes. */
1524 if (refit_capacity > 0 && (consist_capleft[cid] < consist_capleft[new_cid] ||
1525 (consist_capleft[cid] == consist_capleft[new_cid] &&
1526 st->goods[cid].cargo.AvailableCount() > st->goods[new_cid].cargo.AvailableCount()))) {
1527 new_cid = cid;
1528 }
1529 }
1530 }
1531 }
1532
1533 /* Refit if given a valid cargo. */
1534 if (new_cid < NUM_CARGO && new_cid != v_start->cargo_type) {
1535 /* INVALID_STATION because in the DT_MANUAL case that's correct and in the DT_(A)SYMMETRIC
1536 * cases the next hop of the vehicle doesn't really tell us anything if the cargo had been
1537 * "via any station" before reserving. We rather produce some more "any station" cargo than
1538 * misrouting it. */
1539 IterateVehicleParts(v_start, ReturnCargoAction(st, INVALID_STATION));
1540 CommandCost cost = std::get<0>(Command<CMD_REFIT_VEHICLE>::Do(DC_EXEC, v_start->index, new_cid, 0xFF, true, false, 1)); // Auto-refit and only this vehicle including artic parts.
1541 if (cost.Succeeded()) v->First()->profit_this_year -= cost.GetCost() << 8;
1542 }
1543
1544 /* Add new capacity to consist capacity and reserve cargo */
1545 IterateVehicleParts(v_start, FinalizeRefitAction(consist_capleft, st, next_station,
1546 is_auto_refit || (v->First()->current_order.GetLoadType() & OLFB_FULL_LOAD) != 0));
1547
1548 cur_company.Restore();
1549}
1550
1557static bool MayLoadUnderExclusiveRights(const Station *st, const Vehicle *v)
1558{
1559 return st->owner != OWNER_NONE || st->town->exclusive_counter == 0 || st->town->exclusivity == v->owner;
1560}
1561
1563 Station *st;
1564 StationIDStack *next_station;
1565
1566 ReserveCargoAction(Station *st, StationIDStack *next_station) :
1567 st(st), next_station(next_station) {}
1568
1569 bool operator()(Vehicle *v)
1570 {
1573 &v->cargo, *next_station, v->GetCargoTile());
1574 }
1575
1576 return true;
1577 }
1578
1579};
1580
1589static void ReserveConsist(Station *st, Vehicle *u, CargoArray *consist_capleft, StationIDStack *next_station)
1590{
1591 /* If there is a cargo payment not all vehicles of the consist have tried to do the refit.
1592 * In that case, only reserve if it's a fixed refit and the equivalent of "articulated chain"
1593 * a vehicle belongs to already has the right cargo. */
1594 bool must_reserve = !u->current_order.IsRefit() || u->cargo_payment == nullptr;
1595 for (Vehicle *v = u; v != nullptr; v = v->Next()) {
1596 assert(v->cargo_cap >= v->cargo.RemainingCount());
1597
1598 /* Exclude various ways in which the vehicle might not be the head of an equivalent of
1599 * "articulated chain". Also don't do the reservation if the vehicle is going to refit
1600 * to a different cargo and hasn't tried to do so, yet. */
1601 if (!v->IsArticulatedPart() &&
1602 (v->type != VEH_TRAIN || !Train::From(v)->IsRearDualheaded()) &&
1603 (v->type != VEH_AIRCRAFT || Aircraft::From(v)->IsNormalAircraft()) &&
1604 (must_reserve || u->current_order.GetRefitCargo() == v->cargo_type)) {
1605 IterateVehicleParts(v, ReserveCargoAction(st, next_station));
1606 }
1607 if (consist_capleft == nullptr || v->cargo_cap == 0) continue;
1608 (*consist_capleft)[v->cargo_type] += v->cargo_cap - v->cargo.RemainingCount();
1609 }
1610}
1611
1619static void UpdateLoadUnloadTicks(Vehicle *front, const Station *st, int ticks)
1620{
1622 /* Each platform tile is worth 2 rail vehicles. */
1623 int overhang = front->GetGroundVehicleCache()->cached_total_length - st->GetPlatformLength(front->tile) * TILE_SIZE;
1624 if (overhang > 0) {
1625 ticks <<= 1;
1626 ticks += (overhang * ticks) / 8;
1627 }
1628 }
1629 /* Always wait at least 1, otherwise we'll wait 'infinitively' long. */
1630 front->load_unload_ticks = std::max(1, ticks);
1631}
1632
1637static void LoadUnloadVehicle(Vehicle *front)
1638{
1639 assert(front->current_order.IsType(OT_LOADING));
1640
1641 StationID last_visited = front->last_station_visited;
1642 Station *st = Station::Get(last_visited);
1643
1644 StationIDStack next_station = front->GetNextStoppingStation();
1645 bool use_autorefit = front->current_order.IsRefit() && front->current_order.GetRefitCargo() == CARGO_AUTO_REFIT;
1646 CargoArray consist_capleft{};
1647 if (_settings_game.order.improved_load && use_autorefit ?
1648 front->cargo_payment == nullptr : (front->current_order.GetLoadType() & OLFB_FULL_LOAD) != 0) {
1649 ReserveConsist(st, front,
1650 (use_autorefit && front->load_unload_ticks != 0) ? &consist_capleft : nullptr,
1651 &next_station);
1652 }
1653
1654 /* We have not waited enough time till the next round of loading/unloading */
1655 if (front->load_unload_ticks != 0) return;
1656
1657 if (front->type == VEH_TRAIN && (!IsTileType(front->tile, MP_STATION) || GetStationIndex(front->tile) != st->index)) {
1658 /* The train reversed in the station. Take the "easy" way
1659 * out and let the train just leave as it always did. */
1661 front->load_unload_ticks = 1;
1662 return;
1663 }
1664
1665 int new_load_unload_ticks = 0;
1666 bool dirty_vehicle = false;
1667 bool dirty_station = false;
1668
1669 bool completely_emptied = true;
1670 bool anything_unloaded = false;
1671 bool anything_loaded = false;
1672 CargoTypes full_load_amount = 0;
1673 CargoTypes cargo_not_full = 0;
1674 CargoTypes cargo_full = 0;
1675 CargoTypes reservation_left = 0;
1676
1677 front->cur_speed = 0;
1678
1679 CargoPayment *payment = front->cargo_payment;
1680
1681 uint artic_part = 0; // Articulated part we are currently trying to load. (not counting parts without capacity)
1682 for (Vehicle *v = front; v != nullptr; v = v->Next()) {
1683 if (v == front || !v->Previous()->HasArticulatedPart()) artic_part = 0;
1684 if (v->cargo_cap == 0) continue;
1685 artic_part++;
1686
1687 GoodsEntry *ge = &st->goods[v->cargo_type];
1688
1689 if (HasBit(v->vehicle_flags, VF_CARGO_UNLOADING) && (front->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0) {
1690 uint cargo_count = v->cargo.UnloadCount();
1691 uint amount_unloaded = _settings_game.order.gradual_loading ? std::min(cargo_count, GetLoadAmount(v)) : cargo_count;
1692 bool remaining = false; // Are there cargo entities in this vehicle that can still be unloaded here?
1693
1694 if (!HasBit(ge->status, GoodsEntry::GES_ACCEPTANCE) && v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER) > 0) {
1695 /* The station does not accept our goods anymore. */
1697 /* Transfer instead of delivering. */
1699 v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER));
1700 } else {
1701 uint new_remaining = v->cargo.RemainingCount() + v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER);
1702 if (v->cargo_cap < new_remaining) {
1703 /* Return some of the reserved cargo to not overload the vehicle. */
1704 v->cargo.Return(new_remaining - v->cargo_cap, &ge->cargo, INVALID_STATION, v->GetCargoTile());
1705 }
1706
1707 /* Keep instead of delivering. This may lead to no cargo being unloaded, so ...*/
1709 v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER));
1710
1711 /* ... say we unloaded something, otherwise we'll think we didn't unload
1712 * something and we didn't load something, so we must be finished
1713 * at this station. Setting the unloaded means that we will get a
1714 * retry for loading in the next cycle. */
1715 anything_unloaded = true;
1716 }
1717 }
1718
1719 if (v->cargo.ActionCount(VehicleCargoList::MTA_TRANSFER) > 0) {
1720 /* Mark the station dirty if we transfer, but not if we only deliver. */
1721 dirty_station = true;
1722
1723 if (!ge->HasRating()) {
1724 /* Upon transferring cargo, make sure the station has a rating. Fake a pickup for the
1725 * first unload to prevent the cargo from quickly decaying after the initial drop. */
1726 ge->time_since_pickup = 0;
1728 }
1729 }
1730
1731 assert(payment != nullptr);
1732 amount_unloaded = v->cargo.Unload(amount_unloaded, &ge->cargo, v->cargo_type, payment, v->GetCargoTile());
1733 remaining = v->cargo.UnloadCount() > 0;
1734 if (amount_unloaded > 0) {
1735 dirty_vehicle = true;
1736 anything_unloaded = true;
1737 new_load_unload_ticks += amount_unloaded;
1738
1739 /* Deliver goods to the station */
1740 st->time_since_unload = 0;
1741 }
1742
1743 if (_settings_game.order.gradual_loading && remaining) {
1744 completely_emptied = false;
1745 } else {
1746 /* We have finished unloading (cargo count == 0) */
1747 ClrBit(v->vehicle_flags, VF_CARGO_UNLOADING);
1748 }
1749
1750 continue;
1751 }
1752
1753 /* Do not pick up goods when we have no-load set or loading is stopped. */
1754 if (front->current_order.GetLoadType() & OLFB_NO_LOAD || HasBit(front->vehicle_flags, VF_STOP_LOADING)) continue;
1755
1756 /* This order has a refit, if this is the first vehicle part carrying cargo and the whole vehicle is empty, try refitting. */
1757 if (front->current_order.IsRefit() && artic_part == 1) {
1758 HandleStationRefit(v, consist_capleft, st, next_station, front->current_order.GetRefitCargo());
1759 ge = &st->goods[v->cargo_type];
1760 }
1761
1762 /* As we're loading here the following link can carry the full capacity of the vehicle. */
1763 v->refit_cap = v->cargo_cap;
1764
1765 /* update stats */
1766 int t;
1767 switch (front->type) {
1768 case VEH_TRAIN:
1769 case VEH_SHIP:
1770 t = front->vcache.cached_max_speed;
1771 break;
1772
1773 case VEH_ROAD:
1774 t = front->vcache.cached_max_speed / 2;
1775 break;
1776
1777 case VEH_AIRCRAFT:
1778 t = Aircraft::From(front)->GetSpeedOldUnits(); // Convert to old units.
1779 break;
1780
1781 default: NOT_REACHED();
1782 }
1783
1784 /* if last speed is 0, we treat that as if no vehicle has ever visited the station. */
1785 ge->last_speed = ClampTo<uint8_t>(t);
1786 ge->last_age = ClampTo<uint8_t>(TimerGameCalendar::year - front->build_year);
1787
1788 assert(v->cargo_cap >= v->cargo.StoredCount());
1789 /* Capacity available for loading more cargo. */
1790 uint cap_left = v->cargo_cap - v->cargo.StoredCount();
1791
1792 if (cap_left > 0) {
1793 /* If vehicle can load cargo, reset time_since_pickup. */
1794 ge->time_since_pickup = 0;
1795
1796 /* If there's goods waiting at the station, and the vehicle
1797 * has capacity for it, load it on the vehicle. */
1798 if ((v->cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0 || ge->cargo.AvailableCount() > 0) && MayLoadUnderExclusiveRights(st, v)) {
1799 if (v->cargo.StoredCount() == 0) TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO);
1800 if (_settings_game.order.gradual_loading) cap_left = std::min(cap_left, GetLoadAmount(v));
1801
1802 uint loaded = ge->cargo.Load(cap_left, &v->cargo, next_station, v->GetCargoTile());
1803 if (v->cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) {
1804 /* Remember if there are reservations left so that we don't stop
1805 * loading before they're loaded. */
1806 SetBit(reservation_left, v->cargo_type);
1807 }
1808
1809 /* Store whether the maximum possible load amount was loaded or not.*/
1810 if (loaded == cap_left) {
1811 SetBit(full_load_amount, v->cargo_type);
1812 } else {
1813 ClrBit(full_load_amount, v->cargo_type);
1814 }
1815
1816 /* TODO: Regarding this, when we do gradual loading, we
1817 * should first unload all vehicles and then start
1818 * loading them. Since this will cause
1819 * VEHICLE_TRIGGER_EMPTY to be called at the time when
1820 * the whole vehicle chain is really totally empty, the
1821 * completely_emptied assignment can then be safely
1822 * removed; that's how TTDPatch behaves too. --pasky */
1823 if (loaded > 0) {
1824 completely_emptied = false;
1825 anything_loaded = true;
1826
1827 st->time_since_load = 0;
1828 st->last_vehicle_type = v->type;
1829
1830 if (ge->cargo.TotalCount() == 0) {
1831 TriggerStationRandomisation(st, st->xy, SRT_CARGO_TAKEN, v->cargo_type);
1832 TriggerStationAnimation(st, st->xy, SAT_CARGO_TAKEN, v->cargo_type);
1833 AirportAnimationTrigger(st, AAT_STATION_CARGO_TAKEN, v->cargo_type);
1834 TriggerRoadStopRandomisation(st, st->xy, RSRT_CARGO_TAKEN, v->cargo_type);
1835 TriggerRoadStopAnimation(st, st->xy, SAT_CARGO_TAKEN, v->cargo_type);
1836 }
1837
1838 new_load_unload_ticks += loaded;
1839
1840 dirty_vehicle = dirty_station = true;
1841 }
1842 }
1843 }
1844
1845 if (v->cargo.StoredCount() >= v->cargo_cap) {
1846 SetBit(cargo_full, v->cargo_type);
1847 } else {
1848 SetBit(cargo_not_full, v->cargo_type);
1849 }
1850 }
1851
1852 if (anything_loaded || anything_unloaded) {
1853 if (front->type == VEH_TRAIN) {
1855 TriggerStationAnimation(st, front->tile, SAT_TRAIN_LOADS);
1856 } else if (front->type == VEH_ROAD) {
1857 TriggerRoadStopRandomisation(st, front->tile, RSRT_VEH_LOADS);
1858 TriggerRoadStopAnimation(st, front->tile, SAT_TRAIN_LOADS);
1859 }
1860 }
1861
1862 /* Only set completely_emptied, if we just unloaded all remaining cargo */
1863 completely_emptied &= anything_unloaded;
1864
1865 if (!anything_unloaded) delete payment;
1866
1868 if (anything_loaded || anything_unloaded) {
1870 /* The time it takes to load one 'slice' of cargo or passengers depends
1871 * on the vehicle type - the values here are those found in TTDPatch */
1872 const uint gradual_loading_wait_time[] = { 40, 20, 10, 20 };
1873
1874 new_load_unload_ticks = gradual_loading_wait_time[front->type];
1875 }
1876 /* We loaded less cargo than possible for all cargo types and it's not full
1877 * load and we're not supposed to wait any longer: stop loading. */
1878 if (!anything_unloaded && full_load_amount == 0 && reservation_left == 0 && !(front->current_order.GetLoadType() & OLFB_FULL_LOAD) &&
1879 front->current_order_time >= std::max(front->current_order.GetTimetabledWait() - front->lateness_counter, 0)) {
1881 }
1882
1883 UpdateLoadUnloadTicks(front, st, new_load_unload_ticks);
1884 } else {
1885 UpdateLoadUnloadTicks(front, st, 20); // We need the ticks for link refreshing.
1886 bool finished_loading = true;
1887 if (front->current_order.GetLoadType() & OLFB_FULL_LOAD) {
1889 /* if the aircraft carries passengers and is NOT full, then
1890 * continue loading, no matter how much mail is in */
1891 if ((front->type == VEH_AIRCRAFT && IsCargoInClass(front->cargo_type, CC_PASSENGERS) && front->cargo_cap > front->cargo.StoredCount()) ||
1892 (cargo_not_full != 0 && (cargo_full & ~cargo_not_full) == 0)) { // There are still non-full cargoes
1893 finished_loading = false;
1894 }
1895 } else if (cargo_not_full != 0) {
1896 finished_loading = false;
1897 }
1898
1899 /* Refresh next hop stats if we're full loading to make the links
1900 * known to the distribution algorithm and allow cargo to be sent
1901 * along them. Otherwise the vehicle could wait for cargo
1902 * indefinitely if it hasn't visited the other links yet, or if the
1903 * links die while it's loading. */
1904 if (!finished_loading) LinkRefresher::Run(front, true, true);
1905 }
1906
1907 SB(front->vehicle_flags, VF_LOADING_FINISHED, 1, finished_loading);
1908 }
1909
1910 /* Calculate the loading indicator fill percent and display
1911 * In the Game Menu do not display indicators
1912 * If _settings_client.gui.loading_indicators == 2, show indicators (bool can be promoted to int as 0 or 1 - results in 2 > 0,1 )
1913 * if _settings_client.gui.loading_indicators == 1, _local_company must be the owner or must be a spectator to show ind., so 1 > 0
1914 * if _settings_client.gui.loading_indicators == 0, do not display indicators ... 0 is never greater than anything
1915 */
1916 if (_game_mode != GM_MENU && (_settings_client.gui.loading_indicators > (uint)(front->owner != _local_company && _local_company != COMPANY_SPECTATOR))) {
1917 StringID percent_up_down = STR_NULL;
1918 int percent = CalcPercentVehicleFilled(front, &percent_up_down);
1919 if (front->fill_percent_te_id == INVALID_TE_ID) {
1920 front->fill_percent_te_id = ShowFillingPercent(front->x_pos, front->y_pos, front->z_pos + 20, percent, percent_up_down);
1921 } else {
1922 UpdateFillingPercent(front->fill_percent_te_id, percent, percent_up_down);
1923 }
1924 }
1925
1926 if (completely_emptied) {
1927 /* Make sure the vehicle is marked dirty, since we need to update the NewGRF
1928 * properties such as weight, power and TE whenever the trigger runs. */
1929 dirty_vehicle = true;
1930 TriggerVehicle(front, VEHICLE_TRIGGER_EMPTY);
1931 }
1932
1933 if (dirty_vehicle) {
1936 front->MarkDirty();
1937 }
1938 if (dirty_station) {
1939 st->MarkTilesDirty(true);
1942 }
1943}
1944
1951{
1952 /* No vehicle is here... */
1953 if (st->loading_vehicles.empty()) return;
1954
1955 Vehicle *last_loading = nullptr;
1956
1957 /* Check if anything will be loaded at all. Otherwise we don't need to reserve either. */
1958 for (Vehicle *v : st->loading_vehicles) {
1959 if ((v->vehstatus & (VS_STOPPED | VS_CRASHED))) continue;
1960
1961 assert(v->load_unload_ticks != 0);
1962 if (--v->load_unload_ticks == 0) last_loading = v;
1963 }
1964
1965 /* We only need to reserve and load/unload up to the last loading vehicle.
1966 * Anything else will be forgotten anyway after returning from this function.
1967 *
1968 * Especially this means we do _not_ need to reserve cargo for a single
1969 * consist in a station which is not allowed to load yet because its
1970 * load_unload_ticks is still not 0.
1971 */
1972 if (last_loading == nullptr) return;
1973
1974 for (Vehicle *v : st->loading_vehicles) {
1975 if (!(v->vehstatus & (VS_STOPPED | VS_CRASHED))) LoadUnloadVehicle(v);
1976 if (v == last_loading) break;
1977 }
1978
1979 /* Call the production machinery of industries */
1982 }
1984}
1985
1989static IntervalTimer<TimerGameCalendar> _calendar_inflation_monthly({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::COMPANY}, [](auto)
1990{
1992 AddInflation();
1994 }
1995});
1996
2000static IntervalTimer<TimerGameEconomy> _economy_companies_monthly({ TimerGameEconomy::MONTH, TimerGameEconomy::Priority::COMPANY }, [](auto)
2001{
2004 HandleEconomyFluctuations();
2005});
2006
2007static void DoAcquireCompany(Company *c, bool hostile_takeover)
2008{
2009 CompanyID ci = c->index;
2010
2011 auto cni = std::make_unique<CompanyNewsInformation>(c, Company::Get(_current_company));
2012
2013 SetDParam(0, STR_NEWS_COMPANY_MERGER_TITLE);
2014 SetDParam(1, hostile_takeover ? STR_NEWS_MERGER_TAKEOVER_TITLE : STR_NEWS_COMPANY_MERGER_DESCRIPTION);
2015 SetDParamStr(2, cni->company_name);
2016 SetDParamStr(3, cni->other_company_name);
2017 SetDParam(4, c->bankrupt_value);
2018 AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, std::move(cni));
2019 AI::BroadcastNewEvent(new ScriptEventCompanyMerger(ci, _current_company));
2020 Game::NewEvent(new ScriptEventCompanyMerger(ci, _current_company));
2021
2023
2024 if (c->is_ai) AI::Stop(c->index);
2025
2031
2032 delete c;
2033}
2034
2045CommandCost CmdBuyCompany(DoCommandFlag flags, CompanyID target_company, bool hostile_takeover)
2046{
2047 Company *c = Company::GetIfValid(target_company);
2048 if (c == nullptr) return CMD_ERROR;
2049
2050 /* If you do a hostile takeover but the company went bankrupt, buy it via bankruptcy rules. */
2051 if (hostile_takeover && HasBit(c->bankrupt_asked, _current_company)) hostile_takeover = false;
2052
2053 /* Disable takeovers when not asked */
2054 if (!hostile_takeover && !HasBit(c->bankrupt_asked, _current_company)) return CMD_ERROR;
2055
2056 /* Only allow hostile takeover of AI companies and when in single player */
2057 if (hostile_takeover && !c->is_ai) return CMD_ERROR;
2058 if (hostile_takeover && _networking) return CMD_ERROR;
2059
2060 /* Disable taking over the local company in singleplayer mode */
2061 if (!_networking && _local_company == c->index) return CMD_ERROR;
2062
2063 /* Do not allow companies to take over themselves */
2064 if (target_company == _current_company) return CMD_ERROR;
2065
2066 /* Do not allow takeover if the resulting company would have too many vehicles. */
2067 if (!CheckTakeoverVehicleLimit(_current_company, target_company)) return CommandCost(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME);
2068
2069 /* Get the cost here as the company is deleted in DoAcquireCompany.
2070 * For bankruptcy this amount is calculated when the offer was made;
2071 * for hostile takeover you pay the current price. */
2072 CommandCost cost(EXPENSES_OTHER, hostile_takeover ? CalculateHostileTakeoverValue(c) : c->bankrupt_value);
2073
2074 if (flags & DC_EXEC) {
2075 DoAcquireCompany(c, hostile_takeover);
2076 }
2077 return cost;
2078}
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.
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr T SB(T &x, const uint8_t s, const uint8_t n, const U d)
Set n bits in x starting at bit s to d.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
constexpr uint CountBits(T value)
Counts the number of set bits 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 CargoID
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:22
bool IsValidCargoID(CargoID t)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:107
uint16_t SourceID
Contains either industry ID, town ID or company ID (or INVALID_SOURCE)
Definition cargo_type.h:143
SourceType
Types of cargo source and destination.
Definition cargo_type.h:137
@ Industry
Source/destination is an industry.
static const CargoID CARGO_AUTO_REFIT
Automatically choose cargo type when doing auto refitting.
Definition cargo_type.h:77
void ClearCargoDeliveryMonitoring(CompanyID company)
Clear all delivery cargo monitors.
void ClearCargoPickupMonitoring(CompanyID company)
Clear all pick-up cargo monitors.
void AddCargoDelivery(CargoID cargo_type, CompanyID company, uint32_t amount, SourceType src_type, SourceID src, const Station *st, IndustryID dest)
Cargo was delivered to its final destination, update the pickup and delivery maps.
Cargo transport monitoring declarations.
bool IsCargoInClass(CargoID c, CargoClass cc)
Does cargo c have cargo class cc?
Definition cargotype.h:239
@ CC_PASSENGERS
Passengers.
Definition cargotype.h:50
static void BroadcastNewEvent(ScriptEvent *event, CompanyID skip_company=MAX_COMPANIES)
Broadcast a new event to all active AIs.
Definition ai_core.cpp:263
static void Stop(CompanyID company)
Stop a company to be controlled by an AI.
Definition ai_core.cpp:107
@ 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.
UnitID UseID(UnitID index)
Use a unit number.
Definition vehicle.cpp:1863
UnitID NextID() const
Find first unused unit number.
Definition vehicle.cpp:1848
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
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 Reserve(uint max_move, VehicleCargoList *dest, StationIDStack next, TileIndex current_tile)
Reserves cargo for loading onto the vehicle.
uint Load(uint max_move, VehicleCargoList *dest, StationIDStack next, TileIndex current_tile)
Loads cargo onto a vehicle.
bool HasCargoFor(StationIDStack next) const
Check for cargo headed for a specific station.
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.
DoCommandFlag
List of flags for a command.
@ DC_BANKRUPT
company bankrupts, skip money check, skip vehicle on tile check in some cases
@ DC_QUERY_COST
query cost only, don't build.
@ DC_EXEC
execute the given command
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:1168
@ CCA_DELETE
Delete a company.
static const uint MAX_HISTORY_QUARTERS
The maximum number of quarters kept as performance's history.
Owner
Enum for all companies/owners.
@ INVALID_COMPANY
An invalid company.
@ INVALID_OWNER
An invalid owner.
@ COMPANY_SPECTATOR
The client is spectating.
@ OWNER_NONE
The tile has no ownership.
@ MAX_COMPANIES
Maximum number of companies.
@ 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:1557
static Money DeliverGoods(int num_pieces, CargoID cargo_type, StationID dest, uint distance, uint16_t periods_in_transit, Company *company, SourceType src_type, SourceID src)
Delivers goods to industries/towns and calculates the payment.
Definition economy.cpp:1111
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:1619
static uint DeliverGoodsToIndustry(const Station *st, CargoID cargo_type, uint num_pieces, IndustryID source, CompanyID company)
Transfer goods from station to industry.
Definition economy.cpp:1056
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:201
static IntervalTimer< TimerGameCalendar > _calendar_inflation_monthly({TimerGameCalendar::MONTH, TimerGameCalendar::Priority::COMPANY}, [](auto) { if(_settings_game.economy.inflation) { AddInflation();RecomputePrices();} })
Every calendar month update of inflation.
const ScoreInfo _score_info[]
Score info, values used for computing the detailed performance rating.
Definition economy.cpp:90
void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
Change the ownership of all the items of a company.
Definition economy.cpp:334
static void CompaniesPayInterest()
Let all companies pay the monthly interest on their loan.
Definition economy.cpp:826
void LoadUnloadStation(Station *st)
Load/unload the vehicles in this station according to the order they entered.
Definition economy.cpp:1950
void RecomputePrices()
Computes all prices, payments and maximum loan.
Definition economy.cpp:759
static void LoadUnloadVehicle(Vehicle *front)
Loads/unload the vehicle if possible.
Definition economy.cpp:1637
Money CalculateHostileTakeoverValue(const Company *c)
Calculate what you have to pay to take over a company.
Definition economy.cpp:176
static Money CalculateCompanyAssetValue(const Company *c)
Calculate the value of the assets of a company.
Definition economy.cpp:114
static SmallIndustryList _cargo_delivery_destinations
The industries we've currently brought cargo to.
Definition economy.cpp:1044
void PrepareUnload(Vehicle *front_v)
Prepare the vehicle to be unloaded.
Definition economy.cpp:1278
static 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.
static uint GetLoadAmount(Vehicle *v)
Gets the amount of cargo the given vehicle can load in the current tick.
Definition economy.cpp:1320
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:1589
CommandCost CmdBuyCompany(DoCommandFlag flags, CompanyID target_company, bool hostile_takeover)
Buy up another company.
Definition economy.cpp:2045
void SetPriceBaseMultiplier(Price price, int factor)
Change a price base by the given factor.
Definition economy.cpp:899
Money GetPrice(Price index, uint cost_factor, const GRFFile *grf_file, int shift)
Determine a certain price.
Definition economy.cpp:966
static void TriggerIndustryProduction(Industry *i)
Inform the industry about just delivered cargo DeliverGoodsToIndustry() silently incremented incoming...
Definition economy.cpp:1161
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:1365
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:80
void InitializeEconomy()
Resets economy to initial values.
Definition economy.cpp:951
static void CompanyCheckBankrupt(Company *c)
Check for bankruptcy of a company.
Definition economy.cpp:565
void ResetPriceBaseMultipliers()
Reset changes to the price base multipliers.
Definition economy.cpp:887
static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station *st, StationIDStack next_station, CargoID new_cid)
Refit a vehicle in a station.
Definition economy.cpp:1497
static void CompaniesGenStatistics()
Update the finances of all companies.
Definition economy.cpp:658
bool AddInflation(bool check_year)
Add monthly inflation.
Definition economy.cpp:721
Money CalculateCompanyValue(const Company *c, bool including_loan)
Calculate the value of the company.
Definition economy.cpp:149
void StartupIndustryDailyChanges(bool init_counter)
Initialize the variables that will maintain the daily industry change system.
Definition economy.cpp:909
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_MAX
The max score that can be in the performance history.
@ 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.
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.
@ PCAT_RUNNING
Price is affected by "vehicle running cost" difficulty setting.
@ PCAT_CONSTRUCTION
Price is affected by "construction cost" difficulty setting.
Base class for engines.
@ EF_NO_DEFAULT_CARGO_MULTIPLIER
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:243
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1529
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.
void ChangeTileOwner(TileIndex tile, Owner old_owner, Owner new_owner)
Change the owner of a tile.
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:550
void ShowFeederIncomeAnimation(int x, int y, int z, Money transfer, Money income)
Display animated feeder income.
Definition misc_gui.cpp:574
void UpdateFillingPercent(TextEffectID te_id, uint8_t percent, StringID string)
Update vehicle loading indicators.
Definition misc_gui.cpp:616
TextEffectID ShowFillingPercent(int x, int y, int z, uint8_t percent, StringID string)
Display vehicle loading indicators.
Definition misc_gui.cpp:601
bool _networking
are we in networking mode?
Definition network.cpp:65
bool _network_server
network-server is active
Definition network.cpp:66
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.
@ IAT_INDUSTRY_RECEIVED_CARGO
Trigger when cargo is received .
@ AAT_STATION_CARGO_TAKEN
Triggered when a cargo type is completely removed from the station (for all tiles at the same time).
@ SAT_TRAIN_LOADS
Trigger platform when train loads/unloads.
@ SAT_CARGO_TAKEN
Trigger station when cargo is completely taken.
@ CBM_IND_PRODUCTION_CARGO_ARRIVAL
call production callback when cargo arrives at the industry
@ CBM_IND_PRODUCTION_256_TICKS
call production callback every 256 ticks
@ 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.
@ CBM_VEHICLE_LOAD_AMOUNT
Load amount.
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
@ CBM_CARGO_PROFIT_CALC
custom profit calculation
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)
Evaluate a newgrf callback for vehicles.
Functions for NewGRF engines.
bool IndustryTemporarilyRefusesCargo(Industry *ind, CargoID cargo_type)
Check whether an industry temporarily refuses to accept a certain cargo.
void IndustryProductionCallback(Industry *ind, int reason)
Get the industry production callback and apply it to the industry.
void TriggerIndustry(Industry *ind, IndustryTileTrigger trigger)
Trigger a random trigger for all industry tiles.
NewGRF handling of industry tiles.
@ INDUSTRY_TRIGGER_RECEIVED_CARGO
Cargo has been delivered.
@ PROP_VEHICLE_LOAD_AMOUNT
Loading speed.
NewGRF definitions and structures for road stops.
@ RSRT_CARGO_TAKEN
Trigger roadstop when cargo is completely taken.
@ RSRT_VEH_LOADS
Trigger roadstop when road vehicle loads.
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(Station *st, TileIndex trigger_tile, StationRandomTrigger trigger, CargoID cargo_type)
Trigger station randomisation.
Header file for NewGRF stations.
@ SRT_TRAIN_LOADS
Trigger platform when train loads/unloads.
@ SRT_CARGO_TAKEN
Trigger station when cargo is completely taken.
Functions related to news.
void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceType reftype1=NR_NONE, uint32_t ref1=UINT32_MAX, NewsReferenceType reftype2=NR_NONE, uint32_t ref2=UINT32_MAX, std::unique_ptr< NewsAllocatedData > &&data=nullptr)
Add a new newsitem to be shown.
Definition news_gui.cpp:897
@ NT_ECONOMY
Economic changes (recession, industry up/dowm)
Definition news_type.h:31
@ NF_NORMAL
Normal news item. (Newspaper with text only)
Definition news_type.h:81
Functions related to objects.
void UpdateCompanyHQ(TileIndex tile, uint score)
Update the CompanyHQ to the state associated with the given score.
@ OLFB_FULL_LOAD
Full load all cargoes of the consist.
Definition order_type.h:64
@ OLFB_NO_LOAD
Do not load anything.
Definition order_type.h:66
@ OLF_FULL_LOAD_ANY
Full load a single cargo of the consist.
Definition order_type.h:65
@ OUFB_TRANSFER
Transfer all cargo onto the platform.
Definition order_type.h:55
@ OUFB_NO_UNLOAD
Totally no unloading will be done.
Definition order_type.h:56
@ OUFB_UNLOAD
Force unloading all cargo onto the platform, possibly not getting paid.
Definition order_type.h:54
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:430
Money SignalMaintenanceCost(uint32_t num)
Calculates the maintenance cost of a number of signals.
Definition rail.h:441
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:413
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:27
@ RAILTYPE_BEGIN
Used for iterations.
Definition rail_type.h:28
@ RAILTYPE_END
Used for iterations.
Definition rail_type.h:33
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:95
RoadType
The different roadtypes we support.
Definition road_type.h:25
@ ROADTYPE_END
Used for iterations.
Definition road_type.h:29
@ ROADTYPE_BEGIN
Used for iterations.
Definition road_type.h:26
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:57
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:56
void AddTrackToSignalBuffer(TileIndex tile, Track track, Owner owner)
Add track to signal update buffer.
Definition signal.cpp:592
void UpdateSignalsInBuffer()
Update signals in buffer Called from 'outside'.
Definition signal.cpp:576
Base class for signs.
Functions related to sound.
@ SND_14_CASHTILL
18 == 0x12 Income from cargo delivery
Definition sound_type.h:65
Money AirportMaintenanceCost(Owner owner)
Calculates the maintenance cost of all airports of a company.
Definition station.cpp:709
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
Definition of base types and functions in a cross-platform compatible way.
#define MAX_UVALUE(type)
The largest value that can be entered in a variable.
Definition stdafx.h:343
StoryPage base class.
void SetDParam(size_t n, uint64_t v)
Set a string parameter v at index n in the global string parameter array.
Definition strings.cpp:104
void SetDParamStr(size_t n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition strings.cpp:371
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.
TimerGameTick::Ticks lateness_counter
How many ticks late (or early if negative) this vehicle is.
uint16_t vehicle_flags
Used for gradual loading and other miscellaneous things (.
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:114
uint GetCount() const
Get the amount of cargos that have an amount.
Definition cargo_type.h:129
const T GetSum() const
Get the sum of all cargo amounts.
Definition cargo_type.h:120
Container for cargo from the same location and time.
Definition cargopacket.h:40
SourceID GetSourceID() const
Gets the ID of the cargo's source.
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.
SourceType GetSourceType() const
Gets the type of the cargo's source.
Helper class to perform the cargo payment.
CargoPayment()
Constructor for pool saveload.
Company * owner
NOSAVE: The owner of the vehicle.
Money PayTransfer(CargoID cargo, const CargoPacket *cp, uint count, TileIndex current_tile)
Handle payment for transfer of the given cargo packet.
Definition economy.cpp:1258
StationID current_station
NOSAVE: The current station.
void PayFinalDelivery(CargoID cargo, const CargoPacket *cp, uint count, TileIndex current_tile)
Handle payment for final delivery of the given cargo packet.
Definition economy.cpp:1236
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:76
uint16_t multiplier
Capacity multiplier for vehicles. (8 fractional bits)
Definition cargotype.h:82
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo ID.
Definition cargotype.h:139
static IterateWrapper Iterate(size_t from=0)
Returns an iterable ensemble of all valid CargoSpec.
Definition cargotype.h:195
uint8_t callback_mask
Bitmask of cargo callbacks that have to be called.
Definition cargotype.h:91
TownAcceptanceEffect town_acceptance_effect
The effect that delivering this cargo type has on towns. Also affects destination of subsidies.
Definition cargotype.h:88
bool IsValid() const
Tests for validity of this cargospec.
Definition cargotype.h:120
GUISettings gui
settings related to the GUI
Statistics about the economy.
Money income
The amount of income.
Money expenses
The amount of expenses.
Money company_value
The value of the company.
CargoArray delivered_cargo
The amount of delivered cargo.
int32_t performance_history
Company score (scale 0-1000)
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
CompanyEconomyEntry old_economy[MAX_HISTORY_QUARTERS]
Economic data of the company of the last MAX_HISTORY_QUARTERS quarters.
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.
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.
uint8_t misc_flags
Miscellaneous flags.
uint16_t 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:1456
CargoArray & consist_capleft
Capacities left in the consist.
Definition economy.cpp:1457
bool do_reserve
If the vehicle should reserve.
Definition economy.cpp:1460
StationIDStack & next_station
Next hops to reserve cargo for.
Definition economy.cpp:1459
bool operator()(Vehicle *v)
Reserve cargo from the station and update the remaining consist capacities with the vehicle's remaini...
Definition economy.cpp:1478
Station * st
Station to reserve cargo from.
Definition economy.cpp:1458
FinalizeRefitAction(CargoArray &consist_capleft, Station *st, StationIDStack &next_station, bool do_reserve)
Create a finalizing action.
Definition economy.cpp:1469
Dynamic data of a loaded NewGRF.
Definition newgrf.h:108
PriceMultipliers price_base_multipliers
Price base multipliers as set by the grf.
Definition newgrf.h:149
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:21
Stores station stats for a single cargo.
bool HasRating() const
Does this cargo have a rating at this station?
@ GES_ACCEPTANCE
Set when the station accepts the cargo currently for final deliveries.
@ GES_RATING
This indicates whether a cargo has a rating at the station.
@ GES_CURRENT_MONTH
Set when cargo was delivered for final delivery this month.
@ GES_EVER_ACCEPTED
Set when a vehicle ever delivered cargo to the station for final delivery.
@ GES_ACCEPTED_BIGTICK
Set when cargo was delivered for final delivery during the current STATION_ACCEPTANCE_TICKS interval.
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.
StationCargoList cargo
The cargo packets of cargo waiting in this station.
uint8_t status
Status of this cargo, see GoodsEntryStatus.
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:72
Defines the data structure for constructing industry.
uint16_t 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:66
IndustryType type
type of industry.
Definition industry.h:102
Owner exclusive_supplier
Which company has exclusive rights to deliver cargo (INVALID_OWNER = anyone)
Definition industry.h:117
AcceptedCargoes::iterator GetCargoAccepted(CargoID cargo)
Get accepted cargo slot for a specific cargo type.
Definition industry.h:189
ProducedCargoes produced
produced cargo slots
Definition industry.h:97
AcceptedCargoes accepted
accepted cargo slots
Definition industry.h:98
uint8_t was_cargo_delivered
flag that indicate this has been the closest industry chosen for cargo delivery by a station....
Definition industry.h:106
Action to check if a vehicle has no stored cargo.
Definition economy.cpp:1383
bool operator()(const Vehicle *v)
Checks if the vehicle has stored cargo.
Definition economy.cpp:1389
static IterateWrapper Iterate()
Returns an iterable ensemble of all Tiles.
Definition map_func.h:363
static debug_inline uint LogX()
Logarithm of the map size along the X side.
Definition map_func.h:251
static uint LogY()
Logarithm of the map size along the y side.
Definition map_func.h:261
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
CargoID GetRefitCargo() const
Get the cargo to to refit to.
Definition order_base.h:131
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition order_base.h:70
OrderLoadFlags GetLoadType() const
How must the consist be loaded?
Definition order_base.h:136
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:188
OrderUnloadFlags GetUnloadType() const
How must the consist be unloaded?
Definition order_base.h:138
bool IsRefit() const
Is this order a refit order.
Definition order_base.h:117
Tindex index
Index of this pool item.
static bool CleaningPool()
Returns current state of pool cleaning - yes or no.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
static Titem * Get(size_t index)
Returns Titem with given index.
Base class for all pools.
Definition pool_type.hpp:80
static constexpr size_t MAX_SIZE
Make template parameter accessible from outside.
Definition pool_type.hpp:84
Refit preparation action.
Definition economy.cpp:1399
CargoTypes & refit_mask
Bitmask of possible refit cargoes.
Definition economy.cpp:1401
PrepareRefitAction(CargoArray &consist_capleft, CargoTypes &refit_mask)
Create a refit preparation action.
Definition economy.cpp:1408
CargoArray & consist_capleft
Capacities left in the consist.
Definition economy.cpp:1400
bool operator()(const Vehicle *v)
Prepares for refitting of a vehicle, subtracting its free capacity from consist_capleft and adding th...
Definition economy.cpp:1417
Money start_price
Default value at game start, before adding multipliers.
Action for returning reserved cargo.
Definition economy.cpp:1429
Station * st
Station to give the returned cargo to.
Definition economy.cpp:1430
bool operator()(Vehicle *v)
Return all reserved cargo from a vehicle.
Definition economy.cpp:1445
ReturnCargoAction(Station *st, StationID next_one)
Construct a cargo return action.
Definition economy.cpp:1438
StationID next_hop
Next hop the cargo should be assigned to.
Definition economy.cpp:1431
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.
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
Returns an iterable ensemble of all valid stations of type T.
static Station * Get(size_t 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:285
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...
GoodsEntry goods[NUM_CARGO]
Goods at this station.
Struct about stories, current and completed.
Definition story_base.h:164
Struct about subsidies, offered and awarded.
Town data structure.
Definition town.h:54
TransportedCargoStat< uint16_t > received[NUM_TAE]
Cargo statistics about received cargotypes.
Definition town.h:80
CompanyID exclusivity
which company has exclusivity
Definition town.h:75
uint8_t exclusive_counter
months till the exclusivity expires
Definition town.h:76
'Train' is either a loco or a wagon.
Definition train.h:89
Tstorage new_act
Actually transported this month.
Definition town_type.h:117
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:747
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.
Vehicle * First() const
Get the first vehicle of this vehicle chain.
Order current_order
The current order (+ status, like: loading)
CargoID cargo_type
type of cargo this vehicle is carrying
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:3155
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.
bool CheckSubsidised(CargoID cargo_type, CompanyID company, SourceType src_type, SourceID src, const Station *st)
Tests whether given delivery is subsidised and possibly awards the subsidy to delivering company.
Definition subsidy.cpp:564
void RebuildSubsidisedSourceAndDestinationCache()
Perform a full rebuild of the subsidies cache.
Definition subsidy.cpp:134
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:43
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:1493
@ VF_STOP_LOADING
Don't load anymore during the next load cycle.
@ VF_CARGO_UNLOADING
Vehicle is unloading cargo.
@ VF_LOADING_FINISHED
Vehicle has finished loading.
@ VS_STOPPED
Vehicle is stopped by the player.
@ VS_CRASHED
Vehicle is crashed.
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.
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:1188
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition window.cpp:3127
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:3219
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition window.cpp:3101
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:3236
@ 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: