OpenTTD Source: src/economy.cpp Source File

OpenTTD Source 15.0-RC2

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