diff --git a/Source/control.cpp b/Source/control.cpp index abd3a2398..eaf93017e 100644 --- a/Source/control.cpp +++ b/Source/control.cpp @@ -860,7 +860,7 @@ void DrawInfoBox(const Surface &out) auto &myPlayer = Players[MyPlayerId]; if (myPlayer.HoldItem._itype == ItemType::Gold) { int nGold = myPlayer.HoldItem._ivalue; - strcpy(infostr, fmt::format(ngettext("{:d} gold piece", "{:d} gold pieces", nGold), nGold).c_str()); + CopyUtf8(infostr, fmt::format(ngettext("{:d} gold piece", "{:d} gold pieces", nGold), nGold), sizeof(infostr)); } else if (!myPlayer.CanUseItem(myPlayer.HoldItem)) { ClearPanel(); AddPanelString(_("Requirements not met")); diff --git a/Source/inv.cpp b/Source/inv.cpp index a984bb04a..447451200 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -29,6 +29,7 @@ #include "utils/language.h" #include "utils/sdl_geometry.h" #include "utils/stdcompat/optional.hpp" +#include "utils/utf8.hpp" namespace devilution { @@ -1968,7 +1969,7 @@ int8_t CheckInvHLight() if (pi->_itype == ItemType::Gold) { int nGold = pi->_ivalue; - strcpy(infostr, fmt::format(ngettext("{:d} gold piece", "{:d} gold pieces", nGold), nGold).c_str()); + CopyUtf8(infostr, fmt::format(ngettext("{:d} gold piece", "{:d} gold pieces", nGold), nGold), sizeof(infostr)); } else { InfoColor = pi->getTextColor(); if (pi->_iIdentified) { diff --git a/Source/items.cpp b/Source/items.cpp index 2e00af4d6..0c247aee5 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -3614,7 +3614,7 @@ void GetItemStr(Item &item) InfoColor = item.getTextColor(); } else { int nGold = item._ivalue; - strcpy(infostr, fmt::format(ngettext("{:d} gold piece", "{:d} gold pieces", nGold), nGold).c_str()); + CopyUtf8(infostr, fmt::format(ngettext("{:d} gold piece", "{:d} gold pieces", nGold), nGold), sizeof(infostr)); } } diff --git a/Source/objects.cpp b/Source/objects.cpp index fcb36942c..c3636a9c2 100644 --- a/Source/objects.cpp +++ b/Source/objects.cpp @@ -34,6 +34,7 @@ #include "track.h" #include "utils/language.h" #include "utils/log.hpp" +#include "utils/utf8.hpp" namespace devilution { @@ -5456,7 +5457,7 @@ void GetObjectStr(const Object &object) break; case OBJ_SHRINEL: case OBJ_SHRINER: - strcpy(infostr, fmt::format(_(/* TRANSLATORS: {:s} will be a name from the Shrine block above */ "{:s} Shrine"), _(ShrineNames[object._oVar1])).c_str()); + CopyUtf8(infostr, fmt::format(_(/* TRANSLATORS: {:s} will be a name from the Shrine block above */ "{:s} Shrine"), _(ShrineNames[object._oVar1])), sizeof(infostr)); break; case OBJ_SKELBOOK: strcpy(infostr, _("Skeleton Tome")); @@ -5524,12 +5525,12 @@ void GetObjectStr(const Object &object) } if (Players[MyPlayerId]._pClass == HeroClass::Rogue) { if (object._oTrapFlag) { - strcpy(infostr, fmt::format(_(/* TRANSLATORS: {:s} will either be a chest or a door */ "Trapped {:s}"), infostr).c_str()); + CopyUtf8(infostr, fmt::format(_(/* TRANSLATORS: {:s} will either be a chest or a door */ "Trapped {:s}"), infostr), sizeof(infostr)); InfoColor = UiFlags::ColorRed; } } if (object.IsDisabled()) { - strcpy(infostr, fmt::format(_(/* TRANSLATORS: If user enabled diablo.ini setting "Disable Crippling Shrines" is set to 1; also used for Na-Kruls leaver */ "{:s} (disabled)"), infostr).c_str()); + CopyUtf8(infostr, fmt::format(_(/* TRANSLATORS: If user enabled diablo.ini setting "Disable Crippling Shrines" is set to 1; also used for Na-Kruls leaver */ "{:s} (disabled)"), infostr), sizeof(infostr)); InfoColor = UiFlags::ColorRed; } } diff --git a/Source/panels/spell_list.cpp b/Source/panels/spell_list.cpp index 405b1e7c4..5980f9764 100644 --- a/Source/panels/spell_list.cpp +++ b/Source/panels/spell_list.cpp @@ -12,6 +12,7 @@ #include "player.h" #include "spells.h" #include "utils/language.h" +#include "utils/utf8.hpp" #define SPLROWICONLS 10 @@ -159,14 +160,14 @@ void DrawSpellList(const Surface &out) case RSPLTYPE_SKILL: spellColor = PAL16_YELLOW - 46; PrintSBookSpellType(out, spellListItem.location, _("Skill"), spellColor); - strcpy(infostr, fmt::format(_("{:s} Skill"), pgettext("spell", spellDataItem.sSkillText)).c_str()); + CopyUtf8(infostr, fmt::format(_("{:s} Skill"), pgettext("spell", spellDataItem.sSkillText)), sizeof(infostr)); break; case RSPLTYPE_SPELL: if (myPlayer.plrlevel != 0) { spellColor = PAL16_BLUE + 5; } PrintSBookSpellType(out, spellListItem.location, _("Spell"), spellColor); - strcpy(infostr, fmt::format(_("{:s} Spell"), pgettext("spell", spellDataItem.sNameText)).c_str()); + CopyUtf8(infostr, fmt::format(_("{:s} Spell"), pgettext("spell", spellDataItem.sNameText)), sizeof(infostr)); if (spellId == SPL_HBOLT) { AddPanelString(_("Damages undead only")); } @@ -180,7 +181,7 @@ void DrawSpellList(const Surface &out) spellColor = PAL16_RED - 59; } PrintSBookSpellType(out, spellListItem.location, _("Scroll"), spellColor); - strcpy(infostr, fmt::format(_("Scroll of {:s}"), pgettext("spell", spellDataItem.sNameText)).c_str()); + CopyUtf8(infostr, fmt::format(_("Scroll of {:s}"), pgettext("spell", spellDataItem.sNameText)), sizeof(infostr)); const InventoryAndBeltPlayerItemsRange items { myPlayer }; const int scrollCount = std::count_if(items.begin(), items.end(), [spellId](const Item &item) { return item.IsScrollOf(spellId); @@ -192,7 +193,7 @@ void DrawSpellList(const Surface &out) spellColor = PAL16_ORANGE + 5; } PrintSBookSpellType(out, spellListItem.location, _("Staff"), spellColor); - strcpy(infostr, fmt::format(_("Staff of {:s}"), pgettext("spell", spellDataItem.sNameText)).c_str()); + CopyUtf8(infostr, fmt::format(_("Staff of {:s}"), pgettext("spell", spellDataItem.sNameText)), sizeof(infostr)); int charges = myPlayer.InvBody[INVLOC_HAND_LEFT]._iCharges; AddPanelString(fmt::format(ngettext("{:d} Charge", "{:d} Charges", charges), charges)); } break; diff --git a/Source/quests.cpp b/Source/quests.cpp index f7dd4e641..ae5d2dc9c 100644 --- a/Source/quests.cpp +++ b/Source/quests.cpp @@ -25,6 +25,7 @@ #include "towners.h" #include "trigs.h" #include "utils/language.h" +#include "utils/utf8.hpp" namespace devilution { @@ -447,7 +448,7 @@ bool ForceQuests() int ql = quest._qslvl - 1; if (EntranceBoundaryContains(quest.position, cursPosition)) { - strcpy(infostr, fmt::format(_(/* TRANSLATORS: Used for Quest Portals. {:s} is a Map Name */ "To {:s}"), _(QuestTriggerNames[ql])).c_str()); + CopyUtf8(infostr, fmt::format(_(/* TRANSLATORS: Used for Quest Portals. {:s} is a Map Name */ "To {:s}"), _(QuestTriggerNames[ql])), sizeof(infostr)); cursPosition = quest.position; return true; } diff --git a/Source/trigs.cpp b/Source/trigs.cpp index a0056dd78..a840a6768 100644 --- a/Source/trigs.cpp +++ b/Source/trigs.cpp @@ -13,6 +13,7 @@ #include "error.h" #include "init.h" #include "utils/language.h" +#include "utils/utf8.hpp" namespace devilution { @@ -410,7 +411,7 @@ bool ForceL1Trig() for (int i = 0; L1UpList[i] != -1; i++) { if (dPiece[cursPosition.x][cursPosition.y] == L1UpList[i]) { if (currlevel > 1) - strcpy(infostr, fmt::format(_("Up to level {:d}"), currlevel - 1).c_str()); + CopyUtf8(infostr, fmt::format(_("Up to level {:d}"), currlevel - 1), sizeof(infostr)); else strcpy(infostr, _("Up to town")); for (int j = 0; j < numtrigs; j++) { @@ -423,7 +424,7 @@ bool ForceL1Trig() } for (int i = 0; L1DownList[i] != -1; i++) { if (dPiece[cursPosition.x][cursPosition.y] == L1DownList[i]) { - strcpy(infostr, fmt::format(_("Down to level {:d}"), currlevel + 1).c_str()); + CopyUtf8(infostr, fmt::format(_("Down to level {:d}"), currlevel + 1), sizeof(infostr)); for (int j = 0; j < numtrigs; j++) { if (trigs[j]._tmsg == WM_DIABNEXTLVL) { cursPosition = trigs[j].position; @@ -435,7 +436,7 @@ bool ForceL1Trig() } else { for (int i = 0; L5UpList[i] != -1; i++) { if (dPiece[cursPosition.x][cursPosition.y] == L5UpList[i]) { - strcpy(infostr, fmt::format(_("Up to Crypt level {:d}"), currlevel - 21).c_str()); + CopyUtf8(infostr, fmt::format(_("Up to Crypt level {:d}"), currlevel - 21), sizeof(infostr)); for (int j = 0; j < numtrigs; j++) { if (trigs[j]._tmsg == WM_DIABPREVLVL) { cursPosition = trigs[j].position; @@ -450,7 +451,7 @@ bool ForceL1Trig() } for (int i = 0; L5DownList[i] != -1; i++) { if (dPiece[cursPosition.x][cursPosition.y] == L5DownList[i]) { - strcpy(infostr, fmt::format(_("Down to Crypt level {:d}"), currlevel - 19).c_str()); + CopyUtf8(infostr, fmt::format(_("Down to Crypt level {:d}"), currlevel - 19), sizeof(infostr)); for (int j = 0; j < numtrigs; j++) { if (trigs[j]._tmsg == WM_DIABNEXTLVL) { cursPosition = trigs[j].position; @@ -490,7 +491,7 @@ bool ForceL2Trig() int dx = abs(trigs[j].position.x - cursPosition.x); int dy = abs(trigs[j].position.y - cursPosition.y); if (dx < 4 && dy < 4) { - strcpy(infostr, fmt::format(_("Up to level {:d}"), currlevel - 1).c_str()); + CopyUtf8(infostr, fmt::format(_("Up to level {:d}"), currlevel - 1), sizeof(infostr)); cursPosition = trigs[j].position; return true; } @@ -501,7 +502,7 @@ bool ForceL2Trig() for (int i = 0; L2DownList[i] != -1; i++) { if (dPiece[cursPosition.x][cursPosition.y] == L2DownList[i]) { - strcpy(infostr, fmt::format(_("Down to level {:d}"), currlevel + 1).c_str()); + CopyUtf8(infostr, fmt::format(_("Down to level {:d}"), currlevel + 1), sizeof(infostr)); for (int j = 0; j < numtrigs; j++) { if (trigs[j]._tmsg == WM_DIABNEXTLVL) { cursPosition = trigs[j].position; @@ -537,7 +538,7 @@ bool ForceL3Trig() if (currlevel < 17) { for (int i = 0; L3UpList[i] != -1; ++i) { if (dPiece[cursPosition.x][cursPosition.y] == L3UpList[i]) { - strcpy(infostr, fmt::format(_("Up to level {:d}"), currlevel - 1).c_str()); + CopyUtf8(infostr, fmt::format(_("Up to level {:d}"), currlevel - 1), sizeof(infostr)); for (int j = 0; j < numtrigs; j++) { if (trigs[j]._tmsg == WM_DIABPREVLVL) { int dx = abs(trigs[j].position.x - cursPosition.x); @@ -554,7 +555,7 @@ bool ForceL3Trig() if (dPiece[cursPosition.x][cursPosition.y] == L3DownList[i] || dPiece[cursPosition.x + 1][cursPosition.y] == L3DownList[i] || dPiece[cursPosition.x + 2][cursPosition.y] == L3DownList[i]) { - strcpy(infostr, fmt::format(_("Down to level {:d}"), currlevel + 1).c_str()); + CopyUtf8(infostr, fmt::format(_("Down to level {:d}"), currlevel + 1), sizeof(infostr)); for (int j = 0; j < numtrigs; j++) { if (trigs[j]._tmsg == WM_DIABNEXTLVL) { cursPosition = trigs[j].position; @@ -566,7 +567,7 @@ bool ForceL3Trig() } else { for (int i = 0; L6UpList[i] != -1; ++i) { if (dPiece[cursPosition.x][cursPosition.y] == L6UpList[i]) { - strcpy(infostr, fmt::format(_("Up to Nest level {:d}"), currlevel - 17).c_str()); + CopyUtf8(infostr, fmt::format(_("Up to Nest level {:d}"), currlevel - 17), sizeof(infostr)); for (int j = 0; j < numtrigs; j++) { if (trigs[j]._tmsg == WM_DIABPREVLVL) { cursPosition = trigs[j].position; @@ -579,7 +580,7 @@ bool ForceL3Trig() if (dPiece[cursPosition.x][cursPosition.y] == L6DownList[i] || dPiece[cursPosition.x + 1][cursPosition.y] == L6DownList[i] || dPiece[cursPosition.x + 2][cursPosition.y] == L6DownList[i]) { - strcpy(infostr, fmt::format(_("Down to level {:d}"), currlevel - 15).c_str()); + CopyUtf8(infostr, fmt::format(_("Down to level {:d}"), currlevel - 15), sizeof(infostr)); for (int j = 0; j < numtrigs; j++) { if (trigs[j]._tmsg == WM_DIABNEXTLVL) { cursPosition = trigs[j].position; @@ -632,7 +633,7 @@ bool ForceL4Trig() { for (int i = 0; L4UpList[i] != -1; ++i) { if (dPiece[cursPosition.x][cursPosition.y] == L4UpList[i]) { - strcpy(infostr, fmt::format(_("Up to level {:d}"), currlevel - 1).c_str()); + CopyUtf8(infostr, fmt::format(_("Up to level {:d}"), currlevel - 1), sizeof(infostr)); for (int j = 0; j < numtrigs; j++) { if (trigs[j]._tmsg == WM_DIABPREVLVL) { cursPosition = trigs[j].position; @@ -644,7 +645,7 @@ bool ForceL4Trig() for (int i = 0; L4DownList[i] != -1; i++) { if (dPiece[cursPosition.x][cursPosition.y] == L4DownList[i]) { - strcpy(infostr, fmt::format(_("Down to level {:d}"), currlevel + 1).c_str()); + CopyUtf8(infostr, fmt::format(_("Down to level {:d}"), currlevel + 1), sizeof(infostr)); for (int j = 0; j < numtrigs; j++) { if (trigs[j]._tmsg == WM_DIABNEXTLVL) { cursPosition = trigs[j].position; @@ -708,7 +709,7 @@ bool ForceSKingTrig() { for (int i = 0; L1UpList[i] != -1; i++) { if (dPiece[cursPosition.x][cursPosition.y] == L1UpList[i]) { - strcpy(infostr, fmt::format(_("Back to Level {:d}"), Quests[Q_SKELKING]._qlevel).c_str()); + CopyUtf8(infostr, fmt::format(_("Back to Level {:d}"), Quests[Q_SKELKING]._qlevel), sizeof(infostr)); cursPosition = trigs[0].position; return true; @@ -722,7 +723,7 @@ bool ForceSChambTrig() { for (int i = 0; L2DownList[i] != -1; i++) { if (dPiece[cursPosition.x][cursPosition.y] == L2DownList[i]) { - strcpy(infostr, fmt::format(_("Back to Level {:d}"), Quests[Q_SCHAMB]._qlevel).c_str()); + CopyUtf8(infostr, fmt::format(_("Back to Level {:d}"), Quests[Q_SCHAMB]._qlevel), sizeof(infostr)); cursPosition = trigs[0].position; return true; @@ -736,7 +737,7 @@ bool ForcePWaterTrig() { for (int i = 0; L3DownList[i] != -1; i++) { if (dPiece[cursPosition.x][cursPosition.y] == L3DownList[i]) { - strcpy(infostr, fmt::format(_("Back to Level {:d}"), Quests[Q_PWATER]._qlevel).c_str()); + CopyUtf8(infostr, fmt::format(_("Back to Level {:d}"), Quests[Q_PWATER]._qlevel), sizeof(infostr)); cursPosition = trigs[0].position; return true;