Feature: [GS] Goal destination can be updated (#10817)
(cherry picked from commit 35ef6c1723
)
This commit is contained in:

committed by
Jonathan G Rennison

parent
6550f3a049
commit
74c0678015
@@ -191,6 +191,7 @@ CommandProc CmdCompanyCtrl;
|
|||||||
CommandProc CmdCustomNewsItem;
|
CommandProc CmdCustomNewsItem;
|
||||||
CommandProc CmdCreateGoal;
|
CommandProc CmdCreateGoal;
|
||||||
CommandProc CmdRemoveGoal;
|
CommandProc CmdRemoveGoal;
|
||||||
|
CommandProcEx CmdSetGoalDestination;
|
||||||
CommandProc CmdSetGoalText;
|
CommandProc CmdSetGoalText;
|
||||||
CommandProc CmdSetGoalProgress;
|
CommandProc CmdSetGoalProgress;
|
||||||
CommandProc CmdSetGoalCompleted;
|
CommandProc CmdSetGoalCompleted;
|
||||||
@@ -448,6 +449,7 @@ static const Command _command_proc_table[] = {
|
|||||||
DEF_CMD(CmdCustomNewsItem, CMD_STR_CTRL | CMD_DEITY | CMD_LOG_AUX, CMDT_OTHER_MANAGEMENT ), // CMD_CUSTOM_NEWS_ITEM
|
DEF_CMD(CmdCustomNewsItem, CMD_STR_CTRL | CMD_DEITY | CMD_LOG_AUX, CMDT_OTHER_MANAGEMENT ), // CMD_CUSTOM_NEWS_ITEM
|
||||||
DEF_CMD(CmdCreateGoal, CMD_STR_CTRL | CMD_DEITY | CMD_LOG_AUX, CMDT_OTHER_MANAGEMENT ), // CMD_CREATE_GOAL
|
DEF_CMD(CmdCreateGoal, CMD_STR_CTRL | CMD_DEITY | CMD_LOG_AUX, CMDT_OTHER_MANAGEMENT ), // CMD_CREATE_GOAL
|
||||||
DEF_CMD(CmdRemoveGoal, CMD_DEITY | CMD_LOG_AUX, CMDT_OTHER_MANAGEMENT ), // CMD_REMOVE_GOAL
|
DEF_CMD(CmdRemoveGoal, CMD_DEITY | CMD_LOG_AUX, CMDT_OTHER_MANAGEMENT ), // CMD_REMOVE_GOAL
|
||||||
|
DEF_CMD(CmdSetGoalDestination, CMD_DEITY | CMD_LOG_AUX, CMDT_OTHER_MANAGEMENT ), // CMD_SET_GOAL_DESTINATION
|
||||||
DEF_CMD(CmdSetGoalText, CMD_STR_CTRL | CMD_DEITY | CMD_LOG_AUX, CMDT_OTHER_MANAGEMENT ), // CMD_SET_GOAL_TEXT
|
DEF_CMD(CmdSetGoalText, CMD_STR_CTRL | CMD_DEITY | CMD_LOG_AUX, CMDT_OTHER_MANAGEMENT ), // CMD_SET_GOAL_TEXT
|
||||||
DEF_CMD(CmdSetGoalProgress, CMD_STR_CTRL | CMD_DEITY | CMD_LOG_AUX, CMDT_OTHER_MANAGEMENT ), // CMD_SET_GOAL_PROGRESS
|
DEF_CMD(CmdSetGoalProgress, CMD_STR_CTRL | CMD_DEITY | CMD_LOG_AUX, CMDT_OTHER_MANAGEMENT ), // CMD_SET_GOAL_PROGRESS
|
||||||
DEF_CMD(CmdSetGoalCompleted, CMD_STR_CTRL | CMD_DEITY | CMD_LOG_AUX, CMDT_OTHER_MANAGEMENT ), // CMD_SET_GOAL_COMPLETED
|
DEF_CMD(CmdSetGoalCompleted, CMD_STR_CTRL | CMD_DEITY | CMD_LOG_AUX, CMDT_OTHER_MANAGEMENT ), // CMD_SET_GOAL_COMPLETED
|
||||||
|
@@ -412,6 +412,7 @@ enum Commands {
|
|||||||
CMD_CUSTOM_NEWS_ITEM, ///< create a custom news message
|
CMD_CUSTOM_NEWS_ITEM, ///< create a custom news message
|
||||||
CMD_CREATE_GOAL, ///< create a new goal
|
CMD_CREATE_GOAL, ///< create a new goal
|
||||||
CMD_REMOVE_GOAL, ///< remove a goal
|
CMD_REMOVE_GOAL, ///< remove a goal
|
||||||
|
CMD_SET_GOAL_DESTINATION, ///< update goal destination of a goal
|
||||||
CMD_SET_GOAL_TEXT, ///< update goal text of a goal
|
CMD_SET_GOAL_TEXT, ///< update goal text of a goal
|
||||||
CMD_SET_GOAL_PROGRESS, ///< update goal progress text of a goal
|
CMD_SET_GOAL_PROGRESS, ///< update goal progress text of a goal
|
||||||
CMD_SET_GOAL_COMPLETED, ///< update goal completed status of a goal
|
CMD_SET_GOAL_COMPLETED, ///< update goal completed status of a goal
|
||||||
|
100
src/goal.cpp
100
src/goal.cpp
@@ -32,6 +32,41 @@ GoalID _new_goal_id;
|
|||||||
GoalPool _goal_pool("Goal");
|
GoalPool _goal_pool("Goal");
|
||||||
INSTANTIATE_POOL_METHODS(Goal)
|
INSTANTIATE_POOL_METHODS(Goal)
|
||||||
|
|
||||||
|
/* static */ bool Goal::IsValidGoalDestination(CompanyID company, GoalType type, GoalTypeID dest)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case GT_NONE:
|
||||||
|
if (dest != 0) return false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GT_TILE:
|
||||||
|
if (!IsValidTile(dest)) return false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GT_INDUSTRY:
|
||||||
|
if (!Industry::IsValidID(dest)) return false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GT_TOWN:
|
||||||
|
if (!Town::IsValidID(dest)) return false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GT_COMPANY:
|
||||||
|
if (!Company::IsValidID(dest)) return false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GT_STORY_PAGE: {
|
||||||
|
if (!StoryPage::IsValidID(dest)) return false;
|
||||||
|
CompanyID story_company = StoryPage::Get(dest)->company;
|
||||||
|
if (company == INVALID_COMPANY ? story_company != INVALID_COMPANY : story_company != INVALID_COMPANY && story_company != company) return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new goal.
|
* Create a new goal.
|
||||||
* @param tile unused.
|
* @param tile unused.
|
||||||
@@ -49,46 +84,17 @@ CommandCost CmdCreateGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
|||||||
|
|
||||||
GoalType type = (GoalType)GB(p1, 0, 8);
|
GoalType type = (GoalType)GB(p1, 0, 8);
|
||||||
CompanyID company = (CompanyID)GB(p1, 8, 8);
|
CompanyID company = (CompanyID)GB(p1, 8, 8);
|
||||||
|
GoalTypeID dest = p2;
|
||||||
|
|
||||||
if (_current_company != OWNER_DEITY) return CMD_ERROR;
|
if (_current_company != OWNER_DEITY) return CMD_ERROR;
|
||||||
if (StrEmpty(text)) return CMD_ERROR;
|
if (StrEmpty(text)) return CMD_ERROR;
|
||||||
if (company != INVALID_COMPANY && !Company::IsValidID(company)) return CMD_ERROR;
|
if (company != INVALID_COMPANY && !Company::IsValidID(company)) return CMD_ERROR;
|
||||||
|
if (!Goal::IsValidGoalDestination(company, type, dest)) return CMD_ERROR;
|
||||||
switch (type) {
|
|
||||||
case GT_NONE:
|
|
||||||
if (p2 != 0) return CMD_ERROR;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GT_TILE:
|
|
||||||
if (!IsValidTile(p2)) return CMD_ERROR;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GT_INDUSTRY:
|
|
||||||
if (!Industry::IsValidID(p2)) return CMD_ERROR;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GT_TOWN:
|
|
||||||
if (!Town::IsValidID(p2)) return CMD_ERROR;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GT_COMPANY:
|
|
||||||
if (!Company::IsValidID(p2)) return CMD_ERROR;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GT_STORY_PAGE: {
|
|
||||||
if (!StoryPage::IsValidID(p2)) return CMD_ERROR;
|
|
||||||
CompanyID story_company = StoryPage::Get(p2)->company;
|
|
||||||
if (company == INVALID_COMPANY ? story_company != INVALID_COMPANY : story_company != INVALID_COMPANY && story_company != company) return CMD_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: return CMD_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
Goal *g = new Goal();
|
Goal *g = new Goal();
|
||||||
g->type = type;
|
g->type = type;
|
||||||
g->dst = p2;
|
g->dst = dest;
|
||||||
g->company = company;
|
g->company = company;
|
||||||
if (StrEmpty(text)) {
|
if (StrEmpty(text)) {
|
||||||
g->text.clear();
|
g->text.clear();
|
||||||
@@ -140,6 +146,36 @@ CommandCost CmdRemoveGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
|||||||
return CommandCost();
|
return CommandCost();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update goal destination of a goal.
|
||||||
|
* @param tile unused.
|
||||||
|
* @param flags type of operation
|
||||||
|
* @param p1 GoalID to update.
|
||||||
|
* @param p2 GoalTypeID of destination.
|
||||||
|
* @param p3 various bitstuffed elements
|
||||||
|
* - p3 = (bit 0 - 7) - GoalType of destination.
|
||||||
|
* @param p2 GoalTypeID of destination.
|
||||||
|
* @param text unused.
|
||||||
|
*/
|
||||||
|
CommandCost CmdSetGoalDestination(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, const CommandAuxiliaryBase *aux_data)
|
||||||
|
{
|
||||||
|
GoalID goal = p1;
|
||||||
|
GoalTypeID dest = p2;
|
||||||
|
GoalType type = (GoalType)GB(p3, 0, 8);
|
||||||
|
|
||||||
|
if (_current_company != OWNER_DEITY) return CMD_ERROR;
|
||||||
|
if (!Goal::IsValidID(goal)) return CMD_ERROR;
|
||||||
|
Goal *g = Goal::Get(goal);
|
||||||
|
if (!Goal::IsValidGoalDestination(g->company, type, dest)) return CMD_ERROR;
|
||||||
|
|
||||||
|
if (flags & DC_EXEC) {
|
||||||
|
g->type = type;
|
||||||
|
g->dst = dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CommandCost();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update goal text of a goal.
|
* Update goal text of a goal.
|
||||||
* @param tile unused.
|
* @param tile unused.
|
||||||
|
@@ -35,6 +35,8 @@ struct Goal : GoalPool::PoolItem<&_goal_pool> {
|
|||||||
* (Empty) destructor has to be defined else operator delete might be called with nullptr parameter
|
* (Empty) destructor has to be defined else operator delete might be called with nullptr parameter
|
||||||
*/
|
*/
|
||||||
inline ~Goal() { }
|
inline ~Goal() { }
|
||||||
|
|
||||||
|
static bool IsValidGoalDestination(CompanyID company, GoalType type, GoalTypeID dest);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* GOAL_BASE_H */
|
#endif /* GOAL_BASE_H */
|
||||||
|
@@ -75,6 +75,8 @@
|
|||||||
* \li GSGroupList
|
* \li GSGroupList
|
||||||
* \li GSVehicleList_Group
|
* \li GSVehicleList_Group
|
||||||
* \li GSVehicleList_DefaultGroup
|
* \li GSVehicleList_DefaultGroup
|
||||||
|
* \li GSGoal::IsValidGoalDestination
|
||||||
|
* \li GSGoal::SetDestination
|
||||||
*
|
*
|
||||||
* API removals:
|
* API removals:
|
||||||
* \li GSError::ERR_PRECONDITION_TOO_MANY_PARAMETERS, that error is never returned anymore.
|
* \li GSError::ERR_PRECONDITION_TOO_MANY_PARAMETERS, that error is never returned anymore.
|
||||||
|
@@ -27,6 +27,20 @@
|
|||||||
return ::Goal::IsValidID(goal_id);
|
return ::Goal::IsValidID(goal_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ bool ScriptGoal::IsValidGoalDestination(ScriptCompany::CompanyID company, GoalType type, SQInteger destination)
|
||||||
|
{
|
||||||
|
CompanyID c = (::CompanyID)company;
|
||||||
|
if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY;
|
||||||
|
StoryPage *story_page = nullptr;
|
||||||
|
if (type == GT_STORY_PAGE && ScriptStoryPage::IsValidStoryPage((ScriptStoryPage::StoryPageID)destination)) story_page = ::StoryPage::Get((ScriptStoryPage::StoryPageID)destination);
|
||||||
|
return (type == GT_NONE && destination == 0) ||
|
||||||
|
(type == GT_TILE && ScriptMap::IsValidTile(destination)) ||
|
||||||
|
(type == GT_INDUSTRY && ScriptIndustry::IsValidIndustry(destination)) ||
|
||||||
|
(type == GT_TOWN && ScriptTown::IsValidTown(destination)) ||
|
||||||
|
(type == GT_COMPANY && ScriptCompany::ResolveCompanyID((ScriptCompany::CompanyID)destination) != ScriptCompany::COMPANY_INVALID) ||
|
||||||
|
(type == GT_STORY_PAGE && story_page != nullptr && (c == INVALID_COMPANY ? story_page->company == INVALID_COMPANY : story_page->company == INVALID_COMPANY || story_page->company == c));
|
||||||
|
}
|
||||||
|
|
||||||
/* static */ ScriptGoal::GoalID ScriptGoal::New(ScriptCompany::CompanyID company, Text *goal, GoalType type, SQInteger destination)
|
/* static */ ScriptGoal::GoalID ScriptGoal::New(ScriptCompany::CompanyID company, Text *goal, GoalType type, SQInteger destination)
|
||||||
{
|
{
|
||||||
CCountedPtr<Text> counter(goal);
|
CCountedPtr<Text> counter(goal);
|
||||||
@@ -36,20 +50,9 @@
|
|||||||
const std::string &text = goal->GetEncodedText();
|
const std::string &text = goal->GetEncodedText();
|
||||||
EnforcePreconditionEncodedText(GOAL_INVALID, text);
|
EnforcePreconditionEncodedText(GOAL_INVALID, text);
|
||||||
EnforcePrecondition(GOAL_INVALID, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID);
|
EnforcePrecondition(GOAL_INVALID, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID);
|
||||||
|
EnforcePrecondition(GOAL_INVALID, IsValidGoalDestination(company, type, destination));
|
||||||
|
|
||||||
uint8 c = company;
|
if (!ScriptObject::DoCommand(0, type | (company << 8), destination, CMD_CREATE_GOAL, text, &ScriptInstance::DoCommandReturnGoalID)) return GOAL_INVALID;
|
||||||
if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY;
|
|
||||||
StoryPage *story_page = nullptr;
|
|
||||||
if (type == GT_STORY_PAGE && ScriptStoryPage::IsValidStoryPage((ScriptStoryPage::StoryPageID)destination)) story_page = ::StoryPage::Get((ScriptStoryPage::StoryPageID)destination);
|
|
||||||
|
|
||||||
EnforcePrecondition(GOAL_INVALID, (type == GT_NONE && destination == 0) ||
|
|
||||||
(type == GT_TILE && ScriptMap::IsValidTile(destination)) ||
|
|
||||||
(type == GT_INDUSTRY && ScriptIndustry::IsValidIndustry(destination)) ||
|
|
||||||
(type == GT_TOWN && ScriptTown::IsValidTown(destination)) ||
|
|
||||||
(type == GT_COMPANY && ScriptCompany::ResolveCompanyID((ScriptCompany::CompanyID)destination) != ScriptCompany::COMPANY_INVALID) ||
|
|
||||||
(type == GT_STORY_PAGE && story_page != nullptr && (c == INVALID_COMPANY ? story_page->company == INVALID_COMPANY : story_page->company == INVALID_COMPANY || story_page->company == c)));
|
|
||||||
|
|
||||||
if (!ScriptObject::DoCommand(0, type | (c << 8), destination, CMD_CREATE_GOAL, text, &ScriptInstance::DoCommandReturnGoalID)) return GOAL_INVALID;
|
|
||||||
|
|
||||||
/* In case of test-mode, we return GoalID 0 */
|
/* In case of test-mode, we return GoalID 0 */
|
||||||
return (ScriptGoal::GoalID)0;
|
return (ScriptGoal::GoalID)0;
|
||||||
@@ -63,6 +66,16 @@
|
|||||||
return ScriptObject::DoCommand(0, goal_id, 0, CMD_REMOVE_GOAL);
|
return ScriptObject::DoCommand(0, goal_id, 0, CMD_REMOVE_GOAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ bool ScriptGoal::SetDestination(GoalID goal_id, GoalType type, SQInteger destination)
|
||||||
|
{
|
||||||
|
EnforceDeityMode(false);
|
||||||
|
EnforcePrecondition(false, IsValidGoal(goal_id));
|
||||||
|
Goal *g = Goal::Get(goal_id);
|
||||||
|
EnforcePrecondition(false, IsValidGoalDestination((ScriptCompany::CompanyID)g->company, type, destination));
|
||||||
|
|
||||||
|
return ScriptObject::DoCommandEx(0, goal_id, destination, type, CMD_SET_GOAL_DESTINATION);
|
||||||
|
}
|
||||||
|
|
||||||
/* static */ bool ScriptGoal::SetText(GoalID goal_id, Text *goal)
|
/* static */ bool ScriptGoal::SetText(GoalID goal_id, Text *goal)
|
||||||
{
|
{
|
||||||
CCountedPtr<Text> counter(goal);
|
CCountedPtr<Text> counter(goal);
|
||||||
|
@@ -89,6 +89,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
static bool IsValidGoal(GoalID goal_id);
|
static bool IsValidGoal(GoalID goal_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether this is a valid goal destination.
|
||||||
|
* @param company The relevant company if a story page is the destination.
|
||||||
|
* @param type The type of the goal.
|
||||||
|
* @param destination The destination of the \a type type.
|
||||||
|
* @return True if and only if this goal destination is valid.
|
||||||
|
*/
|
||||||
|
static bool IsValidGoalDestination(ScriptCompany::CompanyID company, GoalType type, SQInteger destination);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new goal.
|
* Create a new goal.
|
||||||
* @param company The company to create the goal for, or ScriptCompany::COMPANY_INVALID for all.
|
* @param company The company to create the goal for, or ScriptCompany::COMPANY_INVALID for all.
|
||||||
@@ -114,6 +123,18 @@ public:
|
|||||||
*/
|
*/
|
||||||
static bool Remove(GoalID goal_id);
|
static bool Remove(GoalID goal_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update goal destination of a goal.
|
||||||
|
* @param goal_id The goal to update.
|
||||||
|
* @param type The type of the goal.
|
||||||
|
* @param destination The destination of the \a type type.
|
||||||
|
* @return True if the action succeeded.
|
||||||
|
* @pre ScriptCompanyMode::IsDeity().
|
||||||
|
* @pre IsValidGoal(goal_id).
|
||||||
|
* @pre IsValidGoalDestination(g->company, type, destination).
|
||||||
|
*/
|
||||||
|
static bool SetDestination(GoalID goal_id, GoalType type, SQInteger destination);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update goal text of a goal.
|
* Update goal text of a goal.
|
||||||
* @param goal_id The goal to update.
|
* @param goal_id The goal to update.
|
||||||
|
Reference in New Issue
Block a user