Changeset - r23780:2fc4e08e27f6
[Not reviewed]
master
0 3 0
dP - 5 years ago 2019-05-02 23:50:24
dp@dpointer.org
Fix: Make GSGoal.QuestionClient work correctly at least for clients with ID < 2**16
3 files changed with 21 insertions and 17 deletions:
0 comments (0 inline, 0 general)
src/goal.cpp
Show inline comments
 
@@ -236,10 +236,11 @@ CommandCost CmdSetGoalCompleted(TileInde
 
 * @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 ti
 
{
 
	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();
src/script/api/script_goal.cpp
Show inline comments
 
@@ -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<Text> 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)
src/script/api/script_goal.hpp
Show inline comments
 
@@ -211,7 +211,7 @@ protected:
 
	/**
 
	 * 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 */
0 comments (0 inline, 0 general)