From cbea3b8b461c8b35205dfe9d6b51f855773f02ba Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Tue, 28 May 2024 17:58:33 +0100 Subject: [PATCH] Add console command to merge two companies --- src/company_cmd.cpp | 33 +++++++++++++++++++++++++++++++++ src/company_type.h | 1 + src/console_cmds.cpp | 30 ++++++++++++++++++++++++++++++ src/economy.cpp | 7 ++++++- src/economy_func.h | 2 ++ src/network/network.cpp | 3 ++- 6 files changed, 74 insertions(+), 2 deletions(-) diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index d664081089..7e55ad9c52 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -931,6 +931,7 @@ void CompanyAdminRemove(CompanyID company_id, CompanyRemoveReason reason) * - bits 0..15: CompanyCtrlAction * - bits 16..23: CompanyID * - bits 24..31: CompanyRemoveReason (with CCA_DELETE) + * - bits 24..31: CompanyID to merge (with CCA_MERGE) * @param p2 ClientID * @param text unused * @return the cost of this operation or an error @@ -1071,6 +1072,38 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32_t p1, uin break; } + case CCA_MERGE: { + Company *c = Company::GetIfValid(company_id); + if (c == nullptr) return CMD_ERROR; + + CompanyID to_merge_id = (CompanyID)GB(p1, 24, 8); + if (to_merge_id == company_id) return CMD_ERROR; + + Company *to_merge = Company::GetIfValid(to_merge_id); + if (to_merge == nullptr) return CMD_ERROR; + + if (!(flags & DC_EXEC)) return CommandCost(); + + SubtractMoneyFromAnyCompany(c, CommandCost(EXPENSES_OTHER, to_merge->current_loan - to_merge->money)); + + DEBUG(desync, 1, "merge_companies: %s, company_id: %u, merged_company_id: %u", debug_date_dumper().HexDate(), company_id, to_merge_id); + + CompanyNewsInformation *cni = new CompanyNewsInformation(to_merge, c); + + SetDParam(0, STR_NEWS_COMPANY_MERGER_TITLE); + SetDParam(1, STR_NEWS_MERGER_TAKEOVER_TITLE); + SetDParamStr(2, cni->company_name); + SetDParamStr(3, cni->other_company_name); + AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, cni); + AI::BroadcastNewEvent(new ScriptEventCompanyMerger(to_merge_id, company_id)); + Game::NewEvent(new ScriptEventCompanyMerger(to_merge_id, company_id)); + + ChangeOwnershipOfCompanyItems(to_merge_id, company_id); + + PostAcquireCompany(to_merge); + break; + } + default: return CMD_ERROR; } diff --git a/src/company_type.h b/src/company_type.h index d7f4a35e67..aa48b9ac5e 100644 --- a/src/company_type.h +++ b/src/company_type.h @@ -71,6 +71,7 @@ enum CompanyCtrlAction { CCA_NEW_AI, ///< Create a new AI company. CCA_DELETE, ///< Delete a company. CCA_SALE, ///< Offer a company for sale. + CCA_MERGE, ///< Merge companies. CCA_END, ///< Sentinel for end. }; diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index bfe89ba3cb..fb4bf6ece0 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -1183,6 +1183,35 @@ DEF_CONSOLE_CMD(ConOfferCompanySale) return true; } +DEF_CONSOLE_CMD(ConMergeCompanies) +{ + if (argc != 3) { + IConsolePrint(CC_HELP, "Merge two companies together. Usage: 'merge_companies '"); + IConsolePrint(CC_HELP, "The first company ID will be left with the combined assets of both companies."); + IConsolePrint(CC_HELP, "The second company ID will be removed, with all assets transfered to the first company ID."); + IConsolePrint(CC_HELP, "For company-id's, see the list of companies from the dropdown menu. Company 1 is 1, etc."); + return true; + } + + CompanyID main_company = (CompanyID)(atoi(argv[1]) - 1); + CompanyID to_merge_company = (CompanyID)(atoi(argv[2]) - 1); + + /* Check valid range */ + if (!Company::IsValidID(main_company)) { + IConsolePrintF(CC_ERROR, "Main company does not exist. Company-id must be between 1 and %d.", MAX_COMPANIES); + return true; + } + if (!Company::IsValidID(to_merge_company)) { + IConsolePrintF(CC_ERROR, "Company to merge does not exist. Company-id must be between 1 and %d.", MAX_COMPANIES); + return true; + } + + DoCommandP(0, CCA_MERGE | (main_company << 16) | (to_merge_company << 24), 0, CMD_COMPANY_CTRL); + IConsolePrint(CC_DEFAULT, "Companies merged."); + + return true; +} + DEF_CONSOLE_CMD(ConNetworkClients) { if (argc == 0) { @@ -4139,6 +4168,7 @@ void IConsoleStdLibRegister() IConsole::CmdRegister("reset_company", ConResetCompany, ConHookServerOnly); IConsole::AliasRegister("clean_company", "reset_company %A"); IConsole::CmdRegister("offer_company_sale", ConOfferCompanySale, ConHookServerOrNoNetwork); + IConsole::CmdRegister("merge_companies", ConMergeCompanies, ConHookServerOrNoNetwork); IConsole::CmdRegister("client_name", ConClientNickChange, ConHookServerOnly); IConsole::CmdRegister("kick", ConKick, ConHookServerOnly); IConsole::CmdRegister("ban", ConBan, ConHookServerOnly); diff --git a/src/economy.cpp b/src/economy.cpp index ec627d456c..3aff51a1e5 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -2490,11 +2490,16 @@ static void DoAcquireCompany(Company *c, bool hostile_takeover) ChangeOwnershipOfCompanyItems(ci, _current_company); + PostAcquireCompany(c); +} + +void PostAcquireCompany(Company *c) +{ if (c->is_ai) AI::Stop(c->index); c->bankrupt_asked = 0; - DeleteCompanyWindows(ci); + DeleteCompanyWindows(c->index); InvalidateWindowClassesData(WC_TRAINS_LIST, 0); InvalidateWindowClassesData(WC_TRACE_RESTRICT_SLOTS, 0); InvalidateWindowClassesData(WC_SHIPS_LIST, 0); diff --git a/src/economy_func.h b/src/economy_func.h index 213be385a7..b494062019 100644 --- a/src/economy_func.h +++ b/src/economy_func.h @@ -60,4 +60,6 @@ int PercentageToScaleQuantityFactor(uint percentage); void UpdateCargoScalers(); +void PostAcquireCompany(Company *c); + #endif /* ECONOMY_FUNC_H */ diff --git a/src/network/network.cpp b/src/network/network.cpp index bab9a83b77..cfa2f3fb31 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -1285,7 +1285,8 @@ void NetworkGameLoop() } else if (strncmp(p, "msg: ", 5) == 0 || strncmp(p, "client: ", 8) == 0 || strncmp(p, "load: ", 6) == 0 || strncmp(p, "save: ", 6) == 0 || strncmp(p, "new_company: ", 13) == 0 || strncmp(p, "new_company_ai: ", 16) == 0 || - strncmp(p, "buy_company: ", 13) == 0 || strncmp(p, "delete_company: ", 16) == 0) { + strncmp(p, "buy_company: ", 13) == 0 || strncmp(p, "delete_company: ", 16) == 0 || + strncmp(p, "merge_companies: ", 17) == 0) { /* A message that is not very important to the log playback, but part of the log. */ #ifndef DEBUG_FAILED_DUMP_COMMANDS } else if (strncmp(p, "cmdf: ", 6) == 0) {