OpenTTD
company_cmd.cpp
Go to the documentation of this file.
1 /* $Id: company_cmd.cpp 27893 2017-08-13 18:38:42Z frosch $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #include "stdafx.h"
13 #include "company_base.h"
14 #include "company_func.h"
15 #include "company_gui.h"
16 #include "town.h"
17 #include "news_func.h"
18 #include "cmd_helper.h"
19 #include "command_func.h"
20 #include "network/network.h"
21 #include "network/network_func.h"
22 #include "network/network_base.h"
23 #include "network/network_admin.h"
24 #include "ai/ai.hpp"
25 #include "company_manager_face.h"
26 #include "window_func.h"
27 #include "strings_func.h"
28 #include "date_func.h"
29 #include "sound_func.h"
30 #include "rail.h"
31 #include "core/pool_func.hpp"
32 #include "settings_func.h"
33 #include "vehicle_base.h"
34 #include "vehicle_func.h"
35 #include "smallmap_gui.h"
36 #include "game/game.hpp"
37 #include "goal_base.h"
38 #include "story_base.h"
39 
40 #include "table/strings.h"
41 
42 #include "safeguards.h"
43 
45 
52 
53 CompanyPool _company_pool("Company");
55 
56 
61 Company::Company(uint16 name_1, bool is_ai)
62 {
63  this->name_1 = name_1;
64  this->location_of_HQ = INVALID_TILE;
65  this->is_ai = is_ai;
66  this->terraform_limit = _settings_game.construction.terraform_frame_burst << 16;
67  this->clear_limit = _settings_game.construction.clear_frame_burst << 16;
68  this->tree_limit = _settings_game.construction.tree_frame_burst << 16;
69 
70  for (uint j = 0; j < 4; j++) this->share_owners[j] = COMPANY_SPECTATOR;
72 }
73 
76 {
77  if (CleaningPool()) return;
78 
80 }
81 
86 void Company::PostDestructor(size_t index)
87 {
88  InvalidateWindowData(WC_GRAPH_LEGEND, 0, (int)index);
92  /* If the currently shown error message has this company in it, then close it. */
94 }
95 
102 void SetLocalCompany(CompanyID new_company)
103 {
104  /* company could also be COMPANY_SPECTATOR or OWNER_NONE */
105  assert(Company::IsValidID(new_company) || new_company == COMPANY_SPECTATOR || new_company == OWNER_NONE);
106 
107 #ifdef ENABLE_NETWORK
108  /* Delete the chat window, if you were team chatting. */
110 #endif
111 
112  assert(IsLocalCompany());
113 
114  _current_company = _local_company = new_company;
115 
116  /* Delete any construction windows... */
118 
119  /* ... and redraw the whole screen. */
122 }
123 
130 {
131  if (!Company::IsValidID(company)) return (TextColour)_colour_gradient[COLOUR_WHITE][4] | TC_IS_PALETTE_COLOUR;
133 }
134 
141 void DrawCompanyIcon(CompanyID c, int x, int y)
142 {
143  DrawSprite(SPR_COMPANY_ICON, COMPANY_SPRITE_COLOUR(c), x, y);
144 }
145 
153 {
154  if (!AreCompanyManagerFaceBitsValid(cmf, CMFV_GEN_ETHN, GE_WM)) return false;
155 
157  bool has_moustache = !HasBit(ge, GENDER_FEMALE) && GetCompanyManagerFaceBits(cmf, CMFV_HAS_MOUSTACHE, ge) != 0;
158  bool has_tie_earring = !HasBit(ge, GENDER_FEMALE) || GetCompanyManagerFaceBits(cmf, CMFV_HAS_TIE_EARRING, ge) != 0;
159  bool has_glasses = GetCompanyManagerFaceBits(cmf, CMFV_HAS_GLASSES, ge) != 0;
160 
161  if (!AreCompanyManagerFaceBitsValid(cmf, CMFV_EYE_COLOUR, ge)) return false;
162  for (CompanyManagerFaceVariable cmfv = CMFV_CHEEKS; cmfv < CMFV_END; cmfv++) {
163  switch (cmfv) {
164  case CMFV_MOUSTACHE: if (!has_moustache) continue; break;
165  case CMFV_LIPS:
166  case CMFV_NOSE: if (has_moustache) continue; break;
167  case CMFV_TIE_EARRING: if (!has_tie_earring) continue; break;
168  case CMFV_GLASSES: if (!has_glasses) continue; break;
169  default: break;
170  }
171  if (!AreCompanyManagerFaceBitsValid(cmf, cmfv, ge)) return false;
172  }
173 
174  return true;
175 }
176 
181 void InvalidateCompanyWindows(const Company *company)
182 {
183  CompanyID cid = company->index;
184 
185  if (cid == _local_company) SetWindowDirty(WC_STATUS_BAR, 0);
187 }
188 
195 {
196  if (cost.GetCost() > 0) {
197  const Company *c = Company::GetIfValid(_current_company);
198  if (c != NULL && cost.GetCost() > c->money) {
199  SetDParam(0, cost.GetCost());
200  cost.MakeError(STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY);
201  return false;
202  }
203  }
204  return true;
205 }
206 
213 {
214  if (cost.GetCost() == 0) return;
215  assert(cost.GetExpensesType() != INVALID_EXPENSES);
216 
217  c->money -= cost.GetCost();
218  c->yearly_expenses[0][cost.GetExpensesType()] += cost.GetCost();
219 
220  if (HasBit(1 << EXPENSES_TRAIN_INC |
221  1 << EXPENSES_ROADVEH_INC |
222  1 << EXPENSES_AIRCRAFT_INC |
223  1 << EXPENSES_SHIP_INC, cost.GetExpensesType())) {
224  c->cur_economy.income -= cost.GetCost();
225  } else if (HasBit(1 << EXPENSES_TRAIN_RUN |
226  1 << EXPENSES_ROADVEH_RUN |
227  1 << EXPENSES_AIRCRAFT_RUN |
228  1 << EXPENSES_SHIP_RUN |
229  1 << EXPENSES_PROPERTY |
230  1 << EXPENSES_LOAN_INT, cost.GetExpensesType())) {
231  c->cur_economy.expenses -= cost.GetCost();
232  }
233 
235 }
236 
242 {
243  Company *c = Company::GetIfValid(_current_company);
244  if (c != NULL) SubtractMoneyFromAnyCompany(c, cost);
245 }
246 
253 {
254  Company *c = Company::Get(company);
255  byte m = c->money_fraction;
256  Money cost = cst.GetCost();
257 
258  c->money_fraction = m - (byte)cost;
259  cost >>= 8;
260  if (c->money_fraction > m) cost++;
261  if (cost != 0) SubtractMoneyFromAnyCompany(c, CommandCost(cst.GetExpensesType(), cost));
262 }
263 
266 {
267  Company *c;
268  FOR_ALL_COMPANIES(c) {
272  }
273 }
274 
281 void GetNameOfOwner(Owner owner, TileIndex tile)
282 {
283  SetDParam(2, owner);
284 
285  if (owner != OWNER_TOWN) {
286  if (!Company::IsValidID(owner)) {
287  SetDParam(0, STR_COMPANY_SOMEONE);
288  } else {
289  SetDParam(0, STR_COMPANY_NAME);
290  SetDParam(1, owner);
291  }
292  } else {
293  assert(tile != 0);
294  const Town *t = ClosestTownFromTile(tile, UINT_MAX);
295 
296  SetDParam(0, STR_TOWN_NAME);
297  SetDParam(1, t->index);
298  }
299 }
300 
301 
311 {
312  assert(owner < OWNER_END);
313  assert(owner != OWNER_TOWN || tile != 0);
314 
315  if (owner == _current_company) return CommandCost();
316 
317  GetNameOfOwner(owner, tile);
318  return_cmd_error(STR_ERROR_OWNED_BY);
319 }
320 
329 {
330  Owner owner = GetTileOwner(tile);
331 
332  assert(owner < OWNER_END);
333 
334  if (owner == _current_company) return CommandCost();
335 
336  /* no need to get the name of the owner unless we're the local company (saves some time) */
337  if (IsLocalCompany()) GetNameOfOwner(owner, tile);
338  return_cmd_error(STR_ERROR_OWNED_BY);
339 }
340 
346 {
347  /* Reserve space for extra unicode character. We need to do this to be able
348  * to detect too long company name. */
349  char buffer[(MAX_LENGTH_COMPANY_NAME_CHARS + 1) * MAX_CHAR_LENGTH];
350 
351  if (c->name_1 != STR_SV_UNNAMED) return;
352  if (c->last_build_coordinate == 0) return;
353 
355 
356  StringID str;
357  uint32 strp;
358  if (t->name == NULL && IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1)) {
359  str = t->townnametype - SPECSTR_TOWNNAME_START + SPECSTR_COMPANY_NAME_START;
360  strp = t->townnameparts;
361 
362 verify_name:;
363  /* No companies must have this name already */
364  Company *cc;
365  FOR_ALL_COMPANIES(cc) {
366  if (cc->name_1 == str && cc->name_2 == strp) goto bad_town_name;
367  }
368 
369  GetString(buffer, str, lastof(buffer));
370  if (Utf8StringLength(buffer) >= MAX_LENGTH_COMPANY_NAME_CHARS) goto bad_town_name;
371 
372 set_name:;
373  c->name_1 = str;
374  c->name_2 = strp;
375 
377 
378  if (c->is_ai) {
379  CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1);
380  cni->FillData(c);
381  SetDParam(0, STR_NEWS_COMPANY_LAUNCH_TITLE);
382  SetDParam(1, STR_NEWS_COMPANY_LAUNCH_DESCRIPTION);
383  SetDParamStr(2, cni->company_name);
384  SetDParam(3, t->index);
385  AddNewsItem(STR_MESSAGE_NEWS_FORMAT, NT_COMPANY_INFO, NF_COMPANY, NR_TILE, c->last_build_coordinate, NR_NONE, UINT32_MAX, cni);
386  }
387  return;
388  }
389 bad_town_name:;
390 
391  if (c->president_name_1 == SPECSTR_PRESIDENT_NAME) {
392  str = SPECSTR_ANDCO_NAME;
393  strp = c->president_name_2;
394  goto set_name;
395  } else {
396  str = SPECSTR_ANDCO_NAME;
397  strp = Random();
398  goto verify_name;
399  }
400 }
401 
403 static const byte _colour_sort[COLOUR_END] = {2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 2, 2, 3, 1, 1, 1};
405 static const Colours _similar_colour[COLOUR_END][2] = {
406  { COLOUR_BLUE, COLOUR_LIGHT_BLUE }, // COLOUR_DARK_BLUE
407  { COLOUR_GREEN, COLOUR_DARK_GREEN }, // COLOUR_PALE_GREEN
408  { INVALID_COLOUR, INVALID_COLOUR }, // COLOUR_PINK
409  { COLOUR_ORANGE, INVALID_COLOUR }, // COLOUR_YELLOW
410  { INVALID_COLOUR, INVALID_COLOUR }, // COLOUR_RED
411  { COLOUR_DARK_BLUE, COLOUR_BLUE }, // COLOUR_LIGHT_BLUE
412  { COLOUR_PALE_GREEN, COLOUR_DARK_GREEN }, // COLOUR_GREEN
413  { COLOUR_PALE_GREEN, COLOUR_GREEN }, // COLOUR_DARK_GREEN
414  { COLOUR_DARK_BLUE, COLOUR_LIGHT_BLUE }, // COLOUR_BLUE
415  { COLOUR_BROWN, COLOUR_ORANGE }, // COLOUR_CREAM
416  { COLOUR_PURPLE, INVALID_COLOUR }, // COLOUR_MAUVE
417  { COLOUR_MAUVE, INVALID_COLOUR }, // COLOUR_PURPLE
418  { COLOUR_YELLOW, COLOUR_CREAM }, // COLOUR_ORANGE
419  { COLOUR_CREAM, INVALID_COLOUR }, // COLOUR_BROWN
420  { COLOUR_WHITE, INVALID_COLOUR }, // COLOUR_GREY
421  { COLOUR_GREY, INVALID_COLOUR }, // COLOUR_WHITE
422 };
423 
428 static Colours GenerateCompanyColour()
429 {
430  Colours colours[COLOUR_END];
431 
432  /* Initialize array */
433  for (uint i = 0; i < COLOUR_END; i++) colours[i] = (Colours)i;
434 
435  /* And randomize it */
436  for (uint i = 0; i < 100; i++) {
437  uint r = Random();
438  Swap(colours[GB(r, 0, 4)], colours[GB(r, 4, 4)]);
439  }
440 
441  /* Bubble sort it according to the values in table 1 */
442  for (uint i = 0; i < COLOUR_END; i++) {
443  for (uint j = 1; j < COLOUR_END; j++) {
444  if (_colour_sort[colours[j - 1]] < _colour_sort[colours[j]]) {
445  Swap(colours[j - 1], colours[j]);
446  }
447  }
448  }
449 
450  /* Move the colours that look similar to each company's colour to the side */
451  Company *c;
452  FOR_ALL_COMPANIES(c) {
453  Colours pcolour = (Colours)c->colour;
454 
455  for (uint i = 0; i < COLOUR_END; i++) {
456  if (colours[i] == pcolour) {
457  colours[i] = INVALID_COLOUR;
458  break;
459  }
460  }
461 
462  for (uint j = 0; j < 2; j++) {
463  Colours similar = _similar_colour[pcolour][j];
464  if (similar == INVALID_COLOUR) break;
465 
466  for (uint i = 1; i < COLOUR_END; i++) {
467  if (colours[i - 1] == similar) Swap(colours[i - 1], colours[i]);
468  }
469  }
470  }
471 
472  /* Return the first available colour */
473  for (uint i = 0; i < COLOUR_END; i++) {
474  if (colours[i] != INVALID_COLOUR) return colours[i];
475  }
476 
477  NOT_REACHED();
478 }
479 
485 {
486  for (;;) {
487 restart:;
488  c->president_name_2 = Random();
489  c->president_name_1 = SPECSTR_PRESIDENT_NAME;
490 
491  /* Reserve space for extra unicode character. We need to do this to be able
492  * to detect too long president name. */
494  SetDParam(0, c->index);
495  GetString(buffer, STR_PRESIDENT_NAME, lastof(buffer));
496  if (Utf8StringLength(buffer) >= MAX_LENGTH_PRESIDENT_NAME_CHARS) continue;
497 
498  Company *cc;
499  FOR_ALL_COMPANIES(cc) {
500  if (c != cc) {
501  /* Reserve extra space so even overlength president names can be compared. */
502  char buffer2[(MAX_LENGTH_PRESIDENT_NAME_CHARS + 1) * MAX_CHAR_LENGTH];
503  SetDParam(0, cc->index);
504  GetString(buffer2, STR_PRESIDENT_NAME, lastof(buffer2));
505  if (strcmp(buffer2, buffer) == 0) goto restart;
506  }
507  }
508  return;
509  }
510 }
511 
518 {
519  for (LiveryScheme scheme = LS_BEGIN; scheme < LS_END; scheme++) {
520  c->livery[scheme].in_use = false;
521  c->livery[scheme].colour1 = c->colour;
522  c->livery[scheme].colour2 = c->colour;
523  }
524 }
525 
534 {
535  if (!Company::CanAllocateItem()) return NULL;
536 
537  /* we have to generate colour before this company is valid */
538  Colours colour = GenerateCompanyColour();
539 
540  Company *c;
541  if (company == INVALID_COMPANY) {
542  c = new Company(STR_SV_UNNAMED, is_ai);
543  } else {
544  if (Company::IsValidID(company)) return NULL;
545  c = new (company) Company(STR_SV_UNNAMED, is_ai);
546  }
547 
548  c->colour = colour;
549 
551  _company_colours[c->index] = (Colours)c->colour;
552 
553  c->money = c->current_loan = (100000ll * _economy.inflation_prices >> 16) / 50000 * 50000;
554 
555  c->share_owners[0] = c->share_owners[1] = c->share_owners[2] = c->share_owners[3] = INVALID_OWNER;
556 
560  RandomCompanyManagerFaceBits(c->face, (GenderEthnicity)Random(), false, false); // create a random company manager face
561 
564 
566 
573 
574  if (is_ai && (!_networking || _network_server)) AI::StartNew(c->index);
575 
576  AI::BroadcastNewEvent(new ScriptEventCompanyNew(c->index), c->index);
577  Game::NewEvent(new ScriptEventCompanyNew(c->index));
578 
579  return c;
580 }
581 
584 {
586 }
587 
589 static void MaybeStartNewCompany()
590 {
591 #ifdef ENABLE_NETWORK
593 #endif /* ENABLE_NETWORK */
594 
595  Company *c;
596 
597  /* count number of competitors */
598  uint n = 0;
599  FOR_ALL_COMPANIES(c) {
600  if (c->is_ai) n++;
601  }
602 
604  /* Send a command to all clients to start up a new AI.
605  * Works fine for Multiplayer and Singleplayer */
606  DoCommandP(0, 1 | INVALID_COMPANY << 16, 0, CMD_COMPANY_CTRL);
607  }
608 }
609 
612 {
614 }
615 
623 {
624  const Company *c1 = Company::Get(cbig);
625  const Company *c2 = Company::Get(csmall);
626 
627  /* Do the combined vehicle counts stay within the limits? */
632 }
633 
644 {
645  /* Amount of time out for each company to take over a company;
646  * Timeout is a quarter (3 months of 30 days) divided over the
647  * number of companies. The minimum number of days in a quarter
648  * is 90: 31 in January, 28 in February and 31 in March.
649  * Note that the company going bankrupt can't buy itself. */
650  static const int TAKE_OVER_TIMEOUT = 3 * 30 * DAY_TICKS / (MAX_COMPANIES - 1);
651 
652  assert(c->bankrupt_asked != 0);
653 
654  /* We're currently asking some company to buy 'us' */
655  if (c->bankrupt_timeout != 0) {
657  if (c->bankrupt_timeout > 0) return;
658  c->bankrupt_timeout = 0;
659 
660  return;
661  }
662 
663  /* Did we ask everyone for bankruptcy? If so, bail out. */
664  if (c->bankrupt_asked == MAX_UVALUE(CompanyMask)) return;
665 
666  Company *c2, *best = NULL;
667  int32 best_performance = -1;
668 
669  /* Ask the company with the highest performance history first */
670  FOR_ALL_COMPANIES(c2) {
671  if (c2->bankrupt_asked == 0 && // Don't ask companies going bankrupt themselves
672  !HasBit(c->bankrupt_asked, c2->index) &&
673  best_performance < c2->old_economy[1].performance_history &&
674  MayCompanyTakeOver(c2->index, c->index)) {
675  best_performance = c2->old_economy[1].performance_history;
676  best = c2;
677  }
678  }
679 
680  /* Asked all companies? */
681  if (best_performance == -1) {
682  c->bankrupt_asked = MAX_UVALUE(CompanyMask);
683  return;
684  }
685 
686  SetBit(c->bankrupt_asked, best->index);
687 
688  c->bankrupt_timeout = TAKE_OVER_TIMEOUT;
689  if (best->is_ai) {
690  AI::NewEvent(best->index, new ScriptEventCompanyAskMerger(c->index, ClampToI32(c->bankrupt_value)));
691  } else if (IsInteractiveCompany(best->index)) {
693  }
694 }
695 
698 {
699  if (_game_mode == GM_EDITOR) return;
700 
702  if (c != NULL) {
703  if (c->name_1 != 0) GenerateCompanyName(c);
705  }
706 
707  if (_next_competitor_start == 0) {
709  }
710 
711  if (AI::CanStartNew() && _game_mode != GM_MENU && --_next_competitor_start == 0) {
713  }
714 
716 }
717 
723 {
724  Company *c;
725 
726  /* Copy statistics */
727  FOR_ALL_COMPANIES(c) {
728  memmove(&c->yearly_expenses[1], &c->yearly_expenses[0], sizeof(c->yearly_expenses) - sizeof(c->yearly_expenses[0]));
729  memset(&c->yearly_expenses[0], 0, sizeof(c->yearly_expenses[0]));
731  }
732 
733  if (_settings_client.gui.show_finances && _local_company != COMPANY_SPECTATOR) {
734  ShowCompanyFinances(_local_company);
735  c = Company::Get(_local_company);
737  if (_settings_client.sound.new_year) SndPlayFx(SND_01_BAD_YEAR);
738  } else {
739  if (_settings_client.sound.new_year) SndPlayFx(SND_00_GOOD_YEAR);
740  }
741  }
742 }
743 
750 {
751  SetDParam(0, c->index);
752  GetString(this->company_name, STR_COMPANY_NAME, lastof(this->company_name));
753 
754  if (other == NULL) {
755  *this->other_company_name = '\0';
756  } else {
757  SetDParam(0, other->index);
758  GetString(this->other_company_name, STR_COMPANY_NAME, lastof(this->other_company_name));
759  c = other;
760  }
761 
762  SetDParam(0, c->index);
763  GetString(this->president_name, STR_PRESIDENT_NAME_MANAGER, lastof(this->president_name));
764 
765  this->colour = c->colour;
766  this->face = c->face;
767 
768 }
769 
774 void CompanyAdminUpdate(const Company *company)
775 {
776 #ifdef ENABLE_NETWORK
778 #endif /* ENABLE_NETWORK */
779 }
780 
787 {
788 #ifdef ENABLE_NETWORK
790 #endif /* ENABLE_NETWORK */
791 }
792 
807 CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
808 {
810  CompanyID company_id = (CompanyID)GB(p1, 16, 8);
811 #ifdef ENABLE_NETWORK
812  ClientID client_id = (ClientID)p2;
813 #endif /* ENABLE_NETWORK */
814 
815  switch (GB(p1, 0, 16)) {
816  case 0: { // Create a new company
817  /* This command is only executed in a multiplayer game */
818  if (!_networking) return CMD_ERROR;
819 
820 #ifdef ENABLE_NETWORK
821  /* Has the network client a correct ClientIndex? */
822  if (!(flags & DC_EXEC)) return CommandCost();
824 #ifndef DEBUG_DUMP_COMMANDS
825  /* When replaying the client ID is not a valid client; there
826  * are actually no clients at all. However, the company has to
827  * be created, otherwise we cannot rerun the game properly.
828  * So only allow a NULL client info in that case. */
829  if (ci == NULL) return CommandCost();
830 #endif /* NOT DEBUG_DUMP_COMMANDS */
831 
832  /* Delete multiplayer progress bar */
834 
835  Company *c = DoStartupNewCompany(false);
836 
837  /* A new company could not be created, revert to being a spectator */
838  if (c == NULL) {
839  if (_network_server) {
842  }
843  break;
844  }
845 
846  /* This is the client (or non-dedicated server) who wants a new company */
847  if (client_id == _network_own_client_id) {
848  assert(_local_company == COMPANY_SPECTATOR);
852  }
853 
854  /* Now that we have a new company, broadcast our company settings to
855  * all clients so everything is in sync */
857 
859  }
860 
862 #endif /* ENABLE_NETWORK */
863  break;
864  }
865 
866  case 1: { // Make a new AI company
867  if (!(flags & DC_EXEC)) return CommandCost();
868 
869  if (company_id != INVALID_COMPANY && (company_id >= MAX_COMPANIES || Company::IsValidID(company_id))) return CMD_ERROR;
870  Company *c = DoStartupNewCompany(true, company_id);
871 #ifdef ENABLE_NETWORK
872  if (c != NULL) NetworkServerNewCompany(c, NULL);
873 #endif /* ENABLE_NETWORK */
874  break;
875  }
876 
877  case 2: { // Delete a company
878  CompanyRemoveReason reason = (CompanyRemoveReason)GB(p2, 0, 2);
879  if (reason >= CRR_END) return CMD_ERROR;
880 
881  Company *c = Company::GetIfValid(company_id);
882  if (c == NULL) return CMD_ERROR;
883 
884  if (!(flags & DC_EXEC)) return CommandCost();
885 
886  /* Delete any open window of the company */
888  CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1);
889  cni->FillData(c);
890 
891  /* Show the bankrupt news */
892  SetDParam(0, STR_NEWS_COMPANY_BANKRUPT_TITLE);
893  SetDParam(1, STR_NEWS_COMPANY_BANKRUPT_DESCRIPTION);
894  SetDParamStr(2, cni->company_name);
895  AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, cni);
896 
897  /* Remove the company */
899  if (c->is_ai) AI::Stop(c->index);
900 
901  CompanyID c_index = c->index;
902  delete c;
903  AI::BroadcastNewEvent(new ScriptEventCompanyBankrupt(c_index));
904  Game::NewEvent(new ScriptEventCompanyBankrupt(c_index));
905  CompanyAdminRemove(c_index, (CompanyRemoveReason)reason);
906 
908  break;
909  }
910 
911  default: return CMD_ERROR;
912  }
913 
917 
918  return CommandCost();
919 }
920 
930 CommandCost CmdSetCompanyManagerFace(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
931 {
933 
934  if (!IsValidCompanyManagerFace(cmf)) return CMD_ERROR;
935 
936  if (flags & DC_EXEC) {
937  Company::Get(_current_company)->face = cmf;
939  }
940  return CommandCost();
941 }
942 
954 CommandCost CmdSetCompanyColour(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
955 {
956  Colours colour = Extract<Colours, 0, 4>(p2);
957  LiveryScheme scheme = Extract<LiveryScheme, 0, 8>(p1);
958  byte state = GB(p1, 8, 2);
959 
960  if (scheme >= LS_END || state >= 3 || colour == INVALID_COLOUR) return CMD_ERROR;
961 
962  Company *c = Company::Get(_current_company);
963 
964  /* Ensure no two companies have the same primary colour */
965  if (scheme == LS_DEFAULT && state == 0) {
966  const Company *cc;
967  FOR_ALL_COMPANIES(cc) {
968  if (cc != c && cc->colour == colour) return CMD_ERROR;
969  }
970  }
971 
972  if (flags & DC_EXEC) {
973  switch (state) {
974  case 0:
975  c->livery[scheme].colour1 = colour;
976 
977  /* If setting the first colour of the default scheme, adjust the
978  * original and cached company colours too. */
979  if (scheme == LS_DEFAULT) {
981  c->colour = colour;
983  }
984  break;
985 
986  case 1:
987  c->livery[scheme].colour2 = colour;
988  break;
989 
990  case 2:
991  c->livery[scheme].in_use = colour != 0;
992 
993  /* Now handle setting the default scheme's in_use flag.
994  * This is different to the other schemes, as it signifies if any
995  * scheme is active at all. If this flag is not set, then no
996  * processing of vehicle types occurs at all, and only the default
997  * colours will be used. */
998 
999  /* If enabling a scheme, set the default scheme to be in use too */
1000  if (colour != 0) {
1001  c->livery[LS_DEFAULT].in_use = true;
1002  break;
1003  }
1004 
1005  /* Else loop through all schemes to see if any are left enabled.
1006  * If not, disable the default scheme too. */
1007  c->livery[LS_DEFAULT].in_use = false;
1008  for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
1009  if (c->livery[scheme].in_use) {
1010  c->livery[LS_DEFAULT].in_use = true;
1011  break;
1012  }
1013  }
1014  break;
1015 
1016  default:
1017  break;
1018  }
1019  ResetVehicleColourMap();
1021 
1022  /* All graph related to companies use the company colour. */
1029  /* The smallmap owner view also stores the company colours. */
1030  BuildOwnerLegend();
1032 
1033  /* Company colour data is indirectly cached. */
1034  Vehicle *v;
1035  FOR_ALL_VEHICLES(v) {
1036  if (v->owner == _current_company) v->InvalidateNewGRFCache();
1037  }
1038 
1039  extern void UpdateObjectColours(const Company *c);
1041  }
1042  return CommandCost();
1043 }
1044 
1050 static bool IsUniqueCompanyName(const char *name)
1051 {
1052  const Company *c;
1053 
1054  FOR_ALL_COMPANIES(c) {
1055  if (c->name != NULL && strcmp(c->name, name) == 0) return false;
1056  }
1057 
1058  return true;
1059 }
1060 
1070 CommandCost CmdRenameCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
1071 {
1072  bool reset = StrEmpty(text);
1073 
1074  if (!reset) {
1076  if (!IsUniqueCompanyName(text)) return_cmd_error(STR_ERROR_NAME_MUST_BE_UNIQUE);
1077  }
1078 
1079  if (flags & DC_EXEC) {
1080  Company *c = Company::Get(_current_company);
1081  free(c->name);
1082  c->name = reset ? NULL : stredup(text);
1084  CompanyAdminUpdate(c);
1085  }
1086 
1087  return CommandCost();
1088 }
1089 
1095 static bool IsUniquePresidentName(const char *name)
1096 {
1097  const Company *c;
1098 
1099  FOR_ALL_COMPANIES(c) {
1100  if (c->president_name != NULL && strcmp(c->president_name, name) == 0) return false;
1101  }
1102 
1103  return true;
1104 }
1105 
1115 CommandCost CmdRenamePresident(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
1116 {
1117  bool reset = StrEmpty(text);
1118 
1119  if (!reset) {
1121  if (!IsUniquePresidentName(text)) return_cmd_error(STR_ERROR_NAME_MUST_BE_UNIQUE);
1122  }
1123 
1124  if (flags & DC_EXEC) {
1125  Company *c = Company::Get(_current_company);
1126  free(c->president_name);
1127 
1128  if (reset) {
1129  c->president_name = NULL;
1130  } else {
1131  c->president_name = stredup(text);
1132 
1133  if (c->name_1 == STR_SV_UNNAMED && c->name == NULL) {
1134  char buf[80];
1135 
1136  seprintf(buf, lastof(buf), "%s Transport", text);
1137  DoCommand(0, 0, 0, DC_EXEC, CMD_RENAME_COMPANY, buf);
1138  }
1139  }
1140 
1142  CompanyAdminUpdate(c);
1143  }
1144 
1145  return CommandCost();
1146 }
1147 
1155 {
1156  const VehicleDefaultSettings *vds = (c == NULL) ? &_settings_client.company.vehicle : &c->settings.vehicle;
1157  switch (type) {
1158  default: NOT_REACHED();
1159  case VEH_TRAIN: return vds->servint_trains;
1160  case VEH_ROAD: return vds->servint_roadveh;
1161  case VEH_AIRCRAFT: return vds->servint_aircraft;
1162  case VEH_SHIP: return vds->servint_ships;
1163  }
1164 }