OpenTTD Source  20241124-master-g9399a92a4f
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"
19 #include "network/network_func.h"
20 #include "network/network_base.h"
21 #include "network/network_admin.h"
22 #include "ai/ai.hpp"
23 #include "ai/ai_instance.hpp"
24 #include "ai/ai_config.hpp"
25 #include "company_manager_face.h"
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"
41 #include "timer/timer_game_tick.h"
42 
44 
45 #include "table/strings.h"
46 
47 #include "safeguards.h"
48 
50 void UpdateObjectColours(const Company *c);
51 
57 
60 
61 
66 Company::Company(uint16_t 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 
91 void 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 
117 void 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 
161 void 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 
201 void InvalidateCompanyWindows(const Company *company)
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 
231 {
233 }
234 
242 {
243  if (cost.GetCost() <= 0) return true;
244  if (_settings_game.difficulty.infinite_money) 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 
260 static void SubtractMoneyFromAnyCompany(Company *c, const CommandCost &cost)
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 
268  if (HasBit(1 << EXPENSES_TRAIN_REVENUE |
271  1 << EXPENSES_SHIP_REVENUE, cost.GetExpensesType())) {
272  c->cur_economy.income -= cost.GetCost();
273  } else if (HasBit(1 << EXPENSES_TRAIN_RUN |
274  1 << EXPENSES_ROADVEH_RUN |
275  1 << EXPENSES_AIRCRAFT_RUN |
276  1 << EXPENSES_SHIP_RUN |
277  1 << EXPENSES_PROPERTY |
278  1 << EXPENSES_LOAN_INTEREST, cost.GetExpensesType())) {
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 
312 static 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 
319 {
320  for (Company *c : Company::Iterate()) {
325  }
326 }
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_cmd_error(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_cmd_error(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_LAST + 1)) {
409  str = t->townnametype - SPECSTR_TOWNNAME_START + SPECSTR_COMPANY_NAME_START;
410  strp = t->townnameparts;
411 
412 verify_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 
422 set_name:;
423  c->name_1 = str;
424  c->name_2 = strp;
425 
427 
428  if (c->is_ai) {
430  SetDParam(0, STR_NEWS_COMPANY_LAUNCH_TITLE);
431  SetDParam(1, STR_NEWS_COMPANY_LAUNCH_DESCRIPTION);
432  SetDParamStr(2, cni->company_name);
433  SetDParam(3, t->index);
434  AddNewsItem(STR_MESSAGE_NEWS_FORMAT, NT_COMPANY_INFO, NF_COMPANY, NR_TILE, c->last_build_coordinate.base(), NR_NONE, UINT32_MAX, cni);
435  }
436  return;
437  }
438 bad_town_name:;
439 
440  if (c->president_name_1 == SPECSTR_PRESIDENT_NAME) {
441  str = SPECSTR_ANDCO_NAME;
442  strp = c->president_name_2;
443  goto set_name;
444  } else {
445  str = SPECSTR_ANDCO_NAME;
446  strp = Random();
447  goto verify_name;
448  }
449 }
450 
452 static const uint8_t _colour_sort[COLOUR_END] = {2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 2, 2, 3, 1, 1, 1};
454 static const Colours _similar_colour[COLOUR_END][2] = {
455  { COLOUR_BLUE, COLOUR_LIGHT_BLUE }, // COLOUR_DARK_BLUE
456  { COLOUR_GREEN, COLOUR_DARK_GREEN }, // COLOUR_PALE_GREEN
457  { INVALID_COLOUR, INVALID_COLOUR }, // COLOUR_PINK
458  { COLOUR_ORANGE, INVALID_COLOUR }, // COLOUR_YELLOW
459  { INVALID_COLOUR, INVALID_COLOUR }, // COLOUR_RED
460  { COLOUR_DARK_BLUE, COLOUR_BLUE }, // COLOUR_LIGHT_BLUE
461  { COLOUR_PALE_GREEN, COLOUR_DARK_GREEN }, // COLOUR_GREEN
462  { COLOUR_PALE_GREEN, COLOUR_GREEN }, // COLOUR_DARK_GREEN
463  { COLOUR_DARK_BLUE, COLOUR_LIGHT_BLUE }, // COLOUR_BLUE
464  { COLOUR_BROWN, COLOUR_ORANGE }, // COLOUR_CREAM
465  { COLOUR_PURPLE, INVALID_COLOUR }, // COLOUR_MAUVE
466  { COLOUR_MAUVE, INVALID_COLOUR }, // COLOUR_PURPLE
467  { COLOUR_YELLOW, COLOUR_CREAM }, // COLOUR_ORANGE
468  { COLOUR_CREAM, INVALID_COLOUR }, // COLOUR_BROWN
469  { COLOUR_WHITE, INVALID_COLOUR }, // COLOUR_GREY
470  { COLOUR_GREY, INVALID_COLOUR }, // COLOUR_WHITE
471 };
472 
477 static Colours GenerateCompanyColour()
478 {
479  Colours colours[COLOUR_END];
480 
481  /* Initialize array */
482  for (uint i = 0; i < COLOUR_END; i++) colours[i] = static_cast<Colours>(i);
483 
484  /* And randomize it */
485  for (uint i = 0; i < 100; i++) {
486  uint r = Random();
487  Swap(colours[GB(r, 0, 4)], colours[GB(r, 4, 4)]);
488  }
489 
490  /* Bubble sort it according to the values in table 1 */
491  for (uint i = 0; i < COLOUR_END; i++) {
492  for (uint j = 1; j < COLOUR_END; j++) {
493  if (_colour_sort[colours[j - 1]] < _colour_sort[colours[j]]) {
494  Swap(colours[j - 1], colours[j]);
495  }
496  }
497  }
498 
499  /* Move the colours that look similar to each company's colour to the side */
500  for (const Company *c : Company::Iterate()) {
501  Colours pcolour = c->colour;
502 
503  for (uint i = 0; i < COLOUR_END; i++) {
504  if (colours[i] == pcolour) {
505  colours[i] = INVALID_COLOUR;
506  break;
507  }
508  }
509 
510  for (uint j = 0; j < 2; j++) {
511  Colours similar = _similar_colour[pcolour][j];
512  if (similar == INVALID_COLOUR) break;
513 
514  for (uint i = 1; i < COLOUR_END; i++) {
515  if (colours[i - 1] == similar) Swap(colours[i - 1], colours[i]);
516  }
517  }
518  }
519 
520  /* Return the first available colour */
521  for (uint i = 0; i < COLOUR_END; i++) {
522  if (colours[i] != INVALID_COLOUR) return colours[i];
523  }
524 
525  NOT_REACHED();
526 }
527 
533 {
534  for (;;) {
535 restart:;
536  c->president_name_2 = Random();
537  c->president_name_1 = SPECSTR_PRESIDENT_NAME;
538 
539  /* Reserve space for extra unicode character. We need to do this to be able
540  * to detect too long president name. */
541  SetDParam(0, c->index);
542  std::string name = GetString(STR_PRESIDENT_NAME);
543  if (Utf8StringLength(name) >= MAX_LENGTH_PRESIDENT_NAME_CHARS) continue;
544 
545  for (const Company *cc : Company::Iterate()) {
546  if (c != cc) {
547  SetDParam(0, cc->index);
548  std::string other_name = GetString(STR_PRESIDENT_NAME);
549  if (name == other_name) goto restart;
550  }
551  }
552  return;
553  }
554 }
555 
562 {
563  for (LiveryScheme scheme = LS_BEGIN; scheme < LS_END; scheme++) {
564  c->livery[scheme].in_use = 0;
565  c->livery[scheme].colour1 = c->colour;
566  c->livery[scheme].colour2 = c->colour;
567  }
568 
569  for (Group *g : Group::Iterate()) {
570  if (g->owner == c->index) {
571  g->livery.in_use = 0;
572  g->livery.colour1 = c->colour;
573  g->livery.colour2 = c->colour;
574  }
575  }
576 }
577 
586 {
587  if (!Company::CanAllocateItem()) return nullptr;
588 
589  /* we have to generate colour before this company is valid */
590  Colours colour = GenerateCompanyColour();
591 
592  Company *c;
593  if (company == INVALID_COMPANY) {
594  c = new Company(STR_SV_UNNAMED, is_ai);
595  } else {
596  if (Company::IsValidID(company)) return nullptr;
597  c = new (company) Company(STR_SV_UNNAMED, is_ai);
598  }
599 
600  c->colour = colour;
601 
603  _company_colours[c->index] = c->colour;
604 
605  /* Scale the initial loan based on the inflation rounded down to the loan interval. The maximum loan has already been inflation adjusted. */
606  c->money = c->current_loan = std::min<int64_t>((INITIAL_LOAN * _economy.inflation_prices >> 16) / LOAN_INTERVAL * LOAN_INTERVAL, _economy.max_loan);
607 
612 
613  /* If starting a player company in singleplayer and a favorite company manager face is selected, choose it. Otherwise, use a random face.
614  * In a network game, we'll choose the favorite face later in CmdCompanyCtrl to sync it to all clients. */
615  if (_company_manager_face != 0 && !is_ai && !_networking) {
617  } else {
619  }
620 
623 
625 
631 
632  if (is_ai && (!_networking || _network_server)) AI::StartNew(c->index);
633 
634  AI::BroadcastNewEvent(new ScriptEventCompanyNew(c->index), c->index);
635  Game::NewEvent(new ScriptEventCompanyNew(c->index));
636 
637  return c;
638 }
639 
641 TimeoutTimer<TimerGameTick> _new_competitor_timeout({ TimerGameTick::Priority::COMPETITOR_TIMEOUT, 0 }, []() {
642  if (_game_mode == GM_MENU || !AI::CanStartNew()) return;
644 
645  /* count number of competitors */
646  uint8_t n = 0;
647  for (const Company *c : Company::Iterate()) {
648  if (c->is_ai) n++;
649  }
650 
652 
653  /* Send a command to all clients to start up a new AI.
654  * Works fine for Multiplayer and Singleplayer */
656 });
657 
660 {
661  /* Ensure the timeout is aborted, so it doesn't fire based on information of the last game. */
662  _new_competitor_timeout.Abort();
663 }
664 
667 {
669 }
670 
678 {
679  const Company *c1 = Company::Get(cbig);
680  const Company *c2 = Company::Get(csmall);
681 
682  /* Do the combined vehicle counts stay within the limits? */
687 }
688 
699 {
700  /* Amount of time out for each company to take over a company;
701  * Timeout is a quarter (3 months of 30 days) divided over the
702  * number of companies. The minimum number of days in a quarter
703  * is 90: 31 in January, 28 in February and 31 in March.
704  * Note that the company going bankrupt can't buy itself. */
705  static const int TAKE_OVER_TIMEOUT = 3 * 30 * Ticks::DAY_TICKS / (MAX_COMPANIES - 1);
706 
707  assert(c->bankrupt_asked != 0);
708 
709  /* We're currently asking some company to buy 'us' */
710  if (c->bankrupt_timeout != 0) {
712  if (c->bankrupt_timeout > 0) return;
713  c->bankrupt_timeout = 0;
714 
715  return;
716  }
717 
718  /* Did we ask everyone for bankruptcy? If so, bail out. */
719  if (c->bankrupt_asked == MAX_UVALUE(CompanyMask)) return;
720 
721  Company *best = nullptr;
722  int32_t best_performance = -1;
723 
724  /* Ask the company with the highest performance history first */
725  for (Company *c2 : Company::Iterate()) {
726  if (c2->bankrupt_asked == 0 && // Don't ask companies going bankrupt themselves
727  !HasBit(c->bankrupt_asked, c2->index) &&
728  best_performance < c2->old_economy[1].performance_history &&
729  CheckTakeoverVehicleLimit(c2->index, c->index)) {
730  best_performance = c2->old_economy[1].performance_history;
731  best = c2;
732  }
733  }
734 
735  /* Asked all companies? */
736  if (best_performance == -1) {
737  c->bankrupt_asked = MAX_UVALUE(CompanyMask);
738  return;
739  }
740 
741  SetBit(c->bankrupt_asked, best->index);
742 
743  c->bankrupt_timeout = TAKE_OVER_TIMEOUT;
744 
745  AI::NewEvent(best->index, new ScriptEventCompanyAskMerger(c->index, c->bankrupt_value));
746  if (IsInteractiveCompany(best->index)) {
747  ShowBuyCompanyDialog(c->index, false);
748  }
749 }
750 
753 {
754  if (_game_mode == GM_EDITOR) return;
755 
757  if (c != nullptr) {
758  if (c->name_1 != 0) GenerateCompanyName(c);
760  }
761 
762  if (_new_competitor_timeout.HasFired() && _game_mode != GM_MENU && AI::CanStartNew()) {
764  /* If the interval is zero, start as many competitors as needed then check every ~10 minutes if a company went bankrupt and needs replacing. */
765  if (timeout == 0) {
766  /* count number of competitors */
767  uint8_t n = 0;
768  for (const Company *cc : Company::Iterate()) {
769  if (cc->is_ai) n++;
770  }
771 
772  for (auto i = 0; i < _settings_game.difficulty.max_no_competitors; i++) {
774  if (n++ >= _settings_game.difficulty.max_no_competitors) break;
776  }
777  timeout = 10 * 60 * Ticks::TICKS_PER_SECOND;
778  }
779  /* Randomize a bit when the AI is actually going to start; ranges from 87.5% .. 112.5% of indicated value. */
780  timeout += ScriptObject::GetRandomizer(OWNER_NONE).Next(timeout / 4) - timeout / 8;
781 
782  _new_competitor_timeout.Reset({ TimerGameTick::Priority::COMPETITOR_TIMEOUT, static_cast<uint>(std::max(1, timeout)) });
783  }
784 
786 }
787 
792 static IntervalTimer<TimerGameEconomy> _economy_companies_yearly({TimerGameEconomy::YEAR, TimerGameEconomy::Priority::COMPANY}, [](auto)
793 {
794  /* Copy statistics */
795  for (Company *c : Company::Iterate()) {
796  /* Move expenses to previous years. */
797  std::rotate(std::rbegin(c->yearly_expenses), std::rbegin(c->yearly_expenses) + 1, std::rend(c->yearly_expenses));
798  c->yearly_expenses[0] = {};
799  SetWindowDirty(WC_FINANCES, c->index);
800  }
801 
807  } else {
809  }
810  }
811 });
812 
819 {
820  SetDParam(0, c->index);
821  this->company_name = GetString(STR_COMPANY_NAME);
822 
823  if (other != nullptr) {
824  SetDParam(0, other->index);
825  this->other_company_name = GetString(STR_COMPANY_NAME);
826  c = other;
827  }
828 
829  SetDParam(0, c->index);
830  this->president_name = GetString(STR_PRESIDENT_NAME_MANAGER);
831 
832  this->colour = c->colour;
833  this->face = c->face;
834 
835 }
836 
841 void CompanyAdminUpdate(const Company *company)
842 {
844 }
845 
852 {
854 }
855 
865 {
867 
868  switch (cca) {
869  case CCA_NEW: { // Create a new company
870  /* This command is only executed in a multiplayer game */
871  if (!_networking) return CMD_ERROR;
872 
873  /* Has the network client a correct ClientIndex? */
874  if (!(flags & DC_EXEC)) return CommandCost();
875 
877 
878  /* Delete multiplayer progress bar */
880 
881  Company *c = DoStartupNewCompany(false);
882 
883  /* A new company could not be created, revert to being a spectator */
884  if (c == nullptr) {
885  /* We check for "ci != nullptr" as a client could have left by
886  * the time we execute this command. */
887  if (_network_server && ci != nullptr) {
890  }
891  break;
892  }
893 
896 
897  /* This is the client (or non-dedicated server) who wants a new company */
898  if (client_id == _network_own_client_id) {
901 
902  /*
903  * If a favorite company manager face is selected, choose it. Otherwise, use a random face.
904  * Because this needs to be synchronised over the network, only the client knows
905  * its configuration and we are currently in the execution of a command, we have
906  * to circumvent the normal ::Post logic for commands and just send the command.
907  */
909 
910  /* Now that we have a new company, broadcast our company settings to
911  * all clients so everything is in sync */
913 
915  }
916  break;
917  }
918 
919  case CCA_NEW_AI: { // Make a new AI company
920  if (company_id != INVALID_COMPANY && company_id >= MAX_COMPANIES) return CMD_ERROR;
921 
922  /* For network games, company deletion is delayed. */
923  if (!_networking && company_id != INVALID_COMPANY && Company::IsValidID(company_id)) return CMD_ERROR;
924 
925  if (!(flags & DC_EXEC)) return CommandCost();
926 
927  /* For network game, just assume deletion happened. */
928  assert(company_id == INVALID_COMPANY || !Company::IsValidID(company_id));
929 
930  Company *c = DoStartupNewCompany(true, company_id);
931  if (c != nullptr) {
933  NetworkServerNewCompany(c, nullptr);
934  }
935  break;
936  }
937 
938  case CCA_DELETE: { // Delete a company
939  if (reason >= CRR_END) return CMD_ERROR;
940 
941  /* We can't delete the last existing company in singleplayer mode. */
942  if (!_networking && Company::GetNumItems() == 1) return CMD_ERROR;
943 
944  Company *c = Company::GetIfValid(company_id);
945  if (c == nullptr) return CMD_ERROR;
946 
947  if (!(flags & DC_EXEC)) return CommandCost();
948 
950 
951  /* Show the bankrupt news */
952  SetDParam(0, STR_NEWS_COMPANY_BANKRUPT_TITLE);
953  SetDParam(1, STR_NEWS_COMPANY_BANKRUPT_DESCRIPTION);
954  SetDParamStr(2, cni->company_name);
955  AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, cni);
956 
957  /* Remove the company */
959  if (c->is_ai) AI::Stop(c->index);
960 
961  CompanyID c_index = c->index;
962  delete c;
963  AI::BroadcastNewEvent(new ScriptEventCompanyBankrupt(c_index));
964  Game::NewEvent(new ScriptEventCompanyBankrupt(c_index));
965  CompanyAdminRemove(c_index, (CompanyRemoveReason)reason);
966 
969 
970  break;
971  }
972 
973  default: return CMD_ERROR;
974  }
975 
979 
980  return CommandCost();
981 }
982 
983 static bool ExecuteAllowListCtrlAction(CompanyAllowListCtrlAction action, Company *c, const std::string &public_key)
984 {
985  switch (action) {
986  case CALCA_ADD:
987  return c->allow_list.Add(public_key);
988 
989  case CALCA_REMOVE:
990  return c->allow_list.Remove(public_key);
991 
992  default:
993  NOT_REACHED();
994  }
995 }
996 
1005 {
1007  if (c == nullptr) return CMD_ERROR;
1008 
1009  /* The public key length includes the '\0'. */
1010  if (public_key.size() != NETWORK_PUBLIC_KEY_LENGTH - 1) return CMD_ERROR;
1011 
1012  switch (action) {
1013  case CALCA_ADD:
1014  case CALCA_REMOVE:
1015  break;
1016 
1017  default:
1018  return CMD_ERROR;
1019  }
1020 
1021  if (flags & DC_EXEC) {
1022  if (ExecuteAllowListCtrlAction(action, c, public_key)) {
1025  }
1026  }
1027 
1028  return CommandCost();
1029 }
1030 
1038 {
1039  if (!IsValidCompanyManagerFace(cmf)) return CMD_ERROR;
1040 
1041  if (flags & DC_EXEC) {
1042  Company::Get(_current_company)->face = cmf;
1044  }
1045  return CommandCost();
1046 }
1047 
1054 {
1055  for (int i = 1; i < LS_END; i++) {
1056  if (!HasBit(c->livery[i].in_use, 0)) c->livery[i].colour1 = c->livery[LS_DEFAULT].colour1;
1057  if (!HasBit(c->livery[i].in_use, 1)) c->livery[i].colour2 = c->livery[LS_DEFAULT].colour2;
1058  }
1060 }
1061 
1070 CommandCost CmdSetCompanyColour(DoCommandFlag flags, LiveryScheme scheme, bool primary, Colours colour)
1071 {
1072  if (scheme >= LS_END || (colour >= COLOUR_END && colour != INVALID_COLOUR)) return CMD_ERROR;
1073 
1074  /* Default scheme can't be reset to invalid. */
1075  if (scheme == LS_DEFAULT && colour == INVALID_COLOUR) return CMD_ERROR;
1076 
1078 
1079  /* Ensure no two companies have the same primary colour */
1080  if (scheme == LS_DEFAULT && primary) {
1081  for (const Company *cc : Company::Iterate()) {
1082  if (cc != c && cc->colour == colour) return CMD_ERROR;
1083  }
1084  }
1085 
1086  if (flags & DC_EXEC) {
1087  if (primary) {
1088  if (scheme != LS_DEFAULT) AssignBit(c->livery[scheme].in_use, 0, colour != INVALID_COLOUR);
1089  if (colour == INVALID_COLOUR) colour = c->livery[LS_DEFAULT].colour1;
1090  c->livery[scheme].colour1 = colour;
1091 
1092  /* If setting the first colour of the default scheme, adjust the
1093  * original and cached company colours too. */
1094  if (scheme == LS_DEFAULT) {
1097  c->colour = colour;
1098  CompanyAdminUpdate(c);
1099  }
1100  } else {
1101  if (scheme != LS_DEFAULT) AssignBit(c->livery[scheme].in_use, 1, colour != INVALID_COLOUR);
1102  if (colour == INVALID_COLOUR) colour = c->livery[LS_DEFAULT].colour2;
1103  c->livery[scheme].colour2 = colour;
1104 
1105  if (scheme == LS_DEFAULT) {
1107  }
1108  }
1109 
1110  if (c->livery[scheme].in_use != 0) {
1111  /* If enabling a scheme, set the default scheme to be in use too */
1112  c->livery[LS_DEFAULT].in_use = 1;
1113  } else {
1114  /* Else loop through all schemes to see if any are left enabled.
1115  * If not, disable the default scheme too. */
1116  c->livery[LS_DEFAULT].in_use = 0;
1117  for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
1118  if (c->livery[scheme].in_use != 0) {
1119  c->livery[LS_DEFAULT].in_use = 1;
1120  break;
1121  }
1122  }
1123  }
1124 
1125  ResetVehicleColourMap();
1127 
1128  /* All graph related to companies use the company colour. */
1135  /* The smallmap owner view also stores the company colours. */
1136  BuildOwnerLegend();
1138 
1139  /* Company colour data is indirectly cached. */
1140  for (Vehicle *v : Vehicle::Iterate()) {
1141  if (v->owner == _current_company) v->InvalidateNewGRFCache();
1142  }
1143 
1145  }
1146  return CommandCost();
1147 }
1148 
1154 static bool IsUniqueCompanyName(const std::string &name)
1155 {
1156  for (const Company *c : Company::Iterate()) {
1157  if (!c->name.empty() && c->name == name) return false;
1158  }
1159 
1160  return true;
1161 }
1162 
1169 CommandCost CmdRenameCompany(DoCommandFlag flags, const std::string &text)
1170 {
1171  bool reset = text.empty();
1172 
1173  if (!reset) {
1175  if (!IsUniqueCompanyName(text)) return_cmd_error(STR_ERROR_NAME_MUST_BE_UNIQUE);
1176  }
1177 
1178  if (flags & DC_EXEC) {
1180  if (reset) {
1181  c->name.clear();
1182  } else {
1183  c->name = text;
1184  }
1186  CompanyAdminUpdate(c);
1187  }
1188 
1189  return CommandCost();
1190 }
1191 
1197 static bool IsUniquePresidentName(const std::string &name)
1198 {
1199  for (const Company *c : Company::Iterate()) {
1200  if (!c->president_name.empty() && c->president_name == name) return false;
1201  }
1202 
1203  return true;
1204 }
1205 
1212 CommandCost CmdRenamePresident(DoCommandFlag flags, const std::string &text)
1213 {
1214  bool reset = text.empty();
1215 
1216  if (!reset) {
1218  if (!IsUniquePresidentName(text)) return_cmd_error(STR_ERROR_NAME_MUST_BE_UNIQUE);
1219  }
1220 
1221  if (flags & DC_EXEC) {
1223 
1224  if (reset) {
1225  c->president_name.clear();
1226  } else {
1227  c->president_name = text;
1228 
1229  if (c->name_1 == STR_SV_UNNAMED && c->name.empty()) {
1230  Command<CMD_RENAME_COMPANY>::Do(DC_EXEC, text + " Transport");
1231  }
1232  }
1233 
1236  CompanyAdminUpdate(c);
1237  }
1238 
1239  return CommandCost();
1240 }
1241 
1249 {
1250  const VehicleDefaultSettings *vds = (c == nullptr) ? &_settings_client.company.vehicle : &c->settings.vehicle;
1251  switch (type) {
1252  default: NOT_REACHED();
1253  case VEH_TRAIN: return vds->servint_trains;
1254  case VEH_ROAD: return vds->servint_roadveh;
1255  case VEH_AIRCRAFT: return vds->servint_aircraft;
1256  case VEH_SHIP: return vds->servint_ships;
1257  }
1258 }
1259 
1265 {
1266  uint32_t total = 0;
1267  for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
1268  if (RoadTypeIsRoad(rt)) total += this->road[rt];
1269  }
1270  return total;
1271 }
1272 
1278 {
1279  uint32_t total = 0;
1280  for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
1281  if (RoadTypeIsTram(rt)) total += this->road[rt];
1282  }
1283  return total;
1284 }
1285 
1297 {
1299 
1301  CommandCost amount(EXPENSES_OTHER, std::min<Money>(money, 20000000LL));
1302 
1303  /* You can only transfer funds that is in excess of your loan */
1304  if (c->money - c->current_loan < amount.GetCost() || amount.GetCost() < 0) return_cmd_error(STR_ERROR_INSUFFICIENT_FUNDS);
1305  if (!Company::IsValidID(dest_company)) return CMD_ERROR;
1306 
1307  if (flags & DC_EXEC) {
1308  /* Add money to company */
1309  Backup<CompanyID> cur_company(_current_company, dest_company);
1311  cur_company.Restore();
1312 
1313  if (_networking) {
1314  SetDParam(0, dest_company);
1315  std::string dest_company_name = GetString(STR_COMPANY_NAME);
1316 
1318  std::string from_company_name = GetString(STR_COMPANY_NAME);
1319 
1320  NetworkTextMessage(NETWORK_ACTION_GIVE_MONEY, GetDrawStringCompanyColour(_current_company), false, from_company_name, dest_company_name, amount.GetCost());
1321  }
1322  }
1323 
1324  /* Subtract money from local-company */
1325  return amount;
1326 }
1327 
1338 {
1339  for (Company *c : Company::Iterate()) {
1340  if (Company::IsHumanID(c->index)) {
1341  return c->index;
1342  }
1343  }
1344 
1345  if (Company::CanAllocateItem()) {
1346  for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
1347  if (!Company::IsValidID(c)) {
1348  return c;
1349  }
1350  }
1351  }
1352 
1353  return COMPANY_FIRST;
1354 }
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.
constexpr debug_inline 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.
constexpr static debug_inline 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.
Definition: command_type.h:23
ExpensesType GetExpensesType() const
The expense type of the cost.
Definition: command_type.h:92
Money GetCost() const
The costs as made up to this moment.
Definition: command_type.h:83
void MakeError(StringID message, StringID extra_message=INVALID_STRING_ID)
Makes this CommandCost behave like an error command.
Definition: command_type.h:101
static void NewEvent(class ScriptEvent *event)
Queue a new event for a Game Script.
Definition: game_core.cpp:146
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
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.
Definition: command_func.h:28
#define return_cmd_error(errcode)
Returns from a function with a specific StringID as error.
Definition: command_func.h:38
DoCommandFlag
List of flags for a command.
Definition: command_type.h:374
@ DC_EXEC
execute the given command
Definition: command_type.h:376
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:969
void UpdateObjectColours(const Company *c)
Updates the colour of the object whenever a company changes.
Definition: object_cmd.cpp:183
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.
Definition: company_cmd.cpp:54
static void SubtractMoneyFromAnyCompany(Company *c, const CommandCost &cost)
Deduct costs of a command from the money of a company.
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]={};SetWindowDirty(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...
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.
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.
Company * DoStartupNewCompany(bool is_ai, CompanyID company=INVALID_COMPANY)
Create a new company and sets all company variables default values.
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.
Definition: company_cmd.cpp:52
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
Definition: company_cmd.cpp:56
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
Definition: company_cmd.cpp:55
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.
Definition: company_cmd.cpp:53
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?
Definition: company_func.h:57
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.
Definition: company_func.h:20
bool IsLocalCompany()
Is the current company the local company?
Definition: company_func.h:47
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:1168
Functionality related to the company manager's face.
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.
uint GetCompanyManagerFaceBits(CompanyManagerFace cmf, CompanyManagerFaceVariable cmfv, [[maybe_unused]] GenderEthnicity ge)
Make sure the table's size is right.
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'.
Definition: company_type.h:40
static const uint MAX_LENGTH_COMPANY_NAME_CHARS
The maximum length of a company name in characters including '\0'.
Definition: company_type.h:41
CompanyCtrlAction
The action to do with CMD_COMPANY_CTRL.
Definition: company_type.h:67
@ CCA_NEW_AI
Create a new AI company.
Definition: company_type.h:69
@ CCA_DELETE
Delete a company.
Definition: company_type.h:70
@ CCA_NEW
Create a new company.
Definition: company_type.h:68
CompanyAllowListCtrlAction
The action to do with CMD_COMPANY_ALLOW_LIST_CTRL.
Definition: company_type.h:76
@ CALCA_REMOVE
Remove a public key.
Definition: company_type.h:78
@ CALCA_ADD
Create a public key.
Definition: company_type.h:77
uint32_t CompanyManagerFace
Company manager face bits, info see in company_manager_face.h.
Definition: company_type.h:52
Owner
Enum for all companies/owners.
Definition: company_type.h:18
@ INVALID_COMPANY
An invalid company.
Definition: company_type.h:30
@ INVALID_OWNER
An invalid owner.
Definition: company_type.h:29
@ OWNER_END
Last + 1 owner.
Definition: company_type.h:28
@ COMPANY_SPECTATOR
The client is spectating.
Definition: company_type.h:35
@ COMPANY_FIRST
First company, same as owner.
Definition: company_type.h:22
@ OWNER_NONE
The tile has no ownership.
Definition: company_type.h:25
@ OWNER_TOWN
A town owns the tile, or a town is expanding.
Definition: company_type.h:24
@ MAX_COMPANIES
Maximum number of companies.
Definition: company_type.h:23
CompanyRemoveReason
The reason why the company was removed.
Definition: company_type.h:56
@ CRR_END
Sentinel for end.
Definition: company_type.h:61
@ CRR_NONE
Dummy reason for actions that don't need one.
Definition: company_type.h:63
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.
Definition: economy_type.h:176
@ EXPENSES_TRAIN_RUN
Running costs trains.
Definition: economy_type.h:175
@ EXPENSES_AIRCRAFT_REVENUE
Revenue from aircraft.
Definition: economy_type.h:182
@ EXPENSES_AIRCRAFT_RUN
Running costs aircraft.
Definition: economy_type.h:177
@ EXPENSES_ROADVEH_REVENUE
Revenue from road vehicles.
Definition: economy_type.h:181
@ EXPENSES_PROPERTY
Property costs.
Definition: economy_type.h:179
@ EXPENSES_OTHER
Other expenses.
Definition: economy_type.h:185
@ EXPENSES_SHIP_REVENUE
Revenue from ships.
Definition: economy_type.h:183
@ EXPENSES_LOAN_INTEREST
Interest payments over the loan.
Definition: economy_type.h:184
@ EXPENSES_TRAIN_REVENUE
Revenue from trains.
Definition: economy_type.h:180
@ EXPENSES_SHIP_RUN
Running costs ships.
Definition: economy_type.h:178
@ INVALID_EXPENSES
Invalid expense type.
Definition: economy_type.h:187
static const int LOAN_INTERVAL
The "steps" in loan size, in British Pounds!
Definition: economy_type.h:215
static const int64_t INITIAL_LOAN
The size of loan for a new company, in British Pounds!
Definition: economy_type.h:217
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:260
@ TC_IS_PALETTE_COLOUR
Colour value is already a real palette colour index, not an index of a StringColour.
Definition: gfx_type.h:283
Goal base class.
void UpdateCompanyGroupLiveries(const Company *c)
Update group liveries for a company.
Definition: group_cmd.cpp:311
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition: gfx.cpp:1529
LiveryScheme
List of different livery schemes.
Definition: livery.h:21
constexpr bool IsInsideMM(const T x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
Definition: math_func.hpp:268
constexpr void Swap(T &a, T &b)
Type safe swap operation.
Definition: math_func.hpp:283
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)
Definition: network_type.h:81
ClientID
'Unique' identifier to be given to clients
Definition: network_type.h:49
@ INVALID_CLIENT_ID
Client is not part of anything.
Definition: network_type.h:50
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, const NewsAllocatedData *data=nullptr)
Add a new newsitem to be shown.
Definition: news_gui.cpp:829
@ 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:54
@ NR_NONE
Empty reference.
Definition: news_type.h:53
@ NF_COMPANY
Company news item. (Newspaper with face)
Definition: news_type.h:83
uint8_t GetColourGradient(Colours colour, ColourShade shade)
Get colour gradient palette index.
Definition: palette.cpp:314
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.
Definition: pool_func.hpp:237
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.
Definition: random_func.cpp:37
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.
Definition: settings.cpp:1795
void SetDefaultCompanySettings(CompanyID cid)
Set the company settings for a new company to their default values.
Definition: settings.cpp:1783
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:79
@ SND_00_GOOD_YEAR
39 == 0x27 New year: performance improved
Definition: sound_type.h:78
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.
#define MAX_UVALUE(type)
The largest value that can be entered in a variable.
Definition: stdafx.h:343
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:319
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:357
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
Class to backup a specific variable and restore it later.
Definition: backup_type.hpp:21
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.
Definition: company_base.h:25
Money expenses
The amount of expenses.
Definition: company_base.h:26
int32_t performance_history
Company score (scale 0-1000)
Definition: company_base.h:28
std::array< uint32_t, ROADTYPE_END > road
Count of company owned track bits for each road type.
Definition: company_base.h:34
uint32_t GetRoadTotal() const
Get total sum of all owned road bits.
uint32_t GetTramTotal() const
Get total sum of all owned tram bits.
Data that needs to be stored for company news messages.
Definition: news_type.h:153
uint32_t face
The face of the president.
Definition: news_type.h:158
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:159
std::string president_name
The name of the president.
Definition: news_type.h:155
std::string company_name
The name of the company.
Definition: news_type.h:154
std::string other_company_name
The name of the company taking over this one.
Definition: news_type.h:156
CompanyMask bankrupt_asked
which companies were asked about buying it?
Definition: company_base.h:99
std::string president_name
Name of the president if the user changed it.
Definition: company_base.h:76
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:100
CompanySettings settings
settings specific for each company
Definition: company_base.h:122
NetworkAuthorizedKeys allow_list
Public keys of clients that are allowed to join this company.
Definition: company_base.h:78
CompanyEconomyEntry old_economy[MAX_HISTORY_QUARTERS]
Economic data of the company of the last MAX_HISTORY_QUARTERS quarters.
Definition: company_base.h:116
uint32_t name_2
Parameter of name_1.
Definition: company_base.h:70
uint8_t money_fraction
Fraction of money of the company, too small to represent in money.
Definition: company_base.h:83
bool is_ai
If true, the company is (also) controlled by the computer (a NoAI program).
Definition: company_base.h:112
uint32_t president_name_2
Parameter of president_name_1.
Definition: company_base.h:75
StringID name_1
Name of the company if the user did not change it.
Definition: company_base.h:71
Money current_loan
Amount of money borrowed from the bank.
Definition: company_base.h:84
TimerGameCalendar::Year inaugurated_year_calendar
Calendar year of starting the company. Used to display proper Inauguration year while in wallclock mo...
Definition: company_base.h:95
TimerGameEconomy::Year inaugurated_year
Economy year of starting the company.
Definition: company_base.h:94
CompanyEconomyEntry cur_economy
Economic data of the company of this quarter.
Definition: company_base.h:115
Colours colour
Company colour.
Definition: company_base.h:87
CompanyManagerFace face
Face description of the president.
Definition: company_base.h:80
Money max_loan
Max allowed amount of the loan or COMPANY_MAX_LOAN_DEFAULT.
Definition: company_base.h:85
std::array< Expenses, 3 > yearly_expenses
Expenses of the company for the last three years.
Definition: company_base.h:114
TileIndex last_build_coordinate
Coordinate of the last build thing by this company.
Definition: company_base.h:92
StringID president_name_1
Name of the president if the user did not change it.
Definition: company_base.h:74
std::string name
Name of the company if the user changed it.
Definition: company_base.h:72
Money money
Money owned by the company.
Definition: company_base.h:82
uint8_t num_valid_stat_ent
Number of valid statistical entries in old_economy.
Definition: company_base.h:117
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?
Definition: company_base.h:184
RoadTypes avail_roadtypes
Road types available to this company.
Definition: company_base.h:138
~Company()
Destructor.
Definition: company_cmd.cpp:80
RailTypes avail_railtypes
Rail types available to this company.
Definition: company_base.h:137
static void PostDestructor(size_t index)
Invalidating some stuff after removing item from the pool.
Definition: company_cmd.cpp:91
GroupStatistics group_all[VEH_COMPANY_END]
NOSAVE: Statistics for the ALL_GROUP group.
Definition: company_base.h:144
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)
Definition: settings_type.h:99
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.
Definition: economy_type.h:51
Money max_loan
NOSAVE: Maximum possible loan.
Definition: economy_type.h:44
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.
Definition: network_base.h:24
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)
Definition: network_base.h:28
ClientID client_id
Client identifier (same as ClientState->client_id)
Definition: network_base.h:25
uint8_t max_companies
maximum amount of companies
Tindex index
Index of this pool item.
Definition: pool_type.hpp:238
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:339
static size_t GetNumItems()
Returns number of valid items in the pool.
Definition: pool_type.hpp:369
static bool CleaningPool()
Returns current state of pool cleaning - yes or no.
Definition: pool_type.hpp:318
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Definition: pool_type.hpp:328
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
Definition: pool_type.hpp:309
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:350
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition: pool_type.hpp:388
Base class for all pools.
Definition: pool_type.hpp:80
bool new_year
Play sound on new year, summarising the performance during the last year.
Town data structure.
Definition: town.h:54
std::string name
Custom town name. If empty, the town was not renamed and uses the generated name.
Definition: town.h:63
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.
Definition: vehicle_base.h:244
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.
Definition: town_cmd.cpp:3870
Base class for all vehicles.
Functions related to vehicles.
VehicleType
Available vehicle types.
Definition: vehicle_type.h:21
@ VEH_ROAD
Road vehicle type.
Definition: vehicle_type.h:25
@ VEH_AIRCRAFT
Aircraft vehicle type.
Definition: vehicle_type.h:27
@ VEH_SHIP
Ship vehicle type.
Definition: vehicle_type.h:26
@ VEH_TRAIN
Train vehicle type.
Definition: vehicle_type.h:24
void CloseConstructionWindows()
Close all windows that are used for construction of vehicle etc.
Definition: window.cpp:3297
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:1140
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:3211
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:3106
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition: window.cpp:3093
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:3228
Window functions not directly related to making/drawing windows.
@ WN_NETWORK_STATUS_WINDOW_JOIN
Network join status.
Definition: window_type.h:39
@ WC_PERFORMANCE_HISTORY
Performance history graph; Window numbers:
Definition: window_type.h:551
@ WC_COMPANY_LEAGUE
Company league window; Window numbers:
Definition: window_type.h:563
@ WC_SIGN_LIST
Sign list; Window numbers:
Definition: window_type.h:278
@ WC_PERFORMANCE_DETAIL
Performance detail window; Window numbers:
Definition: window_type.h:575
@ WC_GRAPH_LEGEND
Legend for graphs; Window numbers:
Definition: window_type.h:521
@ WC_LINKGRAPH_LEGEND
Linkgraph legend; Window numbers:
Definition: window_type.h:692
@ WC_STATUS_BAR
Statusbar (at the bottom of your screen); Window numbers:
Definition: window_type.h:64
@ WC_SEND_NETWORK_MSG
Chatbox; Window numbers:
Definition: window_type.h:509
@ WC_ERRMSG
Error message; Window numbers:
Definition: window_type.h:110
@ WC_SCRIPT_SETTINGS
Script settings; Window numbers:
Definition: window_type.h:175
@ WC_SCRIPT_LIST
Scripts list; Window numbers:
Definition: window_type.h:284
@ WC_GOALS_LIST
Goals list; Window numbers:
Definition: window_type.h:290
@ WC_OPERATING_PROFIT
Operating profit graph; Window numbers:
Definition: window_type.h:539
@ WC_CLIENT_LIST
Client list; Window numbers:
Definition: window_type.h:484
@ WC_GAME_OPTIONS
Game options window; Window numbers:
Definition: window_type.h:624
@ WC_FINANCES
Finances of a company; Window numbers:
Definition: window_type.h:527
@ WC_INCOME_GRAPH
Income graph; Window numbers:
Definition: window_type.h:533
@ WC_SMALLMAP
Small map; Window numbers:
Definition: window_type.h:104
@ WC_DELIVERED_CARGO
Delivered cargo graph; Window numbers:
Definition: window_type.h:545
@ WC_COMPANY_VALUE
Company value graph; Window numbers:
Definition: window_type.h:557
@ WC_MAIN_TOOLBAR
Main toolbar (the long bar at the top); Window numbers:
Definition: window_type.h:58
@ WC_COMPANY
Company view; Window numbers:
Definition: window_type.h:369
@ WC_NETWORK_STATUS_WINDOW
Network status window; Window numbers:
Definition: window_type.h:491