From 3443cb26327c04b5fea1fea9fe4b546f33a9d36b Mon Sep 17 00:00:00 2001 From: morfidon <57798071+morfidon@users.noreply.github.com> Date: Tue, 10 Mar 2026 14:05:30 +0100 Subject: [PATCH 1/8] Extract shared identify-all item helpers --- Source/items.cpp | 31 +++++++++++++++++++++++++++++++ Source/items.h | 3 +++ Source/objects.cpp | 8 +------- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/Source/items.cpp b/Source/items.cpp index 2f6ce462c..7cacdbc06 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -3816,6 +3816,37 @@ void GetItemStr(Item &item) } } +bool IsItemIdentifiableByStoryteller(const Item &item) +{ + if (item.isEmpty()) { + return false; + } + if (item._iMagical == ITEM_QUALITY_NORMAL) { + return false; + } + return !item._iIdentified; +} + +int CountIdentifiablePlayerItems(const Player &player) +{ + return static_cast(std::count_if(PlayerItemsRange { player }.begin(), PlayerItemsRange { player }.end(), [](const Item &item) { + return IsItemIdentifiableByStoryteller(item); + })); +} + +int IdentifyPlayerItems(Player &player) +{ + const int identifiedItemCount = static_cast(std::count_if(PlayerItemsRange { player }.begin(), PlayerItemsRange { player }.end(), [](Item &item) { + if (!IsItemIdentifiableByStoryteller(item)) { + return false; + } + item._iIdentified = true; + return true; + })); + CalcPlrInv(player, true); + return identifiedItemCount; +} + void CheckIdentify(Player &player, int cii) { Item *pi; diff --git a/Source/items.h b/Source/items.h index 9c855a405..3695fe0c7 100644 --- a/Source/items.h +++ b/Source/items.h @@ -545,6 +545,9 @@ void ProcessItems(); void FreeItemGFX(); void GetItemFrm(Item &item); void GetItemStr(Item &item); +bool IsItemIdentifiableByStoryteller(const Item &item); +int CountIdentifiablePlayerItems(const Player &player); +int IdentifyPlayerItems(Player &player); void CheckIdentify(Player &player, int cii); void DoRepair(Player &player, int cii); void DoRecharge(Player &player, int cii); diff --git a/Source/objects.cpp b/Source/objects.cpp index b489fa3d7..54c7d342e 100644 --- a/Source/objects.cpp +++ b/Source/objects.cpp @@ -2745,13 +2745,7 @@ void OperateShrineGlimmering(Player &player) if (&player != MyPlayer) return; - for (Item &item : PlayerItemsRange { player }) { - if (item._iMagical != ITEM_QUALITY_NORMAL && !item._iIdentified) { - item._iIdentified = true; - } - } - - CalcPlrInv(player, true); + IdentifyPlayerItems(player); RedrawEverything(); InitDiabloMsg(EMSG_SHRINE_GLIMMERING); From 289325ced42f0ac2abe8bfd89e3192bf3c951456 Mon Sep 17 00:00:00 2001 From: morfidon <57798071+morfidon@users.noreply.github.com> Date: Tue, 10 Mar 2026 14:05:34 +0100 Subject: [PATCH 2/8] Add Cain identify all option --- Source/stores.cpp | 58 +++++++++++++++++++++++++++++++++++++++++------ Source/stores.h | 1 + 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/Source/stores.cpp b/Source/stores.cpp index bd5cb919f..c53698043 100644 --- a/Source/stores.cpp +++ b/Source/stores.cpp @@ -903,6 +903,15 @@ void StoreConfirm(Item &item) HasScrollbar = false; ClearSText(5, 23); + if (OldActiveStore == TalkID::StorytellerIdentifyAll) { + AddSText(0, 10, _("Identify all items?"), UiFlags::ColorWhite | UiFlags::AlignCenter, false); + AddSText(0, 12, fmt::format(fmt::runtime(_("Cost: {:s} gold")), FormatInteger(item._iIvalue)), UiFlags::ColorWhitegold | UiFlags::AlignCenter, false); + AddSText(0, 15, _("Are you sure you want to identify all items?"), UiFlags::ColorWhite | UiFlags::AlignCenter, false); + AddSText(0, 18, _("Yes"), UiFlags::ColorWhite | UiFlags::AlignCenter, true); + AddSText(0, 20, _("No"), UiFlags::ColorWhite | UiFlags::AlignCenter, true); + return; + } + const UiFlags itemColor = item.getTextColorWithStatCheck(); AddSText(20, 8, item.getName(), itemColor, false); AddSTextVal(8, item._iIvalue); @@ -917,6 +926,9 @@ void StoreConfirm(Item &item) case TalkID::StorytellerIdentify: prompt = _("Are you sure you want to identify this item?"); break; + case TalkID::StorytellerIdentifyAll: + prompt = _("Are you sure you want to identify all items?"); + break; case TalkID::HealerBuy: case TalkID::SmithPremiumBuy: case TalkID::WitchBuy: @@ -1050,19 +1062,14 @@ void StartStoryteller() AddSText(0, 9, _("Would you like to:"), UiFlags::ColorWhitegold | UiFlags::AlignCenter, false); AddSText(0, 12, _("Talk to Cain"), UiFlags::ColorBlue | UiFlags::AlignCenter, true); AddSText(0, 14, _("Identify an item"), UiFlags::ColorWhite | UiFlags::AlignCenter, true); + AddSText(0, 16, _("Identify all items"), UiFlags::ColorWhite | UiFlags::AlignCenter, true); AddSText(0, 18, _("Say goodbye"), UiFlags::ColorWhite | UiFlags::AlignCenter, true); AddSLine(5); } bool IdItemOk(Item *i) { - if (i->isEmpty()) { - return false; - } - if (i->_iMagical == ITEM_QUALITY_NORMAL) { - return false; - } - return !i->_iIdentified; + return IsItemIdentifiableByStoryteller(*i); } void AddStoreHoldId(Item itm, int8_t i) @@ -1174,6 +1181,13 @@ void StartStorytellerIdentifyShow(Item &item) AddSText(0, 18, _("Done"), UiFlags::ColorWhite | UiFlags::AlignCenter, true); } +void StorytellerIdentifyAllItems() +{ + Player &myPlayer = *MyPlayer; + TakePlrsMoney(CountIdentifiablePlayerItems(myPlayer) * 100); + IdentifyPlayerItems(myPlayer); +} + void StartTalk() { int la; @@ -1779,6 +1793,11 @@ void ConfirmEnter(Item &item) StorytellerIdentifyItem(item); StartStore(TalkID::StorytellerIdentifyShow); return; + case TalkID::StorytellerIdentifyAll: + StorytellerIdentifyAllItems(); + StartStore(TalkID::Storyteller); + CurrentTextLine = 16; + return; case TalkID::SmithPremiumBuy: SmithBuyPItem(item); break; @@ -1858,6 +1877,22 @@ void StorytellerEnter() case 14: StartStore(TalkID::StorytellerIdentify); break; + case 16: + OldActiveStore = TalkID::StorytellerIdentifyAll; + OldTextLine = 16; + OldScrollPos = 0; + TempItem.clear(); + TempItem._iIvalue = CountIdentifiablePlayerItems(*MyPlayer) * 100; + if (TempItem._iIvalue == 0) { + StartStore(TalkID::StorytellerIdentify); + return; + } + if (!PlayerCanAfford(TempItem._iIvalue)) { + StartStore(TalkID::NoMoney); + return; + } + StartStore(TalkID::Confirm); + return; case 18: ActiveStore = TalkID::None; break; @@ -2293,6 +2328,8 @@ void StartStore(TalkID s) case TalkID::StorytellerIdentify: StartStorytellerIdentify(); break; + case TalkID::StorytellerIdentifyAll: + break; case TalkID::SmithPremiumBuy: if (!StartSmithPremiumBuy()) return; @@ -2438,6 +2475,10 @@ void StoreESC() StartStore(TalkID::Storyteller); CurrentTextLine = 14; break; + case TalkID::StorytellerIdentifyAll: + StartStore(TalkID::Storyteller); + CurrentTextLine = 16; + break; case TalkID::StorytellerIdentifyShow: StartStore(TalkID::StorytellerIdentify); break; @@ -2635,6 +2676,9 @@ void StoreEnter() case TalkID::StorytellerIdentify: StorytellerIdentifyEnter(); break; + case TalkID::StorytellerIdentifyAll: + StartStore(TalkID::Confirm); + break; case TalkID::Gossip: TalkEnter(); break; diff --git a/Source/stores.h b/Source/stores.h index fc38e00db..86b60adce 100644 --- a/Source/stores.h +++ b/Source/stores.h @@ -54,6 +54,7 @@ enum class TalkID : uint8_t { Storyteller, HealerBuy, StorytellerIdentify, + StorytellerIdentifyAll, SmithPremiumBuy, Gossip, StorytellerIdentifyShow, From fd3d7f28ff80a4c029adf528989d418642d3621a Mon Sep 17 00:00:00 2001 From: morfidon <57798071+morfidon@users.noreply.github.com> Date: Tue, 10 Mar 2026 14:12:07 +0100 Subject: [PATCH 3/8] clang formatting fix --- Source/items.cpp | 34 +++++++++++++++++----------------- Source/items.h | 4 ++-- Source/objects.cpp | 20 ++++++++++---------- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/Source/items.cpp b/Source/items.cpp index 7cacdbc06..b7b9ad4eb 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -442,7 +442,7 @@ bool ItemPlace(Point position) Point GetRandomAvailableItemPosition() { - Point position = {}; + Point position = { }; do { position = Point { GenerateRnd(80), GenerateRnd(80) } + Displacement { 16, 16 }; } while (!ItemPlace(position)); @@ -1950,7 +1950,7 @@ void SpawnOnePremium(Item &premiumItem, int plvl, const Player &player) const int maxCount = 150; const bool unlimited = !gbIsHellfire; // TODO: This could lead to an infinite loop if a suitable item can never be generated for (int count = 0; unlimited || count < maxCount; count++) { - premiumItem = {}; + premiumItem = { }; premiumItem._iSeed = AdvanceRndSeed(); SetRndSeed(premiumItem._iSeed); const _item_indexes itemType = RndPremiumItem(player, plvl / 4, plvl); @@ -2177,7 +2177,7 @@ void CreateMagicItem(Point position, int lvl, ItemType itemType, int imid, int i _item_indexes idx = RndTypeItems(itemType, imid, lvl); while (true) { - item = {}; + item = { }; SetupAllItems(*MyPlayer, item, idx, AdvanceRndSeed(), 2 * lvl, 1, true, delta); TryRandomUniqueItem(item, idx, 2 * lvl, 1, true, delta); SetupItem(item); @@ -2919,7 +2919,7 @@ void InitializeItem(Item &item, _item_indexes itemData) auto &pAllItem = AllItemsList[static_cast(itemData)]; // zero-initialize struct - item = {}; + item = { }; item._itype = pAllItem.itype; item._iCurs = pAllItem.iCurs; @@ -3080,7 +3080,7 @@ int AllocateItem() const int inum = ActiveItems[ActiveItemCount]; ActiveItemCount++; - Items[inum] = {}; + Items[inum] = { }; return inum; } @@ -3333,7 +3333,7 @@ void TryRandomUniqueItem(Item &item, _item_indexes idx, int8_t mLevel, int uper, // Force generate a non-unique item. DiabloGenerator itemGenerator(item._iSeed); do { - item = {}; // Reset item data + item = { }; // Reset item data item.position = itemPos; SetupAllItems(*MyPlayer, item, idx, itemGenerator.advanceRndSeed(), mLevel, uper, onlygood, pregen); } while (item._iMagical == ITEM_QUALITY_UNIQUE); @@ -3384,7 +3384,7 @@ void TryRandomUniqueItem(Item &item, _item_indexes idx, int8_t mLevel, int uper, // Force generate items until we find a uid match. DiabloGenerator itemGenerator(item._iSeed); do { - item = {}; // Reset item data + item = { }; // Reset item data item.position = itemPos; // Set onlygood = true, to always get the required item base level for the unique. SetupAllItems(*MyPlayer, item, idx, itemGenerator.advanceRndSeed(), targetLvl, uper, true, pregen); @@ -3392,7 +3392,7 @@ void TryRandomUniqueItem(Item &item, _item_indexes idx, int8_t mLevel, int uper, } else { // Recreate the item with new offset, this creates the desired unique item but is not reverse compatible. const int seed = item._iSeed; - item = {}; // Reset item data + item = { }; // Reset item data item.position = itemPos; SetupAllItems(*MyPlayer, item, idx, seed, mLevel, uper, onlygood, pregen, uidOffset); item.dwBuff |= (uidOffset << 1) & CF_UIDOFFSET; @@ -4034,13 +4034,13 @@ bool DoOil(Player &player, int cii) return _(/*xgettext:no-c-format*/ "hit steals 3% mana"); if (HasAnyOf(item._iFlags, ItemSpecialEffect::StealMana5)) return _(/*xgettext:no-c-format*/ "hit steals 5% mana"); - return {}; + return { }; case IPL_STEALLIFE: if (HasAnyOf(item._iFlags, ItemSpecialEffect::StealLife3)) return _(/*xgettext:no-c-format*/ "hit steals 3% life"); if (HasAnyOf(item._iFlags, ItemSpecialEffect::StealLife5)) return _(/*xgettext:no-c-format*/ "hit steals 5% life"); - return {}; + return { }; case IPL_TARGAC: return _("penetrates target's armor"); case IPL_FASTATTACK: @@ -4427,7 +4427,7 @@ void SpawnSmith(int lvl) while (SmithItems.size() < iCnt) { Item newItem; do { - newItem = {}; + newItem = { }; newItem._iSeed = AdvanceRndSeed(); SetRndSeed(newItem._iSeed); const _item_indexes itemData = RndSmithItem(*MyPlayer, lvl); @@ -4457,7 +4457,7 @@ void SpawnPremium(const Player &player) while (PremiumItems.size() < maxItems) { int plvl = PremiumItemLevel + (gbIsHellfire ? itemLevelAddHf[PremiumItems.size()] : itemLevelAdd[PremiumItems.size()]); - Item item = {}; + Item item = { }; SpawnOnePremium(item, plvl, player); PremiumItems.push_back(item); } @@ -4495,7 +4495,7 @@ void SpawnWitch(int lvl) WitchItems.clear(); for (int i = 0; i < itemCount; i++) { - Item item = {}; + Item item = { }; if (i < PinnedItemCount) { item._iSeed = AdvanceRndSeed(); @@ -4524,7 +4524,7 @@ void SpawnWitch(int lvl) } do { - item = {}; + item = { }; item._iSeed = AdvanceRndSeed(); SetRndSeed(item._iSeed); const _item_indexes itemData = RndWitchItem(*MyPlayer, lvl); @@ -4567,7 +4567,7 @@ void SpawnBoy(int lvl) return; do { keepgoing = false; - BoyItem = {}; + BoyItem = { }; BoyItem._iSeed = AdvanceRndSeed(); SetRndSeed(BoyItem._iSeed); const _item_indexes itype = RndBoyItem(*MyPlayer, lvl); @@ -4671,7 +4671,7 @@ void SpawnHealer(int lvl) HealerItems.clear(); for (size_t i = 0; i < itemCount; i++) { - Item item = {}; + Item item = { }; if (i < PinnedItemCount || (gbIsMultiplayer && i < NumHealerPinnedItemsMp)) { item._iSeed = AdvanceRndSeed(); @@ -4731,7 +4731,7 @@ void CreateSpellBook(Point position, SpellID ispell, bool sendmsg, bool delta) auto &item = Items[ii]; while (true) { - item = {}; + item = { }; SetupAllItems(*MyPlayer, item, idx, AdvanceRndSeed(), 2 * lvl, 1, true, delta); SetupItem(item); if (item._iMiscId == IMISC_BOOK && item._iSpell == ispell) diff --git a/Source/items.h b/Source/items.h index 3695fe0c7..fb343f8b5 100644 --- a/Source/items.h +++ b/Source/items.h @@ -201,8 +201,8 @@ struct Item { bool _iPostDraw = false; bool _iIdentified = false; item_quality _iMagical = ITEM_QUALITY_NORMAL; - char _iName[ItemNameLength] = {}; - char _iIName[ItemNameLength] = {}; + char _iName[ItemNameLength] = { }; + char _iIName[ItemNameLength] = { }; item_equip_type _iLoc = ILOC_NONE; item_class _iClass = ICLASS_NONE; uint8_t _iCurs = 0; diff --git a/Source/objects.cpp b/Source/objects.cpp index 54c7d342e..b202a0a5c 100644 --- a/Source/objects.cpp +++ b/Source/objects.cpp @@ -308,7 +308,7 @@ std::optional GetRandomObjectPosition(Displacement standoff) if (CanPlaceRandomObject(position, standoff)) return position; } - return {}; + return { }; } void InitRndLocObj5x5(int min, int max, _object_id objtype) @@ -325,7 +325,7 @@ void InitRndLocObj5x5(int min, int max, _object_id objtype) void ClrAllObjects() { for (Object &object : Objects) { - object = {}; + object = { }; } ActiveObjectCount = 0; for (int i = 0; i < MAXOBJECTS; i++) { @@ -556,7 +556,7 @@ void AddChestTraps() } } -void LoadMapObjects(const char *path, Point start, WorldTileRectangle mapRange = {}, int leveridx = 0) +void LoadMapObjects(const char *path, Point start, WorldTileRectangle mapRange = { }, int leveridx = 0) { LoadingMapObjects = true; @@ -1269,7 +1269,7 @@ void AddObjectLight(Object &object) return; } - DoLighting(object.position, radius, {}); + DoLighting(object.position, radius, { }); if (LoadingMapObjects) { DoUnLight(object.position, radius); UpdateLighting = true; @@ -1300,7 +1300,7 @@ void AddShrine(Object &shrine) shrine._oPreFlag = true; const int shrineCount = gbIsHellfire ? NumberOfShrineTypes : 26; - bool slist[NumberOfShrineTypes] = {}; + bool slist[NumberOfShrineTypes] = { }; for (int i = 0; i < shrineCount; i++) { bool isShrineAvailable = true; @@ -1846,7 +1846,7 @@ void OperateBook(Player &player, Object &book, bool sendmsg) } if (setlevel && setlvlnum == SL_VILEBETRAYER) { - Point target {}; + Point target { }; if (book.position == Point { 26, 45 }) { target = { 27, 29 }; } else if (book.position == Point { 45, 46 }) { @@ -3677,7 +3677,7 @@ bool IsItemBlockingObjectAtPosition(Point position) tl::expected LoadLevelObjects(uint16_t filesWidths[65]) { if (HeadlessMode) - return {}; + return { }; for (const ObjectData objectData : AllObjects) { if (leveltype == objectData.olvltype) { @@ -3696,12 +3696,12 @@ tl::expected LoadLevelObjects(uint16_t filesWidths[65]) ASSIGN_OR_RETURN(pObjCels[numobjfiles], LoadCelWithStatus(filestr, filesWidths[i])); numobjfiles++; } - return {}; + return { }; } tl::expected InitObjectGFX() { - uint16_t filesWidths[65] = {}; + uint16_t filesWidths[65] = { }; if (IsAnyOf(currlevel, 4, 8, 12)) { for (const auto id : { OBJ_STORYBOOK, OBJ_STORYCANDLE }) { @@ -3964,7 +3964,7 @@ void InitObjects() void SetMapObjects(const uint16_t *dunData, int startx, int starty) { - uint16_t filesWidths[65] = {}; + uint16_t filesWidths[65] = { }; ClrAllObjects(); From fc07014b1c653524b7977ad11d807b00659c3ace Mon Sep 17 00:00:00 2001 From: morfidon <57798071+morfidon@users.noreply.github.com> Date: Tue, 10 Mar 2026 14:15:05 +0100 Subject: [PATCH 4/8] Revert "clang formatting fix" This reverts commit fd3d7f28ff80a4c029adf528989d418642d3621a. --- Source/items.cpp | 34 +++++++++++++++++----------------- Source/items.h | 4 ++-- Source/objects.cpp | 20 ++++++++++---------- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/Source/items.cpp b/Source/items.cpp index b7b9ad4eb..7cacdbc06 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -442,7 +442,7 @@ bool ItemPlace(Point position) Point GetRandomAvailableItemPosition() { - Point position = { }; + Point position = {}; do { position = Point { GenerateRnd(80), GenerateRnd(80) } + Displacement { 16, 16 }; } while (!ItemPlace(position)); @@ -1950,7 +1950,7 @@ void SpawnOnePremium(Item &premiumItem, int plvl, const Player &player) const int maxCount = 150; const bool unlimited = !gbIsHellfire; // TODO: This could lead to an infinite loop if a suitable item can never be generated for (int count = 0; unlimited || count < maxCount; count++) { - premiumItem = { }; + premiumItem = {}; premiumItem._iSeed = AdvanceRndSeed(); SetRndSeed(premiumItem._iSeed); const _item_indexes itemType = RndPremiumItem(player, plvl / 4, plvl); @@ -2177,7 +2177,7 @@ void CreateMagicItem(Point position, int lvl, ItemType itemType, int imid, int i _item_indexes idx = RndTypeItems(itemType, imid, lvl); while (true) { - item = { }; + item = {}; SetupAllItems(*MyPlayer, item, idx, AdvanceRndSeed(), 2 * lvl, 1, true, delta); TryRandomUniqueItem(item, idx, 2 * lvl, 1, true, delta); SetupItem(item); @@ -2919,7 +2919,7 @@ void InitializeItem(Item &item, _item_indexes itemData) auto &pAllItem = AllItemsList[static_cast(itemData)]; // zero-initialize struct - item = { }; + item = {}; item._itype = pAllItem.itype; item._iCurs = pAllItem.iCurs; @@ -3080,7 +3080,7 @@ int AllocateItem() const int inum = ActiveItems[ActiveItemCount]; ActiveItemCount++; - Items[inum] = { }; + Items[inum] = {}; return inum; } @@ -3333,7 +3333,7 @@ void TryRandomUniqueItem(Item &item, _item_indexes idx, int8_t mLevel, int uper, // Force generate a non-unique item. DiabloGenerator itemGenerator(item._iSeed); do { - item = { }; // Reset item data + item = {}; // Reset item data item.position = itemPos; SetupAllItems(*MyPlayer, item, idx, itemGenerator.advanceRndSeed(), mLevel, uper, onlygood, pregen); } while (item._iMagical == ITEM_QUALITY_UNIQUE); @@ -3384,7 +3384,7 @@ void TryRandomUniqueItem(Item &item, _item_indexes idx, int8_t mLevel, int uper, // Force generate items until we find a uid match. DiabloGenerator itemGenerator(item._iSeed); do { - item = { }; // Reset item data + item = {}; // Reset item data item.position = itemPos; // Set onlygood = true, to always get the required item base level for the unique. SetupAllItems(*MyPlayer, item, idx, itemGenerator.advanceRndSeed(), targetLvl, uper, true, pregen); @@ -3392,7 +3392,7 @@ void TryRandomUniqueItem(Item &item, _item_indexes idx, int8_t mLevel, int uper, } else { // Recreate the item with new offset, this creates the desired unique item but is not reverse compatible. const int seed = item._iSeed; - item = { }; // Reset item data + item = {}; // Reset item data item.position = itemPos; SetupAllItems(*MyPlayer, item, idx, seed, mLevel, uper, onlygood, pregen, uidOffset); item.dwBuff |= (uidOffset << 1) & CF_UIDOFFSET; @@ -4034,13 +4034,13 @@ bool DoOil(Player &player, int cii) return _(/*xgettext:no-c-format*/ "hit steals 3% mana"); if (HasAnyOf(item._iFlags, ItemSpecialEffect::StealMana5)) return _(/*xgettext:no-c-format*/ "hit steals 5% mana"); - return { }; + return {}; case IPL_STEALLIFE: if (HasAnyOf(item._iFlags, ItemSpecialEffect::StealLife3)) return _(/*xgettext:no-c-format*/ "hit steals 3% life"); if (HasAnyOf(item._iFlags, ItemSpecialEffect::StealLife5)) return _(/*xgettext:no-c-format*/ "hit steals 5% life"); - return { }; + return {}; case IPL_TARGAC: return _("penetrates target's armor"); case IPL_FASTATTACK: @@ -4427,7 +4427,7 @@ void SpawnSmith(int lvl) while (SmithItems.size() < iCnt) { Item newItem; do { - newItem = { }; + newItem = {}; newItem._iSeed = AdvanceRndSeed(); SetRndSeed(newItem._iSeed); const _item_indexes itemData = RndSmithItem(*MyPlayer, lvl); @@ -4457,7 +4457,7 @@ void SpawnPremium(const Player &player) while (PremiumItems.size() < maxItems) { int plvl = PremiumItemLevel + (gbIsHellfire ? itemLevelAddHf[PremiumItems.size()] : itemLevelAdd[PremiumItems.size()]); - Item item = { }; + Item item = {}; SpawnOnePremium(item, plvl, player); PremiumItems.push_back(item); } @@ -4495,7 +4495,7 @@ void SpawnWitch(int lvl) WitchItems.clear(); for (int i = 0; i < itemCount; i++) { - Item item = { }; + Item item = {}; if (i < PinnedItemCount) { item._iSeed = AdvanceRndSeed(); @@ -4524,7 +4524,7 @@ void SpawnWitch(int lvl) } do { - item = { }; + item = {}; item._iSeed = AdvanceRndSeed(); SetRndSeed(item._iSeed); const _item_indexes itemData = RndWitchItem(*MyPlayer, lvl); @@ -4567,7 +4567,7 @@ void SpawnBoy(int lvl) return; do { keepgoing = false; - BoyItem = { }; + BoyItem = {}; BoyItem._iSeed = AdvanceRndSeed(); SetRndSeed(BoyItem._iSeed); const _item_indexes itype = RndBoyItem(*MyPlayer, lvl); @@ -4671,7 +4671,7 @@ void SpawnHealer(int lvl) HealerItems.clear(); for (size_t i = 0; i < itemCount; i++) { - Item item = { }; + Item item = {}; if (i < PinnedItemCount || (gbIsMultiplayer && i < NumHealerPinnedItemsMp)) { item._iSeed = AdvanceRndSeed(); @@ -4731,7 +4731,7 @@ void CreateSpellBook(Point position, SpellID ispell, bool sendmsg, bool delta) auto &item = Items[ii]; while (true) { - item = { }; + item = {}; SetupAllItems(*MyPlayer, item, idx, AdvanceRndSeed(), 2 * lvl, 1, true, delta); SetupItem(item); if (item._iMiscId == IMISC_BOOK && item._iSpell == ispell) diff --git a/Source/items.h b/Source/items.h index fb343f8b5..3695fe0c7 100644 --- a/Source/items.h +++ b/Source/items.h @@ -201,8 +201,8 @@ struct Item { bool _iPostDraw = false; bool _iIdentified = false; item_quality _iMagical = ITEM_QUALITY_NORMAL; - char _iName[ItemNameLength] = { }; - char _iIName[ItemNameLength] = { }; + char _iName[ItemNameLength] = {}; + char _iIName[ItemNameLength] = {}; item_equip_type _iLoc = ILOC_NONE; item_class _iClass = ICLASS_NONE; uint8_t _iCurs = 0; diff --git a/Source/objects.cpp b/Source/objects.cpp index b202a0a5c..54c7d342e 100644 --- a/Source/objects.cpp +++ b/Source/objects.cpp @@ -308,7 +308,7 @@ std::optional GetRandomObjectPosition(Displacement standoff) if (CanPlaceRandomObject(position, standoff)) return position; } - return { }; + return {}; } void InitRndLocObj5x5(int min, int max, _object_id objtype) @@ -325,7 +325,7 @@ void InitRndLocObj5x5(int min, int max, _object_id objtype) void ClrAllObjects() { for (Object &object : Objects) { - object = { }; + object = {}; } ActiveObjectCount = 0; for (int i = 0; i < MAXOBJECTS; i++) { @@ -556,7 +556,7 @@ void AddChestTraps() } } -void LoadMapObjects(const char *path, Point start, WorldTileRectangle mapRange = { }, int leveridx = 0) +void LoadMapObjects(const char *path, Point start, WorldTileRectangle mapRange = {}, int leveridx = 0) { LoadingMapObjects = true; @@ -1269,7 +1269,7 @@ void AddObjectLight(Object &object) return; } - DoLighting(object.position, radius, { }); + DoLighting(object.position, radius, {}); if (LoadingMapObjects) { DoUnLight(object.position, radius); UpdateLighting = true; @@ -1300,7 +1300,7 @@ void AddShrine(Object &shrine) shrine._oPreFlag = true; const int shrineCount = gbIsHellfire ? NumberOfShrineTypes : 26; - bool slist[NumberOfShrineTypes] = { }; + bool slist[NumberOfShrineTypes] = {}; for (int i = 0; i < shrineCount; i++) { bool isShrineAvailable = true; @@ -1846,7 +1846,7 @@ void OperateBook(Player &player, Object &book, bool sendmsg) } if (setlevel && setlvlnum == SL_VILEBETRAYER) { - Point target { }; + Point target {}; if (book.position == Point { 26, 45 }) { target = { 27, 29 }; } else if (book.position == Point { 45, 46 }) { @@ -3677,7 +3677,7 @@ bool IsItemBlockingObjectAtPosition(Point position) tl::expected LoadLevelObjects(uint16_t filesWidths[65]) { if (HeadlessMode) - return { }; + return {}; for (const ObjectData objectData : AllObjects) { if (leveltype == objectData.olvltype) { @@ -3696,12 +3696,12 @@ tl::expected LoadLevelObjects(uint16_t filesWidths[65]) ASSIGN_OR_RETURN(pObjCels[numobjfiles], LoadCelWithStatus(filestr, filesWidths[i])); numobjfiles++; } - return { }; + return {}; } tl::expected InitObjectGFX() { - uint16_t filesWidths[65] = { }; + uint16_t filesWidths[65] = {}; if (IsAnyOf(currlevel, 4, 8, 12)) { for (const auto id : { OBJ_STORYBOOK, OBJ_STORYCANDLE }) { @@ -3964,7 +3964,7 @@ void InitObjects() void SetMapObjects(const uint16_t *dunData, int startx, int starty) { - uint16_t filesWidths[65] = { }; + uint16_t filesWidths[65] = {}; ClrAllObjects(); From 6619672a6ac615d4a53182b366305c165b68c04b Mon Sep 17 00:00:00 2001 From: morfidon <57798071+morfidon@users.noreply.github.com> Date: Tue, 10 Mar 2026 14:39:28 +0100 Subject: [PATCH 5/8] Fix Cain identify-all cancel navigation --- Source/stores.cpp | 96 +++++++++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 40 deletions(-) diff --git a/Source/stores.cpp b/Source/stores.cpp index c53698043..0517d6d1d 100644 --- a/Source/stores.cpp +++ b/Source/stores.cpp @@ -897,11 +897,11 @@ void StoreNoRoom() AddSText(0, 14, _("You do not have enough room in inventory"), UiFlags::ColorWhite | UiFlags::AlignCenter, true); } -void StoreConfirm(Item &item) -{ - StartStore(OldActiveStore); - HasScrollbar = false; - ClearSText(5, 23); +void StoreConfirm(Item &item) +{ + StartStore(OldActiveStore); + HasScrollbar = false; + ClearSText(5, 23); if (OldActiveStore == TalkID::StorytellerIdentifyAll) { AddSText(0, 10, _("Identify all items?"), UiFlags::ColorWhite | UiFlags::AlignCenter, false); @@ -949,14 +949,28 @@ void StoreConfirm(Item &item) app_fatal(StrCat("Unknown store dialog ", static_cast(OldActiveStore))); } AddSText(0, 15, prompt, UiFlags::ColorWhite | UiFlags::AlignCenter, false); - AddSText(0, 18, _("Yes"), UiFlags::ColorWhite | UiFlags::AlignCenter, true); - AddSText(0, 20, _("No"), UiFlags::ColorWhite | UiFlags::AlignCenter, true); -} - -void StartBoy() -{ - IsTextFullSize = false; - HasScrollbar = false; + AddSText(0, 18, _("Yes"), UiFlags::ColorWhite | UiFlags::AlignCenter, true); + AddSText(0, 20, _("No"), UiFlags::ColorWhite | UiFlags::AlignCenter, true); +} + +void RestoreStoreFromOldState() +{ + if (OldActiveStore == TalkID::StorytellerIdentifyAll) { + StartStore(TalkID::Storyteller); + CurrentTextLine = 16; + ScrollPos = 0; + return; + } + + StartStore(OldActiveStore); + CurrentTextLine = OldTextLine; + ScrollPos = OldScrollPos; +} + +void StartBoy() +{ + IsTextFullSize = false; + HasScrollbar = false; AddSText(0, 2, _("Wirt the Peg-legged boy"), UiFlags::ColorWhitegold | UiFlags::AlignCenter, false); AddSLine(5); if (!BoyItem.isEmpty()) { @@ -1806,13 +1820,19 @@ void ConfirmEnter(Item &item) } } - StartStore(OldActiveStore); - - if (CurrentTextLine == BackButtonLine()) - return; - - CurrentTextLine = OldTextLine; - ScrollPos = std::min(OldScrollPos, NumTextLines); + StartStore(OldActiveStore); + + if (CurrentTextLine == BackButtonLine()) + return; + + if (OldActiveStore == TalkID::StorytellerIdentifyAll) { + CurrentTextLine = 16; + ScrollPos = 0; + return; + } + + CurrentTextLine = OldTextLine; + ScrollPos = std::min(OldScrollPos, NumTextLines); while (CurrentTextLine != -1 && !TextLine[CurrentTextLine].isSelectable()) { CurrentTextLine--; @@ -2482,17 +2502,15 @@ void StoreESC() case TalkID::StorytellerIdentifyShow: StartStore(TalkID::StorytellerIdentify); break; - case TalkID::NoMoney: - case TalkID::NoRoom: - case TalkID::Confirm: - StartStore(OldActiveStore); - CurrentTextLine = OldTextLine; - ScrollPos = OldScrollPos; - break; - case TalkID::None: - break; - } -} + case TalkID::NoMoney: + case TalkID::NoRoom: + case TalkID::Confirm: + RestoreStoreFromOldState(); + break; + case TalkID::None: + break; + } +} void StoreUp() { @@ -2649,15 +2667,13 @@ void StoreEnter() case TalkID::WitchRecharge: WitchRechargeEnter(); break; - case TalkID::NoMoney: - case TalkID::NoRoom: - StartStore(OldActiveStore); - CurrentTextLine = OldTextLine; - ScrollPos = OldScrollPos; - break; - case TalkID::Confirm: - ConfirmEnter(TempItem); - break; + case TalkID::NoMoney: + case TalkID::NoRoom: + RestoreStoreFromOldState(); + break; + case TalkID::Confirm: + ConfirmEnter(TempItem); + break; case TalkID::Boy: BoyEnter(); break; From f08ebcd9ce176cfd4601034568a2d5c823c5c6c9 Mon Sep 17 00:00:00 2001 From: morfidon <57798071+morfidon@users.noreply.github.com> Date: Tue, 10 Mar 2026 16:08:18 +0100 Subject: [PATCH 6/8] Fix empty "Identify all" storyteller flow --- Source/stores.cpp | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/Source/stores.cpp b/Source/stores.cpp index 0517d6d1d..e09f7c645 100644 --- a/Source/stores.cpp +++ b/Source/stores.cpp @@ -1159,15 +1159,19 @@ void StartStorytellerIdentify() } } - if (!idok) { - HasScrollbar = false; - - RenderGold = true; - AddSText(20, 1, _("You have nothing to identify."), UiFlags::ColorWhitegold, false); - AddSLine(3); - AddItemListBackButton(/*selectable=*/true); - return; - } + if (!idok) { + HasScrollbar = false; + + RenderGold = true; + if (OldActiveStore == TalkID::StorytellerIdentifyAll) { + AddSText(20, 1, _("There are no items to identify."), UiFlags::ColorWhitegold, false); + } else { + AddSText(20, 1, _("You have nothing to identify."), UiFlags::ColorWhitegold, false); + } + AddSLine(3); + AddItemListBackButton(/*selectable=*/true); + return; + } HasScrollbar = true; ScrollPos = 0; @@ -1919,13 +1923,13 @@ void StorytellerEnter() } } -void StorytellerIdentifyEnter() -{ - if (CurrentTextLine == BackButtonLine()) { - StartStore(TalkID::Storyteller); - CurrentTextLine = 14; - return; - } +void StorytellerIdentifyEnter() +{ + if (CurrentTextLine == BackButtonLine()) { + StartStore(TalkID::Storyteller); + CurrentTextLine = OldActiveStore == TalkID::StorytellerIdentifyAll ? 16 : 14; + return; + } OldActiveStore = TalkID::StorytellerIdentify; OldTextLine = CurrentTextLine; From 435e901054bc251fddc1b80c6d5b8a84d92e52aa Mon Sep 17 00:00:00 2001 From: morfidon <57798071+morfidon@users.noreply.github.com> Date: Tue, 10 Mar 2026 19:53:10 +0100 Subject: [PATCH 7/8] Fix i/mixed to i/crlf --- Source/stores.cpp | 152 +++++++++++++++++++++++----------------------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/Source/stores.cpp b/Source/stores.cpp index e09f7c645..56334568d 100644 --- a/Source/stores.cpp +++ b/Source/stores.cpp @@ -897,11 +897,11 @@ void StoreNoRoom() AddSText(0, 14, _("You do not have enough room in inventory"), UiFlags::ColorWhite | UiFlags::AlignCenter, true); } -void StoreConfirm(Item &item) -{ - StartStore(OldActiveStore); - HasScrollbar = false; - ClearSText(5, 23); +void StoreConfirm(Item &item) +{ + StartStore(OldActiveStore); + HasScrollbar = false; + ClearSText(5, 23); if (OldActiveStore == TalkID::StorytellerIdentifyAll) { AddSText(0, 10, _("Identify all items?"), UiFlags::ColorWhite | UiFlags::AlignCenter, false); @@ -949,28 +949,28 @@ void StoreConfirm(Item &item) app_fatal(StrCat("Unknown store dialog ", static_cast(OldActiveStore))); } AddSText(0, 15, prompt, UiFlags::ColorWhite | UiFlags::AlignCenter, false); - AddSText(0, 18, _("Yes"), UiFlags::ColorWhite | UiFlags::AlignCenter, true); - AddSText(0, 20, _("No"), UiFlags::ColorWhite | UiFlags::AlignCenter, true); -} - -void RestoreStoreFromOldState() -{ - if (OldActiveStore == TalkID::StorytellerIdentifyAll) { - StartStore(TalkID::Storyteller); - CurrentTextLine = 16; - ScrollPos = 0; - return; - } - - StartStore(OldActiveStore); - CurrentTextLine = OldTextLine; - ScrollPos = OldScrollPos; -} - -void StartBoy() -{ - IsTextFullSize = false; - HasScrollbar = false; + AddSText(0, 18, _("Yes"), UiFlags::ColorWhite | UiFlags::AlignCenter, true); + AddSText(0, 20, _("No"), UiFlags::ColorWhite | UiFlags::AlignCenter, true); +} + +void RestoreStoreFromOldState() +{ + if (OldActiveStore == TalkID::StorytellerIdentifyAll) { + StartStore(TalkID::Storyteller); + CurrentTextLine = 16; + ScrollPos = 0; + return; + } + + StartStore(OldActiveStore); + CurrentTextLine = OldTextLine; + ScrollPos = OldScrollPos; +} + +void StartBoy() +{ + IsTextFullSize = false; + HasScrollbar = false; AddSText(0, 2, _("Wirt the Peg-legged boy"), UiFlags::ColorWhitegold | UiFlags::AlignCenter, false); AddSLine(5); if (!BoyItem.isEmpty()) { @@ -1159,19 +1159,19 @@ void StartStorytellerIdentify() } } - if (!idok) { - HasScrollbar = false; - - RenderGold = true; - if (OldActiveStore == TalkID::StorytellerIdentifyAll) { - AddSText(20, 1, _("There are no items to identify."), UiFlags::ColorWhitegold, false); - } else { - AddSText(20, 1, _("You have nothing to identify."), UiFlags::ColorWhitegold, false); - } - AddSLine(3); - AddItemListBackButton(/*selectable=*/true); - return; - } + if (!idok) { + HasScrollbar = false; + + RenderGold = true; + if (OldActiveStore == TalkID::StorytellerIdentifyAll) { + AddSText(20, 1, _("There are no items to identify."), UiFlags::ColorWhitegold, false); + } else { + AddSText(20, 1, _("You have nothing to identify."), UiFlags::ColorWhitegold, false); + } + AddSLine(3); + AddItemListBackButton(/*selectable=*/true); + return; + } HasScrollbar = true; ScrollPos = 0; @@ -1824,19 +1824,19 @@ void ConfirmEnter(Item &item) } } - StartStore(OldActiveStore); - - if (CurrentTextLine == BackButtonLine()) - return; - - if (OldActiveStore == TalkID::StorytellerIdentifyAll) { - CurrentTextLine = 16; - ScrollPos = 0; - return; - } - - CurrentTextLine = OldTextLine; - ScrollPos = std::min(OldScrollPos, NumTextLines); + StartStore(OldActiveStore); + + if (CurrentTextLine == BackButtonLine()) + return; + + if (OldActiveStore == TalkID::StorytellerIdentifyAll) { + CurrentTextLine = 16; + ScrollPos = 0; + return; + } + + CurrentTextLine = OldTextLine; + ScrollPos = std::min(OldScrollPos, NumTextLines); while (CurrentTextLine != -1 && !TextLine[CurrentTextLine].isSelectable()) { CurrentTextLine--; @@ -1923,13 +1923,13 @@ void StorytellerEnter() } } -void StorytellerIdentifyEnter() -{ - if (CurrentTextLine == BackButtonLine()) { - StartStore(TalkID::Storyteller); - CurrentTextLine = OldActiveStore == TalkID::StorytellerIdentifyAll ? 16 : 14; - return; - } +void StorytellerIdentifyEnter() +{ + if (CurrentTextLine == BackButtonLine()) { + StartStore(TalkID::Storyteller); + CurrentTextLine = OldActiveStore == TalkID::StorytellerIdentifyAll ? 16 : 14; + return; + } OldActiveStore = TalkID::StorytellerIdentify; OldTextLine = CurrentTextLine; @@ -2506,15 +2506,15 @@ void StoreESC() case TalkID::StorytellerIdentifyShow: StartStore(TalkID::StorytellerIdentify); break; - case TalkID::NoMoney: - case TalkID::NoRoom: - case TalkID::Confirm: - RestoreStoreFromOldState(); - break; - case TalkID::None: - break; - } -} + case TalkID::NoMoney: + case TalkID::NoRoom: + case TalkID::Confirm: + RestoreStoreFromOldState(); + break; + case TalkID::None: + break; + } +} void StoreUp() { @@ -2671,13 +2671,13 @@ void StoreEnter() case TalkID::WitchRecharge: WitchRechargeEnter(); break; - case TalkID::NoMoney: - case TalkID::NoRoom: - RestoreStoreFromOldState(); - break; - case TalkID::Confirm: - ConfirmEnter(TempItem); - break; + case TalkID::NoMoney: + case TalkID::NoRoom: + RestoreStoreFromOldState(); + break; + case TalkID::Confirm: + ConfirmEnter(TempItem); + break; case TalkID::Boy: BoyEnter(); break; From c217927bf400b98f322707f95b5d297a75a9fb87 Mon Sep 17 00:00:00 2001 From: morfidon <57798071+morfidon@users.noreply.github.com> Date: Wed, 11 Mar 2026 23:26:52 +0100 Subject: [PATCH 8/8] Center identify-all confirm layout --- Source/stores.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Source/stores.cpp b/Source/stores.cpp index 56334568d..90e6dabfa 100644 --- a/Source/stores.cpp +++ b/Source/stores.cpp @@ -904,11 +904,12 @@ void StoreConfirm(Item &item) ClearSText(5, 23); if (OldActiveStore == TalkID::StorytellerIdentifyAll) { - AddSText(0, 10, _("Identify all items?"), UiFlags::ColorWhite | UiFlags::AlignCenter, false); - AddSText(0, 12, fmt::format(fmt::runtime(_("Cost: {:s} gold")), FormatInteger(item._iIvalue)), UiFlags::ColorWhitegold | UiFlags::AlignCenter, false); - AddSText(0, 15, _("Are you sure you want to identify all items?"), UiFlags::ColorWhite | UiFlags::AlignCenter, false); - AddSText(0, 18, _("Yes"), UiFlags::ColorWhite | UiFlags::AlignCenter, true); - AddSText(0, 20, _("No"), UiFlags::ColorWhite | UiFlags::AlignCenter, true); + AddSText(0, 7, _("Identify all items?"), UiFlags::ColorWhite | UiFlags::AlignCenter, false); + AddSText(0, 9, fmt::format(fmt::runtime(_("Cost: {:s} gold")), FormatInteger(item._iIvalue)), UiFlags::ColorWhitegold | UiFlags::AlignCenter, false); + AddSText(0, 12, _("Are you sure you want to"), UiFlags::ColorWhite | UiFlags::AlignCenter, false); + AddSText(0, 14, _("identify all items?"), UiFlags::ColorWhite | UiFlags::AlignCenter, false); + AddSText(0, 17, _("Yes"), UiFlags::ColorWhite | UiFlags::AlignCenter, true); + AddSText(0, 19, _("No"), UiFlags::ColorWhite | UiFlags::AlignCenter, true); return; }