Browse Source

Checks conditions for spell again, cause initial check was done when spell was queued

pull/5101/head
obligaron 4 years ago committed by Anders Jenbo
parent
commit
279e92e69c
  1. 17
      Source/inv.cpp
  2. 4
      Source/inv.h
  3. 25
      Source/player.cpp
  4. 3
      Source/spells.cpp
  5. 29
      test/inv_test.cpp

17
Source/inv.cpp

@ -1897,15 +1897,12 @@ int8_t CheckInvHLight()
return rv;
}
bool UseScroll(const spell_id spell)
bool UseScroll(Player &player, spell_id spell)
{
if (pcurs != CURSOR_HAND)
return false;
if (leveltype == DTYPE_TOWN && !spelldata[spell].sTownSpell)
return false;
return HasInventoryOrBeltItem(*MyPlayer, [spell](const Item &item) {
return HasInventoryOrBeltItem(player, [spell](const Item &item) {
return item.isScrollOf(spell);
});
}
@ -1921,15 +1918,9 @@ void UseStaffCharge(Player &player)
CalcPlrStaff(player);
}
bool UseStaff(const spell_id spell)
bool CanUseStaff(Player &player, spell_id spellId)
{
if (pcurs != CURSOR_HAND) {
return false;
}
Player &myPlayer = *MyPlayer;
return CanUseStaff(myPlayer.InvBody[INVLOC_HAND_LEFT], spell);
return CanUseStaff(player.InvBody[INVLOC_HAND_LEFT], spellId);
}
Item &GetInventoryItem(Player &player, int location)

4
Source/inv.h

@ -225,9 +225,9 @@ int InvPutItem(const Player &player, Point position, const Item &item);
int SyncPutItem(const Player &player, Point position, int idx, uint16_t icreateinfo, int iseed, int Id, int dur, int mdur, int ch, int mch, int ivalue, uint32_t ibuff, int toHit, int maxDam, int minStr, int minMag, int minDex, int ac);
int SyncDropItem(Point position, int idx, uint16_t icreateinfo, int iseed, int id, int dur, int mdur, int ch, int mch, int ivalue, uint32_t ibuff, int toHit, int maxDam, int minStr, int minMag, int minDex, int ac);
int8_t CheckInvHLight();
bool UseScroll(spell_id spell);
bool UseScroll(Player &player, spell_id spell);
void UseStaffCharge(Player &player);
bool UseStaff(spell_id spell);
bool CanUseStaff(Player &player, spell_id spellId);
Item &GetInventoryItem(Player &player, int location);
bool UseInvItem(int pnum, int cii);
void DoTelekinesis();

25
Source/player.cpp

@ -498,6 +498,27 @@ void StartSpell(Player &player, Direction d, WorldTileCoord cx, WorldTileCoord c
return;
}
// Checks conditions for spell again, cause initial check was done when spell was queued and the parameters could be changed meanwhile
bool isValid = true;
switch (player.queuedSpell.spellType) {
case RSPLTYPE_SKILL:
case RSPLTYPE_SPELL:
isValid = CheckSpell(player, player.queuedSpell.spellId, player.queuedSpell.spellType, true) == SpellCheckResult::Success;
break;
case RSPLTYPE_SCROLL:
isValid = UseScroll(player, player.queuedSpell.spellId);
break;
case RSPLTYPE_CHARGES:
isValid = CanUseStaff(player, player.queuedSpell.spellId);
break;
case RSPLTYPE_INVALID:
// Scroll is removed previous, so don't check again
isValid = true;
break;
}
if (!isValid)
return;
auto animationFlags = AnimationDistributionFlags::ProcessAnimationPending;
if (player._pmode == PM_SPELL)
animationFlags = static_cast<AnimationDistributionFlags>(animationFlags | AnimationDistributionFlags::RepeatedAction);
@ -3448,10 +3469,10 @@ void CheckPlrSpell(bool isShiftHeld, spell_id spellID, spell_type spellType)
addflag = spellcheck == SpellCheckResult::Success;
break;
case RSPLTYPE_SCROLL:
addflag = UseScroll(spellID);
addflag = pcurs == CURSOR_HAND && UseScroll(myPlayer, spellID);
break;
case RSPLTYPE_CHARGES:
addflag = UseStaff(spellID);
addflag = pcurs == CURSOR_HAND && CanUseStaff(myPlayer, spellID);
break;
case RSPLTYPE_INVALID:
return;

3
Source/spells.cpp

@ -173,9 +173,6 @@ int GetManaAmount(const Player &player, spell_id sn)
void UseMana(Player &player, spell_id sn)
{
if (&player != MyPlayer)
return;
switch (player.executedSpell.spellType) {
case RSPLTYPE_SKILL:
case RSPLTYPE_INVALID:

29
test/inv_test.cpp

@ -32,14 +32,14 @@ TEST(Inv, UseScroll_from_inventory)
{
set_up_scroll(MyPlayer->InvList[2], SPL_FIREBOLT);
MyPlayer->_pNumInv = 5;
EXPECT_TRUE(UseScroll(MyPlayer->_pRSpell));
EXPECT_TRUE(UseScroll(*MyPlayer, SPL_FIREBOLT));
}
// Test that the scroll is used in the belt in correct conditions
TEST(Inv, UseScroll_from_belt)
{
set_up_scroll(MyPlayer->SpdList[2], SPL_FIREBOLT);
EXPECT_TRUE(UseScroll(MyPlayer->_pRSpell));
EXPECT_TRUE(UseScroll(*MyPlayer, SPL_FIREBOLT));
}
// Test that the scroll is not used in the inventory for each invalid condition
@ -50,25 +50,24 @@ TEST(Inv, UseScroll_from_inventory_invalid_conditions)
MyPlayer->SpdList[i].clear();
}
set_up_scroll(MyPlayer->InvList[2], SPL_FIREBOLT);
pcurs = CURSOR_IDENTIFY;
EXPECT_FALSE(UseScroll(MyPlayer->_pRSpell));
// Adjust inventory size
MyPlayer->_pNumInv = 5;
set_up_scroll(MyPlayer->InvList[2], SPL_FIREBOLT);
leveltype = DTYPE_TOWN;
EXPECT_FALSE(UseScroll(MyPlayer->_pRSpell));
EXPECT_FALSE(UseScroll(*MyPlayer, SPL_FIREBOLT));
set_up_scroll(MyPlayer->InvList[2], SPL_FIREBOLT);
MyPlayer->_pRSpell = static_cast<spell_id>(SPL_HEAL);
EXPECT_FALSE(UseScroll(MyPlayer->_pRSpell));
EXPECT_FALSE(UseScroll(*MyPlayer, SPL_HEAL));
set_up_scroll(MyPlayer->InvList[2], SPL_FIREBOLT);
MyPlayer->InvList[2]._iMiscId = IMISC_STAFF;
EXPECT_FALSE(UseScroll(MyPlayer->_pRSpell));
EXPECT_FALSE(UseScroll(*MyPlayer, SPL_FIREBOLT));
set_up_scroll(MyPlayer->InvList[2], SPL_FIREBOLT);
MyPlayer->InvList[2].clear();
EXPECT_FALSE(UseScroll(MyPlayer->_pRSpell));
EXPECT_FALSE(UseScroll(*MyPlayer, SPL_FIREBOLT));
}
// Test that the scroll is not used in the belt for each invalid condition
@ -77,25 +76,21 @@ TEST(Inv, UseScroll_from_belt_invalid_conditions)
// Disable the inventory to prevent using a scroll from the inventory
MyPlayer->_pNumInv = 0;
set_up_scroll(MyPlayer->SpdList[2], SPL_FIREBOLT);
pcurs = CURSOR_IDENTIFY;
EXPECT_FALSE(UseScroll(MyPlayer->_pRSpell));
set_up_scroll(MyPlayer->SpdList[2], SPL_FIREBOLT);
leveltype = DTYPE_TOWN;
EXPECT_FALSE(UseScroll(MyPlayer->_pRSpell));
EXPECT_FALSE(UseScroll(*MyPlayer, SPL_FIREBOLT));
set_up_scroll(MyPlayer->SpdList[2], SPL_FIREBOLT);
MyPlayer->_pRSpell = static_cast<spell_id>(SPL_HEAL);
EXPECT_FALSE(UseScroll(MyPlayer->_pRSpell));
EXPECT_FALSE(UseScroll(*MyPlayer, SPL_HEAL));
set_up_scroll(MyPlayer->SpdList[2], SPL_FIREBOLT);
MyPlayer->SpdList[2]._iMiscId = IMISC_STAFF;
EXPECT_FALSE(UseScroll(MyPlayer->_pRSpell));
EXPECT_FALSE(UseScroll(*MyPlayer, SPL_FIREBOLT));
set_up_scroll(MyPlayer->SpdList[2], SPL_FIREBOLT);
MyPlayer->SpdList[2].clear();
EXPECT_FALSE(UseScroll(MyPlayer->_pRSpell));
EXPECT_FALSE(UseScroll(*MyPlayer, SPL_FIREBOLT));
}
// Test gold calculation

Loading…
Cancel
Save