diff --git a/src/goal.cpp b/src/goal.cpp index 208678678d..d6866ade02 100644 --- a/src/goal.cpp +++ b/src/goal.cpp @@ -84,8 +84,7 @@ std::tuple CmdCreateGoal(DoCommandFlag flags, CompanyID com g->type = type; g->dst = dest; g->company = company; - g->text = stredup(text.c_str()); - g->progress = nullptr; + g->text = text; g->completed = false; if (g->company == INVALID_COMPANY) { @@ -143,8 +142,7 @@ CommandCost CmdSetGoalText(DoCommandFlag flags, GoalID goal, const std::string & if (flags & DC_EXEC) { Goal *g = Goal::Get(goal); - free(g->text); - g->text = stredup(text.c_str()); + g->text = text; if (g->company == INVALID_COMPANY) { InvalidateWindowClassesData(WC_GOALS_LIST); @@ -170,12 +168,7 @@ CommandCost CmdSetGoalProgress(DoCommandFlag flags, GoalID goal, const std::stri if (flags & DC_EXEC) { Goal *g = Goal::Get(goal); - free(g->progress); - if (text.empty()) { - g->progress = nullptr; - } else { - g->progress = stredup(text.c_str()); - } + g->progress = text; if (g->company == INVALID_COMPANY) { InvalidateWindowClassesData(WC_GOALS_LIST); @@ -255,7 +248,7 @@ CommandCost CmdGoalQuestion(DoCommandFlag flags, uint16 uniqueid, uint32 target, if (company == INVALID_COMPANY && !Company::IsValidID(_local_company)) return CommandCost(); if (company != INVALID_COMPANY && company != _local_company) return CommandCost(); } - ShowGoalQuestion(uniqueid, type, button_mask, text.c_str()); + ShowGoalQuestion(uniqueid, type, button_mask, text); } return CommandCost(); diff --git a/src/goal_base.h b/src/goal_base.h index ceeb0ef933..c73699514e 100644 --- a/src/goal_base.h +++ b/src/goal_base.h @@ -19,12 +19,12 @@ extern GoalPool _goal_pool; /** Struct about goals, current and completed */ struct Goal : GoalPool::PoolItem<&_goal_pool> { - CompanyID company; ///< Goal is for a specific company; INVALID_COMPANY if it is global - GoalType type; ///< Type of the goal - GoalTypeID dst; ///< Index of type - char *text; ///< Text of the goal. - char *progress; ///< Progress text of the goal. - bool completed; ///< Is the goal completed or not? + CompanyID company; ///< Goal is for a specific company; INVALID_COMPANY if it is global + GoalType type; ///< Type of the goal + GoalTypeID dst; ///< Index of type + std::string text; ///< Text of the goal. + std::string progress; ///< Progress text of the goal. + bool completed; ///< Is the goal completed or not? /** * We need an (empty) constructor so struct isn't zeroed (as C++ standard states) @@ -34,7 +34,7 @@ struct Goal : GoalPool::PoolItem<&_goal_pool> { /** * (Empty) destructor has to be defined else operator delete might be called with nullptr parameter */ - inline ~Goal() { free(this->text); free(this->progress); } + inline ~Goal() { } }; #endif /* GOAL_BASE_H */ diff --git a/src/goal_gui.cpp b/src/goal_gui.cpp index bf7381c140..bdf9d3fca6 100644 --- a/src/goal_gui.cpp +++ b/src/goal_gui.cpp @@ -212,7 +212,7 @@ struct GoalListWindow : public Window { } case GC_PROGRESS: - if (s->progress != nullptr) { + if (!s->progress.empty()) { SetDParamStr(0, s->progress); StringID str = s->completed ? STR_GOALS_PROGRESS_COMPLETE : STR_GOALS_PROGRESS; DrawString(r.WithWidth(progress_col_width, !rtl), str, TC_FROMSTRING, SA_RIGHT | SA_FORCE); @@ -242,7 +242,7 @@ struct GoalListWindow : public Window { /* Calculate progress column width. */ uint max_width = 0; for (const Goal *s : Goal::Iterate()) { - if (s->progress != nullptr) { + if (!s->progress.empty()) { SetDParamStr(0, s->progress); StringID str = s->completed ? STR_GOALS_PROGRESS_COMPLETE : STR_GOALS_PROGRESS; uint str_width = GetStringBoundingBox(str).width; @@ -322,14 +322,14 @@ void ShowGoalsList(CompanyID company) /** Ask a question about a goal. */ struct GoalQuestionWindow : public Window { - char *question; ///< Question to ask (private copy). - int buttons; ///< Number of valid buttons in #button. - int button[3]; ///< Buttons to display. - TextColour colour; ///< Colour of the question text. + std::string question; ///< Question to ask (private copy). + int buttons; ///< Number of valid buttons in #button. + int button[3]; ///< Buttons to display. + TextColour colour; ///< Colour of the question text. - GoalQuestionWindow(WindowDesc *desc, WindowNumber window_number, TextColour colour, uint32 button_mask, const char *question) : Window(desc), colour(colour) + GoalQuestionWindow(WindowDesc *desc, WindowNumber window_number, TextColour colour, uint32 button_mask, const std::string &question) : Window(desc), colour(colour) { - this->question = stredup(question); + this->question = question; /* Figure out which buttons we have to enable. */ int n = 0; @@ -352,10 +352,6 @@ struct GoalQuestionWindow : public Window { this->FinishInitNested(window_number); } - ~GoalQuestionWindow() - { - free(this->question); - } void SetStringParameters(int widget) const override { @@ -554,7 +550,7 @@ static WindowDesc _goal_question_list_desc[] = { * @param button_mask Buttons to display. * @param question Question to ask. */ -void ShowGoalQuestion(uint16 id, byte type, uint32 button_mask, const char *question) +void ShowGoalQuestion(uint16 id, byte type, uint32 button_mask, const std::string &question) { assert(type < GQT_END); new GoalQuestionWindow(&_goal_question_list_desc[type], id, type == 3 ? TC_WHITE : TC_BLACK, button_mask, question); diff --git a/src/gui.h b/src/gui.h index 4eb2fb7f66..a489648193 100644 --- a/src/gui.h +++ b/src/gui.h @@ -49,7 +49,7 @@ void ShowIndustryDirectory(); void ShowIndustryCargoesWindow(); void ShowSubsidiesList(); void ShowGoalsList(CompanyID company); -void ShowGoalQuestion(uint16 id, byte type, uint32 button_mask, const char *question); +void ShowGoalQuestion(uint16 id, byte type, uint32 button_mask, const std::string &question); void ShowStoryBook(CompanyID company, uint16 page_id = INVALID_STORY_PAGE); void ShowEstimatedCostOrIncome(Money cost, int x, int y); diff --git a/src/saveload/goal_sl.cpp b/src/saveload/goal_sl.cpp index ae6b8577b2..003e92b20f 100644 --- a/src/saveload/goal_sl.cpp +++ b/src/saveload/goal_sl.cpp @@ -17,12 +17,12 @@ #include "../safeguards.h" static const SaveLoad _goals_desc[] = { - SLE_VAR(Goal, company, SLE_FILE_U16 | SLE_VAR_U8), - SLE_VAR(Goal, type, SLE_FILE_U16 | SLE_VAR_U8), - SLE_VAR(Goal, dst, SLE_UINT32), - SLE_STR(Goal, text, SLE_STR | SLF_ALLOW_CONTROL, 0), - SLE_CONDSTR(Goal, progress, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_182, SL_MAX_VERSION), - SLE_CONDVAR(Goal, completed, SLE_BOOL, SLV_182, SL_MAX_VERSION), + SLE_VAR(Goal, company, SLE_FILE_U16 | SLE_VAR_U8), + SLE_VAR(Goal, type, SLE_FILE_U16 | SLE_VAR_U8), + SLE_VAR(Goal, dst, SLE_UINT32), + SLE_SSTR(Goal, text, SLE_STR | SLF_ALLOW_CONTROL), + SLE_CONDSSTR(Goal, progress, SLE_STR | SLF_ALLOW_CONTROL, SLV_182, SL_MAX_VERSION), + SLE_CONDVAR(Goal, completed, SLE_BOOL, SLV_182, SL_MAX_VERSION), }; struct GOALChunkHandler : ChunkHandler {