Browse Source

Player by reference part 3

pull/2224/head
Anders Jenbo 5 years ago
parent
commit
ee7b32d8f6
  1. 2
      Source/control.cpp
  2. 4
      Source/diablo.cpp
  3. 9
      Source/inv.cpp
  4. 4
      Source/inv.h
  5. 206
      Source/items.cpp
  6. 1
      Source/items.h
  7. 34
      Source/loadsave.cpp
  8. 6
      Source/loadsave.h
  9. 14
      Source/miniwin/misc_msg.cpp
  10. 467
      Source/missiles.cpp
  11. 2
      Source/missiles.h
  12. 20
      Source/multi.cpp
  13. 4
      Source/pfile.cpp
  14. 17
      Source/player.cpp
  15. 3
      Source/player.h
  16. 10
      Source/scrollrt.cpp
  17. 47
      Source/spells.cpp
  18. 2
      Source/spells.h
  19. 4
      test/inv_test.cpp

2
Source/control.cpp

@ -1640,7 +1640,7 @@ void DrawSpellBook(const CelOutputBuffer &out)
strcpy(tempstr, fmt::format(ngettext("Staff ({:d} charge)", "Staff ({:d} charges)", charges), charges).c_str());
} break;
default: {
int mana = GetManaAmount(myplr, sn) >> 6;
int mana = GetManaAmount(myPlayer, sn) >> 6;
int min;
int max;
GetDamageAmt(sn, &min, &max);

4
Source/diablo.cpp

@ -1734,7 +1734,7 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir)
for (int i = 0; i < MAX_PLRS; i++) {
auto &player = plr[i];
if (player.plractive && currlevel == player.plrlevel) {
InitPlayerGFX(i);
InitPlayerGFX(player);
if (lvldir != ENTRY_LOAD)
InitPlayer(i, firstflag);
}
@ -1828,7 +1828,7 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir)
for (int i = 0; i < MAX_PLRS; i++) {
auto &player = plr[i];
if (player.plractive && currlevel == player.plrlevel) {
InitPlayerGFX(i);
InitPlayerGFX(player);
if (lvldir != ENTRY_LOAD)
InitPlayer(i, firstflag);
}

9
Source/inv.cpp

@ -1993,10 +1993,8 @@ char CheckInvHLight()
return rv;
}
void RemoveScroll(int pnum)
void RemoveScroll(PlayerStruct &player)
{
auto &player = plr[pnum];
for (int i = 0; i < player._pNumInv; i++) {
if (!player.InvList[i].isEmpty()
&& (player.InvList[i]._iMiscId == IMISC_SCROLL || player.InvList[i]._iMiscId == IMISC_SCROLLT)
@ -2053,16 +2051,15 @@ static bool CanUseStaff(ItemStruct &staff, spell_id spell)
&& staff._iCharges > 0;
}
void UseStaffCharge(int pnum)
void UseStaffCharge(PlayerStruct &player)
{
auto &player = plr[pnum];
auto &staff = player.InvBody[INVLOC_HAND_LEFT];
if (!CanUseStaff(staff, player._pRSpell))
return;
staff._iCharges--;
CalcPlrStaff(pnum);
CalcPlrStaff(player);
}
bool UseStaff()

4
Source/inv.h

@ -114,9 +114,9 @@ bool TryInvPut();
int InvPutItem(PlayerStruct &player, Point position);
int SyncPutItem(PlayerStruct &player, Point position, int idx, uint16_t icreateinfo, int iseed, int Id, int dur, int mdur, int ch, int mch, int ivalue, DWORD ibuff, int toHit, int maxDam, int minStr, int minMag, int minDex, int ac);
char CheckInvHLight();
void RemoveScroll(int pnum);
void RemoveScroll(PlayerStruct &player);
bool UseScroll();
void UseStaffCharge(int pnum);
void UseStaffCharge(PlayerStruct &player);
bool UseStaff();
bool UseInvItem(int pnum, int cii);
void DoTelekinesis();

206
Source/items.cpp

@ -922,16 +922,6 @@ void CalcPlrItemVals(int playerId, bool Loadgfx)
drawhpflag = true;
}
void CalcPlrStaff(int p)
{
plr[p]._pISpells = 0;
if (!plr[p].InvBody[INVLOC_HAND_LEFT].isEmpty()
&& plr[p].InvBody[INVLOC_HAND_LEFT]._iStatFlag
&& plr[p].InvBody[INVLOC_HAND_LEFT]._iCharges > 0) {
plr[p]._pISpells |= GetSpellBitmask(plr[p].InvBody[INVLOC_HAND_LEFT]._iSpell);
}
}
void CalcSelfItems(PlayerStruct &player)
{
int i;
@ -1050,7 +1040,7 @@ void CalcPlrInv(int playerId, bool Loadgfx)
if (playerId == myplr) {
CalcPlrBookVals(player);
player.CalcScrolls();
CalcPlrStaff(playerId);
CalcPlrStaff(player);
if (playerId == myplr && currlevel == 0)
RecalcStoreStats();
}
@ -3894,41 +3884,43 @@ void UseItem(int p, item_misc_id Mid, spell_id spl)
{
int l, j;
auto &player = plr[p];
switch (Mid) {
case IMISC_HEAL:
case IMISC_FOOD:
j = plr[p]._pMaxHP >> 8;
j = player._pMaxHP >> 8;
l = ((j >> 1) + GenerateRnd(j)) << 6;
if (plr[p]._pClass == HeroClass::Warrior || plr[p]._pClass == HeroClass::Barbarian)
if (player._pClass == HeroClass::Warrior || player._pClass == HeroClass::Barbarian)
l *= 2;
if (plr[p]._pClass == HeroClass::Rogue || plr[p]._pClass == HeroClass::Monk || plr[p]._pClass == HeroClass::Bard)
if (player._pClass == HeroClass::Rogue || player._pClass == HeroClass::Monk || player._pClass == HeroClass::Bard)
l += l / 2;
plr[p]._pHitPoints = std::min(l + plr[p]._pHitPoints, plr[p]._pMaxHP);
plr[p]._pHPBase = std::min(l + plr[p]._pHPBase, plr[p]._pMaxHPBase);
player._pHitPoints = std::min(l + player._pHitPoints, player._pMaxHP);
player._pHPBase = std::min(l + player._pHPBase, player._pMaxHPBase);
drawhpflag = true;
break;
case IMISC_FULLHEAL:
plr[p]._pHitPoints = plr[p]._pMaxHP;
plr[p]._pHPBase = plr[p]._pMaxHPBase;
player._pHitPoints = player._pMaxHP;
player._pHPBase = player._pMaxHPBase;
drawhpflag = true;
break;
case IMISC_MANA:
j = plr[p]._pMaxMana >> 8;
j = player._pMaxMana >> 8;
l = ((j >> 1) + GenerateRnd(j)) << 6;
if (plr[p]._pClass == HeroClass::Sorcerer)
if (player._pClass == HeroClass::Sorcerer)
l *= 2;
if (plr[p]._pClass == HeroClass::Rogue || plr[p]._pClass == HeroClass::Monk || plr[p]._pClass == HeroClass::Bard)
if (player._pClass == HeroClass::Rogue || player._pClass == HeroClass::Monk || player._pClass == HeroClass::Bard)
l += l / 2;
if ((plr[p]._pIFlags & ISPL_NOMANA) == 0) {
plr[p]._pMana = std::min(l + plr[p]._pMana, plr[p]._pMaxMana);
plr[p]._pManaBase = std::min(l + plr[p]._pManaBase, plr[p]._pMaxManaBase);
if ((player._pIFlags & ISPL_NOMANA) == 0) {
player._pMana = std::min(l + player._pMana, player._pMaxMana);
player._pManaBase = std::min(l + player._pManaBase, player._pMaxManaBase);
drawmanaflag = true;
}
break;
case IMISC_FULLMANA:
if ((plr[p]._pIFlags & ISPL_NOMANA) == 0) {
plr[p]._pMana = plr[p]._pMaxMana;
plr[p]._pManaBase = plr[p]._pMaxManaBase;
if ((player._pIFlags & ISPL_NOMANA) == 0) {
player._pMana = player._pMaxMana;
player._pManaBase = player._pMaxManaBase;
drawmanaflag = true;
}
break;
@ -3938,8 +3930,8 @@ void UseItem(int p, item_misc_id Mid, spell_id spl)
case IMISC_ELIXMAG:
ModifyPlrMag(p, 1);
if (gbIsHellfire) {
plr[p]._pMana = plr[p]._pMaxMana;
plr[p]._pManaBase = plr[p]._pMaxManaBase;
player._pMana = player._pMaxMana;
player._pManaBase = player._pMaxManaBase;
drawmanaflag = true;
}
break;
@ -3949,89 +3941,89 @@ void UseItem(int p, item_misc_id Mid, spell_id spl)
case IMISC_ELIXVIT:
ModifyPlrVit(p, 1);
if (gbIsHellfire) {
plr[p]._pHitPoints = plr[p]._pMaxHP;
plr[p]._pHPBase = plr[p]._pMaxHPBase;
player._pHitPoints = player._pMaxHP;
player._pHPBase = player._pMaxHPBase;
drawhpflag = true;
}
break;
case IMISC_REJUV:
j = plr[p]._pMaxHP >> 8;
j = player._pMaxHP >> 8;
l = ((j / 2) + GenerateRnd(j)) << 6;
if (plr[p]._pClass == HeroClass::Warrior || plr[p]._pClass == HeroClass::Barbarian)
if (player._pClass == HeroClass::Warrior || player._pClass == HeroClass::Barbarian)
l *= 2;
if (plr[p]._pClass == HeroClass::Rogue)
if (player._pClass == HeroClass::Rogue)
l += l / 2;
plr[p]._pHitPoints = std::min(plr[p]._pHitPoints + l, plr[p]._pMaxHP);
plr[p]._pHPBase = std::min(plr[p]._pHPBase + l, plr[p]._pMaxHPBase);
player._pHitPoints = std::min(player._pHitPoints + l, player._pMaxHP);
player._pHPBase = std::min(player._pHPBase + l, player._pMaxHPBase);
drawhpflag = true;
j = plr[p]._pMaxMana >> 8;
j = player._pMaxMana >> 8;
l = ((j / 2) + GenerateRnd(j)) << 6;
if (plr[p]._pClass == HeroClass::Sorcerer)
if (player._pClass == HeroClass::Sorcerer)
l *= 2;
if (plr[p]._pClass == HeroClass::Rogue)
if (player._pClass == HeroClass::Rogue)
l += l / 2;
if ((plr[p]._pIFlags & ISPL_NOMANA) == 0) {
plr[p]._pMana = std::min(plr[p]._pMana + l, plr[p]._pMaxMana);
plr[p]._pManaBase = std::min(plr[p]._pManaBase + l, plr[p]._pMaxManaBase);
if ((player._pIFlags & ISPL_NOMANA) == 0) {
player._pMana = std::min(player._pMana + l, player._pMaxMana);
player._pManaBase = std::min(player._pManaBase + l, player._pMaxManaBase);
drawmanaflag = true;
}
break;
case IMISC_FULLREJUV:
plr[p]._pHitPoints = plr[p]._pMaxHP;
plr[p]._pHPBase = plr[p]._pMaxHPBase;
player._pHitPoints = player._pMaxHP;
player._pHPBase = player._pMaxHPBase;
drawhpflag = true;
if ((plr[p]._pIFlags & ISPL_NOMANA) == 0) {
plr[p]._pMana = plr[p]._pMaxMana;
plr[p]._pManaBase = plr[p]._pMaxManaBase;
if ((player._pIFlags & ISPL_NOMANA) == 0) {
player._pMana = player._pMaxMana;
player._pManaBase = player._pMaxManaBase;
drawmanaflag = true;
}
break;
case IMISC_SCROLL:
if (spelldata[spl].sTargeted) {
plr[p]._pTSpell = spl;
plr[p]._pTSplType = RSPLTYPE_INVALID;
player._pTSpell = spl;
player._pTSplType = RSPLTYPE_INVALID;
if (p == myplr)
NewCursor(CURSOR_TELEPORT);
} else {
ClrPlrPath(plr[p]);
plr[p]._pSpell = spl;
plr[p]._pSplType = RSPLTYPE_INVALID;
plr[p]._pSplFrom = 3;
plr[p].destAction = ACTION_SPELL;
plr[p].destParam1 = cursmx;
plr[p].destParam2 = cursmy;
ClrPlrPath(player);
player._pSpell = spl;
player._pSplType = RSPLTYPE_INVALID;
player._pSplFrom = 3;
player.destAction = ACTION_SPELL;
player.destParam1 = cursmx;
player.destParam2 = cursmy;
if (p == myplr && spl == SPL_NOVA)
NetSendCmdLoc(myplr, true, CMD_NOVA, { cursmx, cursmy });
}
break;
case IMISC_SCROLLT:
if (spelldata[spl].sTargeted) {
plr[p]._pTSpell = spl;
plr[p]._pTSplType = RSPLTYPE_INVALID;
player._pTSpell = spl;
player._pTSplType = RSPLTYPE_INVALID;
if (p == myplr)
NewCursor(CURSOR_TELEPORT);
} else {
ClrPlrPath(plr[p]);
plr[p]._pSpell = spl;
plr[p]._pSplType = RSPLTYPE_INVALID;
plr[p]._pSplFrom = 3;
plr[p].destAction = ACTION_SPELL;
plr[p].destParam1 = cursmx;
plr[p].destParam2 = cursmy;
ClrPlrPath(player);
player._pSpell = spl;
player._pSplType = RSPLTYPE_INVALID;
player._pSplFrom = 3;
player.destAction = ACTION_SPELL;
player.destParam1 = cursmx;
player.destParam2 = cursmy;
}
break;
case IMISC_BOOK:
plr[p]._pMemSpells |= GetSpellBitmask(spl);
if (plr[p]._pSplLvl[spl] < MAX_SPELL_LEVEL)
plr[p]._pSplLvl[spl]++;
if ((plr[p]._pIFlags & ISPL_NOMANA) == 0) {
plr[p]._pMana += spelldata[spl].sManaCost << 6;
plr[p]._pMana = std::min(plr[p]._pMana, plr[p]._pMaxMana);
plr[p]._pManaBase += spelldata[spl].sManaCost << 6;
plr[p]._pManaBase = std::min(plr[p]._pManaBase, plr[p]._pMaxManaBase);
player._pMemSpells |= GetSpellBitmask(spl);
if (player._pSplLvl[spl] < MAX_SPELL_LEVEL)
player._pSplLvl[spl]++;
if ((player._pIFlags & ISPL_NOMANA) == 0) {
player._pMana += spelldata[spl].sManaCost << 6;
player._pMana = std::min(player._pMana, player._pMaxMana);
player._pManaBase += spelldata[spl].sManaCost << 6;
player._pManaBase = std::min(player._pManaBase, player._pMaxManaBase);
}
if (p == myplr)
CalcPlrBookVals(plr[p]);
CalcPlrBookVals(player);
drawmanaflag = true;
break;
case IMISC_MAPOFDOOM:
@ -4047,7 +4039,7 @@ void UseItem(int p, item_misc_id Mid, spell_id spl)
case IMISC_OILPERM:
case IMISC_OILHARD:
case IMISC_OILIMP:
plr[p]._pOilType = Mid;
player._pOilType = Mid;
if (p != myplr) {
return;
}
@ -4066,32 +4058,32 @@ void UseItem(int p, item_misc_id Mid, spell_id spl)
ModifyPlrVit(p, 3);
break;
case IMISC_RUNEF:
plr[p]._pTSpell = SPL_RUNEFIRE;
plr[p]._pTSplType = RSPLTYPE_INVALID;
player._pTSpell = SPL_RUNEFIRE;
player._pTSplType = RSPLTYPE_INVALID;
if (p == myplr)
NewCursor(CURSOR_TELEPORT);
break;
case IMISC_RUNEL:
plr[p]._pTSpell = SPL_RUNELIGHT;
plr[p]._pTSplType = RSPLTYPE_INVALID;
player._pTSpell = SPL_RUNELIGHT;
player._pTSplType = RSPLTYPE_INVALID;
if (p == myplr)
NewCursor(CURSOR_TELEPORT);
break;
case IMISC_GR_RUNEL:
plr[p]._pTSpell = SPL_RUNENOVA;
plr[p]._pTSplType = RSPLTYPE_INVALID;
player._pTSpell = SPL_RUNENOVA;
player._pTSplType = RSPLTYPE_INVALID;
if (p == myplr)
NewCursor(CURSOR_TELEPORT);
break;
case IMISC_GR_RUNEF:
plr[p]._pTSpell = SPL_RUNEIMMOLAT;
plr[p]._pTSplType = RSPLTYPE_INVALID;
player._pTSpell = SPL_RUNEIMMOLAT;
player._pTSplType = RSPLTYPE_INVALID;
if (p == myplr)
NewCursor(CURSOR_TELEPORT);
break;
case IMISC_RUNES:
plr[p]._pTSpell = SPL_RUNESTONE;
plr[p]._pTSplType = RSPLTYPE_INVALID;
player._pTSpell = SPL_RUNESTONE;
player._pTSplType = RSPLTYPE_INVALID;
if (p == myplr)
NewCursor(CURSOR_TELEPORT);
break;
@ -4102,11 +4094,13 @@ void UseItem(int p, item_misc_id Mid, spell_id spl)
bool StoreStatOk(ItemStruct *h)
{
if (plr[myplr]._pStrength < h->_iMinStr)
const auto &myPlayer = plr[myplr];
if (myPlayer._pStrength < h->_iMinStr)
return false;
if (plr[myplr]._pMagic < h->_iMinMag)
if (myPlayer._pMagic < h->_iMinMag)
return false;
if (plr[myplr]._pDexterity < h->_iMinDex)
if (myPlayer._pDexterity < h->_iMinDex)
return false;
return true;
@ -4248,9 +4242,11 @@ static void SpawnOnePremium(int i, int plvl, int myplr)
bool keepgoing = false;
ItemStruct holditem = items[0];
int strength = std::max(plr[myplr].GetMaximumAttributeValue(CharacterAttribute::Strength), plr[myplr]._pStrength);
int dexterity = std::max(plr[myplr].GetMaximumAttributeValue(CharacterAttribute::Dexterity), plr[myplr]._pDexterity);
int magic = std::max(plr[myplr].GetMaximumAttributeValue(CharacterAttribute::Magic), plr[myplr]._pMagic);
auto &myPlayer = plr[myplr];
int strength = std::max(myPlayer.GetMaximumAttributeValue(CharacterAttribute::Strength), myPlayer._pStrength);
int dexterity = std::max(myPlayer.GetMaximumAttributeValue(CharacterAttribute::Dexterity), myPlayer._pDexterity);
int magic = std::max(myPlayer.GetMaximumAttributeValue(CharacterAttribute::Magic), myPlayer._pMagic);
strength *= 1.2;
dexterity *= 1.2;
magic *= 1.2;
@ -4279,7 +4275,7 @@ static void SpawnOnePremium(int i, int plvl, int myplr)
case ITYPE_LARMOR:
case ITYPE_MARMOR:
case ITYPE_HARMOR: {
const auto mostValuablePlayerArmor = plr[myplr].GetMostValuableItem(
const auto mostValuablePlayerArmor = myPlayer.GetMostValuableItem(
[](const ItemStruct &item) {
return item._itype == ITYPE_LARMOR
|| item._itype == ITYPE_MARMOR
@ -4298,7 +4294,7 @@ static void SpawnOnePremium(int i, int plvl, int myplr)
case ITYPE_STAFF:
case ITYPE_RING:
case ITYPE_AMULET: {
const auto mostValuablePlayerItem = plr[myplr].GetMostValuableItem(
const auto mostValuablePlayerItem = myPlayer.GetMostValuableItem(
[](const ItemStruct &item) { return item._itype == items[0]._itype; });
ivalue = mostValuablePlayerItem == nullptr ? 0 : mostValuablePlayerItem->_iIvalue;
@ -4498,10 +4494,12 @@ void SpawnBoy(int lvl)
bool keepgoing = false;
int count = 0;
HeroClass pc = plr[myplr]._pClass;
int strength = std::max(plr[myplr].GetMaximumAttributeValue(CharacterAttribute::Strength), plr[myplr]._pStrength);
int dexterity = std::max(plr[myplr].GetMaximumAttributeValue(CharacterAttribute::Dexterity), plr[myplr]._pDexterity);
int magic = std::max(plr[myplr].GetMaximumAttributeValue(CharacterAttribute::Magic), plr[myplr]._pMagic);
auto &myPlayer = plr[myplr];
HeroClass pc = myPlayer._pClass;
int strength = std::max(myPlayer.GetMaximumAttributeValue(CharacterAttribute::Strength), myPlayer._pStrength);
int dexterity = std::max(myPlayer.GetMaximumAttributeValue(CharacterAttribute::Dexterity), myPlayer._pDexterity);
int magic = std::max(myPlayer.GetMaximumAttributeValue(CharacterAttribute::Magic), myPlayer._pMagic);
strength *= 1.2;
dexterity *= 1.2;
magic *= 1.2;
@ -4532,7 +4530,7 @@ void SpawnBoy(int lvl)
case ITYPE_LARMOR:
case ITYPE_MARMOR:
case ITYPE_HARMOR: {
const auto mostValuablePlayerArmor = plr[myplr].GetMostValuableItem(
const auto mostValuablePlayerArmor = myPlayer.GetMostValuableItem(
[](const ItemStruct &item) {
return item._itype == ITYPE_LARMOR
|| item._itype == ITYPE_MARMOR
@ -4551,7 +4549,7 @@ void SpawnBoy(int lvl)
case ITYPE_STAFF:
case ITYPE_RING:
case ITYPE_AMULET: {
const auto mostValuablePlayerItem = plr[myplr].GetMostValuableItem(
const auto mostValuablePlayerItem = myPlayer.GetMostValuableItem(
[itemType](const ItemStruct &item) { return item._itype == itemType; });
ivalue = mostValuablePlayerItem == nullptr ? 0 : mostValuablePlayerItem->_iIvalue;
@ -4616,14 +4614,16 @@ bool HealerItemOk(int i)
return AllItemsList[i].iSpell == SPL_HEALOTHER && gbIsMultiplayer;
if (!gbIsMultiplayer) {
auto &myPlayer = plr[myplr];
if (AllItemsList[i].iMiscId == IMISC_ELIXSTR)
return !gbIsHellfire || plr[myplr]._pBaseStr < plr[myplr].GetMaximumAttributeValue(CharacterAttribute::Strength);
return !gbIsHellfire || myPlayer._pBaseStr < myPlayer.GetMaximumAttributeValue(CharacterAttribute::Strength);
if (AllItemsList[i].iMiscId == IMISC_ELIXMAG)
return !gbIsHellfire || plr[myplr]._pBaseMag < plr[myplr].GetMaximumAttributeValue(CharacterAttribute::Magic);
return !gbIsHellfire || myPlayer._pBaseMag < myPlayer.GetMaximumAttributeValue(CharacterAttribute::Magic);
if (AllItemsList[i].iMiscId == IMISC_ELIXDEX)
return !gbIsHellfire || plr[myplr]._pBaseDex < plr[myplr].GetMaximumAttributeValue(CharacterAttribute::Dexterity);
return !gbIsHellfire || myPlayer._pBaseDex < myPlayer.GetMaximumAttributeValue(CharacterAttribute::Dexterity);
if (AllItemsList[i].iMiscId == IMISC_ELIXVIT)
return !gbIsHellfire || plr[myplr]._pBaseVit < plr[myplr].GetMaximumAttributeValue(CharacterAttribute::Vitality);
return !gbIsHellfire || myPlayer._pBaseVit < myPlayer.GetMaximumAttributeValue(CharacterAttribute::Vitality);
}
if (AllItemsList[i].iMiscId == IMISC_REJUV)

1
Source/items.h

@ -407,7 +407,6 @@ bool IsUniqueAvailable(int i);
void InitItemGFX();
void InitItems();
void CalcPlrItemVals(int p, bool Loadgfx);
void CalcPlrStaff(int p);
void CalcPlrInv(int p, bool Loadgfx);
void SetPlrHandItem(ItemStruct *h, int idata);
void GetPlrHandSeed(ItemStruct *h);

34
Source/loadsave.cpp

@ -981,31 +981,35 @@ void LoadHotkeys()
if (!file.isValid())
return;
for (auto &spellId : plr[myplr]._pSplHotKey) {
auto &myPlayer = plr[myplr];
for (auto &spellId : myPlayer._pSplHotKey) {
spellId = static_cast<spell_id>(file.nextLE<int32_t>());
}
for (auto &spellType : plr[myplr]._pSplTHotKey) {
for (auto &spellType : myPlayer._pSplTHotKey) {
spellType = static_cast<spell_type>(file.nextLE<int8_t>());
}
plr[myplr]._pRSpell = static_cast<spell_id>(file.nextLE<int32_t>());
plr[myplr]._pRSplType = static_cast<spell_type>(file.nextLE<int8_t>());
myPlayer._pRSpell = static_cast<spell_id>(file.nextLE<int32_t>());
myPlayer._pRSplType = static_cast<spell_type>(file.nextLE<int8_t>());
}
void SaveHotkeys()
{
const size_t nHotkeyTypes = sizeof(plr[myplr]._pSplHotKey) / sizeof(plr[myplr]._pSplHotKey[0]);
const size_t nHotkeySpells = sizeof(plr[myplr]._pSplTHotKey) / sizeof(plr[myplr]._pSplTHotKey[0]);
auto &myPlayer = plr[myplr];
const size_t nHotkeyTypes = sizeof(myPlayer._pSplHotKey) / sizeof(myPlayer._pSplHotKey[0]);
const size_t nHotkeySpells = sizeof(myPlayer._pSplTHotKey) / sizeof(myPlayer._pSplTHotKey[0]);
SaveHelper file("hotkeys", (nHotkeyTypes * 4) + nHotkeySpells + 4 + 1);
for (auto &spellId : plr[myplr]._pSplHotKey) {
for (auto &spellId : myPlayer._pSplHotKey) {
file.writeLE<int32_t>(spellId);
}
for (auto &spellType : plr[myplr]._pSplTHotKey) {
for (auto &spellType : myPlayer._pSplTHotKey) {
file.writeLE<uint8_t>(spellType);
}
file.writeLE<int32_t>(plr[myplr]._pRSpell);
file.writeLE<uint8_t>(plr[myplr]._pRSplType);
file.writeLE<int32_t>(myPlayer._pRSpell);
file.writeLE<uint8_t>(myPlayer._pRSplType);
}
static void LoadMatchingItems(LoadHelper *file, const int n, ItemStruct *pItem)
@ -1037,12 +1041,12 @@ void LoadHeroItems(PlayerStruct &player)
gbIsHellfireSaveGame = gbIsHellfire;
}
void RemoveEmptyInventory(int pnum)
void RemoveEmptyInventory(PlayerStruct &player)
{
for (int i = NUM_INV_GRID_ELEM; i > 0; i--) {
int idx = plr[pnum].InvGrid[i - 1];
if (idx > 0 && plr[pnum].InvList[idx - 1].isEmpty()) {
plr[pnum].RemoveInvItem(idx - 1);
int idx = player.InvGrid[i - 1];
if (idx > 0 && player.InvList[idx - 1].isEmpty()) {
player.RemoveInvItem(idx - 1);
}
};
}
@ -1121,7 +1125,7 @@ void LoadGame(bool firstflag)
if (gbIsHellfireSaveGame != gbIsHellfire) {
ConvertLevels();
RemoveEmptyInventory(myplr);
RemoveEmptyInventory(plr[myplr]);
}
LoadGameLevel(firstflag, ENTRY_LOAD);

6
Source/loadsave.h

@ -19,15 +19,15 @@ _item_indexes RemapItemIdxFromSpawn(_item_indexes i);
_item_indexes RemapItemIdxToSpawn(_item_indexes i);
bool IsHeaderValid(uint32_t magicNumber);
void LoadHotkeys();
void LoadHeroItems(PlayerStruct &pPlayer);
void LoadHeroItems(PlayerStruct &player);
/**
* @brief Remove invalid inventory items from the inventory grid
* @param pnum The id of the player
*/
void RemoveEmptyInventory(int pnum);
void RemoveEmptyInventory(PlayerStruct &player);
void LoadGame(bool firstflag);
void SaveHotkeys();
void SaveHeroItems(PlayerStruct &pPlayer);
void SaveHeroItems(PlayerStruct &player);
void SaveGameData();
void SaveGame();
void SaveLevel();

14
Source/miniwin/misc_msg.cpp

@ -50,28 +50,30 @@ void SetCursorPos(int x, int y)
// Moves the mouse to the first attribute "+" button.
void FocusOnCharInfo()
{
if (invflag || plr[myplr]._pStatPts <= 0)
auto &myPlayer = plr[myplr];
if (invflag || myPlayer._pStatPts <= 0)
return;
// Find the first incrementable stat.
int stat = -1;
for (auto attribute : enum_values<CharacterAttribute>()) {
int max = plr[myplr].GetMaximumAttributeValue(attribute);
int max = myPlayer.GetMaximumAttributeValue(attribute);
switch (attribute) {
case CharacterAttribute::Strength:
if (plr[myplr]._pBaseStr >= max)
if (myPlayer._pBaseStr >= max)
continue;
break;
case CharacterAttribute::Magic:
if (plr[myplr]._pBaseMag >= max)
if (myPlayer._pBaseMag >= max)
continue;
break;
case CharacterAttribute::Dexterity:
if (plr[myplr]._pBaseDex >= max)
if (myPlayer._pBaseDex >= max)
continue;
break;
case CharacterAttribute::Vitality:
if (plr[myplr]._pBaseVit >= max)
if (myPlayer._pBaseVit >= max)
continue;
break;
}

467
Source/missiles.cpp

@ -36,30 +36,33 @@ void GetDamageAmt(int i, int *mind, int *maxd)
assert(myplr >= 0 && myplr < MAX_PLRS);
assert(i >= 0 && i < 64);
sl = plr[myplr]._pSplLvl[i] + plr[myplr]._pISplLvlAdd;
auto &myPlayer = plr[myplr];
sl = myPlayer._pSplLvl[i] + myPlayer._pISplLvlAdd;
switch (i) {
case SPL_FIREBOLT:
*mind = (plr[myplr]._pMagic / 8) + sl + 1;
*maxd = (plr[myplr]._pMagic / 8) + sl + 10;
*mind = (myPlayer._pMagic / 8) + sl + 1;
*maxd = (myPlayer._pMagic / 8) + sl + 10;
break;
case SPL_HEAL: /// BUGFIX: healing calculation is unused
*mind = plr[myplr]._pLevel + sl + 1;
if (plr[myplr]._pClass == HeroClass::Warrior || plr[myplr]._pClass == HeroClass::Monk || plr[myplr]._pClass == HeroClass::Barbarian) {
*mind = myPlayer._pLevel + sl + 1;
if (myPlayer._pClass == HeroClass::Warrior || myPlayer._pClass == HeroClass::Monk || myPlayer._pClass == HeroClass::Barbarian) {
*mind *= 2;
} else if (plr[myplr]._pClass == HeroClass::Rogue || plr[myplr]._pClass == HeroClass::Bard) {
} else if (myPlayer._pClass == HeroClass::Rogue || myPlayer._pClass == HeroClass::Bard) {
*mind += *mind / 2;
}
*maxd = 10;
for (k = 0; k < plr[myplr]._pLevel; k++) {
for (k = 0; k < myPlayer._pLevel; k++) {
*maxd += 4;
}
for (k = 0; k < sl; k++) {
*maxd += 6;
}
if (plr[myplr]._pClass == HeroClass::Warrior || plr[myplr]._pClass == HeroClass::Monk || plr[myplr]._pClass == HeroClass::Barbarian) {
if (myPlayer._pClass == HeroClass::Warrior || myPlayer._pClass == HeroClass::Monk || myPlayer._pClass == HeroClass::Barbarian) {
*maxd *= 2;
} else if (plr[myplr]._pClass == HeroClass::Rogue || plr[myplr]._pClass == HeroClass::Bard) {
} else if (myPlayer._pClass == HeroClass::Rogue || myPlayer._pClass == HeroClass::Bard) {
*maxd += *maxd / 2;
}
*mind = -1;
@ -68,10 +71,10 @@ void GetDamageAmt(int i, int *mind, int *maxd)
case SPL_LIGHTNING:
case SPL_RUNELIGHT:
*mind = 2;
*maxd = plr[myplr]._pLevel + 2;
*maxd = myPlayer._pLevel + 2;
break;
case SPL_FLASH:
*mind = plr[myplr]._pLevel;
*mind = myPlayer._pLevel;
for (k = 0; k < sl; k++) {
*mind += *mind / 8;
}
@ -107,48 +110,48 @@ void GetDamageAmt(int i, int *mind, int *maxd)
case SPL_FIREWALL:
case SPL_LIGHTWALL:
case SPL_FIRERING:
*mind = 2 * plr[myplr]._pLevel + 4;
*maxd = 2 * plr[myplr]._pLevel + 40;
*mind = 2 * myPlayer._pLevel + 4;
*maxd = 2 * myPlayer._pLevel + 40;
break;
case SPL_FIREBALL:
case SPL_RUNEFIRE:
*mind = 2 * plr[myplr]._pLevel + 4;
*mind = 2 * myPlayer._pLevel + 4;
for (k = 0; k < sl; k++) {
*mind += *mind / 8;
}
*maxd = 2 * plr[myplr]._pLevel + 40;
*maxd = 2 * myPlayer._pLevel + 40;
for (k = 0; k < sl; k++) {
*maxd += *maxd / 8;
}
break;
case SPL_GUARDIAN:
*mind = (plr[myplr]._pLevel / 2) + 1;
*mind = (myPlayer._pLevel / 2) + 1;
for (k = 0; k < sl; k++) {
*mind += *mind / 8;
}
*maxd = (plr[myplr]._pLevel / 2) + 10;
*maxd = (myPlayer._pLevel / 2) + 10;
for (k = 0; k < sl; k++) {
*maxd += *maxd / 8;
}
break;
case SPL_CHAIN:
*mind = 4;
*maxd = 2 * plr[myplr]._pLevel + 4;
*maxd = 2 * myPlayer._pLevel + 4;
break;
case SPL_WAVE:
*mind = 6 * (plr[myplr]._pLevel + 1);
*maxd = 6 * (plr[myplr]._pLevel + 10);
*mind = 6 * (myPlayer._pLevel + 1);
*maxd = 6 * (myPlayer._pLevel + 10);
break;
case SPL_NOVA:
case SPL_IMMOLAT:
case SPL_RUNEIMMOLAT:
case SPL_RUNENOVA:
*mind = (plr[myplr]._pLevel + 5) / 2;
*mind = (myPlayer._pLevel + 5) / 2;
for (k = 0; k < sl; k++) {
*mind += *mind / 8;
}
*mind *= 5;
*maxd = (plr[myplr]._pLevel + 30) / 2;
*maxd = (myPlayer._pLevel + 30) / 2;
for (k = 0; k < sl; k++) {
*maxd += *maxd / 8;
}
@ -156,7 +159,7 @@ void GetDamageAmt(int i, int *mind, int *maxd)
break;
case SPL_FLAME:
*mind = 3;
*maxd = plr[myplr]._pLevel + 4;
*maxd = myPlayer._pLevel + 4;
*maxd += *maxd / 2;
break;
case SPL_GOLEM:
@ -165,21 +168,21 @@ void GetDamageAmt(int i, int *mind, int *maxd)
break;
case SPL_APOCA:
*mind = 0;
for (k = 0; k < plr[myplr]._pLevel; k++) {
for (k = 0; k < myPlayer._pLevel; k++) {
*mind += 1;
}
*maxd = 0;
for (k = 0; k < plr[myplr]._pLevel; k++) {
for (k = 0; k < myPlayer._pLevel; k++) {
*maxd += 6;
}
break;
case SPL_ELEMENT:
*mind = 2 * plr[myplr]._pLevel + 4;
*mind = 2 * myPlayer._pLevel + 4;
for (k = 0; k < sl; k++) {
*mind += *mind / 8;
}
/// BUGFIX: add here '*mind /= 2;'
*maxd = 2 * plr[myplr]._pLevel + 40;
*maxd = 2 * myPlayer._pLevel + 40;
for (k = 0; k < sl; k++) {
*maxd += *maxd / 8;
}
@ -187,38 +190,38 @@ void GetDamageAmt(int i, int *mind, int *maxd)
break;
case SPL_CBOLT:
*mind = 1;
*maxd = (plr[myplr]._pMagic / 4) + 1;
*maxd = (myPlayer._pMagic / 4) + 1;
break;
case SPL_HBOLT:
*mind = plr[myplr]._pLevel + 9;
*maxd = plr[myplr]._pLevel + 18;
*mind = myPlayer._pLevel + 9;
*maxd = myPlayer._pLevel + 18;
break;
case SPL_HEALOTHER: /// BUGFIX: healing calculation is unused
*mind = plr[myplr]._pLevel + sl + 1;
if (plr[myplr]._pClass == HeroClass::Warrior || plr[myplr]._pClass == HeroClass::Monk || plr[myplr]._pClass == HeroClass::Barbarian) {
*mind = myPlayer._pLevel + sl + 1;
if (myPlayer._pClass == HeroClass::Warrior || myPlayer._pClass == HeroClass::Monk || myPlayer._pClass == HeroClass::Barbarian) {
*mind *= 2;
}
if (plr[myplr]._pClass == HeroClass::Rogue || plr[myplr]._pClass == HeroClass::Bard) {
if (myPlayer._pClass == HeroClass::Rogue || myPlayer._pClass == HeroClass::Bard) {
*mind += *mind / 2;
}
*maxd = 10;
for (k = 0; k < plr[myplr]._pLevel; k++) {
for (k = 0; k < myPlayer._pLevel; k++) {
*maxd += 4;
}
for (k = 0; k < sl; k++) {
*maxd += 6;
}
if (plr[myplr]._pClass == HeroClass::Warrior || plr[myplr]._pClass == HeroClass::Monk || plr[myplr]._pClass == HeroClass::Barbarian) {
if (myPlayer._pClass == HeroClass::Warrior || myPlayer._pClass == HeroClass::Monk || myPlayer._pClass == HeroClass::Barbarian) {
*maxd *= 2;
}
if (plr[myplr]._pClass == HeroClass::Rogue || plr[myplr]._pClass == HeroClass::Bard) {
if (myPlayer._pClass == HeroClass::Rogue || myPlayer._pClass == HeroClass::Bard) {
*maxd += *maxd / 2;
}
*mind = -1;
*maxd = -1;
break;
case SPL_FLARE:
*mind = (plr[myplr]._pMagic / 2) + 3 * sl - (plr[myplr]._pMagic / 8);
*mind = (myPlayer._pMagic / 2) + 3 * sl - (myPlayer._pMagic / 8);
*maxd = *mind;
break;
}
@ -265,8 +268,10 @@ int GetSpellLevel(int id, spell_id sn)
{
int result;
auto &player = plr[id];
if (id == myplr)
result = plr[id]._pISplLvlAdd + plr[id]._pSplLvl[sn];
result = player._pISplLvlAdd + player._pSplLvl[sn];
else
result = 1;
@ -576,23 +581,24 @@ bool MonsterMHit(int pnum, int m, int mindam, int maxdam, int dist, int t, bool
hit = GenerateRnd(100);
if (pnum != -1) {
const auto &player = plr[pnum];
if (missiledata[t].mType == 0) {
hper = plr[pnum]._pDexterity;
hper += plr[pnum]._pIBonusToHit;
hper += plr[pnum]._pLevel;
hper = player._pDexterity;
hper += player._pIBonusToHit;
hper += player._pLevel;
hper -= monster[m].mArmorClass;
hper -= (dist * dist) / 2;
hper += plr[pnum]._pIEnAc;
hper += player._pIEnAc;
hper += 50;
if (plr[pnum]._pClass == HeroClass::Rogue)
if (player._pClass == HeroClass::Rogue)
hper += 20;
if (plr[pnum]._pClass == HeroClass::Warrior || plr[pnum]._pClass == HeroClass::Bard)
if (player._pClass == HeroClass::Warrior || player._pClass == HeroClass::Bard)
hper += 10;
} else {
hper = plr[pnum]._pMagic - (monster[m].mLevel * 2) - dist + 50;
if (plr[pnum]._pClass == HeroClass::Sorcerer)
hper = player._pMagic - (monster[m].mLevel * 2) - dist + 50;
if (player._pClass == HeroClass::Sorcerer)
hper += 20;
else if (plr[pnum]._pClass == HeroClass::Bard)
else if (player._pClass == HeroClass::Bard)
hper += 10;
}
} else {
@ -618,11 +624,12 @@ bool MonsterMHit(int pnum, int m, int mindam, int maxdam, int dist, int t, bool
dam = mindam + GenerateRnd(maxdam - mindam + 1);
}
if (missiledata[t].mType == 0) {
dam = plr[pnum]._pIBonusDamMod + dam * plr[pnum]._pIBonusDam / 100 + dam;
if (plr[pnum]._pClass == HeroClass::Rogue)
dam += plr[pnum]._pDamageMod;
const auto &player = plr[pnum];
dam = player._pIBonusDamMod + dam * player._pIBonusDam / 100 + dam;
if (player._pClass == HeroClass::Rogue)
dam += player._pDamageMod;
else
dam += (plr[pnum]._pDamageMod / 2);
dam += (player._pDamageMod / 2);
}
if (!shift)
dam <<= 6;
@ -671,15 +678,17 @@ bool PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, bool s
int hit, hper, tac, dam, blk, blkper, resper;
*blocked = false;
if (plr[pnum]._pHitPoints >> 6 <= 0) {
auto &player = plr[pnum];
if (player._pHitPoints >> 6 <= 0) {
return false;
}
if (plr[pnum]._pInvincible) {
if (player._pInvincible) {
return false;
}
if (plr[pnum]._pSpellFlags & 1 && missiledata[mtype].mType == 0) {
if (player._pSpellFlags & 1 && missiledata[mtype].mType == 0) {
return false;
}
@ -689,10 +698,10 @@ bool PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, bool s
hit = 1000;
#endif
if (missiledata[mtype].mType == 0) {
tac = plr[pnum]._pIAC + plr[pnum]._pIBonusAC + plr[pnum]._pDexterity / 5;
tac = player._pIAC + player._pIBonusAC + player._pDexterity / 5;
if (m != -1) {
hper = monster[m].mHit
+ ((monster[m].mLevel - plr[pnum]._pLevel) * 2)
+ ((monster[m].mLevel - player._pLevel) * 2)
+ 30
- (dist * 2) - tac;
} else {
@ -700,7 +709,7 @@ bool PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, bool s
}
} else {
if (m != -1) {
hper = +40 - (plr[pnum]._pLevel * 2) - (dist * 2) + (monster[m].mLevel * 2);
hper = +40 - (player._pLevel * 2) - (dist * 2) + (monster[m].mLevel * 2);
} else {
hper = 40;
}
@ -718,7 +727,7 @@ bool PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, bool s
hper = 30;
}
if ((plr[pnum]._pmode == PM_STAND || plr[pnum]._pmode == PM_ATTACK) && plr[pnum]._pBlockFlag) {
if ((player._pmode == PM_STAND || player._pmode == PM_ATTACK) && player._pBlockFlag) {
blk = GenerateRnd(100);
} else {
blk = 100;
@ -729,9 +738,9 @@ bool PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, bool s
if (mtype == MIS_ACIDPUD)
blk = 100;
if (m != -1)
blkper = plr[pnum]._pBaseToBlk + plr[pnum]._pDexterity - ((monster[m].mLevel - plr[pnum]._pLevel) * 2);
blkper = player._pBaseToBlk + player._pDexterity - ((monster[m].mLevel - player._pLevel) * 2);
else
blkper = plr[pnum]._pBaseToBlk + plr[pnum]._pDexterity;
blkper = player._pBaseToBlk + player._pDexterity;
if (blkper < 0)
blkper = 0;
if (blkper > 100)
@ -739,14 +748,14 @@ bool PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, bool s
switch (missiledata[mtype].mResist) {
case MISR_FIRE:
resper = plr[pnum]._pFireResist;
resper = player._pFireResist;
break;
case MISR_LIGHTNING:
resper = plr[pnum]._pLghtResist;
resper = player._pLghtResist;
break;
case MISR_MAGIC:
case MISR_ACID:
resper = plr[pnum]._pMagResist;
resper = player._pMagResist;
break;
default:
resper = 0;
@ -755,30 +764,30 @@ bool PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, bool s
if (hit < hper) {
if (mtype == MIS_BONESPIRIT) {
dam = plr[pnum]._pHitPoints / 3;
dam = player._pHitPoints / 3;
} else {
if (!shift) {
dam = (mind << 6) + GenerateRnd((maxd - mind + 1) << 6);
if (m == -1)
if ((plr[pnum]._pIFlags & ISPL_ABSHALFTRAP) != 0)
if ((player._pIFlags & ISPL_ABSHALFTRAP) != 0)
dam /= 2;
dam += (plr[pnum]._pIGetHit << 6);
dam += (player._pIGetHit << 6);
} else {
dam = mind + GenerateRnd(maxd - mind + 1);
if (m == -1)
if ((plr[pnum]._pIFlags & ISPL_ABSHALFTRAP) != 0)
if ((player._pIFlags & ISPL_ABSHALFTRAP) != 0)
dam /= 2;
dam += plr[pnum]._pIGetHit;
dam += player._pIGetHit;
}
if (dam < 64)
dam = 64;
}
if ((resper <= 0 || gbIsHellfire) && blk < blkper) {
Direction dir = plr[pnum]._pdir;
Direction dir = player._pdir;
if (m != -1) {
dir = GetDirection(plr[pnum].position.tile, monster[m].position.tile);
dir = GetDirection(player.position.tile, monster[m].position.tile);
}
*blocked = true;
StartPlrBlock(pnum, dir);
@ -791,15 +800,15 @@ bool PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, bool s
ApplyPlrDamage(pnum, 0, 0, dam, earflag);
}
if (plr[pnum]._pHitPoints >> 6 > 0) {
plr[pnum].Say(HeroSpeech::ArghClang);
if (player._pHitPoints >> 6 > 0) {
player.Say(HeroSpeech::ArghClang);
}
return true;
}
if (pnum == myplr) {
ApplyPlrDamage(pnum, 0, 0, dam, earflag);
}
if (plr[pnum]._pHitPoints >> 6 > 0) {
if (player._pHitPoints >> 6 > 0) {
StartPlrHit(pnum, dam, false);
}
return true;
@ -816,7 +825,10 @@ bool Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, b
*blocked = false;
if (plr[p]._pInvincible) {
auto &player = plr[pnum];
auto &target = plr[p];
if (target._pInvincible) {
return false;
}
@ -824,20 +836,20 @@ bool Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, b
return false;
}
if (plr[p]._pSpellFlags & 1 && missiledata[mtype].mType == 0) {
if (target._pSpellFlags & 1 && missiledata[mtype].mType == 0) {
return false;
}
switch (missiledata[mtype].mResist) {
case MISR_FIRE:
resper = plr[p]._pFireResist;
resper = target._pFireResist;
break;
case MISR_LIGHTNING:
resper = plr[p]._pLghtResist;
resper = target._pLghtResist;
break;
case MISR_MAGIC:
case MISR_ACID:
resper = plr[p]._pMagResist;
resper = target._pMagResist;
break;
default:
resper = 0;
@ -845,25 +857,25 @@ bool Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, b
}
hper = GenerateRnd(100);
if (missiledata[mtype].mType == 0) {
hit = plr[pnum]._pIBonusToHit
+ plr[pnum]._pLevel
hit = player._pIBonusToHit
+ player._pLevel
- (dist * dist / 2)
- plr[p]._pDexterity / 5
- plr[p]._pIBonusAC
- plr[p]._pIAC
+ plr[pnum]._pDexterity + 50;
if (plr[pnum]._pClass == HeroClass::Rogue)
- target._pDexterity / 5
- target._pIBonusAC
- target._pIAC
+ player._pDexterity + 50;
if (player._pClass == HeroClass::Rogue)
hit += 20;
if (plr[pnum]._pClass == HeroClass::Warrior || plr[pnum]._pClass == HeroClass::Bard)
if (player._pClass == HeroClass::Warrior || player._pClass == HeroClass::Bard)
hit += 10;
} else {
hit = plr[pnum]._pMagic
- (plr[p]._pLevel * 2)
hit = player._pMagic
- (target._pLevel * 2)
- dist
+ 50;
if (plr[pnum]._pClass == HeroClass::Sorcerer)
if (player._pClass == HeroClass::Sorcerer)
hit += 20;
else if (plr[pnum]._pClass == HeroClass::Bard)
else if (player._pClass == HeroClass::Bard)
hit += 10;
}
if (hit < 5)
@ -871,14 +883,14 @@ bool Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, b
if (hit > 95)
hit = 95;
if (hper < hit) {
if ((plr[p]._pmode == PM_STAND || plr[p]._pmode == PM_ATTACK) && plr[p]._pBlockFlag) {
if ((target._pmode == PM_STAND || target._pmode == PM_ATTACK) && target._pBlockFlag) {
blkper = GenerateRnd(100);
} else {
blkper = 100;
}
if (shift)
blkper = 100;
blk = plr[p]._pDexterity + plr[p]._pBaseToBlk + (plr[p]._pLevel * 2) - (plr[pnum]._pLevel * 2);
blk = target._pDexterity + target._pBaseToBlk + (target._pLevel * 2) - (player._pLevel * 2);
if (blk < 0) {
blk = 0;
@ -888,11 +900,11 @@ bool Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, b
}
if (mtype == MIS_BONESPIRIT) {
dam = plr[p]._pHitPoints / 3;
dam = target._pHitPoints / 3;
} else {
dam = mindam + GenerateRnd(maxdam - mindam + 1);
if (missiledata[mtype].mType == 0)
dam += plr[pnum]._pIBonusDamMod + plr[pnum]._pDamageMod + dam * plr[pnum]._pIBonusDam / 100;
dam += player._pIBonusDamMod + player._pDamageMod + dam * player._pIBonusDam / 100;
if (!shift)
dam <<= 6;
}
@ -902,11 +914,11 @@ bool Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, b
dam -= (dam * resper) / 100;
if (pnum == myplr)
NetSendCmdDamage(true, p, dam);
plr[p].Say(HeroSpeech::ArghClang);
player.Say(HeroSpeech::ArghClang);
return true;
}
if (blkper < blk) {
StartPlrBlock(p, GetDirection(plr[p].position.tile, plr[pnum].position.tile));
StartPlrBlock(p, GetDirection(target.position.tile, player.position.tile));
*blocked = true;
} else {
if (pnum == myplr)
@ -1198,9 +1210,11 @@ void InitMissiles()
{
int mi, src, i, j;
auto &myPlayer = plr[myplr];
AutoMapShowItems = false;
plr[myplr]._pSpellFlags &= ~0x1;
if (plr[myplr]._pInfraFlag) {
myPlayer._pSpellFlags &= ~0x1;
if (myPlayer._pInfraFlag) {
for (i = 0; i < nummissiles; ++i) {
mi = missileactive[i];
if (missile[mi]._mitype == MIS_INFRA) {
@ -1211,14 +1225,14 @@ void InitMissiles()
}
}
if ((plr[myplr]._pSpellFlags & 2) == 2 || (plr[myplr]._pSpellFlags & 4) == 4) {
plr[myplr]._pSpellFlags &= ~0x2;
plr[myplr]._pSpellFlags &= ~0x4;
if ((myPlayer._pSpellFlags & 2) == 2 || (myPlayer._pSpellFlags & 4) == 4) {
myPlayer._pSpellFlags &= ~0x2;
myPlayer._pSpellFlags &= ~0x4;
for (i = 0; i < nummissiles; ++i) {
mi = missileactive[i];
if (missile[mi]._mitype == MIS_BLODBOIL) {
if (missile[mi]._misource == myplr) {
int missingHP = plr[myplr]._pMaxHP - plr[myplr]._pHitPoints;
int missingHP = myPlayer._pMaxHP - myPlayer._pHitPoints;
CalcPlrItemVals(myplr, true);
ApplyPlrDamage(myplr, 0, 1, missingHP + missile[mi]._miVar2);
}
@ -1242,7 +1256,7 @@ void InitMissiles()
dFlags[i][j] &= ~BFLAG_MISSILE;
}
}
plr[myplr].wReflections = 0;
myPlayer.wReflections = 0;
}
void AddHiveExplosion(int mi, Point src, Point dst, int midir, int8_t mienemy, int id, int dam)
@ -1491,21 +1505,21 @@ void AddStealPotions(int mi, Point src, Point dst, int midir, int8_t mienemy, in
int pnum = dPlayer[tx][ty];
if (pnum == 0)
continue;
pnum = pnum > 0 ? pnum - 1 : -(pnum + 1);
auto &player = plr[pnum > 0 ? pnum - 1 : -(pnum + 1)];
bool hasPlayedSFX = false;
for (int si = 0; si < MAXBELTITEMS; si++) {
int ii = -1;
if (plr[pnum].SpdList[si]._itype == ITYPE_MISC) {
if (player.SpdList[si]._itype == ITYPE_MISC) {
if (GenerateRnd(2) == 0)
continue;
switch (plr[pnum].SpdList[si]._iMiscId) {
switch (player.SpdList[si]._iMiscId) {
case IMISC_FULLHEAL:
ii = ItemMiscIdIdx(IMISC_HEAL);
break;
case IMISC_HEAL:
case IMISC_MANA:
plr[pnum].RemoveSpdBarItem(si);
player.RemoveSpdBarItem(si);
break;
case IMISC_FULLMANA:
ii = ItemMiscIdIdx(IMISC_MANA);
@ -1535,10 +1549,10 @@ void AddStealPotions(int mi, Point src, Point dst, int midir, int8_t mienemy, in
}
}
if (ii != -1) {
SetPlrHandItem(&plr[pnum].HoldItem, ii);
GetPlrHandSeed(&plr[pnum].HoldItem);
plr[pnum].HoldItem._iStatFlag = true;
plr[pnum].SpdList[si] = plr[pnum].HoldItem;
SetPlrHandItem(&player.HoldItem, ii);
GetPlrHandSeed(&player.HoldItem);
player.HoldItem._iStatFlag = true;
player.SpdList[si] = plr[pnum].HoldItem;
}
if (!hasPlayedSFX) {
PlaySfxLoc(IS_POPPOP2, tx, ty);
@ -1566,12 +1580,10 @@ void AddManaTrap(int mi, Point src, Point dst, int midir, int8_t mienemy, int id
if (0 < tx && tx < MAXDUNX && 0 < ty && ty < MAXDUNY) {
pid = dPlayer[tx][ty];
if (pid != 0) {
if (pid > 0)
pid = pid - 1;
else
pid = -(pid + 1);
plr[pid]._pMana = 0;
plr[pid]._pManaBase = plr[pid]._pMana + plr[pid]._pMaxManaBase - plr[pid]._pMaxMana;
auto &player = plr[(pid > 0) ? pid - 1 : -(pid + 1)];
player._pMana = 0;
player._pManaBase = player._pMana + player._pMaxManaBase - player._pMaxMana;
CalcPlrInv(pid, false);
drawmanaflag = true;
PlaySfxLoc(TSFX_COW7, tx, ty);
@ -1590,18 +1602,20 @@ void AddSpecArrow(int mi, Point src, Point dst, int midir, int8_t mienemy, int i
av = 0;
if (mienemy == TARGET_MONSTERS) {
if (plr[id]._pClass == HeroClass::Rogue)
av += (plr[id]._pLevel - 1) / 4;
else if (plr[id]._pClass == HeroClass::Warrior || plr[id]._pClass == HeroClass::Bard)
av += (plr[id]._pLevel - 1) / 8;
auto &player = plr[id];
if (player._pClass == HeroClass::Rogue)
av += (player._pLevel - 1) / 4;
else if (player._pClass == HeroClass::Warrior || player._pClass == HeroClass::Bard)
av += (player._pLevel - 1) / 8;
if ((plr[id]._pIFlags & ISPL_QUICKATTACK) != 0)
if ((player._pIFlags & ISPL_QUICKATTACK) != 0)
av++;
if ((plr[id]._pIFlags & ISPL_FASTATTACK) != 0)
if ((player._pIFlags & ISPL_FASTATTACK) != 0)
av += 2;
if ((plr[id]._pIFlags & ISPL_FASTERATTACK) != 0)
if ((player._pIFlags & ISPL_FASTERATTACK) != 0)
av += 4;
if ((plr[id]._pIFlags & ISPL_FASTESTATTACK) != 0)
if ((player._pIFlags & ISPL_FASTESTATTACK) != 0)
av += 8;
}
missile[mi]._mirange = 1;
@ -1748,23 +1762,25 @@ void AddMana(int mi, Point src, Point dst, int midir, int8_t mienemy, int id, in
{
int i, ManaAmount;
auto &player = plr[id];
ManaAmount = (GenerateRnd(10) + 1) << 6;
for (i = 0; i < plr[id]._pLevel; i++) {
for (i = 0; i < player._pLevel; i++) {
ManaAmount += (GenerateRnd(4) + 1) << 6;
}
for (i = 0; i < missile[mi]._mispllvl; i++) {
ManaAmount += (GenerateRnd(6) + 1) << 6;
}
if (plr[id]._pClass == HeroClass::Sorcerer)
if (player._pClass == HeroClass::Sorcerer)
ManaAmount *= 2;
if (plr[id]._pClass == HeroClass::Rogue || plr[id]._pClass == HeroClass::Bard)
if (player._pClass == HeroClass::Rogue || player._pClass == HeroClass::Bard)
ManaAmount += ManaAmount / 2;
plr[id]._pMana += ManaAmount;
if (plr[id]._pMana > plr[id]._pMaxMana)
plr[id]._pMana = plr[id]._pMaxMana;
plr[id]._pManaBase += ManaAmount;
if (plr[id]._pManaBase > plr[id]._pMaxManaBase)
plr[id]._pManaBase = plr[id]._pMaxManaBase;
player._pMana += ManaAmount;
if (player._pMana > player._pMaxMana)
player._pMana = player._pMaxMana;
player._pManaBase += ManaAmount;
if (player._pManaBase > player._pMaxManaBase)
player._pManaBase = player._pMaxManaBase;
UseMana(id, SPL_MANA);
missile[mi]._miDelFlag = true;
drawmanaflag = true;
@ -1772,8 +1788,10 @@ void AddMana(int mi, Point src, Point dst, int midir, int8_t mienemy, int id, in
void AddMagi(int mi, Point src, Point dst, int midir, int8_t mienemy, int id, int dam)
{
plr[id]._pMana = plr[id]._pMaxMana;
plr[id]._pManaBase = plr[id]._pMaxManaBase;
auto &player = plr[id];
player._pMana = player._pMaxMana;
player._pManaBase = player._pMaxManaBase;
UseMana(id, SPL_MAGI);
missile[mi]._miDelFlag = true;
drawmanaflag = true;
@ -1860,22 +1878,23 @@ void AddLArrow(int mi, Point src, Point dst, int midir, int8_t mienemy, int id,
}
int av = 32;
if (mienemy == TARGET_MONSTERS) {
if (plr[id]._pClass == HeroClass::Rogue)
av += (plr[id]._pLevel) / 4;
else if (plr[id]._pClass == HeroClass::Warrior || plr[id]._pClass == HeroClass::Bard)
av += (plr[id]._pLevel) / 8;
auto &player = plr[id];
if (player._pClass == HeroClass::Rogue)
av += (player._pLevel) / 4;
else if (player._pClass == HeroClass::Warrior || player._pClass == HeroClass::Bard)
av += (player._pLevel) / 8;
if (gbIsHellfire) {
if ((plr[id]._pIFlags & ISPL_QUICKATTACK) != 0)
if ((player._pIFlags & ISPL_QUICKATTACK) != 0)
av++;
if ((plr[id]._pIFlags & ISPL_FASTATTACK) != 0)
if ((player._pIFlags & ISPL_FASTATTACK) != 0)
av += 2;
if ((plr[id]._pIFlags & ISPL_FASTERATTACK) != 0)
if ((player._pIFlags & ISPL_FASTERATTACK) != 0)
av += 4;
if ((plr[id]._pIFlags & ISPL_FASTESTATTACK) != 0)
if ((player._pIFlags & ISPL_FASTESTATTACK) != 0)
av += 8;
} else {
if (plr[id]._pClass == HeroClass::Rogue || plr[id]._pClass == HeroClass::Warrior || plr[id]._pClass == HeroClass::Bard)
if (player._pClass == HeroClass::Rogue || player._pClass == HeroClass::Warrior || player._pClass == HeroClass::Bard)
av -= 1;
}
}
@ -1895,21 +1914,22 @@ void AddArrow(int mi, Point src, Point dst, int midir, int8_t mienemy, int id, i
}
int av = 32;
if (mienemy == TARGET_MONSTERS) {
if ((plr[id]._pIFlags & ISPL_RNDARROWVEL) != 0) {
auto &player = plr[id];
if ((player._pIFlags & ISPL_RNDARROWVEL) != 0) {
av = GenerateRnd(32) + 16;
}
if (plr[id]._pClass == HeroClass::Rogue)
av += (plr[id]._pLevel - 1) / 4;
else if (plr[id]._pClass == HeroClass::Warrior || plr[id]._pClass == HeroClass::Bard)
av += (plr[id]._pLevel - 1) / 8;
if (player._pClass == HeroClass::Rogue)
av += (player._pLevel - 1) / 4;
else if (player._pClass == HeroClass::Warrior || player._pClass == HeroClass::Bard)
av += (player._pLevel - 1) / 8;
if (gbIsHellfire) {
if ((plr[id]._pIFlags & ISPL_QUICKATTACK) != 0)
if ((player._pIFlags & ISPL_QUICKATTACK) != 0)
av++;
if ((plr[id]._pIFlags & ISPL_FASTATTACK) != 0)
if ((player._pIFlags & ISPL_FASTATTACK) != 0)
av += 2;
if ((plr[id]._pIFlags & ISPL_FASTERATTACK) != 0)
if ((player._pIFlags & ISPL_FASTERATTACK) != 0)
av += 4;
if ((plr[id]._pIFlags & ISPL_FASTESTATTACK) != 0)
if ((player._pIFlags & ISPL_FASTESTATTACK) != 0)
av += 8;
}
}
@ -2603,13 +2623,15 @@ void AddEtherealize(int mi, Point src, Point dst, int midir, int8_t mienemy, int
{
int i;
missile[mi]._mirange = 16 * plr[id]._pLevel / 2;
auto &player = plr[id];
missile[mi]._mirange = 16 * player._pLevel / 2;
for (i = missile[mi]._mispllvl; i > 0; i--) {
missile[mi]._mirange += missile[mi]._mirange / 8;
}
missile[mi]._mirange += missile[mi]._mirange * plr[id]._pISplDur / 128;
missile[mi]._miVar1 = plr[id]._pHitPoints;
missile[mi]._miVar2 = plr[id]._pHPBase;
missile[mi]._mirange += missile[mi]._mirange * player._pISplDur / 128;
missile[mi]._miVar1 = player._pHitPoints;
missile[mi]._miVar2 = player._pHPBase;
if (mienemy == TARGET_MONSTERS)
UseMana(id, SPL_ETHEREALIZE);
}
@ -2648,26 +2670,28 @@ void AddHeal(int mi, Point src, Point dst, int midir, int8_t mienemy, int id, in
int i;
int HealAmount;
auto &player = plr[id];
HealAmount = (GenerateRnd(10) + 1) << 6;
for (i = 0; i < plr[id]._pLevel; i++) {
for (i = 0; i < player._pLevel; i++) {
HealAmount += (GenerateRnd(4) + 1) << 6;
}
for (i = 0; i < missile[mi]._mispllvl; i++) {
HealAmount += (GenerateRnd(6) + 1) << 6;
}
if (plr[id]._pClass == HeroClass::Warrior || plr[id]._pClass == HeroClass::Barbarian || plr[id]._pClass == HeroClass::Monk)
if (player._pClass == HeroClass::Warrior || player._pClass == HeroClass::Barbarian || player._pClass == HeroClass::Monk)
HealAmount *= 2;
else if (plr[id]._pClass == HeroClass::Rogue || plr[id]._pClass == HeroClass::Bard)
else if (player._pClass == HeroClass::Rogue || player._pClass == HeroClass::Bard)
HealAmount += HealAmount / 2;
plr[id]._pHitPoints += HealAmount;
if (plr[id]._pHitPoints > plr[id]._pMaxHP)
plr[id]._pHitPoints = plr[id]._pMaxHP;
player._pHitPoints += HealAmount;
if (player._pHitPoints > player._pMaxHP)
player._pHitPoints = player._pMaxHP;
plr[id]._pHPBase += HealAmount;
if (plr[id]._pHPBase > plr[id]._pMaxHPBase)
plr[id]._pHPBase = plr[id]._pMaxHPBase;
player._pHPBase += HealAmount;
if (player._pHPBase > player._pMaxHPBase)
player._pHPBase = player._pMaxHPBase;
UseMana(id, SPL_HEAL);
missile[mi]._miDelFlag = true;
@ -2811,22 +2835,22 @@ void AddNova(int mi, Point src, Point dst, int midir, int8_t mienemy, int id, in
void AddBlodboil(int mi, Point src, Point dst, int midir, int8_t mienemy, int id, int dam)
{
if (id == -1 || plr[id]._pSpellFlags & 6 || plr[id]._pHitPoints <= plr[id]._pLevel << 6) {
auto &player = plr[id];
if (player._pSpellFlags & 6 || player._pHitPoints <= player._pLevel << 6) {
missile[mi]._miDelFlag = true;
} else {
UseMana(id, SPL_BLODBOIL);
missile[mi]._miVar1 = id;
int tmp = 3 * plr[id]._pLevel;
int tmp = 3 * player._pLevel;
tmp <<= 7;
plr[id]._pSpellFlags |= 2u;
player._pSpellFlags |= 2U;
missile[mi]._miVar2 = tmp;
int lvl = 2;
if (id > -1)
lvl = plr[id]._pLevel * 2;
int lvl = player._pLevel * 2;
missile[mi]._mirange = lvl + 10 * missile[mi]._mispllvl + 245;
CalcPlrItemVals(id, true);
force_redraw = 255;
plr[id].Say(HeroSpeech::Aaaaargh);
player.Say(HeroSpeech::Aaaaargh);
}
}
@ -3045,10 +3069,11 @@ void AddDiabApoca(int mi, Point src, Point dst, int midir, int8_t mienemy, int i
int players = gbIsMultiplayer ? MAX_PLRS : 1;
for (pnum = 0; pnum < players; pnum++) {
if (!plr[pnum].plractive)
auto &player = plr[pnum];
if (!player.plractive)
continue;
if (LineClearMissile(src, plr[pnum].position.future)) {
AddMissile({ 0, 0 }, plr[pnum].position.future, 0, MIS_BOOM2, mienemy, id, dam, 0);
if (LineClearMissile(src, player.position.future)) {
AddMissile({ 0, 0 }, player.position.future, 0, MIS_BOOM2, mienemy, id, dam, 0);
}
}
missile[mi]._miDelFlag = true;
@ -4017,11 +4042,12 @@ void MI_Town(int i)
}
for (p = 0; p < MAX_PLRS; p++) {
if (plr[p].plractive && currlevel == plr[p].plrlevel && !plr[p]._pLvlChanging && plr[p]._pmode == PM_STAND && plr[p].position.tile == missile[i].position.tile) {
ClrPlrPath(plr[p]);
auto &player = plr[p];
if (player.plractive && currlevel == player.plrlevel && !player._pLvlChanging && player._pmode == PM_STAND && player.position.tile == missile[i].position.tile) {
ClrPlrPath(player);
if (p == myplr) {
NetSendCmdParam1(true, CMD_WARP, missile[i]._misource);
plr[p]._pmode = PM_NEWLVL;
player._pmode = PM_NEWLVL;
}
}
}
@ -4097,29 +4123,29 @@ void MI_Manashield(int i)
void MI_Etherealize(int i)
{
int src;
missile[i]._mirange--;
src = missile[i]._misource;
missile[i].position.tile = plr[src].position.tile;
missile[i].position.traveled.x = plr[src].position.offset.x << 16;
missile[i].position.traveled.y = plr[src].position.offset.y << 16;
if (plr[src]._pmode == PM_WALK3) {
missile[i].position.start = plr[src].position.future;
auto &player = plr[missile[i]._misource];
missile[i].position.tile = player.position.tile;
missile[i].position.traveled.x = player.position.offset.x << 16;
missile[i].position.traveled.y = player.position.offset.y << 16;
if (player._pmode == PM_WALK3) {
missile[i].position.start = player.position.future;
} else {
missile[i].position.start = plr[src].position.tile;
missile[i].position.start = player.position.tile;
}
GetMissilePos(i);
if (plr[src]._pmode == PM_WALK3) {
if (plr[src]._pdir == DIR_W)
if (player._pmode == PM_WALK3) {
if (player._pdir == DIR_W)
missile[i].position.tile.x++;
else
missile[i].position.tile.y++;
}
plr[src]._pSpellFlags |= 1;
if (missile[i]._mirange == 0 || plr[src]._pHitPoints <= 0) {
player._pSpellFlags |= 1;
if (missile[i]._mirange == 0 || player._pHitPoints <= 0) {
missile[i]._miDelFlag = true;
plr[src]._pSpellFlags &= ~0x1;
player._pSpellFlags &= ~0x1;
}
PutMissile(i);
}
@ -4360,21 +4386,23 @@ void MI_Teleport(int i)
if (missile[i]._mirange <= 0) {
missile[i]._miDelFlag = true;
} else {
dPlayer[plr[id].position.tile.x][plr[id].position.tile.y] = 0;
PlrClrTrans(plr[id].position.tile);
plr[id].position.tile = { missile[i].position.tile.x, missile[i].position.tile.y };
plr[id].position.future = plr[id].position.tile;
plr[id].position.old = plr[id].position.tile;
PlrDoTrans(plr[id].position.tile);
auto &player = plr[id];
dPlayer[player.position.tile.x][player.position.tile.y] = 0;
PlrClrTrans(player.position.tile);
player.position.tile = { missile[i].position.tile.x, missile[i].position.tile.y };
player.position.future = player.position.tile;
player.position.old = player.position.tile;
PlrDoTrans(player.position.tile);
missile[i]._miVar1 = 1;
dPlayer[plr[id].position.tile.x][plr[id].position.tile.y] = id + 1;
dPlayer[player.position.tile.x][player.position.tile.y] = id + 1;
if (leveltype != DTYPE_TOWN) {
ChangeLightXY(plr[id]._plid, plr[id].position.tile);
ChangeVisionXY(plr[id]._pvid, plr[id].position.tile);
ChangeLightXY(player._plid, player.position.tile);
ChangeVisionXY(player._pvid, player.position.tile);
}
if (id == myplr) {
ViewX = plr[id].position.tile.x - ScrollInfo.tile.x;
ViewY = plr[id].position.tile.y - ScrollInfo.tile.y;
ViewX = player.position.tile.x - ScrollInfo.tile.x;
ViewY = player.position.tile.y - ScrollInfo.tile.y;
}
}
}
@ -4576,7 +4604,8 @@ void MI_Wave(int i)
int pn = dPiece[na.x][na.y];
assert((DWORD)pn <= MAXTILES);
if (!nMissileTable[pn]) {
AddMissile(na, na + sd, plr[id]._pdir, MIS_FIREMOVE, TARGET_MONSTERS, id, 0, missile[i]._mispllvl);
Direction pdir = plr[id]._pdir;
AddMissile(na, na + sd, pdir, MIS_FIREMOVE, TARGET_MONSTERS, id, 0, missile[i]._mispllvl);
na += dira;
Point nb = src + sd + dirb;
for (int j = 0; j < (missile[i]._mispllvl / 2) + 2; j++) {
@ -4585,7 +4614,7 @@ void MI_Wave(int i)
if (nMissileTable[pn] || f1 || !InDungeonBounds(na)) {
f1 = true;
} else {
AddMissile(na, na + sd, plr[id]._pdir, MIS_FIREMOVE, TARGET_MONSTERS, id, 0, missile[i]._mispllvl);
AddMissile(na, na + sd, pdir, MIS_FIREMOVE, TARGET_MONSTERS, id, 0, missile[i]._mispllvl);
na += dira;
}
pn = dPiece[nb.x][nb.y]; // BUGFIX: dPiece is accessed before check against dungeon size and 0
@ -4593,7 +4622,7 @@ void MI_Wave(int i)
if (nMissileTable[pn] || f2 || !InDungeonBounds(nb)) {
f2 = true;
} else {
AddMissile(nb, nb + sd, plr[id]._pdir, MIS_FIREMOVE, TARGET_MONSTERS, id, 0, missile[i]._mispllvl);
AddMissile(nb, nb + sd, pdir, MIS_FIREMOVE, TARGET_MONSTERS, id, 0, missile[i]._mispllvl);
nb += dirb;
}
}
@ -4636,28 +4665,28 @@ void MI_Blodboil(int i)
int id, hpdif;
missile[i]._mirange--;
if (missile[i]._mirange == 0) {
id = missile[i]._miVar1;
if ((plr[id]._pSpellFlags & 2) == 2) {
plr[id]._pSpellFlags &= ~0x2;
plr[id]._pSpellFlags |= 4;
int lvl = 2;
if (id > -1)
lvl = plr[id]._pLevel * 2;
auto &player = plr[id];
if ((player._pSpellFlags & 2) == 2) {
player._pSpellFlags &= ~0x2;
player._pSpellFlags |= 4;
int lvl = player._pLevel * 2;
missile[i]._mirange = lvl + 10 * missile[i]._mispllvl + 245;
hpdif = plr[id]._pMaxHP - plr[id]._pHitPoints;
hpdif = player._pMaxHP - player._pHitPoints;
CalcPlrItemVals(id, true);
ApplyPlrDamage(id, 0, 1, hpdif);
force_redraw = 255;
plr[id].Say(HeroSpeech::HeavyBreathing);
player.Say(HeroSpeech::HeavyBreathing);
} else {
missile[i]._miDelFlag = true;
plr[id]._pSpellFlags &= ~0x4;
hpdif = plr[id]._pMaxHP - plr[id]._pHitPoints;
player._pSpellFlags &= ~0x4;
hpdif = player._pMaxHP - player._pHitPoints;
CalcPlrItemVals(id, true);
ApplyPlrDamage(id, 0, 1, hpdif + missile[i]._miVar2);
force_redraw = 255;
plr[id].Say(HeroSpeech::HeavyBreathing);
player.Say(HeroSpeech::HeavyBreathing);
}
}
}

2
Source/missiles.h

@ -113,7 +113,7 @@ extern int nummissiles;
extern bool MissilePreFlag;
void GetDamageAmt(int i, int *mind, int *maxd);
int GetSpellLevel(int id, spell_id sn);
int GetSpellLevel(int playerId, spell_id sn);
Direction16 GetDirection16(Point p1, Point p2);
void DeleteMissile(int mi, int i);
bool MonsterTrapHit(int m, int mindam, int maxdam, int dist, int t, bool shift);

20
Source/multi.cpp

@ -859,8 +859,8 @@ void recv_plrinfo(int pnum, TCmdPlrInfoHdr *p, bool recv)
return;
}
ResetPlayerGFX(plr[pnum]);
plr[pnum].plractive = true;
ResetPlayerGFX(player);
player.plractive = true;
gbActivePlayers++;
if (sgbPlayerTurnBitTbl[pnum]) {
@ -868,19 +868,19 @@ void recv_plrinfo(int pnum, TCmdPlrInfoHdr *p, bool recv)
} else {
szEvent = _("Player '{:s}' (level {:d}) is already in the game");
}
EventPlrMsg(fmt::format(szEvent, plr[pnum]._pName, plr[pnum]._pLevel).c_str());
EventPlrMsg(fmt::format(szEvent, player._pName, player._pLevel).c_str());
SyncInitPlr(pnum);
if (plr[pnum].plrlevel == currlevel) {
if (plr[pnum]._pHitPoints >> 6 > 0) {
if (player.plrlevel == currlevel) {
if (player._pHitPoints >> 6 > 0) {
StartStand(pnum, DIR_S);
} else {
plr[pnum]._pgfxnum = 0;
plr[pnum]._pmode = PM_DEATH;
NewPlrAnim(player, player_graphic::Death, DIR_S, plr[pnum]._pDFrames, 1);
plr[pnum].AnimInfo.CurrentFrame = plr[pnum].AnimInfo.NumberOfFrames - 1;
dFlags[plr[pnum].position.tile.x][plr[pnum].position.tile.y] |= BFLAG_DEAD_PLAYER;
player._pgfxnum = 0;
player._pmode = PM_DEATH;
NewPlrAnim(player, player_graphic::Death, DIR_S, player._pDFrames, 1);
player.AnimInfo.CurrentFrame = player.AnimInfo.NumberOfFrames - 1;
dFlags[player.position.tile.x][player.position.tile.y] |= BFLAG_DEAD_PLAYER;
}
}
}

4
Source/pfile.cpp

@ -276,7 +276,7 @@ bool pfile_ui_set_hero_infos(bool (*ui_add_hero_info)(_uiheroinfo *))
pfile_SFileCloseArchive(&archive);
LoadHeroItems(plr[0]);
RemoveEmptyInventory(0);
RemoveEmptyInventory(plr[0]);
CalcPlrInv(0, false);
game_2_ui_player(plr[0], &uihero, hasSaveGame);
@ -402,7 +402,7 @@ void pfile_read_player_from_save(char name[16], int playerId)
UnPackPlayer(&pkplr, playerId, false);
LoadHeroItems(plr[playerId]);
RemoveEmptyInventory(playerId);
RemoveEmptyInventory(plr[playerId]);
CalcPlrInv(playerId, false);
}

17
Source/player.cpp

@ -687,13 +687,8 @@ void LoadPlrGFX(PlayerStruct &player, player_graphic graphic)
SetPlayerGPtrs(pszName, animationData.RawData, animationData.CelSpritesForDirections, animationWidth);
}
void InitPlayerGFX(int pnum)
void InitPlayerGFX(PlayerStruct &player)
{
if ((DWORD)pnum >= MAX_PLRS) {
app_fatal("InitPlayerGFX: illegal player %i", pnum);
}
auto &player = plr[pnum];
if (player._pHitPoints >> 6 == 0) {
player._pgfxnum = 0;
LoadPlrGFX(player, player_graphic::Death);
@ -3602,6 +3597,16 @@ void MakePlrPath(int pnum, Point targetPosition, bool endspace)
player.walkpath[path] = WALK_NONE;
}
void CalcPlrStaff(PlayerStruct &player)
{
player._pISpells = 0;
if (!player.InvBody[INVLOC_HAND_LEFT].isEmpty()
&& player.InvBody[INVLOC_HAND_LEFT]._iStatFlag
&& player.InvBody[INVLOC_HAND_LEFT]._iCharges > 0) {
player._pISpells |= GetSpellBitmask(player.InvBody[INVLOC_HAND_LEFT]._iSpell);
}
}
void CheckPlrSpell()
{
bool addflag = false;

3
Source/player.h

@ -410,7 +410,7 @@ extern bool deathflag;
extern int ToBlkTbl[enum_size<HeroClass>::value];
void LoadPlrGFX(PlayerStruct &player, player_graphic graphic);
void InitPlayerGFX(int pnum);
void InitPlayerGFX(PlayerStruct &player);
void ResetPlayerGFX(PlayerStruct &player);
/**
@ -459,6 +459,7 @@ void ProcessPlayers();
void ClrPlrPath(PlayerStruct &player);
bool PosOkPlayer(int pnum, Point position);
void MakePlrPath(int pnum, Point targetPosition, bool endspace);
void CalcPlrStaff(PlayerStruct &player);
void CheckPlrSpell();
void SyncPlrAnim(int pnum);
void SyncInitPlrPos(int pnum);

10
Source/scrollrt.cpp

@ -422,21 +422,21 @@ static void DrawPlayer(const CelOutputBuffer &out, int pnum, int x, int y, int p
int nCel = player.AnimInfo.GetFrameToUseForRendering();
if (pCelSprite == nullptr) {
Log("Drawing player {} \"{}\": NULL CelSprite", pnum, plr[pnum]._pName);
Log("Drawing player {} \"{}\": NULL CelSprite", pnum, player._pName);
return;
}
int frames = SDL_SwapLE32(*reinterpret_cast<const DWORD *>(pCelSprite->Data()));
if (nCel < 1 || frames > 50 || nCel > frames) {
const char *szMode = "unknown action";
if (plr[pnum]._pmode <= PM_QUIT)
szMode = szPlrModeAssert[plr[pnum]._pmode];
if (player._pmode <= PM_QUIT)
szMode = szPlrModeAssert[player._pmode];
Log(
"Drawing player {} \"{}\" {}: facing {}, frame {} of {}",
pnum,
plr[pnum]._pName,
player._pName,
szMode,
plr[pnum]._pdir,
player._pdir,
nCel,
frames);
return;

47
Source/spells.cpp

@ -14,7 +14,7 @@
namespace devilution {
int GetManaAmount(int id, spell_id sn)
int GetManaAmount(PlayerStruct &player, spell_id sn)
{
int ma; // mana amount
@ -22,7 +22,7 @@ int GetManaAmount(int id, spell_id sn)
int adj = 0;
// spell level
int sl = plr[id]._pSplLvl[sn] + plr[id]._pISplLvlAdd - 1;
int sl = player._pSplLvl[sn] + player._pISplLvlAdd - 1;
if (sl < 0) {
sl = 0;
@ -39,9 +39,9 @@ int GetManaAmount(int id, spell_id sn)
}
if (sn == SPL_HEAL || sn == SPL_HEALOTHER) {
ma = (spelldata[SPL_HEAL].sManaCost + 2 * plr[id]._pLevel - adj);
ma = (spelldata[SPL_HEAL].sManaCost + 2 * player._pLevel - adj);
} else if (spelldata[sn].sManaCost == 255) {
ma = ((BYTE)plr[id]._pMaxManaBase - adj);
ma = ((BYTE)player._pMaxManaBase - adj);
} else {
ma = (spelldata[sn].sManaCost - adj);
}
@ -50,9 +50,9 @@ int GetManaAmount(int id, spell_id sn)
ma = 0;
ma <<= 6;
if (gbIsHellfire && plr[id]._pClass == HeroClass::Sorcerer) {
if (gbIsHellfire && player._pClass == HeroClass::Sorcerer) {
ma /= 2;
} else if (plr[id]._pClass == HeroClass::Rogue || plr[id]._pClass == HeroClass::Monk || plr[id]._pClass == HeroClass::Bard) {
} else if (player._pClass == HeroClass::Rogue || player._pClass == HeroClass::Monk || player._pClass == HeroClass::Bard) {
ma -= ma / 4;
}
@ -73,16 +73,16 @@ void UseMana(int id, spell_id sn)
case RSPLTYPE_INVALID:
break;
case RSPLTYPE_SCROLL:
RemoveScroll(id);
RemoveScroll(plr[id]);
break;
case RSPLTYPE_CHARGES:
UseStaffCharge(id);
UseStaffCharge(plr[id]);
break;
case RSPLTYPE_SPELL:
#ifdef _DEBUG
if (!debug_mode_key_inverted_v) {
#endif
ma = GetManaAmount(id, sn);
ma = GetManaAmount(plr[id], sn);
plr[id]._pMana -= ma;
plr[id]._pManaBase -= ma;
drawmanaflag = true;
@ -169,7 +169,9 @@ bool CheckSpell(int id, spell_id sn, spell_type st, bool manaonly)
if (GetSpellLevel(id, sn) <= 0) {
result = false;
} else {
result = plr[id]._pMana >= GetManaAmount(id, sn);
auto &player = plr[id];
return player._pMana >= GetManaAmount(player, sn);
}
}
}
@ -300,10 +302,13 @@ void DoHealOther(int pnum, int rid)
NewCursor(CURSOR_HAND);
}
if ((char)rid != -1 && (plr[rid]._pHitPoints >> 6) > 0) {
auto &player = plr[pnum];
auto &target = plr[rid];
if ((char)rid != -1 && (target._pHitPoints >> 6) > 0) {
hp = (GenerateRnd(10) + 1) << 6;
for (i = 0; i < plr[pnum]._pLevel; i++) {
for (i = 0; i < player._pLevel; i++) {
hp += (GenerateRnd(4) + 1) << 6;
}
@ -311,24 +316,24 @@ void DoHealOther(int pnum, int rid)
hp += (GenerateRnd(6) + 1) << 6;
}
if (plr[pnum]._pClass == HeroClass::Warrior || plr[pnum]._pClass == HeroClass::Barbarian) {
if (player._pClass == HeroClass::Warrior || player._pClass == HeroClass::Barbarian) {
hp *= 2;
} else if (plr[pnum]._pClass == HeroClass::Rogue || plr[pnum]._pClass == HeroClass::Bard) {
} else if (player._pClass == HeroClass::Rogue || player._pClass == HeroClass::Bard) {
hp += hp / 2;
} else if (plr[pnum]._pClass == HeroClass::Monk) {
} else if (player._pClass == HeroClass::Monk) {
hp *= 3;
}
plr[rid]._pHitPoints += hp;
target._pHitPoints += hp;
if (plr[rid]._pHitPoints > plr[rid]._pMaxHP) {
plr[rid]._pHitPoints = plr[rid]._pMaxHP;
if (target._pHitPoints > target._pMaxHP) {
target._pHitPoints = target._pMaxHP;
}
plr[rid]._pHPBase += hp;
target._pHPBase += hp;
if (plr[rid]._pHPBase > plr[rid]._pMaxHPBase) {
plr[rid]._pHPBase = plr[rid]._pMaxHPBase;
if (target._pHPBase > target._pMaxHPBase) {
target._pHPBase = target._pMaxHPBase;
}
drawhpflag = true;

2
Source/spells.h

@ -9,7 +9,7 @@
namespace devilution {
int GetManaAmount(int id, spell_id sn);
int GetManaAmount(PlayerStruct &player, spell_id sn);
void UseMana(int id, spell_id sn);
bool CheckSpell(int id, spell_id sn, spell_type st, bool manaonly);
void EnsureValidReadiedSpell(PlayerStruct &player);

4
test/inv_test.cpp

@ -203,7 +203,7 @@ TEST(Inv, RemoveScroll_inventory)
plr[myplr].InvList[0]._iMiscId = IMISC_SCROLL;
plr[myplr].InvList[0]._iSpell = SPL_FIREBOLT;
RemoveScroll(myplr);
RemoveScroll(plr[myplr]);
EXPECT_EQ(plr[myplr].InvGrid[0], 0);
EXPECT_EQ(plr[myplr]._pNumInv, 0);
}
@ -221,6 +221,6 @@ TEST(Inv, RemoveScroll_belt)
plr[myplr].SpdList[3]._iMiscId = IMISC_SCROLL;
plr[myplr].SpdList[3]._iSpell = SPL_FIREBOLT;
RemoveScroll(myplr);
RemoveScroll(plr[myplr]);
EXPECT_EQ(plr[myplr].SpdList[3]._itype, ITYPE_NONE);
}

Loading…
Cancel
Save