OpenTTD Source 20250205-master-gfd85ab1e2c
company_cmd.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10#include "stdafx.h"
11#include "company_base.h"
12#include "company_func.h"
13#include "company_gui.h"
14#include "core/backup_type.hpp"
15#include "town.h"
16#include "news_func.h"
17#include "command_func.h"
18#include "network/network.h"
22#include "ai/ai.hpp"
23#include "ai/ai_instance.hpp"
24#include "ai/ai_config.hpp"
26#include "window_func.h"
27#include "strings_func.h"
28#include "sound_func.h"
29#include "rail.h"
30#include "core/pool_func.hpp"
31#include "settings_func.h"
32#include "vehicle_base.h"
33#include "vehicle_func.h"
34#include "smallmap_gui.h"
35#include "game/game.hpp"
36#include "goal_base.h"
37#include "story_base.h"
38#include "company_cmd.h"
39#include "timer/timer.h"
42
44
45#include "table/strings.h"
46
47#include "safeguards.h"
48
50void UpdateObjectColours(const Company *c);
51
57
60
61
66Company::Company(StringID name_1, bool is_ai)
67{
68 this->name_1 = name_1;
69 this->location_of_HQ = INVALID_TILE;
70 this->is_ai = is_ai;
71 this->terraform_limit = (uint32_t)_settings_game.construction.terraform_frame_burst << 16;
72 this->clear_limit = (uint32_t)_settings_game.construction.clear_frame_burst << 16;
73 this->tree_limit = (uint32_t)_settings_game.construction.tree_frame_burst << 16;
74 this->build_object_limit = (uint32_t)_settings_game.construction.build_object_frame_burst << 16;
75
77}
78
81{
82 if (CleaningPool()) return;
83
85}
86
91void Company::PostDestructor(size_t index)
92{
97 /* If the currently shown error message has this company in it, then close it. */
99}
100
106{
107 if (this->max_loan == COMPANY_MAX_LOAN_DEFAULT) return _economy.max_loan;
108 return this->max_loan;
109}
110
117void SetLocalCompany(CompanyID new_company)
118{
119 /* company could also be COMPANY_SPECTATOR or OWNER_NONE */
120 assert(Company::IsValidID(new_company) || new_company == COMPANY_SPECTATOR || new_company == OWNER_NONE);
121
122 /* If actually changing to another company, several windows need closing */
123 bool switching_company = _local_company != new_company;
124
125 /* Delete the chat window, if you were team chatting. */
127
128 assert(IsLocalCompany());
129
130 _current_company = _local_company = new_company;
131
132 if (switching_company) {
134 /* Delete any construction windows... */
136 }
137
138 /* ... and redraw the whole screen. */
142}
143
150{
151 if (!Company::IsValidID(company)) return (TextColour)GetColourGradient(COLOUR_WHITE, SHADE_NORMAL) | TC_IS_PALETTE_COLOUR;
152 return (TextColour)GetColourGradient(_company_colours[company], SHADE_NORMAL) | TC_IS_PALETTE_COLOUR;
153}
154
161void DrawCompanyIcon(CompanyID c, int x, int y)
162{
163 DrawSprite(SPR_COMPANY_ICON, COMPANY_SPRITE_COLOUR(c), x, y);
164}
165
173{
174 if (!AreCompanyManagerFaceBitsValid(cmf, CMFV_GEN_ETHN, GE_WM)) return false;
175
177 bool has_moustache = !HasBit(ge, GENDER_FEMALE) && GetCompanyManagerFaceBits(cmf, CMFV_HAS_MOUSTACHE, ge) != 0;
178 bool has_tie_earring = !HasBit(ge, GENDER_FEMALE) || GetCompanyManagerFaceBits(cmf, CMFV_HAS_TIE_EARRING, ge) != 0;
179 bool has_glasses = GetCompanyManagerFaceBits(cmf, CMFV_HAS_GLASSES, ge) != 0;
180
181 if (!AreCompanyManagerFaceBitsValid(cmf, CMFV_EYE_COLOUR, ge)) return false;
182 for (CompanyManagerFaceVariable cmfv = CMFV_CHEEKS; cmfv < CMFV_END; cmfv++) {
183 switch (cmfv) {
184 case CMFV_MOUSTACHE: if (!has_moustache) continue; break;
185 case CMFV_LIPS:
186 case CMFV_NOSE: if (has_moustache) continue; break;
187 case CMFV_TIE_EARRING: if (!has_tie_earring) continue; break;
188 case CMFV_GLASSES: if (!has_glasses) continue; break;
189 default: break;
190 }
191 if (!AreCompanyManagerFaceBitsValid(cmf, cmfv, ge)) return false;
192 }
193
194 return true;
195}
196
202{
203 CompanyID cid = company->index;
204
207}
208
217{
218 if (_settings_game.difficulty.infinite_money) return INT64_MAX;
219 if (!Company::IsValidID(company)) return INT64_MAX;
220 return Company::Get(company)->money;
221}
222
234
242{
243 if (cost.GetCost() <= 0) return true;
245
247 if (c != nullptr && cost.GetCost() > c->money) {
248 SetDParam(0, cost.GetCost());
249 cost.MakeError(STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY);
250 return false;
251 }
252 return true;
253}
254
261{
262 if (cost.GetCost() == 0) return;
263 assert(cost.GetExpensesType() != INVALID_EXPENSES);
264
265 c->money -= cost.GetCost();
266 c->yearly_expenses[0][cost.GetExpensesType()] += cost.GetCost();
267
272 c->cur_economy.income -= cost.GetCost();
273 } else if (HasBit(1 << EXPENSES_TRAIN_RUN |
276 1 << EXPENSES_SHIP_RUN |
277 1 << EXPENSES_PROPERTY |
279 c->cur_economy.expenses -= cost.GetCost();
280 }
281
283}
284
290{
292 if (c != nullptr) SubtractMoneyFromAnyCompany(c, cost);
293}
294
301{
302 Company *c = Company::Get(company);
303 uint8_t m = c->money_fraction;
304 Money cost = cst.GetCost();
305
306 c->money_fraction = m - (uint8_t)cost;
307 cost >>= 8;
308 if (c->money_fraction > m) cost++;
309 if (cost != 0) SubtractMoneyFromAnyCompany(c, CommandCost(cst.GetExpensesType(), cost));
310}
311
312static constexpr void UpdateLandscapingLimit(uint32_t &limit, uint64_t per_64k_frames, uint64_t burst)
313{
314 limit = static_cast<uint32_t>(std::min<uint64_t>(limit + per_64k_frames, burst << 16));
315}
316
327
335{
337
338 if (owner != OWNER_TOWN) {
339 if (!Company::IsValidID(owner)) {
340 SetDParam(0, STR_COMPANY_SOMEONE);
341 } else {
342 SetDParam(0, STR_COMPANY_NAME);
343 SetDParam(1, owner);
344 }
345 } else {
346 assert(tile != 0);
347 const Town *t = ClosestTownFromTile(tile, UINT_MAX);
348
349 SetDParam(0, STR_TOWN_NAME);
350 SetDParam(1, t->index);
351 }
352}
353
354
364{
365 assert(owner < OWNER_END);
366 assert(owner != OWNER_TOWN || tile != 0);
367
368 if (owner == _current_company) return CommandCost();
369
370 SetDParamsForOwnedBy(owner, tile);
371 return CommandCost(STR_ERROR_OWNED_BY);
372}
373
382{
383 Owner owner = GetTileOwner(tile);
384
385 assert(owner < OWNER_END);
386
387 if (owner == _current_company) return CommandCost();
388
389 /* no need to get the name of the owner unless we're the local company (saves some time) */
390 if (IsLocalCompany()) SetDParamsForOwnedBy(owner, tile);
391 return CommandCost(STR_ERROR_OWNED_BY);
392}
393
399{
400 if (c->name_1 != STR_SV_UNNAMED) return;
401 if (c->last_build_coordinate == 0) return;
402
404
405 StringID str;
406 uint32_t strp;
407 std::string name;
408 if (t->name.empty() && IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_END)) {
409 str = t->townnametype - SPECSTR_TOWNNAME_START + SPECSTR_COMPANY_NAME_START;
410 strp = t->townnameparts;
411
412verify_name:;
413 /* No companies must have this name already */
414 for (const Company *cc : Company::Iterate()) {
415 if (cc->name_1 == str && cc->name_2 == strp) goto bad_town_name;
416 }
417
418 SetDParam(0, strp);
419 name = GetString(str);
420 if (Utf8StringLength(name) >= MAX_LENGTH_COMPANY_NAME_CHARS) goto bad_town_name;
421
422set_name:;
423 c->name_1 = str;
424 c->name_2 = strp;
425
427 AI::BroadcastNewEvent(new ScriptEventCompanyRenamed(c->index, name));
428 Game::NewEvent(new ScriptEventCompanyRenamed(c->index, name));
429
430 if (c->is_ai) {
431 auto cni = std::make_unique<CompanyNewsInformation>(c);
432 SetDParam(0, STR_NEWS_COMPANY_LAUNCH_TITLE);
433 SetDParam(1, STR_NEWS_COMPANY_LAUNCH_DESCRIPTION);
434 SetDParamStr(2, cni->company_name);
435 SetDParam(3, t->index);
436 AddNewsItem(STR_MESSAGE_NEWS_FORMAT, NT_COMPANY_INFO, NF_COMPANY, NR_TILE, c->last_build_coordinate.base(), NR_NONE, UINT32_MAX, std::move(cni));
437 }
438 return;
439 }
440bad_town_name:;
441
443 str = SPECSTR_ANDCO_NAME;
444 strp = c->president_name_2;
445 goto set_name;
446 } else {
447 str = SPECSTR_ANDCO_NAME;
448 strp = Random();
449 goto verify_name;
450 }
451}
452
454static const uint8_t _colour_sort[COLOUR_END] = {2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 2, 2, 3, 1, 1, 1};
456static const Colours _similar_colour[COLOUR_END][2] = {
457 { COLOUR_BLUE, COLOUR_LIGHT_BLUE }, // COLOUR_DARK_BLUE
458 { COLOUR_GREEN, COLOUR_DARK_GREEN }, // COLOUR_PALE_GREEN
459 { INVALID_COLOUR, INVALID_COLOUR }, // COLOUR_PINK
460 { COLOUR_ORANGE, INVALID_COLOUR }, // COLOUR_YELLOW
461 { INVALID_COLOUR, INVALID_COLOUR }, // COLOUR_RED
462 { COLOUR_DARK_BLUE, COLOUR_BLUE }, // COLOUR_LIGHT_BLUE
463 { COLOUR_PALE_GREEN, COLOUR_DARK_GREEN }, // COLOUR_GREEN
464 { COLOUR_PALE_GREEN, COLOUR_GREEN }, // COLOUR_DARK_GREEN
465 { COLOUR_DARK_BLUE, COLOUR_LIGHT_BLUE }, // COLOUR_BLUE
466 { COLOUR_BROWN, COLOUR_ORANGE }, // COLOUR_CREAM
467 { COLOUR_PURPLE, INVALID_COLOUR }, // COLOUR_MAUVE
468 { COLOUR_MAUVE, INVALID_COLOUR }, // COLOUR_PURPLE
469 { COLOUR_YELLOW, COLOUR_CREAM }, // COLOUR_ORANGE
470 { COLOUR_CREAM, INVALID_COLOUR }, // COLOUR_BROWN
471 { COLOUR_WHITE, INVALID_COLOUR }, // COLOUR_GREY
472 { COLOUR_GREY, INVALID_COLOUR }, // COLOUR_WHITE
473};
474
479static Colours GenerateCompanyColour()
480{
481 Colours colours[COLOUR_END];
482
483 /* Initialize array */
484 for (uint i = 0; i < COLOUR_END; i++) colours[i] = static_cast<Colours>(i);
485
486 /* And randomize it */
487 for (uint i = 0; i < 100; i++) {
488 uint r = Random();
489 Swap(colours[GB(r, 0, 4)], colours[GB(r, 4, 4)]);
490 }
491
492 /* Bubble sort it according to the values in table 1 */
493 for (uint i = 0; i < COLOUR_END; i++) {
494 for (uint j = 1; j < COLOUR_END; j++) {
495 if (_colour_sort[colours[j - 1]] < _colour_sort[colours[j]]) {
496 Swap(colours[j - 1], colours[j]);
497 }
498 }
499 }
500
501 /* Move the colours that look similar to each company's colour to the side */
502 for (const Company *c : Company::Iterate()) {
503 Colours pcolour = c->colour;
504
505 for (uint i = 0; i < COLOUR_END; i++) {
506 if (colours[i] == pcolour) {
507 colours[i] = INVALID_COLOUR;
508 break;
509 }
510 }
511
512 for (uint j = 0; j < 2; j++) {
513 Colours similar = _similar_colour[pcolour][j];
514 if (similar == INVALID_COLOUR) break;
515
516 for (uint i = 1; i < COLOUR_END; i++) {
517 if (colours[i - 1] == similar) Swap(colours[i - 1], colours[i]);
518 }
519 }
520 }
521
522 /* Return the first available colour */
523 for (uint i = 0; i < COLOUR_END; i++) {
524 if (colours[i] != INVALID_COLOUR) return colours[i];
525 }
526
527 NOT_REACHED();
528}
529
535{
536 for (;;) {
537restart:;
540
541 /* Reserve space for extra unicode character. We need to do this to be able
542 * to detect too long president name. */
543 SetDParam(0, c->index);
544 std::string name = GetString(STR_PRESIDENT_NAME);
546
547 for (const Company *cc : Company::Iterate()) {
548 if (c != cc) {
549 SetDParam(0, cc->index);
550 std::string other_name = GetString(STR_PRESIDENT_NAME);
551 if (name == other_name) goto restart;
552 }
553 }
554 return;
555 }
556}
557
564{
565 for (LiveryScheme scheme = LS_BEGIN; scheme < LS_END; scheme++) {
566 c->livery[scheme].in_use = 0;
567 c->livery[scheme].colour1 = c->colour;
568 c->livery[scheme].colour2 = c->colour;
569 }
570
571 for (Group *g : Group::Iterate()) {
572 if (g->owner == c->index) {
573 g->livery.in_use = 0;
574 g->livery.colour1 = c->colour;
575 g->livery.colour2 = c->colour;
576 }
577 }
578}
579
588{
589 if (!Company::CanAllocateItem()) return nullptr;
590
591 /* we have to generate colour before this company is valid */
592 Colours colour = GenerateCompanyColour();
593
594 Company *c;
595 if (company == INVALID_COMPANY) {
596 c = new Company(STR_SV_UNNAMED, is_ai);
597 } else {
598 if (Company::IsValidID(company)) return nullptr;
599 c = new (company) Company(STR_SV_UNNAMED, is_ai);
600 }
601
602 c->colour = colour;
603
606
607 /* Scale the initial loan based on the inflation rounded down to the loan interval. The maximum loan has already been inflation adjusted. */
608 c->money = c->current_loan = std::min<int64_t>((INITIAL_LOAN * _economy.inflation_prices >> 16) / LOAN_INTERVAL * LOAN_INTERVAL, _economy.max_loan);
609
614
615 /* If starting a player company in singleplayer and a favorite company manager face is selected, choose it. Otherwise, use a random face.
616 * In a network game, we'll choose the favorite face later in CmdCompanyCtrl to sync it to all clients. */
617 if (_company_manager_face != 0 && !is_ai && !_networking) {
619 } else {
621 }
622
625
627
633
634 if (is_ai && (!_networking || _network_server)) AI::StartNew(c->index);
635
636 AI::BroadcastNewEvent(new ScriptEventCompanyNew(c->index), c->index);
637 Game::NewEvent(new ScriptEventCompanyNew(c->index));
638
639 return c;
640}
641
643TimeoutTimer<TimerGameTick> _new_competitor_timeout({ TimerGameTick::Priority::COMPETITOR_TIMEOUT, 0 }, []() {
644 if (_game_mode == GM_MENU || !AI::CanStartNew()) return;
646
647 /* count number of competitors */
648 uint8_t n = 0;
649 for (const Company *c : Company::Iterate()) {
650 if (c->is_ai) n++;
651 }
652
654
655 /* Send a command to all clients to start up a new AI.
656 * Works fine for Multiplayer and Singleplayer */
658});
659
662{
663 /* Ensure the timeout is aborted, so it doesn't fire based on information of the last game. */
665}
666
672
690
701{
702 /* Amount of time out for each company to take over a company;
703 * Timeout is a quarter (3 months of 30 days) divided over the
704 * number of companies. The minimum number of days in a quarter
705 * is 90: 31 in January, 28 in February and 31 in March.
706 * Note that the company going bankrupt can't buy itself. */
707 static const int TAKE_OVER_TIMEOUT = 3 * 30 * Ticks::DAY_TICKS / (MAX_COMPANIES - 1);
708
709 assert(c->bankrupt_asked != 0);
710
711 /* We're currently asking some company to buy 'us' */
712 if (c->bankrupt_timeout != 0) {
714 if (c->bankrupt_timeout > 0) return;
715 c->bankrupt_timeout = 0;
716
717 return;
718 }
719
720 /* Did we ask everyone for bankruptcy? If so, bail out. */
721 if (c->bankrupt_asked == std::numeric_limits<CompanyMask>::max()) return;
722
723 Company *best = nullptr;
724 int32_t best_performance = -1;
725
726 /* Ask the company with the highest performance history first */
727 for (Company *c2 : Company::Iterate()) {
728 if (c2->bankrupt_asked == 0 && // Don't ask companies going bankrupt themselves
729 !HasBit(c->bankrupt_asked, c2->index) &&
730 best_performance < c2->old_economy[1].performance_history &&
731 CheckTakeoverVehicleLimit(c2->index, c->index)) {
732 best_performance = c2->old_economy[1].performance_history;
733 best = c2;
734 }
735 }
736
737 /* Asked all companies? */
738 if (best_performance == -1) {
739 c->bankrupt_asked = std::numeric_limits<CompanyMask>::max();
740 return;
741 }
742
743 SetBit(c->bankrupt_asked, best->index);
744
745 c->bankrupt_timeout = TAKE_OVER_TIMEOUT;
746
747 AI::NewEvent(best->index, new ScriptEventCompanyAskMerger(c->index, c->bankrupt_value));
748 if (IsInteractiveCompany(best->index)) {
749 ShowBuyCompanyDialog(c->index, false);
750 }
751}
752
755{
756 if (_game_mode == GM_EDITOR) return;
757
759 if (c != nullptr) {
760 if (c->name_1 != 0) GenerateCompanyName(c);
762 }
763
764 if (_new_competitor_timeout.HasFired() && _game_mode != GM_MENU && AI::CanStartNew()) {
766 /* If the interval is zero, start as many competitors as needed then check every ~10 minutes if a company went bankrupt and needs replacing. */
767 if (timeout == 0) {
768 /* count number of competitors */
769 uint8_t n = 0;
770 for (const Company *cc : Company::Iterate()) {
771 if (cc->is_ai) n++;
772 }
773
774 for (auto i = 0; i < _settings_game.difficulty.max_no_competitors; i++) {
778 }
779 timeout = 10 * 60 * Ticks::TICKS_PER_SECOND;
780 }
781 /* Randomize a bit when the AI is actually going to start; ranges from 87.5% .. 112.5% of indicated value. */
782 timeout += ScriptObject::GetRandomizer(OWNER_NONE).Next(timeout / 4) - timeout / 8;
783
784 _new_competitor_timeout.Reset({ TimerGameTick::Priority::COMPETITOR_TIMEOUT, static_cast<uint>(std::max(1, timeout)) });
785 }
786
788}
789
794static IntervalTimer<TimerGameEconomy> _economy_companies_yearly({TimerGameEconomy::YEAR, TimerGameEconomy::Priority::COMPANY}, [](auto)
795{
796 /* Copy statistics */
797 for (Company *c : Company::Iterate()) {
798 /* Move expenses to previous years. */
799 std::rotate(std::rbegin(c->yearly_expenses), std::rbegin(c->yearly_expenses) + 1, std::rend(c->yearly_expenses));
800 c->yearly_expenses[0] = {};
802 }
803
809 } else {
811 }
812 }
813});
814
821{
822 SetDParam(0, c->index);
823 this->company_name = GetString(STR_COMPANY_NAME);
824
825 if (other != nullptr) {
826 SetDParam(0, other->index);
827 this->other_company_name = GetString(STR_COMPANY_NAME);
828 c = other;
829 }
830
831 SetDParam(0, c->index);
832 this->president_name = GetString(STR_PRESIDENT_NAME_MANAGER);
833
834 this->colour = c->colour;
835 this->face = c->face;
836
837}
838
843void CompanyAdminUpdate(const Company *company)
844{
846}
847
857
867{
869
870 switch (cca) {
871 case CCA_NEW: { // Create a new company
872 /* This command is only executed in a multiplayer game */
873 if (!_networking) return CMD_ERROR;
874
875 /* Has the network client a correct ClientID? */
876 if (!(flags & DC_EXEC)) return CommandCost();
877
879
880 /* Delete multiplayer progress bar */
882
883 Company *c = DoStartupNewCompany(false);
884
885 /* A new company could not be created, revert to being a spectator */
886 if (c == nullptr) {
887 /* We check for "ci != nullptr" as a client could have left by
888 * the time we execute this command. */
889 if (_network_server && ci != nullptr) {
892 }
893 break;
894 }
895
898
899 /* This is the client (or non-dedicated server) who wants a new company */
900 if (client_id == _network_own_client_id) {
903
904 /*
905 * If a favorite company manager face is selected, choose it. Otherwise, use a random face.
906 * Because this needs to be synchronised over the network, only the client knows
907 * its configuration and we are currently in the execution of a command, we have
908 * to circumvent the normal ::Post logic for commands and just send the command.
909 */
911
912 /* Now that we have a new company, broadcast our company settings to
913 * all clients so everything is in sync */
915
917 }
918 break;
919 }
920
921 case CCA_NEW_AI: { // Make a new AI company
922 if (company_id != INVALID_COMPANY && company_id >= MAX_COMPANIES) return CMD_ERROR;
923
924 /* For network games, company deletion is delayed. */
925 if (!_networking && company_id != INVALID_COMPANY && Company::IsValidID(company_id)) return CMD_ERROR;
926
927 if (!(flags & DC_EXEC)) return CommandCost();
928
929 /* For network game, just assume deletion happened. */
930 assert(company_id == INVALID_COMPANY || !Company::IsValidID(company_id));
931
932 Company *c = DoStartupNewCompany(true, company_id);
933 if (c != nullptr) {
935 NetworkServerNewCompany(c, nullptr);
936 }
937 break;
938 }
939
940 case CCA_DELETE: { // Delete a company
941 if (reason >= CRR_END) return CMD_ERROR;
942
943 /* We can't delete the last existing company in singleplayer mode. */
944 if (!_networking && Company::GetNumItems() == 1) return CMD_ERROR;
945
946 Company *c = Company::GetIfValid(company_id);
947 if (c == nullptr) return CMD_ERROR;
948
949 if (!(flags & DC_EXEC)) return CommandCost();
950
951 auto cni = std::make_unique<CompanyNewsInformation>(c);
952
953 /* Show the bankrupt news */
954 SetDParam(0, STR_NEWS_COMPANY_BANKRUPT_TITLE);
955 SetDParam(1, STR_NEWS_COMPANY_BANKRUPT_DESCRIPTION);
956 SetDParamStr(2, cni->company_name);
957 AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, std::move(cni));
958
959 /* Remove the company */
961 if (c->is_ai) AI::Stop(c->index);
962
963 CompanyID c_index = c->index;
964 delete c;
965 AI::BroadcastNewEvent(new ScriptEventCompanyBankrupt(c_index));
966 Game::NewEvent(new ScriptEventCompanyBankrupt(c_index));
967 CompanyAdminRemove(c_index, (CompanyRemoveReason)reason);
968
971
972 break;
973 }
974
975 default: return CMD_ERROR;
976 }
977
981
982 return CommandCost();
983}
984
985static bool ExecuteAllowListCtrlAction(CompanyAllowListCtrlAction action, Company *c, const std::string &public_key)
986{
987 switch (action) {
988 case CALCA_ADD:
989 return c->allow_list.Add(public_key);
990
991 case CALCA_REMOVE:
992 return c->allow_list.Remove(public_key);
993
994 default:
995 NOT_REACHED();
996 }
997}
998
1007{
1009 if (c == nullptr) return CMD_ERROR;
1010
1011 /* The public key length includes the '\0'. */
1012 if (public_key.size() != NETWORK_PUBLIC_KEY_LENGTH - 1) return CMD_ERROR;
1013
1014 switch (action) {
1015 case CALCA_ADD:
1016 case CALCA_REMOVE:
1017 break;
1018
1019 default:
1020 return CMD_ERROR;
1021 }
1022
1023 if (flags & DC_EXEC) {
1024 if (ExecuteAllowListCtrlAction(action, c, public_key)) {
1027 }
1028 }
1029
1030 return CommandCost();
1031}
1032
1040{
1041 if (!IsValidCompanyManagerFace(cmf)) return CMD_ERROR;
1042
1043 if (flags & DC_EXEC) {
1044 Company::Get(_current_company)->face = cmf;
1046 }
1047 return CommandCost();
1048}
1049
1056{
1057 for (int i = 1; i < LS_END; i++) {
1058 if (!HasBit(c->livery[i].in_use, 0)) c->livery[i].colour1 = c->livery[LS_DEFAULT].colour1;
1059 if (!HasBit(c->livery[i].in_use, 1)) c->livery[i].colour2 = c->livery[LS_DEFAULT].colour2;
1060 }
1062}
1063
1072CommandCost CmdSetCompanyColour(DoCommandFlag flags, LiveryScheme scheme, bool primary, Colours colour)
1073{
1074 if (scheme >= LS_END || (colour >= COLOUR_END && colour != INVALID_COLOUR)) return CMD_ERROR;
1075
1076 /* Default scheme can't be reset to invalid. */
1077 if (scheme == LS_DEFAULT && colour == INVALID_COLOUR) return CMD_ERROR;
1078
1080
1081 /* Ensure no two companies have the same primary colour */
1082 if (scheme == LS_DEFAULT && primary) {
1083 for (const Company *cc : Company::Iterate()) {
1084 if (cc != c && cc->colour == colour) return CMD_ERROR;
1085 }
1086 }
1087
1088 if (flags & DC_EXEC) {
1089 if (primary) {
1090 if (scheme != LS_DEFAULT) AssignBit(c->livery[scheme].in_use, 0, colour != INVALID_COLOUR);
1091 if (colour == INVALID_COLOUR) colour = c->livery[LS_DEFAULT].colour1;
1092 c->livery[scheme].colour1 = colour;
1093
1094 /* If setting the first colour of the default scheme, adjust the
1095 * original and cached company colours too. */
1096 if (scheme == LS_DEFAULT) {
1099 c->colour = colour;
1101 }
1102 } else {
1103 if (scheme != LS_DEFAULT) AssignBit(c->livery[scheme].in_use, 1, colour != INVALID_COLOUR);
1104 if (colour == INVALID_COLOUR) colour = c->livery[LS_DEFAULT].colour2;
1105 c->livery[scheme].colour2 = colour;
1106
1107 if (scheme == LS_DEFAULT) {
1109 }
1110 }
1111
1112 if (c->livery[scheme].in_use != 0) {
1113 /* If enabling a scheme, set the default scheme to be in use too */
1114 c->livery[LS_DEFAULT].in_use = 1;
1115 } else {
1116 /* Else loop through all schemes to see if any are left enabled.
1117 * If not, disable the default scheme too. */
1118 c->livery[LS_DEFAULT].in_use = 0;
1119 for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
1120 if (c->livery[scheme].in_use != 0) {
1121 c->livery[LS_DEFAULT].in_use = 1;
1122 break;
1123 }
1124 }
1125 }
1126
1127 ResetVehicleColourMap();
1129
1130 /* All graph related to companies use the company colour. */
1137 /* The smallmap owner view also stores the company colours. */
1140
1141 /* Company colour data is indirectly cached. */
1142 for (Vehicle *v : Vehicle::Iterate()) {
1143 if (v->owner == _current_company) v->InvalidateNewGRFCache();
1144 }
1145
1147 }
1148 return CommandCost();
1149}
1150
1156static bool IsUniqueCompanyName(const std::string &name)
1157{
1158 for (const Company *c : Company::Iterate()) {
1159 if (!c->name.empty() && c->name == name) return false;
1160 }
1161
1162 return true;
1163}
1164
1171CommandCost CmdRenameCompany(DoCommandFlag flags, const std::string &text)
1172{
1173 bool reset = text.empty();
1174
1175 if (!reset) {
1177 if (!IsUniqueCompanyName(text)) return CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE);
1178 }
1179
1180 if (flags & DC_EXEC) {
1182 if (reset) {
1183 c->name.clear();
1184 } else {
1185 c->name = text;
1186 }
1189
1190 SetDParam(0, c->index);
1191 std::string new_name = GetString(STR_COMPANY_NAME);
1192 AI::BroadcastNewEvent(new ScriptEventCompanyRenamed(c->index, new_name));
1193 Game::NewEvent(new ScriptEventCompanyRenamed(c->index, new_name));
1194 }
1195
1196 return CommandCost();
1197}
1198
1204static bool IsUniquePresidentName(const std::string &name)
1205{
1206 for (const Company *c : Company::Iterate()) {
1207 if (!c->president_name.empty() && c->president_name == name) return false;
1208 }
1209
1210 return true;
1211}
1212
1219CommandCost CmdRenamePresident(DoCommandFlag flags, const std::string &text)
1220{
1221 bool reset = text.empty();
1222
1223 if (!reset) {
1225 if (!IsUniquePresidentName(text)) return CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE);
1226 }
1227
1228 if (flags & DC_EXEC) {
1230
1231 if (reset) {
1232 c->president_name.clear();
1233 } else {
1234 c->president_name = text;
1235
1236 if (c->name_1 == STR_SV_UNNAMED && c->name.empty()) {
1237 Command<CMD_RENAME_COMPANY>::Do(DC_EXEC, text + " Transport");
1238 }
1239 }
1240
1244
1245 SetDParam(0, c->index);
1246 std::string new_name = GetString(STR_PRESIDENT_NAME);
1247 AI::BroadcastNewEvent(new ScriptEventPresidentRenamed(c->index, new_name));
1248 Game::NewEvent(new ScriptEventPresidentRenamed(c->index, new_name));
1249 }
1250
1251 return CommandCost();
1252}
1253
1261{
1262 const VehicleDefaultSettings *vds = (c == nullptr) ? &_settings_client.company.vehicle : &c->settings.vehicle;
1263 switch (type) {
1264 default: NOT_REACHED();
1265 case VEH_TRAIN: return vds->servint_trains;
1266 case VEH_ROAD: return vds->servint_roadveh;
1267 case VEH_AIRCRAFT: return vds->servint_aircraft;
1268 case VEH_SHIP: return vds->servint_ships;
1269 }
1270}
1271
1277{
1278 uint32_t total = 0;
1279 for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
1280 if (RoadTypeIsRoad(rt)) total += this->road[rt];
1281 }
1282 return total;
1283}
1284
1290{
1291 uint32_t total = 0;
1292 for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
1293 if (RoadTypeIsTram(rt)) total += this->road[rt];
1294 }
1295 return total;
1296}
1297
1309{
1311
1313 CommandCost amount(EXPENSES_OTHER, std::min<Money>(money, 20000000LL));
1314
1315 /* You can only transfer funds that is in excess of your loan */
1316 if (c->money - c->current_loan < amount.GetCost() || amount.GetCost() < 0) return CommandCost(STR_ERROR_INSUFFICIENT_FUNDS);
1317 if (!Company::IsValidID(dest_company)) return CMD_ERROR;
1318
1319 if (flags & DC_EXEC) {
1320 /* Add money to company */
1321 Backup<CompanyID> cur_company(_current_company, dest_company);
1323 cur_company.Restore();
1324
1325 if (_networking) {
1326 SetDParam(0, dest_company);
1327 std::string dest_company_name = GetString(STR_COMPANY_NAME);
1328
1330 std::string from_company_name = GetString(STR_COMPANY_NAME);
1331
1332 NetworkTextMessage(NETWORK_ACTION_GIVE_MONEY, GetDrawStringCompanyColour(_current_company), false, from_company_name, dest_company_name, amount.GetCost());
1333 }
1334 }
1335
1336 /* Subtract money from local-company */
1337 return amount;
1338}
1339
1350{
1351 for (Company *c : Company::Iterate()) {
1352 if (Company::IsHumanID(c->index)) {
1353 return c->index;
1354 }
1355 }
1356
1358 for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
1359 if (!Company::IsValidID(c)) {
1360 return c;
1361 }
1362 }
1363 }
1364
1365 return COMPANY_FIRST;
1366}
Base functions for all AIs.
AIConfig stores the configuration settings of every AI.
The AIInstance tracks an AI.
Class for backupping variables and making sure they are restored later.
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr T AssignBit(T &x, const uint8_t y, bool value)
Assigns a bit in a variable.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
debug_inline static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
static bool CanStartNew()
Is it possible to start a new AI company?
Definition ai_core.cpp:30
static void BroadcastNewEvent(ScriptEvent *event, CompanyID skip_company=MAX_COMPANIES)
Broadcast a new event to all active AIs.
Definition ai_core.cpp:263
static void StartNew(CompanyID company)
Start a new AI company.
Definition ai_core.cpp:36
static void Stop(CompanyID company)
Stop a company to be controlled by an AI.
Definition ai_core.cpp:107
static void NewEvent(CompanyID company, ScriptEvent *event)
Queue a new event for an AI.
Definition ai_core.cpp:243
Common return value for all commands.
ExpensesType GetExpensesType() const
The expense type of the cost.
Money GetCost() const
The costs as made up to this moment.
void MakeError(StringID message, StringID extra_message=INVALID_STRING_ID)
Makes this CommandCost behave like an error command.
static void NewEvent(class ScriptEvent *event)
Queue a new event for a Game Script.
An interval timer will fire every interval, and will continue to fire until it is deleted.
Definition timer.h:76
bool Add(std::string_view key)
Add the given key to the authorized keys, when it is not already contained.
Definition network.cpp:188
bool Remove(std::string_view key)
Remove the given key from the authorized keys, when it is exists.
Definition network.cpp:204
static constexpr TimerGameTick::Ticks DAY_TICKS
1 day is 74 ticks; TimerGameCalendar::date_fract used to be uint16_t and incremented by 885.
static constexpr TimerGameTick::Ticks TICKS_PER_SECOND
Estimation of how many ticks fit in a single second.
A timeout timer will fire once after the interval.
Definition timer.h:116
void Abort()
Abort the timer so it doesn't fire if it hasn't yet.
Definition timer.h:161
static Year year
Current year, starting at 0.
static Year year
Current year, starting at 0.
Functions related to commands.
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
DoCommandFlag
List of flags for a command.
@ DC_EXEC
execute the given command
Definition of stuff that is very close to a company, like the company struct itself.
void ClearEnginesHiddenFlagOfCompany(CompanyID cid)
Clear the 'hidden' flag for all engines of a new company.
Definition engine.cpp:1005
void UpdateObjectColours(const Company *c)
Updates the colour of the object whenever a company changes.
static void GenerateCompanyName(Company *c)
Generate the name of a company from the last build coordinate.
static bool IsValidCompanyManagerFace(CompanyManagerFace cmf)
Checks whether a company manager's face is a valid encoding.
void OnTick_Companies()
Called every tick for updating some company info.
Colours _company_colours[MAX_COMPANIES]
NOSAVE: can be determined from company structs.
static IntervalTimer< TimerGameEconomy > _economy_companies_yearly({TimerGameEconomy::YEAR, TimerGameEconomy::Priority::COMPANY}, [](auto) { for(Company *c :Company::Iterate()) { std::rotate(std::rbegin(c->yearly_expenses), std::rbegin(c->yearly_expenses)+1, std::rend(c->yearly_expenses));c->yearly_expenses[0]={};InvalidateWindowData(WC_FINANCES, c->index);} if(_settings_client.gui.show_finances &&_local_company !=COMPANY_SPECTATOR) { ShowCompanyFinances(_local_company);Company *c=Company::Get(_local_company);if(c->num_valid_stat_ent > 5 &&c->old_economy[0].performance_history< c->old_economy[4].performance_history) { if(_settings_client.sound.new_year) SndPlayFx(SND_01_BAD_YEAR);} else { if(_settings_client.sound.new_year) SndPlayFx(SND_00_GOOD_YEAR);} } })
A year has passed, update the economic data of all companies, and perhaps show the financial overview...
static void SubtractMoneyFromAnyCompany(Company *c, const CommandCost &cost)
Deduct costs of a command from the money of a company.
CommandCost CmdSetCompanyColour(DoCommandFlag flags, LiveryScheme scheme, bool primary, Colours colour)
Change the company's company-colour.
void DrawCompanyIcon(CompanyID c, int x, int y)
Draw the icon of a company.
CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID company_id, CompanyRemoveReason reason, ClientID client_id)
Control the companies: add, delete, etc.
static Colours GenerateCompanyColour()
Generate a company colour.
static void GeneratePresidentName(Company *c)
Generate a random president name of a company.
static const Colours _similar_colour[COLOUR_END][2]
Similar colours, so we can try to prevent same coloured companies.
CommandCost CmdSetCompanyManagerFace(DoCommandFlag flags, CompanyManagerFace cmf)
Change the company manager's face.
CommandCost CmdGiveMoney(DoCommandFlag flags, Money money, CompanyID dest_company)
Transfer funds (money) from one company to another.
void ResetCompanyLivery(Company *c)
Reset the livery schemes to the company's primary colour.
void UpdateCompanyLiveries(Company *c)
Update liveries for a company.
CommandCost CheckTileOwnership(TileIndex tile)
Check whether the current owner owns the stuff on the given tile.
TimeoutTimer< TimerGameTick > _new_competitor_timeout({ TimerGameTick::Priority::COMPETITOR_TIMEOUT, 0 }, []() { if(_game_mode==GM_MENU||!AI::CanStartNew()) return;if(_networking &&Company::GetNumItems() >=_settings_client.network.max_companies) return;uint8_t n=0;for(const Company *c :Company::Iterate()) { if(c->is_ai) n++;} if(n >=_settings_game.difficulty.max_no_competitors) return;Command< CMD_COMPANY_CTRL >::Post(CCA_NEW_AI, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID);})
Start a new competitor company if possible.
Company * DoStartupNewCompany(bool is_ai, CompanyID company=INVALID_COMPANY)
Create a new company and sets all company variables default values.
void InvalidateCompanyWindows(const Company *company)
Refresh all windows owned by a company.
int CompanyServiceInterval(const Company *c, VehicleType type)
Get the service interval for the given company and vehicle type.
bool CheckCompanyHasMoney(CommandCost &cost)
Verify whether the company can pay the bill.
CommandCost CmdRenamePresident(DoCommandFlag flags, const std::string &text)
Change the name of the president.
CompanyID GetFirstPlayableCompanyID()
Get the index of the first available company.
TextColour GetDrawStringCompanyColour(CompanyID company)
Get the colour for DrawString-subroutines which matches the colour of the company.
Money GetAvailableMoneyForCommand()
This functions returns the money which can be used to execute a command.
void CompanyAdminUpdate(const Company *company)
Called whenever company related information changes in order to notify admins.
CommandCost CheckOwnership(Owner owner, TileIndex tile)
Check whether the current owner owns something.
void CompanyAdminRemove(CompanyID company_id, CompanyRemoveReason reason)
Called whenever a company is removed in order to notify admins.
CommandCost CmdCompanyAllowListCtrl(DoCommandFlag flags, CompanyAllowListCtrlAction action, const std::string &public_key)
Add or remove the given public key to the allow list of this company.
void SetDParamsForOwnedBy(Owner owner, TileIndex tile)
Set the right DParams for STR_ERROR_OWNED_BY.
void SubtractMoneyFromCompany(const CommandCost &cost)
Subtract money from the _current_company, if the company is valid.
CompanyPool _company_pool("Company")
Pool of companies.
Money GetAvailableMoney(CompanyID company)
Get the amount of money that a company has available, or INT64_MAX if there is no such valid company.
void UpdateLandscapingLimits()
Update the landscaping limits per company.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
void InitializeCompanies()
Initialize the pool of companies.
uint _cur_company_tick_index
used to generate a name for one company that doesn't have a name yet per tick
CommandCost CmdRenameCompany(DoCommandFlag flags, const std::string &text)
Change the name of the company.
void StartupCompanies()
Start of a new game.
bool CheckTakeoverVehicleLimit(CompanyID cbig, CompanyID csmall)
Can company cbig buy company csmall without exceeding vehicle limits?
CompanyManagerFace _company_manager_face
for company manager face storage in openttd.cfg
static bool IsUniqueCompanyName(const std::string &name)
Is the given name in use as name of a company?
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...
static bool IsUniquePresidentName(const std::string &name)
Is the given name in use as president name of a company?
CompanyID _current_company
Company currently doing an action.
static void HandleBankruptcyTakeover(Company *c)
Handle the bankruptcy take over of a company.
void SubtractMoneyFromCompanyFract(CompanyID company, const CommandCost &cst)
Subtract money from a company, including the money fraction.
static const uint8_t _colour_sort[COLOUR_END]
Sorting weights for the company colours.
Command definitions related to companies.
Functions related to companies.
bool IsInteractiveCompany(CompanyID company)
Is the user representing company?
void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
Change the ownership of all the items of a company.
Definition economy.cpp:334
void ShowBuyCompanyDialog(CompanyID company, bool hostile_takeover)
Show the query to buy another company.
static const int OWNED_BY_OWNER_IN_PARAMETERS_OFFSET
The index in the parameters for the owner information.
bool IsLocalCompany()
Is the current company the local company?
void ShowCompanyFinances(CompanyID company)
Open the finances window of a company.
GUI Functions related to companies.
void CloseCompanyWindows(CompanyID company)
Close all windows of a company.
Definition window.cpp:1165
Functionality related to the company manager's face.
uint GetCompanyManagerFaceBits(CompanyManagerFace cmf, CompanyManagerFaceVariable cmfv, GenderEthnicity ge)
Make sure the table's size is right.
GenderEthnicity
The gender/race combinations that we have faces for.
@ GE_WM
A male of Caucasian origin (white)
@ GENDER_FEMALE
This bit set means a female, otherwise male.
void RandomCompanyManagerFaceBits(CompanyManagerFace &cmf, GenderEthnicity ge, bool adv, Randomizer &randomizer)
Make a random new face.
CompanyManagerFaceVariable
Bitgroups of the CompanyManagerFace variable.
bool AreCompanyManagerFaceBitsValid(CompanyManagerFace cmf, CompanyManagerFaceVariable cmfv, GenderEthnicity ge)
Checks whether the company manager's face bits have a valid range.
static const uint MAX_LENGTH_PRESIDENT_NAME_CHARS
The maximum length of a president name in characters including '\0'.
static const uint MAX_LENGTH_COMPANY_NAME_CHARS
The maximum length of a company name in characters including '\0'.
CompanyCtrlAction
The action to do with CMD_COMPANY_CTRL.
@ CCA_NEW_AI
Create a new AI company.
@ CCA_DELETE
Delete a company.
@ CCA_NEW
Create a new company.
CompanyAllowListCtrlAction
The action to do with CMD_COMPANY_ALLOW_LIST_CTRL.
@ CALCA_REMOVE
Remove a public key.
@ CALCA_ADD
Create a public key.
uint32_t CompanyManagerFace
Company manager face bits, info see in company_manager_face.h.
Owner
Enum for all companies/owners.
@ INVALID_COMPANY
An invalid company.
@ INVALID_OWNER
An invalid owner.
@ OWNER_END
Last + 1 owner.
@ COMPANY_SPECTATOR
The client is spectating.
@ COMPANY_FIRST
First company, same as owner.
@ OWNER_NONE
The tile has no ownership.
@ OWNER_TOWN
A town owns the tile, or a town is expanding.
@ MAX_COMPANIES
Maximum number of companies.
CompanyRemoveReason
The reason why the company was removed.
@ CRR_END
Sentinel for end.
@ CRR_NONE
Dummy reason for actions that don't need one.
static const uint NETWORK_PUBLIC_KEY_LENGTH
The maximum length of the hexadecimal encoded public keys, in bytes including '\0'.
Definition config.h:101
@ EXPENSES_ROADVEH_RUN
Running costs road vehicles.
@ EXPENSES_TRAIN_RUN
Running costs trains.
@ EXPENSES_AIRCRAFT_REVENUE
Revenue from aircraft.
@ EXPENSES_AIRCRAFT_RUN
Running costs aircraft.
@ EXPENSES_ROADVEH_REVENUE
Revenue from road vehicles.
@ EXPENSES_PROPERTY
Property costs.
@ EXPENSES_OTHER
Other expenses.
@ EXPENSES_SHIP_REVENUE
Revenue from ships.
@ EXPENSES_LOAN_INTEREST
Interest payments over the loan.
@ EXPENSES_TRAIN_REVENUE
Revenue from trains.
@ EXPENSES_SHIP_RUN
Running costs ships.
@ INVALID_EXPENSES
Invalid expense type.
static const int LOAN_INTERVAL
The "steps" in loan size, in British Pounds!
static const int64_t INITIAL_LOAN
The size of loan for a new company, in British Pounds!
Base functions for all Games.
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition gfx.cpp:988
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
Definition gfx_type.h:294
@ TC_IS_PALETTE_COLOUR
Colour value is already a real palette colour index, not an index of a StringColour.
Definition gfx_type.h:317
Goal base class.
void UpdateCompanyGroupLiveries(const Company *c)
Update group liveries for a company.
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1529
@ Random
Randomise borders.
LiveryScheme
List of different livery schemes.
Definition livery.h:21
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
constexpr void Swap(T &a, T &b)
Type safe swap operation.
bool _networking
are we in networking mode?
Definition network.cpp:65
bool _network_server
network-server is active
Definition network.cpp:66
ClientID _network_own_client_id
Our client identifier.
Definition network.cpp:70
Basic functions/variables used all over the place.
void NetworkAdminCompanyUpdate(const Company *company)
Notify the admin network of company updates.
void NetworkAdminCompanyNew(const Company *company)
Notify the admin network of a new company.
void NetworkAdminCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason bcrr)
Notify the admin network of a company to be removed (including the reason why).
Server part of the admin network protocol.
Base core network types and some helper functions to access them.
Network functions used by other parts of OpenTTD.
void NetworkServerNewCompany(const Company *company, NetworkClientInfo *ci)
Perform all the server specific administration of a new company.
void NetworkUpdateClientInfo(ClientID client_id)
Send updated client info of a particular client.
@ DESTTYPE_TEAM
Send message/notice to everyone playing the same company (Team)
ClientID
'Unique' identifier to be given to clients
@ INVALID_CLIENT_ID
Client is not part of anything.
Functions related to news.
void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceType reftype1=NR_NONE, uint32_t ref1=UINT32_MAX, NewsReferenceType reftype2=NR_NONE, uint32_t ref2=UINT32_MAX, std::unique_ptr< NewsAllocatedData > &&data=nullptr, AdviceType advice_type=AdviceType::Invalid)
Add a new newsitem to be shown.
Definition news_gui.cpp:899
@ NT_COMPANY_INFO
Company info (new companies, bankruptcy messages)
Definition news_type.h:28
@ NR_TILE
Reference tile. Scroll to tile when clicking on the news.
Definition news_type.h:69
@ NR_NONE
Empty reference.
Definition news_type.h:68
@ NF_COMPANY
Company news item. (Newspaper with face)
Definition news_type.h:98
uint8_t GetColourGradient(Colours colour, ColourShade shade)
Get colour gradient palette index.
Definition palette.cpp:387
Some methods of Pool are placed here in order to reduce compilation time and binary size.
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
RailTypes GetCompanyRailTypes(CompanyID company, bool introduces)
Get the rail types the given company can build.
Definition rail.cpp:251
Rail specific functions.
Randomizer _random
Random used in the game state calculations.
RoadTypes GetCompanyRoadTypes(CompanyID company, bool introduces)
Get the road types the given company can build.
Definition road.cpp:199
RoadType
The different roadtypes we support.
Definition road_type.h:25
@ ROADTYPE_END
Used for iterations.
Definition road_type.h:29
@ ROADTYPE_BEGIN
Used for iterations.
Definition road_type.h:26
A number of safeguards to prevent using unsafe methods.
void SyncCompanySettings()
Sync all company settings in a multiplayer game.
void SetDefaultCompanySettings(CompanyID cid)
Set the company settings for a new company to their default values.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:57
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:56
Functions related to setting/changing the settings.
void BuildOwnerLegend()
Completes the array for the owned property legend.
Smallmap GUI functions.
Functions related to sound.
@ SND_01_BAD_YEAR
40 == 0x28 New year: performance declined
Definition sound_type.h:87
@ SND_00_GOOD_YEAR
39 == 0x27 New year: performance improved
Definition sound_type.h:86
Types related to the statusbar widgets.
@ WID_S_RIGHT
Right part; bank balance.
Definition of base types and functions in a cross-platform compatible way.
StoryPage base class.
size_t Utf8StringLength(const char *s)
Get the length of an UTF-8 encoded string in number of characters and thus not the number of bytes th...
Definition string.cpp:359
void SetDParam(size_t n, uint64_t v)
Set a string parameter v at index n in the global string parameter array.
Definition strings.cpp:104
std::string GetString(StringID string)
Resolve the given StringID into a std::string with all the associated DParam lookups and formatting.
Definition strings.cpp:332
void SetDParamStr(size_t n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition strings.cpp:370
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
static constexpr StringID SPECSTR_COMPANY_NAME_START
Special strings for company names on the form "TownName transport".
static constexpr StringID SPECSTR_ANDCO_NAME
Special string for Surname & Co company names.
static constexpr StringID SPECSTR_PRESIDENT_NAME
Special string for the president's name.
static constexpr StringID SPECSTR_TOWNNAME_START
Special strings for town names.
Class to backup a specific variable and restore it later.
void Restore()
Restore the variable.
CompanySettings company
default values for per-company settings
NetworkSettings network
settings related to the network
SoundSettings sound
sound effect settings
GUISettings gui
settings related to the GUI
Money income
The amount of income.
Money expenses
The amount of expenses.
int32_t performance_history
Company score (scale 0-1000)
std::array< uint32_t, ROADTYPE_END > road
Count of company owned track bits for each road type.
uint32_t GetRoadTotal() const
Get total sum of all owned road bits.
uint32_t GetTramTotal() const
Get total sum of all owned tram bits.
uint32_t face
The face of the president.
Definition news_type.h:174
CompanyNewsInformation(const struct Company *c, const struct Company *other=nullptr)
Fill the CompanyNewsInformation struct with the required data.
Colours colour
The colour related to the company.
Definition news_type.h:175
std::string president_name
The name of the president.
Definition news_type.h:171
std::string company_name
The name of the company.
Definition news_type.h:170
std::string other_company_name
The name of the company taking over this one.
Definition news_type.h:172
CompanyMask bankrupt_asked
which companies were asked about buying it?
std::string president_name
Name of the president if the user changed it.
int16_t bankrupt_timeout
If bigger than 0, amount of time to wait for an answer on an offer to buy this company.
CompanySettings settings
settings specific for each company
NetworkAuthorizedKeys allow_list
Public keys of clients that are allowed to join this company.
CompanyEconomyEntry old_economy[MAX_HISTORY_QUARTERS]
Economic data of the company of the last MAX_HISTORY_QUARTERS quarters.
uint32_t name_2
Parameter of name_1.
uint8_t money_fraction
Fraction of money of the company, too small to represent in money.
bool is_ai
If true, the company is (also) controlled by the computer (a NoAI program).
uint32_t president_name_2
Parameter of president_name_1.
StringID name_1
Name of the company if the user did not change it.
Money current_loan
Amount of money borrowed from the bank.
TimerGameCalendar::Year inaugurated_year_calendar
Calendar year of starting the company. Used to display proper Inauguration year while in wallclock mo...
TimerGameEconomy::Year inaugurated_year
Economy year of starting the company.
CompanyEconomyEntry cur_economy
Economic data of the company of this quarter.
Colours colour
Company colour.
CompanyManagerFace face
Face description of the president.
Money max_loan
Max allowed amount of the loan or COMPANY_MAX_LOAN_DEFAULT.
std::array< Expenses, 3 > yearly_expenses
Expenses of the company for the last three years.
TileIndex last_build_coordinate
Coordinate of the last build thing by this company.
StringID president_name_1
Name of the president if the user did not change it.
std::string name
Name of the company if the user changed it.
Money money
Money owned by the company.
uint8_t num_valid_stat_ent
Number of valid statistical entries in old_economy.
VehicleDefaultSettings vehicle
default settings for vehicles
Money GetMaxLoan() const
Calculate the max allowed loan for this company.
static bool IsHumanID(size_t index)
Is this company a company not controlled by a NoAI program?
RoadTypes avail_roadtypes
Road types available to this company.
~Company()
Destructor.
RailTypes avail_railtypes
Rail types available to this company.
static void PostDestructor(size_t index)
Invalidating some stuff after removing item from the pool.
GroupStatistics group_all[VEH_COMPANY_END]
NOSAVE: Statistics for the ALL_GROUP group.
uint32_t clear_per_64k_frames
how many tiles may, over a long period, be cleared per 65536 frames?
uint32_t tree_per_64k_frames
how many trees may, over a long period, be planted per 65536 frames?
uint16_t terraform_frame_burst
how many tile heights may, over a short period, be terraformed?
uint16_t tree_frame_burst
how many trees may, over a short period, be planted?
uint16_t build_object_frame_burst
how many tiles may, over a short period, be purchased or have objects built on them?
uint32_t build_object_per_64k_frames
how many tiles may, over a long period, be purchased or have objects built on them per 65536 frames?
uint32_t terraform_per_64k_frames
how many tile heights may, over a long period, be terraformed per 65536 frames?
uint16_t clear_frame_burst
how many tiles may, over a short period, be cleared?
uint8_t max_no_competitors
the number of competitors (AIs)
bool infinite_money
whether spending money despite negative balance is allowed
uint16_t competitors_interval
the interval (in minutes) between adding competitors
bool give_money
allow giving other companies money
uint64_t inflation_prices
Cumulated inflation of prices since game start; 16 bit fractional part.
Money max_loan
NOSAVE: Maximum possible loan.
bool show_finances
show finances at end of year
EconomySettings economy
settings to change the economy
ConstructionSettings construction
construction of things in-game
DifficultySettings difficulty
settings related to the difficulty
VehicleSettings vehicle
options for vehicles
uint16_t num_vehicle
Number of vehicles.
Definition group.h:28
Group data.
Definition group.h:72
Colours colour2
Second colour, for vehicles with 2CC support.
Definition livery.h:81
Colours colour1
First colour, for all vehicles.
Definition livery.h:80
uint8_t in_use
Bit 0 set if this livery should override the default livery first colour, Bit 1 for the second colour...
Definition livery.h:79
Container for all information known about a client.
static NetworkClientInfo * GetByClientID(ClientID client_id)
Return the CI given it's client-identifier.
Definition network.cpp:116
CompanyID client_playas
As which company is this client playing (CompanyID)
ClientID client_id
Client identifier (same as ClientState->client_id)
uint8_t max_companies
maximum amount of companies
Tindex index
Index of this pool item.
static size_t GetNumItems()
Returns number of valid items in the pool.
static bool CleaningPool()
Returns current state of pool cleaning - yes or no.
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
static Titem * Get(size_t index)
Returns Titem with given index.
Base class for all pools.
Definition pool_type.hpp:79
bool new_year
Play sound on new year, summarising the performance during the last year.
Town data structure.
Definition town.h:52
std::string name
Custom town name. If empty, the town was not renamed and uses the generated name.
Definition town.h:61
Default settings for vehicles.
uint16_t servint_aircraft
service interval for aircraft
uint16_t servint_roadveh
service interval for road vehicles
uint16_t servint_ships
service interval for ships
uint16_t servint_trains
service interval for trains
UnitID max_ships
max ships in game per company
UnitID max_trains
max trains in game per company
UnitID max_aircraft
max planes in game per company
UnitID max_roadveh
max trucks in game per company
Vehicle data structure.
AdminCompanyRemoveReason
Reasons for removing a company - communicated to admins.
Definition tcp_admin.h:108
Owner GetTileOwner(Tile tile)
Returns the owner of a tile.
Definition tile_map.h:178
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:95
Definition of Interval and OneShot timers.
Definition of the game-economy-timer.
Definition of the tick-based game-timer.
Base of the town class.
Town * ClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest (in distance or ownership) to a given tile, within a given threshold.
Base class for all vehicles.
Functions related to vehicles.
VehicleType
Available vehicle types.
@ VEH_ROAD
Road vehicle type.
@ VEH_AIRCRAFT
Aircraft vehicle type.
@ VEH_SHIP
Ship vehicle type.
@ VEH_TRAIN
Train vehicle type.
void CloseConstructionWindows()
Close all windows that are used for construction of vehicle etc.
Definition window.cpp:3303
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
Definition window.cpp:1137
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:3217
void SetWindowWidgetDirty(WindowClass cls, WindowNumber number, WidgetID widget_index)
Mark a particular widget in a particular window as dirty (in need of repainting)
Definition window.cpp:3112
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition window.cpp:3099
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:3234
Window functions not directly related to making/drawing windows.
@ WN_NETWORK_STATUS_WINDOW_JOIN
Network join status.
Definition window_type.h:41
@ WC_PERFORMANCE_HISTORY
Performance history graph; Window numbers:
@ WC_COMPANY_LEAGUE
Company league window; Window numbers:
@ WC_SIGN_LIST
Sign list; Window numbers:
@ WC_PERFORMANCE_DETAIL
Performance detail window; Window numbers:
@ WC_GRAPH_LEGEND
Legend for graphs; Window numbers:
@ WC_LINKGRAPH_LEGEND
Linkgraph legend; Window numbers:
@ WC_STATUS_BAR
Statusbar (at the bottom of your screen); Window numbers:
Definition window_type.h:66
@ WC_SEND_NETWORK_MSG
Chatbox; Window numbers:
@ WC_ERRMSG
Error message; Window numbers:
@ WC_SCRIPT_SETTINGS
Script settings; Window numbers:
@ WC_SCRIPT_LIST
Scripts list; Window numbers:
@ WC_GOALS_LIST
Goals list; Window numbers:
@ WC_OPERATING_PROFIT
Operating profit graph; Window numbers:
@ WC_CLIENT_LIST
Client list; Window numbers:
@ WC_GAME_OPTIONS
Game options window; Window numbers:
@ WC_FINANCES
Finances of a company; Window numbers:
@ WC_INCOME_GRAPH
Income graph; Window numbers:
@ WC_SMALLMAP
Small map; Window numbers:
@ WC_DELIVERED_CARGO
Delivered cargo graph; Window numbers:
@ WC_COMPANY_VALUE
Company value graph; Window numbers:
@ WC_MAIN_TOOLBAR
Main toolbar (the long bar at the top); Window numbers:
Definition window_type.h:60
@ WC_COMPANY
Company view; Window numbers:
@ WC_NETWORK_STATUS_WINDOW
Network status window; Window numbers: