Browse Source

Check both SPL_NULL and SPL_INVALID to determine spell validity

pull/4932/head
staphen 4 years ago committed by Anders Jenbo
parent
commit
9e2d6a7500
  1. 2
      Source/control.cpp
  2. 2
      Source/controls/modifier_hints.cpp
  3. 6
      Source/items.cpp
  4. 4
      Source/panels/spell_book.cpp
  5. 20
      Source/panels/spell_list.cpp
  6. 12
      Source/player.cpp
  7. 10
      Source/player.h
  8. 7
      Source/spells.cpp
  9. 1
      Source/spells.h
  10. 4
      Source/stores.cpp

2
Source/control.cpp

@ -717,7 +717,7 @@ void CheckPanelInfo()
AddPanelString(_("Hotkey: 's'"));
auto &myPlayer = Players[MyPlayerId];
const spell_id spellId = myPlayer._pRSpell;
if (spellId != SPL_INVALID && spellId != SPL_NULL) {
if (IsValidSpell(spellId)) {
switch (myPlayer._pRSplType) {
case RSPLTYPE_SKILL:
AddPanelString(fmt::format(_("{:s} Skill"), pgettext("spell", spelldata[spellId].sSkillText)));

2
Source/controls/modifier_hints.cpp

@ -131,7 +131,7 @@ void DrawSpellsCircleMenuHint(const Surface &out, const Point &origin)
for (int slot = 0; slot < 4; ++slot) {
splId = myPlayer._pSplHotKey[slot];
if (splId != SPL_INVALID && splId != SPL_NULL && (spells & GetSpellBitmask(splId)) != 0)
if (IsValidSpell(splId) && (spells & GetSpellBitmask(splId)) != 0)
splType = (currlevel == 0 && !spelldata[splId].sTownSpell) ? RSPLTYPE_INVALID : myPlayer._pSplTHotKey[slot];
else {
splType = RSPLTYPE_INVALID;

6
Source/items.cpp

@ -1907,7 +1907,7 @@ bool SmithItemOk(int i)
return false;
if (AllItemsList[i].itype == ItemType::Gold)
return false;
if (AllItemsList[i].itype == ItemType::Staff && (!gbIsHellfire || AllItemsList[i].iSpell != SPL_NULL))
if (AllItemsList[i].itype == ItemType::Staff && (!gbIsHellfire || IsValidSpell(AllItemsList[i].iSpell)))
return false;
if (AllItemsList[i].itype == ItemType::Ring)
return false;
@ -2426,7 +2426,7 @@ void CalcPlrItemVals(Player &player, bool loadgfx)
maxd += item._iMaxDam;
tac += item._iAC;
if (item._iSpell != SPL_NULL) {
if (IsValidSpell(item._iSpell)) {
spl |= GetSpellBitmask(item._iSpell);
}
@ -4673,7 +4673,7 @@ void RepairItem(Item &item, int lvl)
void RechargeItem(Item &item, Player &player)
{
if (item._itype != ItemType::Staff || item._iSpell == SPL_NULL)
if (item._itype != ItemType::Staff || !IsValidSpell(item._iSpell))
return;
if (item._iCharges == item._iMaxCharges)

4
Source/panels/spell_book.cpp

@ -137,7 +137,7 @@ void DrawSpellBook(const Surface &out)
const int textPaddingTop = 7;
for (int i = 1; i < 8; i++) {
spell_id sn = SpellPages[sbooktab][i - 1];
if (sn != SPL_INVALID && (spl & GetSpellBitmask(sn)) != 0) {
if (IsValidSpell(sn) && (spl & GetSpellBitmask(sn)) != 0) {
spell_type st = GetSBookTrans(sn, true);
SetSpellTrans(st);
const Point spellCellPosition = GetPanelPosition(UiPanels::Spell, { 11, yp + SpellBookDescriptionHeight });
@ -196,7 +196,7 @@ void CheckSBook()
spell_id sn = SpellPages[sbooktab][(MousePosition.y - GetRightPanel().position.y - 18) / 43];
auto &player = Players[MyPlayerId];
uint64_t spl = player._pMemSpells | player._pISpells | player._pAblSpells;
if (sn != SPL_INVALID && (spl & GetSpellBitmask(sn)) != 0) {
if (IsValidSpell(sn) && (spl & GetSpellBitmask(sn)) != 0) {
spell_type st = RSPLTYPE_SPELL;
if ((player._pISpells & GetSpellBitmask(sn)) != 0) {
st = RSPLTYPE_CHARGES;

20
Source/panels/spell_list.cpp

@ -102,18 +102,24 @@ void DrawSpell(const Surface &out)
spell_id spl = myPlayer._pRSpell;
spell_type st = myPlayer._pRSplType;
// BUGFIX: Move the next line into the if statement to avoid OOB (SPL_INVALID is -1) (fixed)
if (st == RSPLTYPE_SPELL && spl != SPL_INVALID) {
if (!IsValidSpell(spl)) {
st = RSPLTYPE_INVALID;
spl = SPL_NULL;
}
if (st == RSPLTYPE_SPELL) {
int tlvl = myPlayer._pISplLvlAdd + myPlayer._pSplLvl[spl];
if (CheckSpell(MyPlayerId, spl, st, true) != SpellCheckResult::Success)
st = RSPLTYPE_INVALID;
if (tlvl <= 0)
st = RSPLTYPE_INVALID;
}
if (currlevel == 0 && st != RSPLTYPE_INVALID && !spelldata[spl].sTownSpell)
st = RSPLTYPE_INVALID;
SetSpellTrans(st);
const int nCel = (spl != SPL_INVALID) ? SpellITbl[spl] : 27;
const int nCel = SpellITbl[spl];
const Point position { PANEL_X + 565, PANEL_Y + 119 };
DrawSpellCel(out, position, nCel);
@ -300,7 +306,8 @@ void ToggleSpell(int slot)
auto &myPlayer = Players[MyPlayerId];
if (myPlayer._pSplHotKey[slot] == SPL_INVALID) {
const spell_id spellId = myPlayer._pSplHotKey[slot];
if (!IsValidSpell(spellId)) {
return;
}
@ -321,8 +328,7 @@ void ToggleSpell(int slot)
return;
}
const spell_id spellId = myPlayer._pSplHotKey[slot];
if (spellId != SPL_INVALID && spellId != SPL_NULL && (spells & GetSpellBitmask(spellId)) != 0) {
if ((spells & GetSpellBitmask(spellId)) != 0) {
myPlayer._pRSpell = spellId;
myPlayer._pRSplType = myPlayer._pSplTHotKey[slot];
force_redraw = 255;
@ -339,7 +345,7 @@ void DoSpeedBook()
auto &myPlayer = Players[MyPlayerId];
if (myPlayer._pRSpell != SPL_INVALID) {
if (IsValidSpell(myPlayer._pRSpell)) {
for (int i = RSPLTYPE_SKILL; i <= RSPLTYPE_CHARGES; i++) {
uint64_t spells;
switch (i) {

12
Source/player.cpp

@ -2117,6 +2117,16 @@ void Player::RestorePartialMana()
}
}
void Player::ReadySpellFromEquipment(inv_body_loc bodyLocation)
{
auto &item = InvBody[bodyLocation];
if (item._itype == ItemType::Staff && IsValidSpell(item._iSpell) && item._iCharges > 0) {
_pRSpell = item._iSpell;
_pRSplType = RSPLTYPE_CHARGES;
force_redraw = 255;
}
}
void Player::UpdatePreviewCelSprite(_cmd_id cmdId, Point point, uint16_t wParam1, uint16_t wParam2)
{
// if game is not running don't show a preview
@ -3551,7 +3561,7 @@ void CheckPlrSpell(bool isShiftHeld, spell_id spellID, spell_type spellType)
}
auto &myPlayer = Players[MyPlayerId];
if (spellID == SPL_INVALID) {
if (!IsValidSpell(spellID)) {
myPlayer.Say(HeroSpeech::IDontHaveASpellReady);
return;
}

10
Source/player.h

@ -671,15 +671,7 @@ struct Player {
* @brief Sets the readied spell to the spell in the specified equipment slot. Does nothing if the item does not have a valid spell.
* @param bodyLocation - the body location whose item will be checked for the spell.
*/
void ReadySpellFromEquipment(inv_body_loc bodyLocation)
{
auto &item = InvBody[bodyLocation];
if (item._itype == ItemType::Staff && item._iSpell != SPL_NULL && item._iCharges > 0) {
_pRSpell = item._iSpell;
_pRSplType = RSPLTYPE_CHARGES;
force_redraw = 255;
}
}
void ReadySpellFromEquipment(inv_body_loc bodyLocation);
/**
* @brief Does the player currently have a ranged weapon equipped?

7
Source/spells.cpp

@ -108,6 +108,13 @@ void PlacePlayer(int pnum)
} // namespace
bool IsValidSpell(spell_id spl)
{
return spl > SPL_NULL
&& spl <= SPL_LAST
&& (spl <= SPL_LASTDIABLO || gbIsHellfire);
}
bool IsWallSpell(spell_id spl)
{
return spl == SPL_FIREWALL || spl == SPL_LIGHTWALL;

1
Source/spells.h

@ -16,6 +16,7 @@ enum class SpellCheckResult : uint8_t {
Fail_Busy,
};
bool IsValidSpell(spell_id spl);
bool IsWallSpell(spell_id spl);
bool TargetsMonster(spell_id id);
int GetManaAmount(Player &player, spell_id sn);

4
Source/stores.cpp

@ -456,7 +456,7 @@ bool SmithSellOk(int i)
return false;
if (pI->_itype == ItemType::Gold)
return false;
if (pI->_itype == ItemType::Staff && (!gbIsHellfire || pI->_iSpell != SPL_NULL))
if (pI->_itype == ItemType::Staff && (!gbIsHellfire || IsValidSpell(pI->_iSpell)))
return false;
if (pI->_iClass == ICLASS_QUEST)
return false;
@ -753,7 +753,7 @@ bool WitchSellOk(int i)
rv = false;
if (pI->_iClass == ICLASS_QUEST)
rv = false;
if (pI->_itype == ItemType::Staff && (!gbIsHellfire || pI->_iSpell != SPL_NULL))
if (pI->_itype == ItemType::Staff && (!gbIsHellfire || IsValidSpell(pI->_iSpell)))
rv = true;
if (pI->IDidx >= IDI_FIRSTQUEST && pI->IDidx <= IDI_LASTQUEST)
rv = false;

Loading…
Cancel
Save