1
0
Fork 0

Codechange: Pass encoded script strings as EncodedString.

This removes the ambiguity of having std::strings that may or may not be encoded.
pull/13741/head
Peter Nelson 2025-03-04 01:00:40 +00:00 committed by Peter Nelson
parent 2a05a845df
commit b55af05626
34 changed files with 126 additions and 114 deletions

View File

@ -75,7 +75,7 @@ INSTANTIATE_POOL_METHODS(Goal)
* @param text Text of the goal.
* @return the cost of this operation or an error
*/
std::tuple<CommandCost, GoalID> CmdCreateGoal(DoCommandFlags flags, CompanyID company, GoalType type, GoalTypeID dest, const std::string &text)
std::tuple<CommandCost, GoalID> CmdCreateGoal(DoCommandFlags flags, CompanyID company, GoalType type, GoalTypeID dest, const EncodedString &text)
{
if (!Goal::CanAllocateItem()) return { CMD_ERROR, GoalID::Invalid() };
@ -157,7 +157,7 @@ CommandCost CmdSetGoalDestination(DoCommandFlags flags, GoalID goal, GoalType ty
* @param text Text of the goal.
* @return the cost of this operation or an error
*/
CommandCost CmdSetGoalText(DoCommandFlags flags, GoalID goal, const std::string &text)
CommandCost CmdSetGoalText(DoCommandFlags flags, GoalID goal, const EncodedString &text)
{
if (_current_company != OWNER_DEITY) return CMD_ERROR;
if (!Goal::IsValidID(goal)) return CMD_ERROR;
@ -184,7 +184,7 @@ CommandCost CmdSetGoalText(DoCommandFlags flags, GoalID goal, const std::string
* @param text Progress text of the goal.
* @return the cost of this operation or an error
*/
CommandCost CmdSetGoalProgress(DoCommandFlags flags, GoalID goal, const std::string &text)
CommandCost CmdSetGoalProgress(DoCommandFlags flags, GoalID goal, const EncodedString &text)
{
if (_current_company != OWNER_DEITY) return CMD_ERROR;
if (!Goal::IsValidID(goal)) return CMD_ERROR;
@ -240,7 +240,7 @@ CommandCost CmdSetGoalCompleted(DoCommandFlags flags, GoalID goal, bool complete
* @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 std::string &text)
CommandCost CmdGoalQuestion(DoCommandFlags flags, uint16_t uniqueid, uint32_t target, bool is_client, uint32_t button_mask, GoalQuestionType type, const EncodedString &text)
{
static_assert(sizeof(uint32_t) >= sizeof(CompanyID));
CompanyID company = (CompanyID)target;

View File

@ -13,6 +13,7 @@
#include "company_type.h"
#include "goal_type.h"
#include "core/pool_type.hpp"
#include "strings_type.h"
using GoalPool = Pool<Goal, GoalID, 64>;
extern GoalPool _goal_pool;
@ -22,15 +23,15 @@ struct Goal : GoalPool::PoolItem<&_goal_pool> {
CompanyID company = CompanyID::Invalid(); ///< Goal is for a specific company; CompanyID::Invalid() if it is global
GoalType type = GT_NONE; ///< Type of the goal
GoalTypeID dst = 0; ///< Index of type
std::string text{}; ///< Text of the goal.
std::string progress{}; ///< Progress text of the goal.
EncodedString text{}; ///< Text of the goal.
EncodedString progress{}; ///< Progress text of the goal.
bool completed = false; ///< Is the goal completed or not?
/**
* We need an (empty) constructor so struct isn't zeroed (as C++ standard states)
*/
Goal() { }
Goal(GoalType type, GoalTypeID dst, CompanyID company, const std::string &text) : company(company), type(type), dst(dst), text(text) {}
Goal(GoalType type, GoalTypeID dst, CompanyID company, const EncodedString &text) : company(company), type(type), dst(dst), text(text) {}
/**
* (Empty) destructor has to be defined else operator delete might be called with nullptr parameter

View File

@ -13,13 +13,13 @@
#include "command_type.h"
#include "goal_type.h"
std::tuple<CommandCost, GoalID> CmdCreateGoal(DoCommandFlags flags, CompanyID company, GoalType type, GoalTypeID dest, const std::string &text);
std::tuple<CommandCost, GoalID> CmdCreateGoal(DoCommandFlags flags, CompanyID company, GoalType type, GoalTypeID dest, const EncodedString &text);
CommandCost CmdRemoveGoal(DoCommandFlags flags, GoalID goal);
CommandCost CmdSetGoalDestination(DoCommandFlags flags, GoalID goal, GoalType type, GoalTypeID dest);
CommandCost CmdSetGoalText(DoCommandFlags flags, GoalID goal, const std::string &text);
CommandCost CmdSetGoalProgress(DoCommandFlags flags, GoalID goal, const std::string &text);
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 std::string &text);
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);
DEF_CMD_TRAIT(CMD_CREATE_GOAL, CmdCreateGoal, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CMDT_OTHER_MANAGEMENT)

View File

@ -204,14 +204,14 @@ struct GoalListWindow : public Window {
case GC_GOAL: {
/* Display the goal. */
uint width_reduction = progress_col_width > 0 ? progress_col_width + WidgetDimensions::scaled.framerect.Horizontal() : 0;
DrawString(r.Indent(width_reduction, !rtl), GetString(STR_GOALS_TEXT, s->text));
DrawString(r.Indent(width_reduction, !rtl), GetString(STR_GOALS_TEXT, s->text.GetDecodedString()));
break;
}
case GC_PROGRESS:
if (!s->progress.empty()) {
StringID str = s->completed ? STR_GOALS_PROGRESS_COMPLETE : STR_GOALS_PROGRESS;
DrawString(r.WithWidth(progress_col_width, !rtl), GetString(str, s->progress), TC_FROMSTRING, SA_RIGHT | SA_FORCE);
DrawString(r.WithWidth(progress_col_width, !rtl), GetString(str, s->progress.GetDecodedString()), TC_FROMSTRING, SA_RIGHT | SA_FORCE);
}
break;
}
@ -240,7 +240,7 @@ struct GoalListWindow : public Window {
for (const Goal *s : Goal::Iterate()) {
if (!s->progress.empty()) {
StringID str = s->completed ? STR_GOALS_PROGRESS_COMPLETE : STR_GOALS_PROGRESS;
uint str_width = GetStringBoundingBox(GetString(str, s->progress)).width;
uint str_width = GetStringBoundingBox(GetString(str, s->progress.GetDecodedString())).width;
if (str_width > max_width) max_width = str_width;
}
}
@ -317,12 +317,12 @@ void ShowGoalsList(CompanyID company)
/** Ask a question about a goal. */
struct GoalQuestionWindow : public Window {
std::string question{}; ///< Question to ask (private copy).
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.
GoalQuestionWindow(WindowDesc &desc, WindowNumber window_number, TextColour colour, uint32_t button_mask, const std::string &question) : Window(desc), colour(colour)
GoalQuestionWindow(WindowDesc &desc, WindowNumber window_number, TextColour colour, uint32_t button_mask, const EncodedString &question) : Window(desc), colour(colour)
{
this->question = question;
@ -387,14 +387,14 @@ struct GoalQuestionWindow : public Window {
{
if (widget != WID_GQ_QUESTION) return;
size.height = GetStringHeight(GetString(STR_JUST_RAW_STRING, this->question), size.width);
size.height = GetStringHeight(this->question.GetDecodedString(), size.width);
}
void DrawWidget(const Rect &r, WidgetID widget) const override
{
if (widget != WID_GQ_QUESTION) return;
DrawStringMultiLine(r, GetString(STR_JUST_RAW_STRING, this->question), this->colour, SA_TOP | SA_HOR_CENTER);
DrawStringMultiLine(r, this->question.GetDecodedString(), this->colour, SA_TOP | SA_HOR_CENTER);
}
};
@ -472,7 +472,7 @@ static WindowDesc _goal_question_list_desc[] = {
* @param button_mask Buttons to display.
* @param question Question to ask.
*/
void ShowGoalQuestion(uint16_t id, uint8_t type, uint32_t button_mask, const std::string &question)
void ShowGoalQuestion(uint16_t id, uint8_t type, uint32_t button_mask, const EncodedString &question)
{
assert(type < GQT_END);
new GoalQuestionWindow(_goal_question_list_desc[type], id, type == 3 ? TC_WHITE : TC_BLACK, button_mask, question);

View File

@ -10,6 +10,7 @@
#ifndef GUI_H
#define GUI_H
#include "strings_type.h"
#include "vehicle_type.h"
#include "economy_type.h"
#include "tile_type.h"
@ -62,7 +63,7 @@ void ShowSubsidiesList();
/* goal_gui.cpp */
void ShowGoalsList(CompanyID company);
void ShowGoalQuestion(uint16_t id, uint8_t type, uint32_t button_mask, const std::string &question);
void ShowGoalQuestion(uint16_t id, uint8_t type, uint32_t button_mask, const EncodedString &question);
/* story_gui.cpp */
void ShowStoryBook(CompanyID company, StoryPageID page_id = StoryPageID::Invalid(), bool centered = false);

View File

@ -113,7 +113,7 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> {
uint8_t selected_layout = 0; ///< Which tile layout was used when creating the industry
Owner exclusive_supplier = INVALID_OWNER; ///< Which company has exclusive rights to deliver cargo (INVALID_OWNER = anyone)
Owner exclusive_consumer = INVALID_OWNER; ///< Which company has exclusive rights to take cargo (INVALID_OWNER = anyone)
std::string text{}; ///< General text with additional information.
EncodedString text{}; ///< General text with additional information.
uint16_t random = 0; ///< Random value used for randomisation of all kinds of things

View File

@ -2161,7 +2161,7 @@ CommandCost CmdIndustrySetFlags(DoCommandFlags flags, IndustryID ind_id, Industr
* @param custom_news Custom news message text.
* @return Empty cost or an error.
*/
CommandCost CmdIndustrySetProduction(DoCommandFlags flags, IndustryID ind_id, uint8_t prod_level, bool show_news, const std::string &custom_news)
CommandCost CmdIndustrySetProduction(DoCommandFlags flags, IndustryID ind_id, uint8_t prod_level, bool show_news, const EncodedString &custom_news)
{
if (_current_company != OWNER_DEITY) return CMD_ERROR;
if (prod_level < PRODLEVEL_MINIMUM || prod_level > PRODLEVEL_MAXIMUM) return CMD_ERROR;
@ -2195,12 +2195,13 @@ CommandCost CmdIndustrySetProduction(DoCommandFlags flags, IndustryID ind_id, ui
/* Set parameters of news string */
EncodedString headline;
if (str == STR_NEWS_CUSTOM_ITEM) {
headline = GetEncodedString(str, custom_news);
headline = GetEncodedString(str, custom_news.GetDecodedString());
} else if (str > STR_LAST_STRINGID) {
headline = GetEncodedString(str, STR_TOWN_NAME, ind->town->index, GetIndustrySpec(ind->type)->name);
} else {
headline = GetEncodedString(str, ind->index);
}
AddIndustryNewsItem(std::move(headline), nt, ind->index);
}
}
@ -2246,7 +2247,7 @@ CommandCost CmdIndustrySetExclusivity(DoCommandFlags flags, IndustryID ind_id, O
* @param text - Additional industry text.
* @return Empty cost or an error.
*/
CommandCost CmdIndustrySetText(DoCommandFlags flags, IndustryID ind_id, const std::string &text)
CommandCost CmdIndustrySetText(DoCommandFlags flags, IndustryID ind_id, const EncodedString &text)
{
if (_current_company != OWNER_DEITY) return CMD_ERROR;

View File

@ -18,8 +18,8 @@
CommandCost CmdBuildIndustry(DoCommandFlags flags, TileIndex tile, IndustryType it, uint32_t first_layout, bool fund, uint32_t seed);
CommandCost CmdIndustrySetFlags(DoCommandFlags flags, IndustryID ind_id, IndustryControlFlags ctlflags);
CommandCost CmdIndustrySetExclusivity(DoCommandFlags flags, IndustryID ind_id, Owner company_id, bool consumer);
CommandCost CmdIndustrySetText(DoCommandFlags flags, IndustryID ind_id, const std::string &text);
CommandCost CmdIndustrySetProduction(DoCommandFlags flags, IndustryID ind_id, uint8_t prod_level, bool show_news, const std::string &text);
CommandCost CmdIndustrySetText(DoCommandFlags flags, IndustryID ind_id, const EncodedString &text);
CommandCost CmdIndustrySetProduction(DoCommandFlags flags, IndustryID ind_id, uint8_t prod_level, bool show_news, const EncodedString &text);
DEF_CMD_TRAIT(CMD_BUILD_INDUSTRY, CmdBuildIndustry, CommandFlag::Deity, CMDT_LANDSCAPE_CONSTRUCTION)
DEF_CMD_TRAIT(CMD_INDUSTRY_SET_FLAGS, CmdIndustrySetFlags, CommandFlag::Deity, CMDT_OTHER_MANAGEMENT)

View File

@ -990,7 +990,7 @@ public:
if (!i->text.empty()) {
ir.top += WidgetDimensions::scaled.vsep_wide;
ir.top = DrawStringMultiLine(ir, GetString(STR_JUST_RAW_STRING, i->text), TC_BLACK);
ir.top = DrawStringMultiLine(ir, i->text.GetDecodedString(), TC_BLACK);
}
/* Return required bottom position, the last pixel row plus some padding. */

View File

@ -14,6 +14,7 @@
#include "goal_type.h"
#include "league_type.h"
#include "core/pool_type.hpp"
#include "strings_type.h"
bool IsValidLink(Link link);
@ -32,15 +33,15 @@ struct LeagueTableElement : LeagueTableElementPool::PoolItem<&_league_table_elem
LeagueTableID table = LeagueTableID::Invalid(); ///< Id of the table which this element belongs to
int64_t rating = 0; ///< Value that determines ordering of elements in the table (higher=better)
CompanyID company = CompanyID::Invalid(); ///< Company Id to show the color blob for or CompanyID::Invalid()
std::string text{}; ///< Text of the element
std::string score{}; ///< String representation of the score associated with the element
EncodedString text{}; ///< Text of the element
EncodedString score{}; ///< String representation of the score associated with the element
Link link{}; ///< What opens when element is clicked
/**
* We need an (empty) constructor so struct isn't zeroed (as C++ standard states)
*/
LeagueTableElement() { }
LeagueTableElement(LeagueTableID table, int64_t rating, CompanyID company, const std::string &text, const std::string &score, const Link &link) :
LeagueTableElement(LeagueTableID table, int64_t rating, CompanyID company, const EncodedString &text, const EncodedString &score, const Link &link) :
table(table), rating(rating), company(company), text(text), score(score), link(link) {}
/**
@ -52,15 +53,15 @@ struct LeagueTableElement : LeagueTableElementPool::PoolItem<&_league_table_elem
/** Struct about custom league tables */
struct LeagueTable : LeagueTablePool::PoolItem<&_league_table_pool> {
std::string title{}; ///< Title of the table
std::string header{}; ///< Text to show above the table
std::string footer{}; ///< Text to show below the table
EncodedString title{}; ///< Title of the table
EncodedString header{}; ///< Text to show above the table
EncodedString footer{}; ///< Text to show below the table
/**
* We need an (empty) constructor so struct isn't zeroed (as C++ standard states)
*/
LeagueTable() { }
LeagueTable(const std::string &title, const std::string &header, const std::string &footer) : title(title), header(header), footer(footer) { }
LeagueTable(const EncodedString &title, const EncodedString &header, const EncodedString &footer) : title(title), header(header), footer(footer) { }
/**
* (Empty) destructor has to be defined else operator delete might be called with nullptr parameter

View File

@ -53,7 +53,7 @@ bool IsValidLink(Link link)
* @param footer Text to show below the table
* @return the cost of this operation or an error
*/
std::tuple<CommandCost, LeagueTableID> CmdCreateLeagueTable(DoCommandFlags flags, const std::string &title, const std::string &header, const std::string &footer)
std::tuple<CommandCost, LeagueTableID> CmdCreateLeagueTable(DoCommandFlags flags, const EncodedString &title, const EncodedString &header, const EncodedString &footer)
{
if (_current_company != OWNER_DEITY) return { CMD_ERROR, LeagueTableID::Invalid() };
if (!LeagueTable::CanAllocateItem()) return { CMD_ERROR, LeagueTableID::Invalid() };
@ -80,7 +80,7 @@ std::tuple<CommandCost, LeagueTableID> CmdCreateLeagueTable(DoCommandFlags flags
* @param link_target Id of the referenced object
* @return the cost of this operation or an error
*/
std::tuple<CommandCost, LeagueTableElementID> CmdCreateLeagueTableElement(DoCommandFlags flags, LeagueTableID table, int64_t rating, CompanyID company, const std::string &text, const std::string &score, LinkType link_type, LinkTargetID link_target)
std::tuple<CommandCost, LeagueTableElementID> CmdCreateLeagueTableElement(DoCommandFlags flags, LeagueTableID table, int64_t rating, CompanyID company, const EncodedString &text, const EncodedString &score, LinkType link_type, LinkTargetID link_target)
{
if (_current_company != OWNER_DEITY) return { CMD_ERROR, LeagueTableElementID::Invalid() };
if (!LeagueTableElement::CanAllocateItem()) return { CMD_ERROR, LeagueTableElementID::Invalid() };
@ -106,7 +106,7 @@ std::tuple<CommandCost, LeagueTableElementID> CmdCreateLeagueTableElement(DoComm
* @param link_target Id of the referenced object
* @return the cost of this operation or an error
*/
CommandCost CmdUpdateLeagueTableElementData(DoCommandFlags flags, LeagueTableElementID element, CompanyID company, const std::string &text, LinkType link_type, LinkTargetID link_target)
CommandCost CmdUpdateLeagueTableElementData(DoCommandFlags flags, LeagueTableElementID element, CompanyID company, const EncodedString &text, LinkType link_type, LinkTargetID link_target)
{
if (_current_company != OWNER_DEITY) return CMD_ERROR;
auto lte = LeagueTableElement::GetIfValid(element);
@ -132,7 +132,7 @@ CommandCost CmdUpdateLeagueTableElementData(DoCommandFlags flags, LeagueTableEle
* @param score String representation of the score associated with the element
* @return the cost of this operation or an error
*/
CommandCost CmdUpdateLeagueTableElementScore(DoCommandFlags flags, LeagueTableElementID element, int64_t rating, const std::string &score)
CommandCost CmdUpdateLeagueTableElementScore(DoCommandFlags flags, LeagueTableElementID element, int64_t rating, const EncodedString &score)
{
if (_current_company != OWNER_DEITY) return CMD_ERROR;
auto lte = LeagueTableElement::GetIfValid(element);

View File

@ -14,10 +14,10 @@
#include "command_type.h"
#include "company_type.h"
std::tuple<CommandCost, LeagueTableID> CmdCreateLeagueTable(DoCommandFlags flags, const std::string &title, const std::string &header, const std::string &footer);
std::tuple<CommandCost, LeagueTableElementID> CmdCreateLeagueTableElement(DoCommandFlags flags, LeagueTableID table, int64_t rating, CompanyID company, const std::string &text, const std::string &score, LinkType link_type, LinkTargetID link_target);
CommandCost CmdUpdateLeagueTableElementData(DoCommandFlags flags, LeagueTableElementID element, CompanyID company, const std::string &text, LinkType link_type, LinkTargetID link_target);
CommandCost CmdUpdateLeagueTableElementScore(DoCommandFlags flags, LeagueTableElementID element, int64_t rating, const std::string &score);
std::tuple<CommandCost, LeagueTableID> CmdCreateLeagueTable(DoCommandFlags flags, const EncodedString &title, const EncodedString &header, const EncodedString &footer);
std::tuple<CommandCost, LeagueTableElementID> CmdCreateLeagueTableElement(DoCommandFlags flags, LeagueTableID table, int64_t rating, CompanyID company, const EncodedString &text, const EncodedString &score, LinkType link_type, LinkTargetID link_target);
CommandCost CmdUpdateLeagueTableElementData(DoCommandFlags flags, LeagueTableElementID element, CompanyID company, const EncodedString &text, LinkType link_type, LinkTargetID link_target);
CommandCost CmdUpdateLeagueTableElementScore(DoCommandFlags flags, LeagueTableElementID element, int64_t rating, const EncodedString &score);
CommandCost CmdRemoveLeagueTableElement(DoCommandFlags flags, LeagueTableElementID element);
DEF_CMD_TRAIT(CMD_CREATE_LEAGUE_TABLE, CmdCreateLeagueTable, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CMDT_OTHER_MANAGEMENT)

View File

@ -257,7 +257,7 @@ private:
uint header_height = 0; ///< Height of the table header
int line_height = 0; ///< Height of the text lines
Dimension icon_size{}; ///< Dimension of the company icon.
std::string title{};
EncodedString title{};
/**
* Rebuild the company league list
@ -265,7 +265,7 @@ private:
void BuildTable()
{
this->rows.clear();
this->title = std::string{};
this->title = {};
const LeagueTable *lt = LeagueTable::GetIfValid(this->table);
if (lt == nullptr) return;
@ -300,8 +300,7 @@ public:
{
if (widget != WID_SLT_CAPTION) return this->Window::GetWidgetString(widget, stringid);
/* Encoded string from game script needs to be formatted. */
return GetString(STR_JUST_RAW_STRING, this->title);
return this->title.GetDecodedString();
}
void OnPaint() override
@ -319,7 +318,7 @@ public:
Rect ir = r.Shrink(WidgetDimensions::scaled.framerect);
if (!lt->header.empty()) {
ir.top = DrawStringMultiLine(ir, GetString(STR_JUST_RAW_STRING, lt->header), TC_BLACK) + WidgetDimensions::scaled.vsep_wide;
ir.top = DrawStringMultiLine(ir, lt->header.GetDecodedString(), TC_BLACK) + WidgetDimensions::scaled.vsep_wide;
}
int icon_y_offset = (this->line_height - this->icon_size.height) / 2;
@ -336,14 +335,14 @@ public:
for (const auto &[rank, lte] : this->rows) {
DrawString(rank_rect.left, rank_rect.right, ir.top + text_y_offset, GetString(STR_COMPANY_LEAGUE_COMPANY_RANK, rank + 1));
if (this->icon_size.width > 0 && lte->company != CompanyID::Invalid()) DrawCompanyIcon(lte->company, icon_rect.left, ir.top + icon_y_offset);
DrawString(text_rect.left, text_rect.right, ir.top + text_y_offset, GetString(STR_JUST_RAW_STRING, lte->text), TC_BLACK);
DrawString(score_rect.left, score_rect.right, ir.top + text_y_offset, GetString(STR_JUST_RAW_STRING, lte->score), TC_BLACK, SA_RIGHT);
DrawString(text_rect.left, text_rect.right, ir.top + text_y_offset, lte->text.GetDecodedString(), TC_BLACK);
DrawString(score_rect.left, score_rect.right, ir.top + text_y_offset, lte->score.GetDecodedString(), TC_BLACK, SA_RIGHT);
ir.top += this->line_height;
}
if (!lt->footer.empty()) {
ir.top += WidgetDimensions::scaled.vsep_wide;
ir.top = DrawStringMultiLine(ir, GetString(STR_JUST_RAW_STRING, lt->footer), TC_BLACK);
ir.top = DrawStringMultiLine(ir, lt->footer.GetDecodedString(), TC_BLACK);
}
}
@ -362,8 +361,8 @@ public:
bool show_icon_column = false;
for (const auto &[rank, lte] : this->rows) {
this->rank_width = std::max(this->rank_width, GetStringBoundingBox(GetString(STR_COMPANY_LEAGUE_COMPANY_RANK, rank + 1)).width);
this->text_width = std::max(this->text_width, GetStringBoundingBox(GetString(STR_JUST_RAW_STRING, lte->text)).width);
this->score_width = std::max(this->score_width, GetStringBoundingBox(GetString(STR_JUST_RAW_STRING, lte->score)).width);
this->text_width = std::max(this->text_width, GetStringBoundingBox(lte->text.GetDecodedString()).width);
this->score_width = std::max(this->score_width, GetStringBoundingBox(lte->score.GetDecodedString()).width);
if (lte->company != CompanyID::Invalid()) show_icon_column = true;
}
@ -381,14 +380,14 @@ public:
this->text_width = size.width - non_text_width;
if (!lt->header.empty()) {
this->header_height = GetStringHeight(GetString(STR_JUST_RAW_STRING, lt->header), size.width - WidgetDimensions::scaled.framerect.Horizontal()) + WidgetDimensions::scaled.vsep_wide;
this->header_height = GetStringHeight(lt->header.GetDecodedString(), size.width - WidgetDimensions::scaled.framerect.Horizontal()) + WidgetDimensions::scaled.vsep_wide;
size.height += header_height;
} else {
this->header_height = 0;
}
if (!lt->footer.empty()) {
size.height += GetStringHeight(GetString(STR_JUST_RAW_STRING, lt->footer), size.width - WidgetDimensions::scaled.framerect.Horizontal()) + WidgetDimensions::scaled.vsep_wide;
size.height += GetStringHeight(lt->footer.GetDecodedString(), size.width - WidgetDimensions::scaled.framerect.Horizontal()) + WidgetDimensions::scaled.vsep_wide;
}
}

View File

@ -12,6 +12,7 @@
#include <string_view>
#include "../core/bitmath_func.hpp"
#include "../strings_type.h"
/**
* Endian-aware buffer adapter that always writes values in little endian order.
@ -29,6 +30,7 @@ public:
EndianBufferWriter(typename Titer::container_type &container) : buffer(std::back_inserter(container)) {}
EndianBufferWriter &operator <<(const std::string &data) { return *this << std::string_view{ data }; }
EndianBufferWriter &operator <<(const EncodedString &data) { return *this << data.string; }
EndianBufferWriter &operator <<(const char *data) { return *this << std::string_view{ data }; }
EndianBufferWriter &operator <<(std::string_view data) { this->Write(data); return *this; }
EndianBufferWriter &operator <<(bool data) { return *this << static_cast<uint8_t>(data ? 1 : 0); }
@ -153,6 +155,7 @@ public:
void rewind() { this->read_pos = 0; }
EndianBufferReader &operator >>(std::string &data) { data = this->ReadStr(); return *this; }
EndianBufferReader &operator >>(EncodedString &data) { data = EncodedString{this->ReadStr()}; return *this; }
EndianBufferReader &operator >>(bool &data) { data = this->Read<uint8_t>() != 0; return *this; }
template <typename... Targs>

View File

@ -14,7 +14,7 @@
#include "company_type.h"
#include "news_func.h"
CommandCost CmdCustomNewsItem(DoCommandFlags flags, NewsType type, CompanyID company, NewsReference reference, const std::string &text);
CommandCost CmdCustomNewsItem(DoCommandFlags flags, NewsType type, CompanyID company, NewsReference reference, const EncodedString &text);
DEF_CMD_TRAIT(CMD_CUSTOM_NEWS_ITEM, CmdCustomNewsItem, CommandFlags({CommandFlag::StrCtrl, CommandFlag::Deity}), CMDT_OTHER_MANAGEMENT)

View File

@ -934,7 +934,7 @@ uint32_t SerialiseNewsReference(const NewsReference &reference)
* @param text The text of the news message.
* @return the cost of this operation or an error
*/
CommandCost CmdCustomNewsItem(DoCommandFlags flags, NewsType type, CompanyID company, NewsReference reference, const std::string &text)
CommandCost CmdCustomNewsItem(DoCommandFlags flags, NewsType type, CompanyID company, NewsReference reference, const EncodedString &text)
{
if (_current_company != OWNER_DEITY) return CMD_ERROR;
@ -957,7 +957,7 @@ CommandCost CmdCustomNewsItem(DoCommandFlags flags, NewsType type, CompanyID com
if (company != INVALID_OWNER && company != _local_company) return CommandCost();
if (flags.Test(DoCommandFlag::Execute)) {
AddNewsItem(GetEncodedString(STR_NEWS_CUSTOM_ITEM, text), type, NewsStyle::Normal, {}, reference, {});
AddNewsItem(GetEncodedString(STR_NEWS_CUSTOM_ITEM, text.GetDecodedString()), type, NewsStyle::Normal, {}, reference, {});
}
return CommandCost();

View File

@ -47,7 +47,7 @@
EnforceDeityMode(GOAL_INVALID);
EnforcePrecondition(GOAL_INVALID, goal != nullptr);
std::string text = goal->GetEncodedText();
EncodedString text = goal->GetEncodedText();
EnforcePreconditionEncodedText(GOAL_INVALID, text);
EnforcePrecondition(GOAL_INVALID, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID);
EnforcePrecondition(GOAL_INVALID, IsValidGoalDestination(company, type, destination));
@ -83,7 +83,7 @@
EnforcePrecondition(false, IsValidGoal(goal_id));
EnforceDeityMode(false);
EnforcePrecondition(false, goal != nullptr);
std::string text = goal->GetEncodedText();
EncodedString text = goal->GetEncodedText();
EnforcePreconditionEncodedText(false, text);
return ScriptObject::Command<CMD_SET_GOAL_TEXT>::Do(goal_id, text);
@ -96,7 +96,7 @@
EnforcePrecondition(false, IsValidGoal(goal_id));
EnforceDeityMode(false);
return ScriptObject::Command<CMD_SET_GOAL_PROGRESS>::Do(goal_id, progress != nullptr ? progress->GetEncodedText() : std::string{});
return ScriptObject::Command<CMD_SET_GOAL_PROGRESS>::Do(goal_id, progress != nullptr ? progress->GetEncodedText() : EncodedString{});
}
/* static */ bool ScriptGoal::SetCompleted(GoalID goal_id, bool completed)
@ -122,7 +122,7 @@
EnforceDeityMode(false);
EnforcePrecondition(false, question != nullptr);
std::string text = question->GetEncodedText();
EncodedString text = question->GetEncodedText();
EnforcePreconditionEncodedText(false, text);
uint min_buttons = (type == QT_QUESTION ? 1 : 0);
EnforcePrecondition(false, CountBits<uint64_t>(buttons) >= min_buttons && CountBits<uint64_t>(buttons) <= 3);

View File

@ -62,7 +62,7 @@
EnforceDeityMode(false);
EnforcePrecondition(false, IsValidIndustry(industry_id));
return ScriptObject::Command<CMD_INDUSTRY_SET_TEXT>::Do(industry_id, text != nullptr ? text->GetEncodedText() : std::string{});
return ScriptObject::Command<CMD_INDUSTRY_SET_TEXT>::Do(industry_id, text != nullptr ? text->GetEncodedText() : EncodedString{});
}
/* static */ ScriptIndustry::CargoAcceptState ScriptIndustry::IsCargoAccepted(IndustryID industry_id, CargoType cargo_type)
@ -310,5 +310,5 @@
EnforcePrecondition(false, IsValidIndustry(industry_id));
EnforcePrecondition(false, prod_level >= PRODLEVEL_MINIMUM && prod_level <= PRODLEVEL_MAXIMUM);
return ScriptObject::Command<CMD_INDUSTRY_SET_PRODUCTION>::Do(industry_id, prod_level, show_news, custom_news != nullptr ? custom_news->GetEncodedText() : std::string{});
return ScriptObject::Command<CMD_INDUSTRY_SET_PRODUCTION>::Do(industry_id, prod_level, show_news, custom_news != nullptr ? custom_news->GetEncodedText() : EncodedString{});
}

View File

@ -32,11 +32,11 @@
EnforceDeityMode(LEAGUE_TABLE_INVALID);
EnforcePrecondition(LEAGUE_TABLE_INVALID, title != nullptr);
std::string encoded_title = title->GetEncodedText();
EncodedString encoded_title = title->GetEncodedText();
EnforcePreconditionEncodedText(LEAGUE_TABLE_INVALID, encoded_title);
std::string encoded_header = (header != nullptr ? header->GetEncodedText() : std::string{});
std::string encoded_footer = (footer != nullptr ? footer->GetEncodedText() : std::string{});
EncodedString encoded_header = (header != nullptr ? header->GetEncodedText() : EncodedString{});
EncodedString encoded_footer = (footer != nullptr ? footer->GetEncodedText() : EncodedString{});
if (!ScriptObject::Command<CMD_CREATE_LEAGUE_TABLE>::Do(&ScriptInstance::DoCommandReturnLeagueTableID, encoded_title, encoded_header, encoded_footer)) return LEAGUE_TABLE_INVALID;
@ -62,11 +62,11 @@
::CompanyID c = ScriptCompany::FromScriptCompanyID(company);
EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, text != nullptr);
std::string encoded_text = text->GetEncodedText();
EncodedString encoded_text = text->GetEncodedText();
EnforcePreconditionEncodedText(LEAGUE_TABLE_ELEMENT_INVALID, encoded_text);
EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, score != nullptr);
std::string encoded_score = score->GetEncodedText();
EncodedString encoded_score = score->GetEncodedText();
EnforcePreconditionEncodedText(LEAGUE_TABLE_ELEMENT_INVALID, encoded_score);
EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, IsValidLink(Link((::LinkType)link_type, link_target)));
@ -88,7 +88,7 @@
::CompanyID c = ScriptCompany::FromScriptCompanyID(company);
EnforcePrecondition(false, text != nullptr);
std::string encoded_text = text->GetEncodedText();
EncodedString encoded_text = text->GetEncodedText();
EnforcePreconditionEncodedText(false, encoded_text);
EnforcePrecondition(false, IsValidLink(Link((::LinkType)link_type, link_target)));
@ -104,7 +104,7 @@
EnforcePrecondition(false, IsValidLeagueTableElement(element));
EnforcePrecondition(false, score != nullptr);
std::string encoded_score = score->GetEncodedText();
EncodedString encoded_score = score->GetEncodedText();
EnforcePreconditionEncodedText(false, encoded_score);
return ScriptObject::Command<CMD_UPDATE_LEAGUE_TABLE_ELEMENT_SCORE>::Do(element, rating, encoded_score);

View File

@ -38,7 +38,7 @@ static NewsReference CreateReference(ScriptNews::NewsReferenceType ref_type, SQI
EnforceDeityMode(false);
EnforcePrecondition(false, text != nullptr);
std::string encoded = text->GetEncodedText();
EncodedString encoded = text->GetEncodedText();
EnforcePreconditionEncodedText(false, encoded);
EnforcePrecondition(false, type == NT_ECONOMY || type == NT_SUBSIDIES || type == NT_GENERAL);
EnforcePrecondition(false, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID);

View File

@ -53,7 +53,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type)
::CompanyID c = ScriptCompany::FromScriptCompanyID(company);
if (!ScriptObject::Command<CMD_CREATE_STORY_PAGE>::Do(&ScriptInstance::DoCommandReturnStoryPageID,
c, title != nullptr ? title->GetEncodedText() : std::string{})) return STORY_PAGE_INVALID;
c, title != nullptr ? title->GetEncodedText() : EncodedString{})) return STORY_PAGE_INVALID;
/* In case of test-mode, we return StoryPageID 0 */
return StoryPageID::Begin();
@ -68,7 +68,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type)
EnforceDeityMode(STORY_PAGE_ELEMENT_INVALID);
EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, IsValidStoryPage(story_page_id));
EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, IsValidStoryPageElementType(type));
std::string encoded_text;
EncodedString encoded_text;
if (StoryPageElementTypeRequiresText(btype)) {
EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, text != nullptr);
encoded_text = text->GetEncodedText();
@ -117,7 +117,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type)
const StoryPage *p = StoryPage::Get(pe->page);
::StoryPageElementType type = pe->type;
std::string encoded_text;
EncodedString encoded_text;
if (StoryPageElementTypeRequiresText(type)) {
EnforcePrecondition(false, text != nullptr);
encoded_text = text->GetEncodedText();
@ -169,7 +169,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type)
EnforcePrecondition(false, IsValidStoryPage(story_page_id));
EnforceDeityMode(false);
return ScriptObject::Command<CMD_SET_STORY_PAGE_TITLE>::Do(story_page_id, title != nullptr ? title->GetEncodedText() : std::string{});
return ScriptObject::Command<CMD_SET_STORY_PAGE_TITLE>::Do(story_page_id, title != nullptr ? title->GetEncodedText() : EncodedString{});
}
/* static */ ScriptCompany::CompanyID ScriptStoryPage::GetCompany(StoryPageID story_page_id)

View File

@ -153,7 +153,7 @@ SQInteger ScriptText::_set(HSQUIRRELVM vm)
return this->_SetParam(k, vm);
}
std::string ScriptText::GetEncodedText()
EncodedString ScriptText::GetEncodedText()
{
ScriptTextList seen_texts;
ParamList params;
@ -163,7 +163,7 @@ std::string ScriptText::GetEncodedText()
this->_FillParamList(params, seen_texts);
this->_GetEncodedText(output, param_count, params, true);
if (param_count > SCRIPT_TEXT_MAX_PARAMETERS) throw Script_FatalError(fmt::format("{}: Too many parameters", GetGameStringName(this->string)));
return result;
return ::EncodedString{std::move(result)};
}
void ScriptText::_FillParamList(ParamList &params, ScriptTextList &seen_texts)
@ -298,5 +298,5 @@ void ScriptText::_GetEncodedText(std::back_insert_iterator<std::string> &output,
const std::string Text::GetDecodedText()
{
return ::GetString(STR_JUST_RAW_STRING, this->GetEncodedText());
return this->GetEncodedText().GetDecodedString();
}

View File

@ -11,6 +11,7 @@
#define SCRIPT_TEXT_HPP
#include "script_object.hpp"
#include "../../strings_func.h"
#include <variant>
@ -25,7 +26,7 @@ public:
* @return A string.
* @api -all
*/
virtual std::string GetEncodedText() = 0;
virtual EncodedString GetEncodedText() = 0;
/**
* Convert a #ScriptText into a decoded normal string.
@ -43,7 +44,7 @@ class RawText : public Text {
public:
RawText(const std::string &text) : text(text) {}
std::string GetEncodedText() override { return this->text; }
EncodedString GetEncodedText() override { return ::GetEncodedString(STR_JUST_RAW_STRING, this->text); }
private:
const std::string text;
};
@ -124,7 +125,7 @@ public:
/**
* @api -all
*/
std::string GetEncodedText() override;
EncodedString GetEncodedText() override;
private:
using ScriptTextRef = ScriptObjectRef<ScriptText>;

View File

@ -61,7 +61,7 @@
EnforceDeityMode(false);
EnforcePrecondition(false, IsValidTown(town_id));
return ScriptObject::Command<CMD_TOWN_SET_TEXT>::Do(town_id, text != nullptr ? text->GetEncodedText() : std::string{});
return ScriptObject::Command<CMD_TOWN_SET_TEXT>::Do(town_id, text != nullptr ? text->GetEncodedText() : EncodedString{});
}
/* static */ SQInteger ScriptTown::GetPopulation(TownID town_id)

View File

@ -56,7 +56,7 @@ StoryPage::~StoryPage()
* @param text The text parameter of the DoCommand proc
* @return true, if and only if the given parameters are valid for the given page element type and page id.
*/
static bool VerifyElementContentParameters(StoryPageID page_id, StoryPageElementType type, TileIndex tile, uint32_t reference, const std::string &text)
static bool VerifyElementContentParameters(StoryPageID page_id, StoryPageElementType type, TileIndex tile, uint32_t reference, const EncodedString &text)
{
StoryPageButtonData button_data{ reference };
@ -103,7 +103,7 @@ static bool VerifyElementContentParameters(StoryPageID page_id, StoryPageElement
* @param reference The reference parameter of the DoCommand proc (p2)
* @param text The text parameter of the DoCommand proc
*/
static void UpdateElement(StoryPageElement &pe, TileIndex tile, uint32_t reference, const std::string &text)
static void UpdateElement(StoryPageElement &pe, TileIndex tile, uint32_t reference, const EncodedString &text)
{
switch (pe.type) {
case SPET_TEXT:
@ -215,7 +215,7 @@ bool StoryPageButtonData::ValidateVehicleType() const
* @param text Title of the story page. Null is allowed in which case a generic page title is provided by OpenTTD.
* @return the cost of this operation or an error
*/
std::tuple<CommandCost, StoryPageID> CmdCreateStoryPage(DoCommandFlags flags, CompanyID company, const std::string &text)
std::tuple<CommandCost, StoryPageID> CmdCreateStoryPage(DoCommandFlags flags, CompanyID company, const EncodedString &text)
{
if (!StoryPage::CanAllocateItem()) return { CMD_ERROR, StoryPageID::Invalid() };
@ -250,7 +250,7 @@ std::tuple<CommandCost, StoryPageID> CmdCreateStoryPage(DoCommandFlags flags, Co
* @param text Text content in case it is a text or location page element
* @return the cost of this operation or an error
*/
std::tuple<CommandCost, StoryPageElementID> CmdCreateStoryPageElement(DoCommandFlags flags, TileIndex tile, StoryPageID page_id, StoryPageElementType type, uint32_t reference, const std::string &text)
std::tuple<CommandCost, StoryPageElementID> CmdCreateStoryPageElement(DoCommandFlags flags, TileIndex tile, StoryPageID page_id, StoryPageElementType type, uint32_t reference, const EncodedString &text)
{
if (!StoryPageElement::CanAllocateItem()) return { CMD_ERROR, StoryPageElementID::Invalid() };
@ -293,7 +293,7 @@ std::tuple<CommandCost, StoryPageElementID> CmdCreateStoryPageElement(DoCommandF
* @param text Text content in case it is a text or location page element
* @return the cost of this operation or an error
*/
CommandCost CmdUpdateStoryPageElement(DoCommandFlags flags, TileIndex tile, StoryPageElementID page_element_id, uint32_t reference, const std::string &text)
CommandCost CmdUpdateStoryPageElement(DoCommandFlags flags, TileIndex tile, StoryPageElementID page_element_id, uint32_t reference, const EncodedString &text)
{
if (_current_company != OWNER_DEITY) return CMD_ERROR;
if (!StoryPageElement::IsValidID(page_element_id)) return CMD_ERROR;
@ -319,7 +319,7 @@ CommandCost CmdUpdateStoryPageElement(DoCommandFlags flags, TileIndex tile, Stor
* @param text title text of the story page.
* @return the cost of this operation or an error
*/
CommandCost CmdSetStoryPageTitle(DoCommandFlags flags, StoryPageID page_id, const std::string &text)
CommandCost CmdSetStoryPageTitle(DoCommandFlags flags, StoryPageID page_id, const EncodedString &text)
{
if (_current_company != OWNER_DEITY) return CMD_ERROR;
if (!StoryPage::IsValidID(page_id)) return CMD_ERROR;

View File

@ -12,6 +12,7 @@
#include "company_type.h"
#include "story_type.h"
#include "strings_type.h"
#include "timer/timer_game_calendar.h"
#include "gfx_type.h"
#include "vehicle_type.h"
@ -147,7 +148,7 @@ struct StoryPageElement : StoryPageElementPool::PoolItem<&_story_page_element_po
StoryPageElementType type; ///< Type of page element
uint32_t referenced_id; ///< Id of referenced object (location, goal etc.)
std::string text; ///< Static content text of page element
EncodedString text; ///< Static content text of page element
/**
* We need an (empty) constructor so struct isn't zeroed (as C++ standard states)
@ -168,13 +169,13 @@ struct StoryPage : StoryPagePool::PoolItem<&_story_page_pool> {
TimerGameCalendar::Date date{}; ///< Date when the page was created.
CompanyID company = CompanyID::Invalid(); ///< StoryPage is for a specific company; CompanyID::Invalid() if it is global
std::string title; ///< Title of story page
EncodedString title; ///< Title of story page
/**
* We need an (empty) constructor so struct isn't zeroed (as C++ standard states)
*/
StoryPage() { }
StoryPage(uint32_t sort_value, TimerGameCalendar::Date date, CompanyID company, const std::string &title) :
StoryPage(uint32_t sort_value, TimerGameCalendar::Date date, CompanyID company, const EncodedString &title) :
sort_value(sort_value), date(date), company(company), title(title) {}
~StoryPage();

View File

@ -15,10 +15,10 @@
#include "story_type.h"
#include "vehicle_type.h"
std::tuple<CommandCost, StoryPageID> CmdCreateStoryPage(DoCommandFlags flags, CompanyID company, const std::string &text);
std::tuple<CommandCost, StoryPageElementID> CmdCreateStoryPageElement(DoCommandFlags flags, TileIndex tile, StoryPageID page_id, StoryPageElementType type, uint32_t reference, const std::string &text);
CommandCost CmdUpdateStoryPageElement(DoCommandFlags flags, TileIndex tile, StoryPageElementID page_element_id, uint32_t reference, const std::string &text);
CommandCost CmdSetStoryPageTitle(DoCommandFlags flags, StoryPageID page_id, const std::string &text);
std::tuple<CommandCost, StoryPageID> CmdCreateStoryPage(DoCommandFlags flags, CompanyID company, const EncodedString &text);
std::tuple<CommandCost, StoryPageElementID> CmdCreateStoryPageElement(DoCommandFlags flags, TileIndex tile, StoryPageID page_id, StoryPageElementType type, uint32_t reference, const EncodedString &text);
CommandCost CmdUpdateStoryPageElement(DoCommandFlags flags, TileIndex tile, StoryPageElementID page_element_id, uint32_t reference, const EncodedString &text);
CommandCost CmdSetStoryPageTitle(DoCommandFlags flags, StoryPageID page_id, const EncodedString &text);
CommandCost CmdSetStoryPageDate(DoCommandFlags flags, StoryPageID page_id, TimerGameCalendar::Date date);
CommandCost CmdShowStoryPage(DoCommandFlags flags, StoryPageID page_id);
CommandCost CmdRemoveStoryPage(DoCommandFlags flags, StoryPageID page_id);

View File

@ -250,7 +250,7 @@ protected:
for (const StoryPage *p : this->story_pages) {
bool current_page = p->index == this->selected_page_id;
if (!p->title.empty()) {
list.push_back(MakeDropDownListStringItem(GetString(STR_JUST_RAW_STRING, p->title), p->index.base(), current_page));
list.push_back(MakeDropDownListStringItem(p->title.GetDecodedString(), p->index.base(), current_page));
} else {
/* No custom title => use a generic page title with page number. */
list.push_back(MakeDropDownListStringItem(GetString(STR_STORY_BOOK_GENERIC_PAGE_ITEM, page_num), p->index.base(), current_page));
@ -284,7 +284,7 @@ protected:
/* Title lines */
height += GetCharacterHeight(FS_NORMAL); // Date always use exactly one line.
height += GetStringHeight(GetString(STR_STORY_BOOK_TITLE, !page->title.empty() ? page->title : this->selected_generic_title), max_width);
height += GetStringHeight(GetString(STR_STORY_BOOK_TITLE, !page->title.empty() ? page->title.GetDecodedString() : this->selected_generic_title), max_width);
return height;
}
@ -320,7 +320,7 @@ protected:
{
switch (pe.type) {
case SPET_TEXT:
return GetStringHeight(GetString(STR_JUST_RAW_STRING, pe.text), max_width);
return GetStringHeight(pe.text.GetDecodedString(), max_width);
case SPET_GOAL:
case SPET_LOCATION: {
@ -331,7 +331,7 @@ protected:
case SPET_BUTTON_PUSH:
case SPET_BUTTON_TILE:
case SPET_BUTTON_VEHICLE: {
Dimension dim = GetStringBoundingBox(pe.text, FS_NORMAL);
Dimension dim = GetStringBoundingBox(pe.text.GetDecodedString(), FS_NORMAL);
return dim.height + WidgetDimensions::scaled.framerect.Vertical() + WidgetDimensions::scaled.frametext.Vertical();
}
@ -374,7 +374,7 @@ protected:
case SPET_BUTTON_PUSH:
case SPET_BUTTON_TILE:
case SPET_BUTTON_VEHICLE: {
Dimension dim = GetStringBoundingBox(pe.text, FS_NORMAL);
Dimension dim = GetStringBoundingBox(pe.text.GetDecodedString(), FS_NORMAL);
return dim.width + WidgetDimensions::scaled.framerect.Vertical() + WidgetDimensions::scaled.frametext.Vertical();
}
@ -642,8 +642,7 @@ public:
switch (widget) {
case WID_SB_SEL_PAGE: {
const StoryPage *page = this->GetSelPage();
/* Encoded string from game script needs to be formatted. */
return GetString(STR_JUST_RAW_STRING, page != nullptr && !page->title.empty() ? page->title : this->selected_generic_title);
return page != nullptr && !page->title.empty() ? page->title.GetDecodedString() : this->selected_generic_title;
}
case WID_SB_CAPTION:
@ -701,7 +700,7 @@ public:
/* Title */
y_offset = DrawStringMultiLine(0, fr.right, y_offset, fr.bottom,
GetString(STR_STORY_BOOK_TITLE, !page->title.empty() ? page->title : this->selected_generic_title), TC_BLACK, SA_TOP | SA_HOR_CENTER);
GetString(STR_STORY_BOOK_TITLE, !page->title.empty() ? page->title.GetDecodedString() : this->selected_generic_title), TC_BLACK, SA_TOP | SA_HOR_CENTER);
/* Page elements */
this->EnsureStoryPageElementLayout();
@ -714,19 +713,19 @@ public:
switch (ce.pe->type) {
case SPET_TEXT:
y_offset = DrawStringMultiLine(ce.bounds.left, ce.bounds.right, ce.bounds.top - scrollpos, ce.bounds.bottom - scrollpos,
GetString(STR_JUST_RAW_STRING, ce.pe->text), TC_BLACK, SA_TOP | SA_LEFT);
ce.pe->text.GetDecodedString(), TC_BLACK, SA_TOP | SA_LEFT);
break;
case SPET_GOAL: {
Goal *g = Goal::Get((GoalID) ce.pe->referenced_id);
DrawActionElement(y_offset, ce.bounds.right - ce.bounds.left, line_height, GetPageElementSprite(*ce.pe),
g == nullptr ? GetString(STR_STORY_BOOK_INVALID_GOAL_REF) : GetString(STR_JUST_RAW_STRING, g->text));
g == nullptr ? GetString(STR_STORY_BOOK_INVALID_GOAL_REF) : g->text.GetDecodedString());
break;
}
case SPET_LOCATION:
DrawActionElement(y_offset, ce.bounds.right - ce.bounds.left, line_height, GetPageElementSprite(*ce.pe),
GetString(STR_JUST_RAW_STRING, ce.pe->text));
ce.pe->text.GetDecodedString());
break;
case SPET_BUTTON_PUSH:
@ -739,7 +738,7 @@ public:
DrawFrameRect(ce.bounds.left, ce.bounds.top - scrollpos, ce.bounds.right, ce.bounds.bottom - scrollpos - 1, bgcolour, frame);
DrawString(ce.bounds.left + WidgetDimensions::scaled.bevel.left, ce.bounds.right - WidgetDimensions::scaled.bevel.right, ce.bounds.top + tmargin - scrollpos,
GetString(STR_JUST_RAW_STRING, ce.pe->text), TC_WHITE, SA_CENTER);
ce.pe->text.GetDecodedString(), TC_WHITE, SA_CENTER);
break;
}
@ -762,7 +761,7 @@ public:
/* Get max title width. */
for (size_t i = 0; i < this->story_pages.size(); i++) {
const StoryPage *s = this->story_pages[i];
Dimension title_d = GetStringBoundingBox(GetString(STR_JUST_RAW_STRING, s->title.empty() ? this->selected_generic_title : s->title));
Dimension title_d = GetStringBoundingBox(s->title.empty() ? this->selected_generic_title : s->title.GetDecodedString());
if (title_d.width > d.width) {
d.width = title_d.width;

View File

@ -114,6 +114,11 @@ private:
explicit EncodedString(std::string &&string) : string(std::move(string)) {}
friend EncodedString GetEncodedStringWithArgs(StringID str, std::span<const StringParameter> params);
template <typename Tcont, typename Titer>
friend class EndianBufferWriter;
friend class EndianBufferReader;
friend class ScriptText;
};
#endif /* STRINGS_TYPE_H */

View File

@ -658,7 +658,7 @@ static void AddDropDownLeagueTableOptions(DropDownList &list)
{
if (LeagueTable::GetNumItems() > 0) {
for (LeagueTable *lt : LeagueTable::Iterate()) {
list.push_back(MakeDropDownListStringItem(GetString(STR_JUST_RAW_STRING, lt->title), lt->index.base()));
list.push_back(MakeDropDownListStringItem(lt->title.GetDecodedString(), lt->index.base()));
}
} else {
list.push_back(MakeDropDownListStringItem(STR_GRAPH_MENU_COMPANY_LEAGUE_TABLE, LTMN_PERFORMANCE_LEAGUE));

View File

@ -78,7 +78,7 @@ struct Town : TownPool::PoolItem<&_town_pool> {
std::array<TransportedCargoStat<uint16_t>, NUM_TAE> received{}; ///< Cargo statistics about received cargotypes.
std::array<uint32_t, NUM_TAE> goal{}; ///< Amount of cargo required for the town to grow.
std::string text{}; ///< General text with additional information.
EncodedString text{}; ///< General text with additional information.
inline uint8_t GetPercentTransported(CargoType cargo_type) const
{

View File

@ -3115,7 +3115,7 @@ CommandCost CmdTownCargoGoal(DoCommandFlags flags, TownID town_id, TownAcceptanc
* @param text The new text (empty to remove the text).
* @return Empty cost or an error.
*/
CommandCost CmdTownSetText(DoCommandFlags flags, TownID town_id, const std::string &text)
CommandCost CmdTownSetText(DoCommandFlags flags, TownID town_id, const EncodedString &text)
{
if (_current_company != OWNER_DEITY) return CMD_ERROR;
Town *t = Town::GetIfValid(town_id);

View File

@ -24,7 +24,7 @@ CommandCost CmdDoTownAction(DoCommandFlags flags, TownID town_id, TownAction act
CommandCost CmdTownGrowthRate(DoCommandFlags flags, TownID town_id, uint16_t growth_rate);
CommandCost CmdTownRating(DoCommandFlags flags, TownID town_id, CompanyID company_id, int16_t rating);
CommandCost CmdTownCargoGoal(DoCommandFlags flags, TownID town_id, TownAcceptanceEffect tae, uint32_t goal);
CommandCost CmdTownSetText(DoCommandFlags flags, TownID town_id, const std::string &text);
CommandCost CmdTownSetText(DoCommandFlags flags, TownID town_id, const EncodedString &text);
CommandCost CmdExpandTown(DoCommandFlags flags, TownID town_id, uint32_t grow_amount);
CommandCost CmdDeleteTown(DoCommandFlags flags, TownID town_id);
CommandCost CmdPlaceHouse(DoCommandFlags flags, TileIndex tile, HouseID house, bool house_protected);

View File

@ -482,7 +482,7 @@ public:
}
if (!this->town->text.empty()) {
tr.top = DrawStringMultiLine(tr, GetString(STR_JUST_RAW_STRING, this->town->text), TC_BLACK);
tr.top = DrawStringMultiLine(tr, this->town->text.GetDecodedString(), TC_BLACK);
}
}
@ -554,7 +554,7 @@ public:
if (_settings_game.economy.station_noise_level) aimed_height += GetCharacterHeight(FS_NORMAL);
if (!this->town->text.empty()) {
aimed_height += GetStringHeight(GetString(STR_JUST_RAW_STRING, this->town->text), width - WidgetDimensions::scaled.framerect.Horizontal());
aimed_height += GetStringHeight(this->town->text.GetDecodedString(), width - WidgetDimensions::scaled.framerect.Horizontal());
}
return aimed_height;