mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2026-07-15 15:19:52 +00:00
Codechange: add GoalQuestionButton scoped enum and EnumBitSet (#15723)
This commit is contained in:
+8
-10
@@ -235,21 +235,18 @@ CommandCost CmdSetGoalCompleted(DoCommandFlags flags, GoalID goal, bool complete
|
||||
* @param uniqueid Unique ID to use for this question.
|
||||
* @param target Company or client for which this question is.
|
||||
* @param is_client Question target: false - company, true - client.
|
||||
* @param button_mask Buttons of the question.
|
||||
* @param buttons Buttons of the question.
|
||||
* @param type Question type.
|
||||
* @param text Text of the question.
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdGoalQuestion(DoCommandFlags flags, uint16_t uniqueid, uint32_t target, bool is_client, uint32_t button_mask, GoalQuestionType type, const EncodedString &text)
|
||||
CommandCost CmdGoalQuestion(DoCommandFlags flags, uint16_t uniqueid, uint32_t target, bool is_client, GoalQuestionButtons buttons, GoalQuestionType type, const EncodedString &text)
|
||||
{
|
||||
static_assert(sizeof(uint32_t) >= sizeof(CompanyID));
|
||||
CompanyID company = (CompanyID)target;
|
||||
static_assert(sizeof(uint32_t) >= sizeof(ClientID));
|
||||
ClientID client = (ClientID)target;
|
||||
|
||||
static_assert(GOAL_QUESTION_BUTTON_COUNT < 29);
|
||||
button_mask &= (1U << GOAL_QUESTION_BUTTON_COUNT) - 1;
|
||||
|
||||
if (_current_company != OWNER_DEITY) return CMD_ERROR;
|
||||
if (text.empty()) return CMD_ERROR;
|
||||
if (is_client) {
|
||||
@@ -261,7 +258,8 @@ CommandCost CmdGoalQuestion(DoCommandFlags flags, uint16_t uniqueid, uint32_t ta
|
||||
if (company != CompanyID::Invalid() && !Company::IsValidID(company)) return CMD_ERROR;
|
||||
}
|
||||
uint min_buttons = (type == GoalQuestionType::Question ? 1 : 0);
|
||||
if (CountBits(button_mask) < min_buttons || CountBits(button_mask) > 3) return CMD_ERROR;
|
||||
if (!buttons.IsValid()) return CMD_ERROR;
|
||||
if (buttons.Count() < min_buttons || buttons.Count() > 3) return CMD_ERROR;
|
||||
if (type >= GoalQuestionType::End) return CMD_ERROR;
|
||||
|
||||
if (flags.Test(DoCommandFlag::Execute)) {
|
||||
@@ -271,7 +269,7 @@ CommandCost CmdGoalQuestion(DoCommandFlags flags, uint16_t uniqueid, uint32_t ta
|
||||
if (company == CompanyID::Invalid() && !Company::IsValidID(_local_company)) return CommandCost();
|
||||
if (company != CompanyID::Invalid() && company != _local_company) return CommandCost();
|
||||
}
|
||||
ShowGoalQuestion(uniqueid, type, button_mask, text);
|
||||
ShowGoalQuestion(uniqueid, type, buttons, text);
|
||||
}
|
||||
|
||||
return CommandCost();
|
||||
@@ -284,9 +282,9 @@ CommandCost CmdGoalQuestion(DoCommandFlags flags, uint16_t uniqueid, uint32_t ta
|
||||
* @param button Button the company pressed
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdGoalQuestionAnswer(DoCommandFlags flags, uint16_t uniqueid, uint8_t button)
|
||||
CommandCost CmdGoalQuestionAnswer(DoCommandFlags flags, uint16_t uniqueid, GoalQuestionButton button)
|
||||
{
|
||||
if (button >= GOAL_QUESTION_BUTTON_COUNT) return CMD_ERROR;
|
||||
if (button >= GoalQuestionButton::End) return CMD_ERROR;
|
||||
|
||||
if (_current_company == OWNER_DEITY) {
|
||||
/* It has been requested to close this specific question on all clients */
|
||||
@@ -301,7 +299,7 @@ CommandCost CmdGoalQuestionAnswer(DoCommandFlags flags, uint16_t uniqueid, uint8
|
||||
}
|
||||
|
||||
if (flags.Test(DoCommandFlag::Execute)) {
|
||||
Game::NewEvent(new ScriptEventGoalQuestionAnswer(uniqueid, _current_company, (ScriptGoal::QuestionButton)(1 << button)));
|
||||
Game::NewEvent(new ScriptEventGoalQuestionAnswer(uniqueid, _current_company, static_cast<ScriptGoal::QuestionButton>(GoalQuestionButtons{button}.base())));
|
||||
}
|
||||
|
||||
return CommandCost();
|
||||
|
||||
+2
-2
@@ -19,8 +19,8 @@ CommandCost CmdSetGoalDestination(DoCommandFlags flags, GoalID goal, GoalType ty
|
||||
CommandCost CmdSetGoalText(DoCommandFlags flags, GoalID goal, const EncodedString &text);
|
||||
CommandCost CmdSetGoalProgress(DoCommandFlags flags, GoalID goal, const EncodedString &text);
|
||||
CommandCost CmdSetGoalCompleted(DoCommandFlags flags, GoalID goal, bool completed);
|
||||
CommandCost CmdGoalQuestion(DoCommandFlags flags, uint16_t uniqueid, uint32_t target, bool is_client, uint32_t button_mask, GoalQuestionType type, const EncodedString &text);
|
||||
CommandCost CmdGoalQuestionAnswer(DoCommandFlags flags, uint16_t uniqueid, uint8_t button);
|
||||
CommandCost CmdGoalQuestion(DoCommandFlags flags, uint16_t uniqueid, uint32_t target, bool is_client, GoalQuestionButtons buttons, GoalQuestionType type, const EncodedString &text);
|
||||
CommandCost CmdGoalQuestionAnswer(DoCommandFlags flags, uint16_t uniqueid, GoalQuestionButton button);
|
||||
|
||||
DEF_CMD_TRAIT(Commands::CreateGoal, CmdCreateGoal, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CommandType::OtherManagement)
|
||||
DEF_CMD_TRAIT(Commands::RemoveGoal, CmdRemoveGoal, CommandFlag::Deity, CommandType::OtherManagement)
|
||||
|
||||
+21
-36
@@ -318,46 +318,39 @@ void ShowGoalsList(CompanyID company)
|
||||
|
||||
/** Ask a question about a goal. */
|
||||
struct GoalQuestionWindow : public Window {
|
||||
EncodedString question{}; ///< Question to ask (private copy).
|
||||
int buttons = 0; ///< Number of valid buttons in #button.
|
||||
std::array<int, 3> button{}; ///< Buttons to display.
|
||||
TextColour colour{}; ///< Colour of the question text.
|
||||
EncodedString question; ///< Question to ask (private copy).
|
||||
GoalQuestionButtons buttons; ///< Buttons to display.
|
||||
TextColour colour; ///< Colour of the question text.
|
||||
|
||||
GoalQuestionWindow(WindowDesc &desc, WindowNumber window_number, TextColour colour, uint32_t button_mask, const EncodedString &question) : Window(desc), colour(colour)
|
||||
/**
|
||||
* Construct a new Goal Question Window.
|
||||
* @param desc Window description.
|
||||
* @param window_number Number for the window.
|
||||
* @param colour Colour of the question text.
|
||||
* @param buttons Buttons to display.
|
||||
* @param question Question to ask.
|
||||
*/
|
||||
GoalQuestionWindow(WindowDesc &desc, WindowNumber window_number, TextColour colour, GoalQuestionButtons buttons, const EncodedString &question)
|
||||
: Window(desc), question(question), buttons(buttons), colour(colour)
|
||||
{
|
||||
this->question = question;
|
||||
|
||||
/* Figure out which buttons we have to enable. */
|
||||
int n = 0;
|
||||
for (uint bit : SetBitIterator(button_mask)) {
|
||||
if (bit >= GOAL_QUESTION_BUTTON_COUNT) break;
|
||||
this->button[n++] = bit;
|
||||
if (n == 3) break;
|
||||
}
|
||||
this->buttons = n;
|
||||
assert(this->buttons < 4);
|
||||
assert(this->buttons.Count() < 4);
|
||||
|
||||
this->CreateNestedTree();
|
||||
if (this->buttons == 0) {
|
||||
if (this->buttons.None()) {
|
||||
this->GetWidget<NWidgetStacked>(WID_GQ_BUTTONS)->SetDisplayedPlane(SZSP_HORIZONTAL);
|
||||
} else {
|
||||
this->GetWidget<NWidgetStacked>(WID_GQ_BUTTONS)->SetDisplayedPlane(this->buttons - 1);
|
||||
this->GetWidget<NWidgetStacked>(WID_GQ_BUTTONS)->SetDisplayedPlane(this->buttons.Count() - 1);
|
||||
}
|
||||
this->FinishInitNested(window_number);
|
||||
}
|
||||
|
||||
|
||||
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_GQ_BUTTON_1:
|
||||
return GetString(STR_GOAL_QUESTION_BUTTON_CANCEL + this->button[0]);
|
||||
|
||||
case WID_GQ_BUTTON_2:
|
||||
return GetString(STR_GOAL_QUESTION_BUTTON_CANCEL + this->button[1]);
|
||||
|
||||
case WID_GQ_BUTTON_3:
|
||||
return GetString(STR_GOAL_QUESTION_BUTTON_CANCEL + this->button[2]);
|
||||
return GetString(STR_GOAL_QUESTION_BUTTON_CANCEL + to_underlying(this->buttons.GetNthSetBit(widget - WID_GQ_BUTTON_1).value_or(GoalQuestionButton::Cancel)));
|
||||
|
||||
default:
|
||||
return this->Window::GetWidgetString(widget, stringid);
|
||||
@@ -368,17 +361,9 @@ struct GoalQuestionWindow : public Window {
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_GQ_BUTTON_1:
|
||||
Command<Commands::GoalQuestionAnswer>::Post(this->window_number, this->button[0]);
|
||||
this->Close();
|
||||
break;
|
||||
|
||||
case WID_GQ_BUTTON_2:
|
||||
Command<Commands::GoalQuestionAnswer>::Post(this->window_number, this->button[1]);
|
||||
this->Close();
|
||||
break;
|
||||
|
||||
case WID_GQ_BUTTON_3:
|
||||
Command<Commands::GoalQuestionAnswer>::Post(this->window_number, this->button[2]);
|
||||
Command<Commands::GoalQuestionAnswer>::Post(this->window_number, this->buttons.GetNthSetBit(widget - WID_GQ_BUTTON_1).value_or(GoalQuestionButton::Cancel));
|
||||
this->Close();
|
||||
break;
|
||||
}
|
||||
@@ -471,11 +456,11 @@ static EnumIndexArray<WindowDesc, GoalQuestionType, GoalQuestionType::End> _goal
|
||||
* Display a goal question.
|
||||
* @param id Window number to use.
|
||||
* @param type Type of question.
|
||||
* @param button_mask Buttons to display.
|
||||
* @param buttons Buttons to display.
|
||||
* @param question Question to ask.
|
||||
*/
|
||||
void ShowGoalQuestion(uint16_t id, GoalQuestionType type, uint32_t button_mask, const EncodedString &question)
|
||||
void ShowGoalQuestion(uint16_t id, GoalQuestionType type, GoalQuestionButtons buttons, const EncodedString &question)
|
||||
{
|
||||
assert(type < GoalQuestionType::End);
|
||||
new GoalQuestionWindow(_goal_question_list_desc[type], id, type == GoalQuestionType::Error ? TextColour::White : TextColour::Black, button_mask, question);
|
||||
new GoalQuestionWindow(_goal_question_list_desc[type], id, type == GoalQuestionType::Error ? TextColour::White : TextColour::Black, buttons, question);
|
||||
}
|
||||
|
||||
+1
-1
@@ -15,6 +15,6 @@
|
||||
#include "strings_type.h"
|
||||
|
||||
void ShowGoalsList(CompanyID company);
|
||||
void ShowGoalQuestion(uint16_t id, GoalQuestionType type, uint32_t button_mask, const EncodedString &question);
|
||||
void ShowGoalQuestion(uint16_t id, GoalQuestionType type, GoalQuestionButtons buttons, const EncodedString &question);
|
||||
|
||||
#endif /* GOAL_TYPE_H */
|
||||
|
||||
+26
-2
@@ -12,8 +12,6 @@
|
||||
|
||||
#include "core/pool_type.hpp"
|
||||
|
||||
static const uint32_t GOAL_QUESTION_BUTTON_COUNT = 18; ///< Amount of buttons available.
|
||||
|
||||
/** Types of goal questions. */
|
||||
enum class GoalQuestionType : uint8_t {
|
||||
Question = 0, ///< Asking a simple question; title: Question.
|
||||
@@ -23,6 +21,32 @@ enum class GoalQuestionType : uint8_t {
|
||||
End, ///< End marker.
|
||||
};
|
||||
|
||||
/** Types of buttons that can be in the question window. */
|
||||
enum class GoalQuestionButton : uint8_t {
|
||||
Cancel, ///< Cancel button.
|
||||
Ok, ///< OK button.
|
||||
No, ///< No button.
|
||||
Yes, ///< Yes button.
|
||||
Decline, ///< Decline button.
|
||||
Accept, ///< Accept button.
|
||||
Ignore, ///< Ignore button.
|
||||
Retry, ///< Retry button.
|
||||
Previous, ///< Previous button.
|
||||
Next, ///< Next button.
|
||||
Stop, ///< Stop button.
|
||||
Start, ///< Start button.
|
||||
Go, ///< Go button.
|
||||
Continue, ///< Continue button.
|
||||
Restart, ///< Restart button.
|
||||
Postpone, ///< Postpone button.
|
||||
Surrender, ///< Surrender button.
|
||||
Close, ///< Close button.
|
||||
End, ///< End marker.
|
||||
};
|
||||
|
||||
/** Bitset of \c GoalQuestionButton elements. */
|
||||
using GoalQuestionButtons = EnumBitSet<GoalQuestionButton, uint32_t, GoalQuestionButton::End>;
|
||||
|
||||
/** Types of goal destinations */
|
||||
enum class GoalType : uint8_t {
|
||||
None, ///< Destination is not linked
|
||||
|
||||
@@ -135,11 +135,11 @@
|
||||
EnforcePreconditionEncodedText(false, text);
|
||||
uint min_buttons = (type == QT_QUESTION ? 1 : 0);
|
||||
EnforcePrecondition(false, CountBits<uint64_t>(buttons) >= min_buttons && CountBits<uint64_t>(buttons) <= 3);
|
||||
EnforcePrecondition(false, buttons >= 0 && buttons < (1 << ::GOAL_QUESTION_BUTTON_COUNT));
|
||||
EnforcePrecondition(false, buttons >= 0 && static_cast<::GoalQuestionButtons>(buttons).IsValid());
|
||||
EnforcePrecondition(false, static_cast<::GoalQuestionType>(type) < ::GoalQuestionType::End);
|
||||
EnforcePrecondition(false, uniqueid >= 0 && uniqueid <= UINT16_MAX);
|
||||
|
||||
return ScriptObject::Command<Commands::GoalQuestion>::Do(uniqueid, target, is_client, buttons, static_cast<::GoalQuestionType>(type), text);
|
||||
return ScriptObject::Command<Commands::GoalQuestion>::Do(uniqueid, target, is_client, static_cast<::GoalQuestionButtons>(buttons), static_cast<::GoalQuestionType>(type), text);
|
||||
}
|
||||
|
||||
/* static */ bool ScriptGoal::Question(SQInteger uniqueid, ScriptCompany::CompanyID company, Text *question, QuestionType type, SQInteger buttons)
|
||||
@@ -160,5 +160,5 @@
|
||||
EnforceDeityMode(false);
|
||||
EnforcePrecondition(false, uniqueid >= 0 && uniqueid <= UINT16_MAX);
|
||||
|
||||
return ScriptObject::Command<Commands::GoalQuestionAnswer>::Do(uniqueid, 0);
|
||||
return ScriptObject::Command<Commands::GoalQuestionAnswer>::Do(uniqueid, ::GoalQuestionButton::Cancel);
|
||||
}
|
||||
|
||||
@@ -56,24 +56,24 @@ public:
|
||||
*/
|
||||
enum QuestionButton {
|
||||
/* Note: these values represent part of the string list starting with STR_GOAL_QUESTION_BUTTON_CANCEL */
|
||||
BUTTON_CANCEL = (1 << 0), ///< Cancel button.
|
||||
BUTTON_OK = (1 << 1), ///< OK button.
|
||||
BUTTON_NO = (1 << 2), ///< No button.
|
||||
BUTTON_YES = (1 << 3), ///< Yes button.
|
||||
BUTTON_DECLINE = (1 << 4), ///< Decline button.
|
||||
BUTTON_ACCEPT = (1 << 5), ///< Accept button.
|
||||
BUTTON_IGNORE = (1 << 6), ///< Ignore button.
|
||||
BUTTON_RETRY = (1 << 7), ///< Retry button.
|
||||
BUTTON_PREVIOUS = (1 << 8), ///< Previous button.
|
||||
BUTTON_NEXT = (1 << 9), ///< Next button.
|
||||
BUTTON_STOP = (1 << 10), ///< Stop button.
|
||||
BUTTON_START = (1 << 11), ///< Start button.
|
||||
BUTTON_GO = (1 << 12), ///< Go button.
|
||||
BUTTON_CONTINUE = (1 << 13), ///< Continue button.
|
||||
BUTTON_RESTART = (1 << 14), ///< Restart button.
|
||||
BUTTON_POSTPONE = (1 << 15), ///< Postpone button.
|
||||
BUTTON_SURRENDER = (1 << 16), ///< Surrender button.
|
||||
BUTTON_CLOSE = (1 << 17), ///< Close button.
|
||||
BUTTON_CANCEL = ::GoalQuestionButtons{::GoalQuestionButton::Cancel}.base(), ///< Cancel button.
|
||||
BUTTON_OK = ::GoalQuestionButtons{::GoalQuestionButton::Ok}.base(), ///< OK button.
|
||||
BUTTON_NO = ::GoalQuestionButtons{::GoalQuestionButton::No}.base(), ///< No button.
|
||||
BUTTON_YES = ::GoalQuestionButtons{::GoalQuestionButton::Yes}.base(), ///< Yes button.
|
||||
BUTTON_DECLINE = ::GoalQuestionButtons{::GoalQuestionButton::Decline}.base(), ///< Decline button.
|
||||
BUTTON_ACCEPT = ::GoalQuestionButtons{::GoalQuestionButton::Accept}.base(), ///< Accept button.
|
||||
BUTTON_IGNORE = ::GoalQuestionButtons{::GoalQuestionButton::Ignore}.base(), ///< Ignore button.
|
||||
BUTTON_RETRY = ::GoalQuestionButtons{::GoalQuestionButton::Retry}.base(), ///< Retry button.
|
||||
BUTTON_PREVIOUS = ::GoalQuestionButtons{::GoalQuestionButton::Previous}.base(), ///< Previous button.
|
||||
BUTTON_NEXT = ::GoalQuestionButtons{::GoalQuestionButton::Next}.base(), ///< Next button.
|
||||
BUTTON_STOP = ::GoalQuestionButtons{::GoalQuestionButton::Stop}.base(), ///< Stop button.
|
||||
BUTTON_START = ::GoalQuestionButtons{::GoalQuestionButton::Start}.base(), ///< Start button.
|
||||
BUTTON_GO = ::GoalQuestionButtons{::GoalQuestionButton::Go}.base(), ///< Go button.
|
||||
BUTTON_CONTINUE = ::GoalQuestionButtons{::GoalQuestionButton::Continue}.base(), ///< Continue button.
|
||||
BUTTON_RESTART = ::GoalQuestionButtons{::GoalQuestionButton::Restart}.base(), ///< Restart button.
|
||||
BUTTON_POSTPONE = ::GoalQuestionButtons{::GoalQuestionButton::Postpone}.base(), ///< Postpone button.
|
||||
BUTTON_SURRENDER = ::GoalQuestionButtons{::GoalQuestionButton::Surrender}.base(), ///< Surrender button.
|
||||
BUTTON_CLOSE = ::GoalQuestionButtons{::GoalQuestionButton::Close}.base(), ///< Close button.
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user