diff --git a/src/goal.cpp b/src/goal.cpp index 30f640b4cea39..407b3a398bc0f 100644 --- a/src/goal.cpp +++ b/src/goal.cpp @@ -236,10 +236,11 @@ CommandCost CmdSetGoalCompleted(TileIndex tile, DoCommandFlag flags, uint32 p1, * @param flags type of operation * @param p1 various bitstuffed elements * - p1 = (bit 0 - 15) - Unique ID to use for this question. - * - p1 = (bit 16 - 23) - Company or client for which this question is. - * - p1 = (bit 24 - 25) - Question type. - * - p1 = (bit 31) - Question target: 0 - company, 1 - client. - * @param p2 Buttons of the question. + * - p1 = (bit 16 - 31) - Company or client for which this question is. + * @param p2 various bitstuffed elements + * - p2 = (bit 0 - 17) - Buttons of the question. + * - p2 = (bit 29 - 30) - Question type. + * - p2 = (bit 31) - Question target: 0 - company, 1 - client. * @param text Text of the question. * @return the cost of this operation or an error */ @@ -247,29 +248,31 @@ CommandCost CmdGoalQuestion(TileIndex tile, DoCommandFlag flags, uint32 p1, uint { uint16 uniqueid = (GoalType)GB(p1, 0, 16); CompanyID company = (CompanyID)GB(p1, 16, 8); - ClientIndex client = (ClientIndex)GB(p1, 16, 8); - byte type = GB(p1, 24, 2); - bool is_client = HasBit(p1, 31); + ClientID client = (ClientID)GB(p1, 16, 16); + + assert_compile(GOAL_QUESTION_BUTTON_COUNT < 29); + uint32 button_mask = GB(p2, 0, GOAL_QUESTION_BUTTON_COUNT); + byte type = GB(p2, 29, 2); + bool is_client = HasBit(p2, 31); if (_current_company != OWNER_DEITY) return CMD_ERROR; if (StrEmpty(text)) return CMD_ERROR; if (is_client) { - if (!NetworkClientInfo::IsValidID(client)) return CMD_ERROR; + if (NetworkClientInfo::GetByClientID(client) == nullptr) return CMD_ERROR; } else { if (company != INVALID_COMPANY && !Company::IsValidID(company)) return CMD_ERROR; } - if (CountBits(p2) < 1 || CountBits(p2) > 3) return CMD_ERROR; - if (p2 >= (1 << GOAL_QUESTION_BUTTON_COUNT)) return CMD_ERROR; + if (CountBits(button_mask) < 1 || CountBits(button_mask) > 3) return CMD_ERROR; if (type >= GOAL_QUESTION_TYPE_COUNT) return CMD_ERROR; if (flags & DC_EXEC) { if (is_client) { - if (NetworkClientInfo::Get(client)->client_id != _network_own_client_id) return CommandCost(); + if (client != _network_own_client_id) return CommandCost(); } else { if (company == INVALID_COMPANY && !Company::IsValidID(_local_company)) return CommandCost(); if (company != INVALID_COMPANY && company != _local_company) return CommandCost(); } - ShowGoalQuestion(uniqueid, type, p2, text); + ShowGoalQuestion(uniqueid, type, button_mask, text); } return CommandCost(); diff --git a/src/script/api/script_goal.cpp b/src/script/api/script_goal.cpp index b5f6ccef2508f..461911d3c5556 100644 --- a/src/script/api/script_goal.cpp +++ b/src/script/api/script_goal.cpp @@ -109,7 +109,7 @@ return g != nullptr && g->completed; } -/* static */ bool ScriptGoal::DoQuestion(uint16 uniqueid, uint8 target, bool is_client, Text *question, QuestionType type, int buttons) +/* static */ bool ScriptGoal::DoQuestion(uint16 uniqueid, uint32 target, bool is_client, Text *question, QuestionType type, uint32 buttons) { CCountedPtr counter(question); @@ -121,7 +121,7 @@ EnforcePrecondition(false, buttons < (1 << ::GOAL_QUESTION_BUTTON_COUNT)); EnforcePrecondition(false, (int)type < ::GOAL_QUESTION_TYPE_COUNT); - return ScriptObject::DoCommand(0, uniqueid | (target << 16) | (type << 24) | (is_client ? (1 << 31) : 0), buttons, CMD_GOAL_QUESTION, text); + return ScriptObject::DoCommand(0, uniqueid | (target << 16), buttons | (type << 29) | (is_client ? (1 << 31) : 0), CMD_GOAL_QUESTION, text); } /* static */ bool ScriptGoal::Question(uint16 uniqueid, ScriptCompany::CompanyID company, Text *question, QuestionType type, int buttons) @@ -137,8 +137,9 @@ { EnforcePrecondition(false, ScriptGame::IsMultiplayer()); EnforcePrecondition(false, ScriptClient::ResolveClientID(client) != ScriptClient::CLIENT_INVALID); - ClientIndex c = NetworkClientInfo::GetByClientID((::ClientID)client)->index; - return DoQuestion(uniqueid, c, true, question, type, buttons); + /* Can only send 16 bits of client_id before proper fix is implemented */ + EnforcePrecondition(false, client < (1 << 16)); + return DoQuestion(uniqueid, client, true, question, type, buttons); } /* static */ bool ScriptGoal::CloseQuestion(uint16 uniqueid) diff --git a/src/script/api/script_goal.hpp b/src/script/api/script_goal.hpp index b8c0873a21f6b..30f7df1257e89 100644 --- a/src/script/api/script_goal.hpp +++ b/src/script/api/script_goal.hpp @@ -211,7 +211,7 @@ class ScriptGoal : public ScriptObject { /** * Does common checks and asks the question. */ - static bool DoQuestion(uint16 uniqueid, uint8 target, bool is_client, Text *question, QuestionType type, int buttons); + static bool DoQuestion(uint16 uniqueid, uint32 target, bool is_client, Text *question, QuestionType type, uint32 buttons); }; #endif /* SCRIPT_GOAL_HPP */