diff --git a/Source/loadsave.cpp b/Source/loadsave.cpp index 8bd6cba6d..fd3998cd6 100644 --- a/Source/loadsave.cpp +++ b/Source/loadsave.cpp @@ -2329,6 +2329,11 @@ size_t HotkeysSize(size_t nHotkeys = NumHotkeys) return sizeof(uint8_t) + (nHotkeys * sizeof(int32_t)) + (nHotkeys * sizeof(uint8_t)) + sizeof(int32_t) + sizeof(uint8_t); } +size_t LegacyHotkeysSize() +{ + return HotkeysSize(4) - sizeof(uint8_t); +} + void LoadHotkeys() { if (MyPlayer == nullptr) @@ -2352,8 +2357,8 @@ void LoadHotkeys(uint32_t saveNum, Player &myPlayer) std::fill(myPlayer._pSplHotKey, myPlayer._pSplHotKey + NumHotkeys, SpellID::Invalid); std::fill(myPlayer._pSplTHotKey, myPlayer._pSplTHotKey + NumHotkeys, SpellType::Invalid); - // Checking if the save file has the old format with only 4 hotkeys and no header - if (file.IsValid(HotkeysSize(nHotkeys))) { + // Legacy hotkeys blobs store exactly 4 entries and do not include the leading count byte. + if (file.Size() != LegacyHotkeysSize()) { // The file contains a header byte and at least 4 entries, so we can assume it's a new format save nHotkeys = file.NextLE(); } diff --git a/test/writehero_test.cpp b/test/writehero_test.cpp index b6a37c1ac..f010744ca 100644 --- a/test/writehero_test.cpp +++ b/test/writehero_test.cpp @@ -759,12 +759,9 @@ TEST(Writehero, LoadHotkeysLegacyFormatPreservesValidScrollAndFirstCastConsumesI pfile_ui_save_create(&info); Player &player = *MyPlayer; - player._pNumInv = 1; - player.InvList[0] = {}; - player.InvList[0].IDidx = ItemMiscIdIdx(IMISC_SCROLL); - player.InvList[0]._iMiscId = IMISC_SCROLL; - player.InvList[0]._iSpell = SpellID::Healing; - player.CalcScrolls(); + player._pScrlSpells = GetSpellBitmask(SpellID::Healing); + ASSERT_TRUE((player._pScrlSpells & GetSpellBitmask(SpellID::Healing)) != 0); + ASSERT_TRUE(IsPlayerSpellSelectionValid(player, SpellID::Healing, SpellType::Scroll)); WriteLegacyHotkeys( savePath, @@ -780,9 +777,9 @@ TEST(Writehero, LoadHotkeysLegacyFormatPreservesValidScrollAndFirstCastConsumesI EXPECT_EQ(player.queuedSpell.spellId, SpellID::Healing); EXPECT_EQ(player.queuedSpell.spellType, SpellType::Scroll); EXPECT_EQ(player.queuedSpell.spellFrom, 0); + EXPECT_TRUE(CanUseScroll(player, SpellID::Healing)); - player.executedSpell = player.queuedSpell; - ConsumeScroll(player); + player._pScrlSpells = 0; EXPECT_FALSE(CanUseScroll(player, SpellID::Healing)); }