Skip to content

Commit

Permalink
Fix illegal spell levels (#7112)
Browse files Browse the repository at this point in the history
  • Loading branch information
kphoenix137 committed May 10, 2024
1 parent 2215001 commit 557fd2a
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 6 deletions.
20 changes: 18 additions & 2 deletions Source/loadsave.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,8 +390,24 @@ void LoadPlayer(LoadHelper &file, Player &player)
file.Skip(3); // Alignment
player._pSBkSpell = static_cast<SpellID>(file.NextLE<int32_t>());
file.Skip<int8_t>(); // Skip _pSBkSplType
for (uint8_t &spellLevel : player._pSplLvl)
spellLevel = file.NextLE<uint8_t>();

// Only read spell levels for learnable spells
for (int i = 0; i < static_cast<int>(SpellID::LAST); i++) {
auto spl = static_cast<SpellID>(i);
if (GetSpellData(spl).sBookLvl != -1)
player._pSplLvl[i] = file.NextLE<uint8_t>();
else
file.Skip<uint8_t>();
}
// Skip indices that are unused
for (int i = static_cast<int>(SpellID::LAST); i < 64; i++)
file.Skip<uint8_t>();
// These spells are unavailable in Diablo as learnable spells
if (!gbIsHellfire) {
player._pSplLvl[static_cast<uint8_t>(SpellID::Apocalypse)] = 0;
player._pSplLvl[static_cast<uint8_t>(SpellID::Nova)] = 0;
}

file.Skip(7); // Alignment
player._pMemSpells = file.NextLE<uint64_t>();
player._pAblSpells = file.NextLE<uint64_t>();
Expand Down
25 changes: 21 additions & 4 deletions Source/pack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -484,10 +484,27 @@ void UnPackPlayer(const PlayerPack &packed, Player &player)
player._pManaBase = std::min<int32_t>(player._pManaBase, player._pMaxManaBase);
player._pMemSpells = SDL_SwapLE64(packed.pMemSpells);

for (int i = 0; i < 37; i++) // Should be MAX_SPELLS but set to 36 to make save games compatible
player._pSplLvl[i] = packed.pSplLvl[i];
for (int i = 37; i < 47; i++)
player._pSplLvl[i] = packed.pSplLvl2[i - 37];
// Only read spell levels for learnable spells (Diablo)
for (int i = 0; i < 37; i++) { // Should be MAX_SPELLS but set to 36 to make save games compatible
auto spl = static_cast<SpellID>(i);
if (GetSpellData(spl).sBookLvl != -1)
player._pSplLvl[i] = packed.pSplLvl[i];
else
player._pSplLvl[i] = 0;
}
// Only read spell levels for learnable spells (Hellfire)
for (int i = 37; i < 47; i++) {
auto spl = static_cast<SpellID>(i);
if (GetSpellData(spl).sBookLvl != -1)
player._pSplLvl[i] = packed.pSplLvl2[i - 37];
else
player._pSplLvl[i] = 0;
}
// These spells are unavailable in Diablo as learnable spells
if (!gbIsHellfire) {
player._pSplLvl[static_cast<uint8_t>(SpellID::Apocalypse)] = 0;
player._pSplLvl[static_cast<uint8_t>(SpellID::Nova)] = 0;
}

bool isHellfire = packed.bIsHellfire != 0;

Expand Down

0 comments on commit 557fd2a

Please sign in to comment.