Browse Source

Player by reference part 2

This mostly change player to be by reference instead of by index.
But additionally it does stript checks for gold in the belt, move some
value types to the initialization and short circute a few functiongs.
pull/2054/head
Anders Jenbo 5 years ago
parent
commit
8a7ec56d3a
  1. 27
      Source/automap.cpp
  2. 477
      Source/control.cpp
  3. 1
      Source/control.h
  4. 112
      Source/controls/plrctrls.cpp
  5. 16
      Source/cursor.cpp
  6. 71
      Source/debug.cpp
  7. 117
      Source/diablo.cpp
  8. 29
      Source/effects.cpp
  9. 14
      Source/gamemenu.cpp
  10. 21
      Source/interfac.cpp
  11. 603
      Source/inv.cpp
  12. 9
      Source/inv.h
  13. 30
      Source/items.cpp
  14. 656
      Source/loadsave.cpp
  15. 4
      Source/loadsave.h
  16. 2
      Source/missiles.cpp
  17. 12
      Source/msg.cpp
  18. 2
      Source/objects.cpp
  19. 30
      Source/pfile.cpp
  20. 152
      Source/player.cpp
  21. 2
      Source/player.h
  22. 34
      Source/portal.cpp
  23. 4
      Source/qol/xpbar.cpp
  24. 35
      Source/scrollrt.cpp
  25. 822
      Source/stores.cpp
  26. 2
      Source/stores.h
  27. 1
      Source/towners.h
  28. 26
      Source/trigs.cpp
  29. 5
      test/control_test.cpp
  30. 12
      test/inv_test.cpp
  31. 10
      test/player_test.cpp
  32. 210
      test/writehero_test.cpp

27
Source/automap.cpp

@ -209,10 +209,11 @@ void DrawAutomapTile(const CelOutputBuffer &out, Point center, uint16_t automapT
void SearchAutomapItem(const CelOutputBuffer &out)
{
Point tile = plr[myplr].position.tile;
if (plr[myplr]._pmode == PM_WALK3) {
tile = plr[myplr].position.future;
if (plr[myplr]._pdir == DIR_W)
auto &myPlayer = plr[myplr];
Point tile = myPlayer.position.tile;
if (myPlayer._pmode == PM_WALK3) {
tile = myPlayer.position.future;
if (myPlayer._pdir == DIR_W)
tile.x++;
else
tile.y++;
@ -256,10 +257,11 @@ void DrawAutomapPlr(const CelOutputBuffer &out, int playerId)
{
int playerColor = MapColorsPlayer + (8 * playerId) % 128;
Point tile = plr[playerId].position.tile;
if (plr[playerId]._pmode == PM_WALK3) {
tile = plr[playerId].position.future;
if (plr[playerId]._pdir == DIR_W)
auto &player = plr[playerId];
Point tile = player.position.tile;
if (player._pmode == PM_WALK3) {
tile = player.position.future;
if (player._pdir == DIR_W)
tile.x++;
else
tile.y++;
@ -269,8 +271,8 @@ void DrawAutomapPlr(const CelOutputBuffer &out, int playerId)
int py = tile.y - 2 * AutomapOffset.y - ViewY;
Point base = {
(plr[playerId].position.offset.x * AutoMapScale / 100 / 2) + (ScrollInfo.offset.x * AutoMapScale / 100 / 2) + (px - py) * AmLine16 + gnScreenWidth / 2,
(plr[playerId].position.offset.y * AutoMapScale / 100 / 2) + (ScrollInfo.offset.y * AutoMapScale / 100 / 2) + (px + py) * AmLine8 + (gnScreenHeight - PANEL_HEIGHT) / 2
(player.position.offset.x * AutoMapScale / 100 / 2) + (ScrollInfo.offset.x * AutoMapScale / 100 / 2) + (px - py) * AmLine16 + gnScreenWidth / 2,
(player.position.offset.y * AutoMapScale / 100 / 2) + (ScrollInfo.offset.y * AutoMapScale / 100 / 2) + (px + py) * AmLine8 + (gnScreenHeight - PANEL_HEIGHT) / 2
};
if (CanPanelsCoverView()) {
@ -281,7 +283,7 @@ void DrawAutomapPlr(const CelOutputBuffer &out, int playerId)
}
base.y -= AmLine8;
switch (plr[playerId]._pdir) {
switch (player._pdir) {
case DIR_N: {
const Point point { base.x, base.y - AmLine16 };
DrawVerticalLine(out, point, AmLine16, playerColor);
@ -615,7 +617,8 @@ void DrawAutomap(const CelOutputBuffer &out)
}
for (unsigned playerId = 0; playerId < MAX_PLRS; playerId++) {
if (plr[playerId].plrlevel == plr[myplr].plrlevel && plr[playerId].plractive && !plr[playerId]._pLvlChanging) {
auto &player = plr[playerId];
if (player.plrlevel == plr[myplr].plrlevel && player.plractive && !player._pLvlChanging) {
DrawAutomapPlr(out, playerId);
}
}

477
Source/control.cpp

@ -298,12 +298,13 @@ void SetSpellTrans(spell_type t)
*/
static void DrawSpell(const CelOutputBuffer &out)
{
spell_id spl = plr[myplr]._pRSpell;
spell_type st = plr[myplr]._pRSplType;
auto &myPlayer = plr[myplr];
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) {
int tlvl = plr[myplr]._pISplLvlAdd + plr[myplr]._pSplLvl[spl];
int tlvl = myPlayer._pISplLvlAdd + myPlayer._pSplLvl[spl];
if (!CheckSpell(myplr, spl, st, true))
st = RSPLTYPE_INVALID;
if (tlvl <= 0)
@ -311,8 +312,6 @@ static void DrawSpell(const CelOutputBuffer &out)
}
if (currlevel == 0 && st != RSPLTYPE_INVALID && !spelldata[spl].sTownSpell)
st = RSPLTYPE_INVALID;
if (plr[myplr]._pRSpell < 0)
st = RSPLTYPE_INVALID;
SetSpellTrans(st);
if (spl != SPL_INVALID)
DrawSpellCel(out, PANEL_X + 565, PANEL_Y + 119, *pSpellCels, SpellITbl[spl]);
@ -320,7 +319,7 @@ static void DrawSpell(const CelOutputBuffer &out)
DrawSpellCel(out, PANEL_X + 565, PANEL_Y + 119, *pSpellCels, 27);
}
static void PrintSBookHotkey(const CelOutputBuffer& out, int x, int y, const std::string &text)
static void PrintSBookHotkey(const CelOutputBuffer &out, int x, int y, const std::string &text)
{
x -= GetLineWidth(text.c_str()) + 5;
x += SPLICONLENGTH;
@ -344,24 +343,25 @@ void DrawSpellList(const CelOutputBuffer &out)
ClearPanel();
for (int i = RSPLTYPE_SKILL; i < RSPLTYPE_INVALID; i++) {
auto &myPlayer = plr[myplr];
switch ((spell_type)i) {
case RSPLTYPE_SKILL:
SetSpellTrans(RSPLTYPE_SKILL);
mask = plr[myplr]._pAblSpells;
mask = myPlayer._pAblSpells;
c = SPLICONLAST + 3;
break;
case RSPLTYPE_SPELL:
mask = plr[myplr]._pMemSpells;
mask = myPlayer._pMemSpells;
c = SPLICONLAST + 4;
break;
case RSPLTYPE_SCROLL:
SetSpellTrans(RSPLTYPE_SCROLL);
mask = plr[myplr]._pScrlSpells;
mask = myPlayer._pScrlSpells;
c = SPLICONLAST + 1;
break;
case RSPLTYPE_CHARGES:
SetSpellTrans(RSPLTYPE_CHARGES);
mask = plr[myplr]._pISpells;
mask = myPlayer._pISpells;
c = SPLICONLAST + 2;
break;
case RSPLTYPE_INVALID:
@ -372,7 +372,7 @@ void DrawSpellList(const CelOutputBuffer &out)
if ((mask & spl) == 0)
continue;
if (i == RSPLTYPE_SPELL) {
s = plr[myplr]._pISplLvlAdd + plr[myplr]._pSplLvl[j];
s = myPlayer._pISplLvlAdd + myPlayer._pSplLvl[j];
if (s < 0)
s = 0;
spell_type trans = RSPLTYPE_INVALID;
@ -388,7 +388,7 @@ void DrawSpellList(const CelOutputBuffer &out)
if (MouseX >= lx && MouseX < lx + SPLICONLENGTH && MouseY >= ly && MouseY < ly + SPLICONLENGTH) {
pSpell = (spell_id)j;
pSplType = (spell_type)i;
if (plr[myplr]._pClass == HeroClass::Monk && j == SPL_SEARCH)
if (myPlayer._pClass == HeroClass::Monk && j == SPL_SEARCH)
pSplType = RSPLTYPE_SKILL;
DrawSpellCel(out, x, y, *pSpellCels, c);
switch (pSplType) {
@ -410,14 +410,14 @@ void DrawSpellList(const CelOutputBuffer &out)
case RSPLTYPE_SCROLL: {
strcpy(infostr, fmt::format(_("Scroll of {:s}"), _(spelldata[pSpell].sNameText)).c_str());
int v = 0;
for (int t = 0; t < plr[myplr]._pNumInv; t++) {
if (!plr[myplr].InvList[t].isEmpty()
&& (plr[myplr].InvList[t]._iMiscId == IMISC_SCROLL || plr[myplr].InvList[t]._iMiscId == IMISC_SCROLLT)
&& plr[myplr].InvList[t]._iSpell == pSpell) {
for (int t = 0; t < myPlayer._pNumInv; t++) {
if (!myPlayer.InvList[t].isEmpty()
&& (myPlayer.InvList[t]._iMiscId == IMISC_SCROLL || myPlayer.InvList[t]._iMiscId == IMISC_SCROLLT)
&& myPlayer.InvList[t]._iSpell == pSpell) {
v++;
}
}
for (auto &item : plr[myplr].SpdList) {
for (auto &item : myPlayer.SpdList) {
if (!item.isEmpty()
&& (item._iMiscId == IMISC_SCROLL || item._iMiscId == IMISC_SCROLLT)
&& item._iSpell == pSpell) {
@ -429,7 +429,7 @@ void DrawSpellList(const CelOutputBuffer &out)
} break;
case RSPLTYPE_CHARGES: {
strcpy(infostr, fmt::format(_("Staff of {:s}"), _(spelldata[pSpell].sNameText)).c_str());
int charges = plr[myplr].InvBody[INVLOC_HAND_LEFT]._iCharges;
int charges = myPlayer.InvBody[INVLOC_HAND_LEFT]._iCharges;
strcpy(tempstr, fmt::format(ngettext("{:d} Charge", "{:d} Charges", charges), charges).c_str());
AddPanelString(tempstr);
} break;
@ -437,7 +437,7 @@ void DrawSpellList(const CelOutputBuffer &out)
break;
}
for (int t = 0; t < 4; t++) {
if (plr[myplr]._pSplHotKey[t] == pSpell && plr[myplr]._pSplTHotKey[t] == pSplType) {
if (myPlayer._pSplHotKey[t] == pSpell && myPlayer._pSplTHotKey[t] == pSplType) {
auto hotkeyName = keymapper.keyNameForAction(quickSpellActionIndexes[t]);
PrintSBookHotkey(out, x, y, hotkeyName);
strcpy(tempstr, fmt::format(_("Spell Hotkey {:s}"), hotkeyName.c_str()).c_str());
@ -463,54 +463,63 @@ void DrawSpellList(const CelOutputBuffer &out)
void SetSpell()
{
spselflag = false;
if (pSpell != SPL_INVALID) {
ClearPanel();
plr[myplr]._pRSpell = pSpell;
plr[myplr]._pRSplType = pSplType;
force_redraw = 255;
if (pSpell == SPL_INVALID) {
return;
}
ClearPanel();
auto &myPlayer = plr[myplr];
myPlayer._pRSpell = pSpell;
myPlayer._pRSplType = pSplType;
force_redraw = 255;
}
void SetSpeedSpell(int slot)
{
if (pSpell != SPL_INVALID) {
for (int i = 0; i < 4; ++i) {
if (plr[myplr]._pSplHotKey[i] == pSpell && plr[myplr]._pSplTHotKey[i] == pSplType)
plr[myplr]._pSplHotKey[i] = SPL_INVALID;
}
plr[myplr]._pSplHotKey[slot] = pSpell;
plr[myplr]._pSplTHotKey[slot] = pSplType;
if (pSpell == SPL_INVALID) {
return;
}
auto &myPlayer = plr[myplr];
for (int i = 0; i < 4; ++i) {
if (myPlayer._pSplHotKey[i] == pSpell && myPlayer._pSplTHotKey[i] == pSplType)
myPlayer._pSplHotKey[i] = SPL_INVALID;
}
myPlayer._pSplHotKey[slot] = pSpell;
myPlayer._pSplTHotKey[slot] = pSplType;
}
void ToggleSpell(int slot)
{
uint64_t spells;
if (plr[myplr]._pSplHotKey[slot] == SPL_INVALID) {
auto &myPlayer = plr[myplr];
if (myPlayer._pSplHotKey[slot] == SPL_INVALID) {
return;
}
switch (plr[myplr]._pSplTHotKey[slot]) {
switch (myPlayer._pSplTHotKey[slot]) {
case RSPLTYPE_SKILL:
spells = plr[myplr]._pAblSpells;
spells = myPlayer._pAblSpells;
break;
case RSPLTYPE_SPELL:
spells = plr[myplr]._pMemSpells;
spells = myPlayer._pMemSpells;
break;
case RSPLTYPE_SCROLL:
spells = plr[myplr]._pScrlSpells;
spells = myPlayer._pScrlSpells;
break;
case RSPLTYPE_CHARGES:
spells = plr[myplr]._pISpells;
spells = myPlayer._pISpells;
break;
case RSPLTYPE_INVALID:
return;
}
if ((spells & GetSpellBitmask(plr[myplr]._pSplHotKey[slot])) != 0) {
plr[myplr]._pRSpell = plr[myplr]._pSplHotKey[slot];
plr[myplr]._pRSplType = plr[myplr]._pSplTHotKey[slot];
if ((spells & GetSpellBitmask(myPlayer._pSplHotKey[slot])) != 0) {
myPlayer._pRSpell = myPlayer._pSplHotKey[slot];
myPlayer._pRSplType = myPlayer._pSplTHotKey[slot];
force_redraw = 255;
}
}
@ -550,7 +559,7 @@ void DrawPanelBox(const CelOutputBuffer &out, int x, int y, int w, int h, int sx
* @param y0 Top of the flask cel section to draw.
* @param y1 Bottom of the flask cel section to draw.
*/
static void DrawFlaskTop(const CelOutputBuffer &out, int sx, int sy, const CelOutputBuffer& celBuf, int y0, int y1)
static void DrawFlaskTop(const CelOutputBuffer &out, int sx, int sy, const CelOutputBuffer &celBuf, int y0, int y1)
{
const BYTE *src = celBuf.at(0, y0);
BYTE *dst = out.at(sx, sy);
@ -588,12 +597,14 @@ static void DrawFlask(const CelOutputBuffer &out, const CelOutputBuffer &celBuf,
void DrawLifeFlask(const CelOutputBuffer &out)
{
auto &myPlayer = plr[myplr];
double p = 0.0;
if (plr[myplr]._pMaxHP > 0) {
p = (double)plr[myplr]._pHitPoints / (double)plr[myplr]._pMaxHP * 80.0;
if (myPlayer._pMaxHP > 0) {
p = (double)myPlayer._pHitPoints / (double)myPlayer._pMaxHP * 80.0;
}
plr[myplr]._pHPPer = p;
int filled = plr[myplr]._pHPPer;
myPlayer._pHPPer = p;
int filled = myPlayer._pHPPer;
if (filled > 80)
filled = 80;
@ -610,12 +621,14 @@ void DrawLifeFlask(const CelOutputBuffer &out)
void UpdateLifeFlask(const CelOutputBuffer &out)
{
auto &myPlayer = plr[myplr];
double p = 0.0;
if (plr[myplr]._pMaxHP > 0) {
p = (double)plr[myplr]._pHitPoints / (double)plr[myplr]._pMaxHP * 80.0;
if (myPlayer._pMaxHP > 0) {
p = (double)myPlayer._pHitPoints / (double)myPlayer._pMaxHP * 80.0;
}
int filled = p;
plr[myplr]._pHPPer = filled;
myPlayer._pHPPer = filled;
if (filled > 69)
filled = 69;
@ -644,19 +657,23 @@ void DrawManaFlask(const CelOutputBuffer &out)
void control_update_life_mana()
{
int maxMana = std::max(plr[myplr]._pMaxMana, 0);
int mana = std::max(plr[myplr]._pMana, 0);
plr[myplr]._pManaPer = maxMana != 0 ? ((double)mana / (double)maxMana * 80.0) : 0;
plr[myplr]._pHPPer = (double)plr[myplr]._pHitPoints / (double)plr[myplr]._pMaxHP * 80.0;
auto &myPlayer = plr[myplr];
int maxMana = std::max(myPlayer._pMaxMana, 0);
int mana = std::max(myPlayer._pMana, 0);
myPlayer._pManaPer = maxMana != 0 ? ((double)mana / (double)maxMana * 80.0) : 0;
myPlayer._pHPPer = (double)myPlayer._pHitPoints / (double)myPlayer._pMaxHP * 80.0;
}
void UpdateManaFlask(const CelOutputBuffer &out)
{
int maxMana = std::max(plr[myplr]._pMaxMana, 0);
int mana = std::max(plr[myplr]._pMana, 0);
auto &myPlayer = plr[myplr];
int maxMana = std::max(myPlayer._pMaxMana, 0);
int mana = std::max(myPlayer._pMana, 0);
int filled = maxMana != 0 ? ((double)mana / (double)maxMana * 80.0) : 0;
plr[myplr]._pManaPer = filled;
myPlayer._pManaPer = filled;
filled = std::min(filled, 69);
if (filled != 69)
@ -729,17 +746,20 @@ void InitControlPan()
pSBkIconCels = LoadCel("Data\\SpellI2.CEL", 37);
sbooktab = 0;
sbookflag = false;
if (plr[myplr]._pClass == HeroClass::Warrior) {
auto &myPlayer = plr[myplr];
if (myPlayer._pClass == HeroClass::Warrior) {
SpellPages[0][0] = SPL_REPAIR;
} else if (plr[myplr]._pClass == HeroClass::Rogue) {
} else if (myPlayer._pClass == HeroClass::Rogue) {
SpellPages[0][0] = SPL_DISARM;
} else if (plr[myplr]._pClass == HeroClass::Sorcerer) {
} else if (myPlayer._pClass == HeroClass::Sorcerer) {
SpellPages[0][0] = SPL_RECHARGE;
} else if (plr[myplr]._pClass == HeroClass::Monk) {
} else if (myPlayer._pClass == HeroClass::Monk) {
SpellPages[0][0] = SPL_SEARCH;
} else if (plr[myplr]._pClass == HeroClass::Bard) {
} else if (myPlayer._pClass == HeroClass::Bard) {
SpellPages[0][0] = SPL_IDENTIFY;
} else if (plr[myplr]._pClass == HeroClass::Barbarian) {
} else if (myPlayer._pClass == HeroClass::Barbarian) {
SpellPages[0][0] = SPL_BLODBOIL;
}
pQLogCel = LoadCel("Data\\Quest.CEL", SPANEL_WIDTH);
@ -785,27 +805,29 @@ void DoSpeedBook()
int x = xo + SPLICONLENGTH / 2;
int y = yo - SPLICONLENGTH / 2;
if (plr[myplr]._pRSpell != SPL_INVALID) {
auto &myPlayer = plr[myplr];
if (myPlayer._pRSpell != SPL_INVALID) {
for (int i = RSPLTYPE_SKILL; i <= RSPLTYPE_CHARGES; i++) {
uint64_t spells;
switch (i) {
case RSPLTYPE_SKILL:
spells = plr[myplr]._pAblSpells;
spells = myPlayer._pAblSpells;
break;
case RSPLTYPE_SPELL:
spells = plr[myplr]._pMemSpells;
spells = myPlayer._pMemSpells;
break;
case RSPLTYPE_SCROLL:
spells = plr[myplr]._pScrlSpells;
spells = myPlayer._pScrlSpells;
break;
case RSPLTYPE_CHARGES:
spells = plr[myplr]._pISpells;
spells = myPlayer._pISpells;
break;
}
uint64_t spell = 1;
for (int j = 1; j < MAX_SPELLS; j++) {
if ((spell & spells) != 0) {
if (j == plr[myplr]._pRSpell && i == plr[myplr]._pRSplType) {
if (j == myPlayer._pRSpell && i == myPlayer._pRSplType) {
x = xo + SPLICONLENGTH / 2;
y = yo - SPLICONLENGTH / 2;
}
@ -847,8 +869,9 @@ void DoPanBtn()
}
if (!spselflag && MouseX >= 565 + PANEL_LEFT && MouseX < 621 + PANEL_LEFT && MouseY >= 64 + PANEL_TOP && MouseY < 120 + PANEL_TOP) {
if ((SDL_GetModState() & KMOD_SHIFT) != 0) {
plr[myplr]._pRSpell = SPL_INVALID;
plr[myplr]._pRSplType = RSPLTYPE_INVALID;
auto &myPlayer = plr[myplr];
myPlayer._pRSpell = SPL_INVALID;
myPlayer._pRSplType = RSPLTYPE_INVALID;
force_redraw = 255;
return;
}
@ -932,9 +955,10 @@ void CheckPanelInfo()
pinfoflag = true;
strcpy(tempstr, _("Hotkey: 's'"));
AddPanelString(tempstr);
spell_id v = plr[myplr]._pRSpell;
auto &myPlayer = plr[myplr];
spell_id v = myPlayer._pRSpell;
if (v != SPL_INVALID) {
switch (plr[myplr]._pRSplType) {
switch (myPlayer._pRSplType) {
case RSPLTYPE_SKILL:
strcpy(tempstr, fmt::format(_("{:s} Skill"), _(spelldata[v].sSkillText)).c_str());
AddPanelString(tempstr);
@ -942,7 +966,7 @@ void CheckPanelInfo()
case RSPLTYPE_SPELL: {
strcpy(tempstr, fmt::format(_("{:s} Spell"), _(spelldata[v].sNameText)).c_str());
AddPanelString(tempstr);
int c = plr[myplr]._pISplLvlAdd + plr[myplr]._pSplLvl[v];
int c = myPlayer._pISplLvlAdd + myPlayer._pSplLvl[v];
if (c < 0)
c = 0;
if (c == 0)
@ -955,14 +979,14 @@ void CheckPanelInfo()
strcpy(tempstr, fmt::format(_("Scroll of {:s}"), _(spelldata[v].sNameText)).c_str());
AddPanelString(tempstr);
int s = 0;
for (int i = 0; i < plr[myplr]._pNumInv; i++) {
if (!plr[myplr].InvList[i].isEmpty()
&& (plr[myplr].InvList[i]._iMiscId == IMISC_SCROLL || plr[myplr].InvList[i]._iMiscId == IMISC_SCROLLT)
&& plr[myplr].InvList[i]._iSpell == v) {
for (int i = 0; i < myPlayer._pNumInv; i++) {
if (!myPlayer.InvList[i].isEmpty()
&& (myPlayer.InvList[i]._iMiscId == IMISC_SCROLL || myPlayer.InvList[i]._iMiscId == IMISC_SCROLLT)
&& myPlayer.InvList[i]._iSpell == v) {
s++;
}
}
for (auto &item : plr[myplr].SpdList) {
for (auto &item : myPlayer.SpdList) {
if (!item.isEmpty()
&& (item._iMiscId == IMISC_SCROLL || item._iMiscId == IMISC_SCROLLT)
&& item._iSpell == v) {
@ -975,7 +999,7 @@ void CheckPanelInfo()
case RSPLTYPE_CHARGES:
strcpy(tempstr, fmt::format(_("Staff of {:s}"), _(spelldata[v].sNameText)).c_str());
AddPanelString(tempstr);
strcpy(tempstr, fmt::format(ngettext("{:d} Charge", "{:d} Charges", plr[myplr].InvBody[INVLOC_HAND_LEFT]._iCharges), plr[myplr].InvBody[INVLOC_HAND_LEFT]._iCharges).c_str());
strcpy(tempstr, fmt::format(ngettext("{:d} Charge", "{:d} Charges", myPlayer.InvBody[INVLOC_HAND_LEFT]._iCharges), myPlayer.InvBody[INVLOC_HAND_LEFT]._iCharges).c_str());
AddPanelString(tempstr);
break;
case RSPLTYPE_INVALID:
@ -1119,21 +1143,22 @@ void DrawInfoBox(const CelOutputBuffer &out)
if (spselflag || trigflag) {
infoclr = UIS_SILVER;
} else if (pcurs >= CURSOR_FIRSTITEM) {
if (plr[myplr].HoldItem._itype == ITYPE_GOLD) {
int nGold = plr[myplr].HoldItem._ivalue;
auto &myPlayer = plr[myplr];
if (myPlayer.HoldItem._itype == ITYPE_GOLD) {
int nGold = myPlayer.HoldItem._ivalue;
strcpy(infostr, fmt::format(ngettext("{:d} gold piece", "{:d} gold pieces", nGold), nGold).c_str());
} else if (!plr[myplr].HoldItem._iStatFlag) {
} else if (!myPlayer.HoldItem._iStatFlag) {
ClearPanel();
AddPanelString(_("Requirements not met"));
pinfoflag = true;
} else {
if (plr[myplr].HoldItem._iIdentified)
strcpy(infostr, plr[myplr].HoldItem._iIName);
if (myPlayer.HoldItem._iIdentified)
strcpy(infostr, myPlayer.HoldItem._iIName);
else
strcpy(infostr, plr[myplr].HoldItem._iName);
if (plr[myplr].HoldItem._iMagical == ITEM_QUALITY_MAGIC)
strcpy(infostr, myPlayer.HoldItem._iName);
if (myPlayer.HoldItem._iMagical == ITEM_QUALITY_MAGIC)
infoclr = UIS_BLUE;
if (plr[myplr].HoldItem._iMagical == ITEM_QUALITY_UNIQUE)
if (myPlayer.HoldItem._iMagical == ITEM_QUALITY_UNIQUE)
infoclr = UIS_GOLD;
}
} else {
@ -1160,11 +1185,12 @@ void DrawInfoBox(const CelOutputBuffer &out)
}
if (pcursplr != -1) {
infoclr = UIS_GOLD;
strcpy(infostr, plr[pcursplr]._pName);
auto &target = plr[pcursplr];
strcpy(infostr, target._pName);
ClearPanel();
strcpy(tempstr, fmt::format(_("{:s}, Level: {:d}"), _(ClassStrTbl[static_cast<std::size_t>(plr[pcursplr]._pClass)]), plr[pcursplr]._pLevel).c_str());
strcpy(tempstr, fmt::format(_("{:s}, Level: {:d}"), _(ClassStrTbl[static_cast<std::size_t>(target._pClass)]), target._pLevel).c_str());
AddPanelString(tempstr);
strcpy(tempstr, fmt::format(_("Hit Points {:d} of {:d}"), plr[pcursplr]._pHitPoints >> 6, plr[pcursplr]._pMaxHP >> 6).c_str());
strcpy(tempstr, fmt::format(_("Hit Points {:d} of {:d}"), target._pHitPoints >> 6, target._pMaxHP >> 6).c_str());
AddPanelString(tempstr);
}
}
@ -1177,71 +1203,73 @@ void DrawChr(const CelOutputBuffer &out)
uint32_t style = UIS_SILVER;
char chrstr[64];
auto &myPlayer = plr[myplr];
CelDrawTo(out, 0, 351, *pChrPanel, 1);
DrawString(out, plr[myplr]._pName, { 20, 32, 131, 0 }, UIS_SILVER | UIS_CENTER);
DrawString(out, myPlayer._pName, { 20, 32, 131, 0 }, UIS_SILVER | UIS_CENTER);
DrawString(out, _(ClassStrTbl[static_cast<std::size_t>(plr[myplr]._pClass)]), { 168, 32, 131, 0 }, UIS_SILVER | UIS_CENTER);
DrawString(out, _(ClassStrTbl[static_cast<std::size_t>(myPlayer._pClass)]), { 168, 32, 131, 0 }, UIS_SILVER | UIS_CENTER);
sprintf(chrstr, "%i", plr[myplr]._pLevel);
sprintf(chrstr, "%i", myPlayer._pLevel);
DrawString(out, chrstr, { 66, 69, 43, 0 }, UIS_SILVER | UIS_CENTER);
sprintf(chrstr, "%i", plr[myplr]._pExperience);
sprintf(chrstr, "%i", myPlayer._pExperience);
DrawString(out, chrstr, { 216, 69, 84, 0 }, UIS_SILVER | UIS_CENTER);
if (plr[myplr]._pLevel == MAXCHARLEVEL - 1) {
if (myPlayer._pLevel == MAXCHARLEVEL - 1) {
strcpy(chrstr, _("None"));
style = UIS_GOLD;
} else {
sprintf(chrstr, "%i", plr[myplr]._pNextExper);
sprintf(chrstr, "%i", myPlayer._pNextExper);
style = UIS_SILVER;
}
DrawString(out, chrstr, { 216, 97, 84, 0 }, style | UIS_CENTER);
sprintf(chrstr, "%i", plr[myplr]._pGold);
sprintf(chrstr, "%i", myPlayer._pGold);
DrawString(out, chrstr, { 216, 146, 84, 0 }, UIS_SILVER | UIS_CENTER);
style = UIS_SILVER;
if (plr[myplr]._pIBonusAC > 0)
if (myPlayer._pIBonusAC > 0)
style = UIS_BLUE;
if (plr[myplr]._pIBonusAC < 0)
if (myPlayer._pIBonusAC < 0)
style = UIS_RED;
sprintf(chrstr, "%i", plr[myplr]._pIBonusAC + plr[myplr]._pIAC + plr[myplr]._pDexterity / 5);
sprintf(chrstr, "%i", myPlayer._pIBonusAC + myPlayer._pIAC + myPlayer._pDexterity / 5);
DrawString(out, chrstr, { 258, 183, 43, 0 }, style | UIS_CENTER);
style = UIS_SILVER;
if (plr[myplr]._pIBonusToHit > 0)
if (myPlayer._pIBonusToHit > 0)
style = UIS_BLUE;
if (plr[myplr]._pIBonusToHit < 0)
if (myPlayer._pIBonusToHit < 0)
style = UIS_RED;
sprintf(chrstr, "%i%%", (plr[myplr]._pDexterity / 2) + plr[myplr]._pIBonusToHit + 50);
sprintf(chrstr, "%i%%", (myPlayer._pDexterity / 2) + myPlayer._pIBonusToHit + 50);
DrawString(out, chrstr, { 258, 211, 43, 0 }, style | UIS_CENTER);
style = UIS_SILVER;
if (plr[myplr]._pIBonusDam > 0)
if (myPlayer._pIBonusDam > 0)
style = UIS_BLUE;
if (plr[myplr]._pIBonusDam < 0)
if (myPlayer._pIBonusDam < 0)
style = UIS_RED;
int mindam = plr[myplr]._pIMinDam;
mindam += plr[myplr]._pIBonusDam * mindam / 100;
mindam += plr[myplr]._pIBonusDamMod;
if (plr[myplr].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_BOW) {
if (plr[myplr]._pClass == HeroClass::Rogue)
mindam += plr[myplr]._pDamageMod;
int mindam = myPlayer._pIMinDam;
mindam += myPlayer._pIBonusDam * mindam / 100;
mindam += myPlayer._pIBonusDamMod;
if (myPlayer.InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_BOW) {
if (myPlayer._pClass == HeroClass::Rogue)
mindam += myPlayer._pDamageMod;
else
mindam += plr[myplr]._pDamageMod / 2;
mindam += myPlayer._pDamageMod / 2;
} else {
mindam += plr[myplr]._pDamageMod;
}
int maxdam = plr[myplr]._pIMaxDam;
maxdam += plr[myplr]._pIBonusDam * maxdam / 100;
maxdam += plr[myplr]._pIBonusDamMod;
if (plr[myplr].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_BOW) {
if (plr[myplr]._pClass == HeroClass::Rogue)
maxdam += plr[myplr]._pDamageMod;
mindam += myPlayer._pDamageMod;
}
int maxdam = myPlayer._pIMaxDam;
maxdam += myPlayer._pIBonusDam * maxdam / 100;
maxdam += myPlayer._pIBonusDamMod;
if (myPlayer.InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_BOW) {
if (myPlayer._pClass == HeroClass::Rogue)
maxdam += myPlayer._pDamageMod;
else
maxdam += plr[myplr]._pDamageMod / 2;
maxdam += myPlayer._pDamageMod / 2;
} else {
maxdam += plr[myplr]._pDamageMod;
maxdam += myPlayer._pDamageMod;
}
sprintf(chrstr, "%i-%i", mindam, maxdam);
if (mindam >= 100 || maxdam >= 100)
@ -1250,10 +1278,10 @@ void DrawChr(const CelOutputBuffer &out)
DrawString(out, chrstr, { 258, 239, 43, 0 }, style | UIS_CENTER, 0);
style = UIS_BLUE;
if (plr[myplr]._pMagResist == 0)
if (myPlayer._pMagResist == 0)
style = UIS_SILVER;
if (plr[myplr]._pMagResist < MAXRESIST) {
sprintf(chrstr, "%i%%", plr[myplr]._pMagResist);
if (myPlayer._pMagResist < MAXRESIST) {
sprintf(chrstr, "%i%%", myPlayer._pMagResist);
} else {
style = UIS_GOLD;
strcpy(chrstr, _(/* TRANSLATORS: UI Constrains. Keep translation short please!*/ "MAX"));
@ -1261,10 +1289,10 @@ void DrawChr(const CelOutputBuffer &out)
DrawString(out, chrstr, { 257, 276, 43, 0 }, style | UIS_CENTER);
style = UIS_BLUE;
if (plr[myplr]._pFireResist == 0)
if (myPlayer._pFireResist == 0)
style = UIS_SILVER;
if (plr[myplr]._pFireResist < MAXRESIST) {
sprintf(chrstr, "%i%%", plr[myplr]._pFireResist);
if (myPlayer._pFireResist < MAXRESIST) {
sprintf(chrstr, "%i%%", myPlayer._pFireResist);
} else {
style = UIS_GOLD;
strcpy(chrstr, _("MAX"));
@ -1272,10 +1300,10 @@ void DrawChr(const CelOutputBuffer &out)
DrawString(out, chrstr, { 257, 304, 43, 0 }, style | UIS_CENTER);
style = UIS_BLUE;
if (plr[myplr]._pLghtResist == 0)
if (myPlayer._pLghtResist == 0)
style = UIS_SILVER;
if (plr[myplr]._pLghtResist < MAXRESIST) {
sprintf(chrstr, "%i%%", plr[myplr]._pLghtResist);
if (myPlayer._pLghtResist < MAXRESIST) {
sprintf(chrstr, "%i%%", myPlayer._pLghtResist);
} else {
style = UIS_GOLD;
strcpy(chrstr, _("MAX"));
@ -1283,97 +1311,97 @@ void DrawChr(const CelOutputBuffer &out)
DrawString(out, chrstr, { 257, 332, 43, 0 }, style | UIS_CENTER);
style = UIS_SILVER;
sprintf(chrstr, "%i", plr[myplr]._pBaseStr);
if (plr[myplr].GetMaximumAttributeValue(CharacterAttribute::Strength) == plr[myplr]._pBaseStr)
sprintf(chrstr, "%i", myPlayer._pBaseStr);
if (myPlayer.GetMaximumAttributeValue(CharacterAttribute::Strength) == myPlayer._pBaseStr)
style = UIS_GOLD;
DrawString(out, chrstr, { 95, 155, 31, 0 }, style | UIS_CENTER);
style = UIS_SILVER;
sprintf(chrstr, "%i", plr[myplr]._pBaseMag);
if (plr[myplr].GetMaximumAttributeValue(CharacterAttribute::Magic) == plr[myplr]._pBaseMag)
sprintf(chrstr, "%i", myPlayer._pBaseMag);
if (myPlayer.GetMaximumAttributeValue(CharacterAttribute::Magic) == myPlayer._pBaseMag)
style = UIS_GOLD;
DrawString(out, chrstr, { 95, 183, 31, 0 }, style | UIS_CENTER);
style = UIS_SILVER;
sprintf(chrstr, "%i", plr[myplr]._pBaseDex);
if (plr[myplr].GetMaximumAttributeValue(CharacterAttribute::Dexterity) == plr[myplr]._pBaseDex)
sprintf(chrstr, "%i", myPlayer._pBaseDex);
if (myPlayer.GetMaximumAttributeValue(CharacterAttribute::Dexterity) == myPlayer._pBaseDex)
style = UIS_GOLD;
DrawString(out, chrstr, { 95, 211, 31, 0 }, style | UIS_CENTER);
style = UIS_SILVER;
sprintf(chrstr, "%i", plr[myplr]._pBaseVit);
if (plr[myplr].GetMaximumAttributeValue(CharacterAttribute::Vitality) == plr[myplr]._pBaseVit)
sprintf(chrstr, "%i", myPlayer._pBaseVit);
if (myPlayer.GetMaximumAttributeValue(CharacterAttribute::Vitality) == myPlayer._pBaseVit)
style = UIS_GOLD;
DrawString(out, chrstr, { 95, 239, 31, 0 }, style | UIS_CENTER);
style = UIS_SILVER;
if (plr[myplr]._pStrength > plr[myplr]._pBaseStr)
if (myPlayer._pStrength > myPlayer._pBaseStr)
style = UIS_BLUE;
if (plr[myplr]._pStrength < plr[myplr]._pBaseStr)
if (myPlayer._pStrength < myPlayer._pBaseStr)
style = UIS_RED;
sprintf(chrstr, "%i", plr[myplr]._pStrength);
sprintf(chrstr, "%i", myPlayer._pStrength);
DrawString(out, chrstr, { 143, 155, 30, 0 }, style | UIS_CENTER);
style = UIS_SILVER;
if (plr[myplr]._pMagic > plr[myplr]._pBaseMag)
if (myPlayer._pMagic > myPlayer._pBaseMag)
style = UIS_BLUE;
if (plr[myplr]._pMagic < plr[myplr]._pBaseMag)
if (myPlayer._pMagic < myPlayer._pBaseMag)
style = UIS_RED;
sprintf(chrstr, "%i", plr[myplr]._pMagic);
sprintf(chrstr, "%i", myPlayer._pMagic);
DrawString(out, chrstr, { 143, 183, 30, 0 }, style | UIS_CENTER);
style = UIS_SILVER;
if (plr[myplr]._pDexterity > plr[myplr]._pBaseDex)
if (myPlayer._pDexterity > myPlayer._pBaseDex)
style = UIS_BLUE;
if (plr[myplr]._pDexterity < plr[myplr]._pBaseDex)
if (myPlayer._pDexterity < myPlayer._pBaseDex)
style = UIS_RED;
sprintf(chrstr, "%i", plr[myplr]._pDexterity);
sprintf(chrstr, "%i", myPlayer._pDexterity);
DrawString(out, chrstr, { 143, 211, 30, 0 }, style | UIS_CENTER);
style = UIS_SILVER;
if (plr[myplr]._pVitality > plr[myplr]._pBaseVit)
if (myPlayer._pVitality > myPlayer._pBaseVit)
style = UIS_BLUE;
if (plr[myplr]._pVitality < plr[myplr]._pBaseVit)
if (myPlayer._pVitality < myPlayer._pBaseVit)
style = UIS_RED;
sprintf(chrstr, "%i", plr[myplr]._pVitality);
sprintf(chrstr, "%i", myPlayer._pVitality);
DrawString(out, chrstr, { 143, 239, 30, 0 }, style | UIS_CENTER);
if (plr[myplr]._pStatPts > 0) {
if (CalcStatDiff(plr[myplr]) < plr[myplr]._pStatPts) {
plr[myplr]._pStatPts = CalcStatDiff(plr[myplr]);
if (myPlayer._pStatPts > 0) {
if (CalcStatDiff(myPlayer) < myPlayer._pStatPts) {
myPlayer._pStatPts = CalcStatDiff(myPlayer);
}
}
if (plr[myplr]._pStatPts > 0) {
sprintf(chrstr, "%i", plr[myplr]._pStatPts);
if (myPlayer._pStatPts > 0) {
sprintf(chrstr, "%i", myPlayer._pStatPts);
DrawString(out, chrstr, { 95, 266, 31, 0 }, UIS_RED | UIS_CENTER);
if (plr[myplr]._pBaseStr < plr[myplr].GetMaximumAttributeValue(CharacterAttribute::Strength))
if (myPlayer._pBaseStr < myPlayer.GetMaximumAttributeValue(CharacterAttribute::Strength))
CelDrawTo(out, 137, 159, *pChrButtons, chrbtn[static_cast<size_t>(CharacterAttribute::Strength)] ? 3 : 2);
if (plr[myplr]._pBaseMag < plr[myplr].GetMaximumAttributeValue(CharacterAttribute::Magic))
if (myPlayer._pBaseMag < myPlayer.GetMaximumAttributeValue(CharacterAttribute::Magic))
CelDrawTo(out, 137, 187, *pChrButtons, chrbtn[static_cast<size_t>(CharacterAttribute::Magic)] ? 5 : 4);
if (plr[myplr]._pBaseDex < plr[myplr].GetMaximumAttributeValue(CharacterAttribute::Dexterity))
if (myPlayer._pBaseDex < myPlayer.GetMaximumAttributeValue(CharacterAttribute::Dexterity))
CelDrawTo(out, 137, 216, *pChrButtons, chrbtn[static_cast<size_t>(CharacterAttribute::Dexterity)] ? 7 : 6);
if (plr[myplr]._pBaseVit < plr[myplr].GetMaximumAttributeValue(CharacterAttribute::Vitality))
if (myPlayer._pBaseVit < myPlayer.GetMaximumAttributeValue(CharacterAttribute::Vitality))
CelDrawTo(out, 137, 244, *pChrButtons, chrbtn[static_cast<size_t>(CharacterAttribute::Vitality)] ? 9 : 8);
}
style = UIS_SILVER;
if (plr[myplr]._pMaxHP > plr[myplr]._pMaxHPBase)
if (myPlayer._pMaxHP > myPlayer._pMaxHPBase)
style = UIS_BLUE;
sprintf(chrstr, "%i", plr[myplr]._pMaxHP >> 6);
sprintf(chrstr, "%i", myPlayer._pMaxHP >> 6);
DrawString(out, chrstr, { 95, 304, 31, 0 }, style | UIS_CENTER);
if (plr[myplr]._pHitPoints != plr[myplr]._pMaxHP)
if (myPlayer._pHitPoints != myPlayer._pMaxHP)
style = UIS_RED;
sprintf(chrstr, "%i", plr[myplr]._pHitPoints >> 6);
sprintf(chrstr, "%i", myPlayer._pHitPoints >> 6);
DrawString(out, chrstr, { 143, 304, 31, 0 }, style | UIS_CENTER);
style = UIS_SILVER;
if (plr[myplr]._pMaxMana > plr[myplr]._pMaxManaBase)
if (myPlayer._pMaxMana > myPlayer._pMaxManaBase)
style = UIS_BLUE;
sprintf(chrstr, "%i", plr[myplr]._pMaxMana >> 6);
sprintf(chrstr, "%i", myPlayer._pMaxMana >> 6);
DrawString(out, chrstr, { 95, 332, 31, 0 }, style | UIS_CENTER);
if (plr[myplr]._pMana != plr[myplr]._pMaxMana)
if (myPlayer._pMana != myPlayer._pMaxMana)
style = UIS_RED;
sprintf(chrstr, "%i", plr[myplr]._pMana >> 6);
sprintf(chrstr, "%i", myPlayer._pMana >> 6);
DrawString(out, chrstr, { 143, 332, 31, 0 }, style | UIS_CENTER);
}
@ -1401,26 +1429,28 @@ void DrawLevelUpIcon(const CelOutputBuffer &out)
void CheckChrBtns()
{
if (chrbtnactive || plr[myplr]._pStatPts == 0)
auto &myPlayer = plr[myplr];
if (chrbtnactive || myPlayer._pStatPts == 0)
return;
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;
default:
@ -1459,26 +1489,26 @@ void ReleaseChrBtns(bool addAllStatPoints)
&& MouseX <= ChrBtnsRect[buttonId].x + ChrBtnsRect[buttonId].w
&& MouseY >= ChrBtnsRect[buttonId].y
&& MouseY <= ChrBtnsRect[buttonId].y + ChrBtnsRect[buttonId].h) {
auto &player = plr[myplr];
auto &myPlayer = plr[myplr];
int statPointsToAdd = 1;
if (addAllStatPoints)
statPointsToAdd = CapStatPointsToAdd(player._pStatPts, player, attribute);
statPointsToAdd = CapStatPointsToAdd(myPlayer._pStatPts, myPlayer, attribute);
switch (attribute) {
case CharacterAttribute::Strength:
NetSendCmdParam1(true, CMD_ADDSTR, statPointsToAdd);
player._pStatPts -= statPointsToAdd;
myPlayer._pStatPts -= statPointsToAdd;
break;
case CharacterAttribute::Magic:
NetSendCmdParam1(true, CMD_ADDMAG, statPointsToAdd);
player._pStatPts -= statPointsToAdd;
myPlayer._pStatPts -= statPointsToAdd;
break;
case CharacterAttribute::Dexterity:
NetSendCmdParam1(true, CMD_ADDDEX, statPointsToAdd);
player._pStatPts -= statPointsToAdd;
myPlayer._pStatPts -= statPointsToAdd;
break;
case CharacterAttribute::Vitality:
NetSendCmdParam1(true, CMD_ADDVIT, statPointsToAdd);
player._pStatPts -= statPointsToAdd;
myPlayer._pStatPts -= statPointsToAdd;
break;
}
}
@ -1535,11 +1565,11 @@ void DrawDurIcon(const CelOutputBuffer &out)
x -= SPANEL_WIDTH - (gnScreenWidth - PANEL_WIDTH) / 2;
}
PlayerStruct *p = &plr[myplr];
x = DrawDurIcon4Item(out, &p->InvBody[INVLOC_HEAD], x, 4);
x = DrawDurIcon4Item(out, &p->InvBody[INVLOC_CHEST], x, 3);
x = DrawDurIcon4Item(out, &p->InvBody[INVLOC_HAND_LEFT], x, 0);
DrawDurIcon4Item(out, &p->InvBody[INVLOC_HAND_RIGHT], x, 0);
auto &myPlayer = plr[myplr];
x = DrawDurIcon4Item(out, &myPlayer.InvBody[INVLOC_HEAD], x, 4);
x = DrawDurIcon4Item(out, &myPlayer.InvBody[INVLOC_CHEST], x, 3);
x = DrawDurIcon4Item(out, &myPlayer.InvBody[INVLOC_HAND_LEFT], x, 0);
DrawDurIcon4Item(out, &myPlayer.InvBody[INVLOC_HAND_RIGHT], x, 0);
}
void RedBack(const CelOutputBuffer &out)
@ -1562,20 +1592,21 @@ static void PrintSBookStr(const CelOutputBuffer &out, int x, int y, const char *
spell_type GetSBookTrans(spell_id ii, bool townok)
{
if ((plr[myplr]._pClass == HeroClass::Monk) && (ii == SPL_SEARCH))
auto &myPlayer = plr[myplr];
if ((myPlayer._pClass == HeroClass::Monk) && (ii == SPL_SEARCH))
return RSPLTYPE_SKILL;
spell_type st = RSPLTYPE_SPELL;
if ((plr[myplr]._pISpells & GetSpellBitmask(ii)) != 0) {
if ((myPlayer._pISpells & GetSpellBitmask(ii)) != 0) {
st = RSPLTYPE_CHARGES;
}
if ((plr[myplr]._pAblSpells & GetSpellBitmask(ii)) != 0) {
if ((myPlayer._pAblSpells & GetSpellBitmask(ii)) != 0) {
st = RSPLTYPE_SKILL;
}
if (st == RSPLTYPE_SPELL) {
if (!CheckSpell(myplr, ii, st, true)) {
st = RSPLTYPE_INVALID;
}
if ((char)(plr[myplr]._pSplLvl[ii] + plr[myplr]._pISplLvlAdd) <= 0) {
if ((char)(myPlayer._pSplLvl[ii] + myPlayer._pISplLvlAdd) <= 0) {
st = RSPLTYPE_INVALID;
}
}
@ -1599,7 +1630,8 @@ void DrawSpellBook(const CelOutputBuffer &out)
}
CelDrawTo(out, sx, 348, *pSBkBtnCel, sbooktab + 1);
}
uint64_t spl = plr[myplr]._pMemSpells | plr[myplr]._pISpells | plr[myplr]._pAblSpells;
auto &myPlayer = plr[myplr];
uint64_t spl = myPlayer._pMemSpells | myPlayer._pISpells | myPlayer._pAblSpells;
int yp = 55;
for (int i = 1; i < 8; i++) {
@ -1608,7 +1640,7 @@ void DrawSpellBook(const CelOutputBuffer &out)
spell_type st = GetSBookTrans(sn, true);
SetSpellTrans(st);
DrawSpellCel(out, RIGHT_PANEL_X + 11, yp, *pSBkIconCels, SpellITbl[sn]);
if (sn == plr[myplr]._pRSpell && st == plr[myplr]._pRSplType) {
if (sn == myPlayer._pRSpell && st == myPlayer._pRSplType) {
SetSpellTrans(RSPLTYPE_SKILL);
DrawSpellCel(out, RIGHT_PANEL_X + 11, yp, *pSBkIconCels, SPLICONLAST);
}
@ -1618,7 +1650,7 @@ void DrawSpellBook(const CelOutputBuffer &out)
strcpy(tempstr, _("Skill"));
break;
case RSPLTYPE_CHARGES: {
int charges = plr[myplr].InvBody[INVLOC_HAND_LEFT]._iCharges;
int charges = myPlayer.InvBody[INVLOC_HAND_LEFT]._iCharges;
strcpy(tempstr, fmt::format(ngettext("Staff ({:d} charge)", "Staff ({:d} charges)", charges), charges).c_str());
} break;
default: {
@ -1635,7 +1667,7 @@ void DrawSpellBook(const CelOutputBuffer &out)
strcpy(tempstr, fmt::format(_(/* TRANSLATORS: Dam refers to damage. UI constrains, keep short please.*/ "Mana: {:d} Dam: 1/3 tgt hp"), mana).c_str());
}
PrintSBookStr(out, 10, yp - 1, tempstr);
int lvl = plr[myplr]._pSplLvl[sn] + plr[myplr]._pISplLvlAdd;
int lvl = myPlayer._pSplLvl[sn] + myPlayer._pISplLvlAdd;
if (lvl < 0) {
lvl = 0;
}
@ -1656,17 +1688,18 @@ void CheckSBook()
{
if (MouseX >= RIGHT_PANEL + 11 && MouseX < RIGHT_PANEL + 48 && MouseY >= 18 && MouseY < 314) {
spell_id sn = SpellPages[sbooktab][(MouseY - 18) / 43];
uint64_t spl = plr[myplr]._pMemSpells | plr[myplr]._pISpells | plr[myplr]._pAblSpells;
auto &myPlayer = plr[myplr];
uint64_t spl = myPlayer._pMemSpells | myPlayer._pISpells | myPlayer._pAblSpells;
if (sn != SPL_INVALID && (spl & GetSpellBitmask(sn)) != 0) {
spell_type st = RSPLTYPE_SPELL;
if ((plr[myplr]._pISpells & GetSpellBitmask(sn)) != 0) {
if ((myPlayer._pISpells & GetSpellBitmask(sn)) != 0) {
st = RSPLTYPE_CHARGES;
}
if ((plr[myplr]._pAblSpells & GetSpellBitmask(sn)) != 0) {
if ((myPlayer._pAblSpells & GetSpellBitmask(sn)) != 0) {
st = RSPLTYPE_SKILL;
}
plr[myplr]._pRSpell = sn;
plr[myplr]._pRSplType = st;
myPlayer._pRSpell = sn;
myPlayer._pRSplType = st;
force_redraw = 255;
}
}
@ -1735,36 +1768,29 @@ void control_drop_gold(char vkey)
}
}
void control_remove_gold(int pnum, int goldIndex)
static void control_set_gold_curs(PlayerStruct &player)
{
if (goldIndex <= INVITEM_INV_LAST) {
int gi = goldIndex - INVITEM_INV_FIRST;
plr[pnum].InvList[gi]._ivalue -= dropGoldValue;
if (plr[pnum].InvList[gi]._ivalue > 0)
SetGoldCurs(pnum, gi);
else
plr[pnum].RemoveInvItem(gi);
} else {
int gi = goldIndex - INVITEM_BELT_FIRST;
plr[pnum].SpdList[gi]._ivalue -= dropGoldValue;
if (plr[pnum].SpdList[gi]._ivalue > 0)
SetSpdbarGoldCurs(pnum, gi);
else
RemoveSpdBarItem(pnum, gi);
}
SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD);
GetGoldSeed(pnum, &plr[pnum].HoldItem);
plr[pnum].HoldItem._ivalue = dropGoldValue;
plr[pnum].HoldItem._iStatFlag = true;
control_set_gold_curs(pnum);
plr[pnum]._pGold = CalculateGold(plr[pnum]);
dropGoldValue = 0;
SetPlrHandGoldCurs(&player.HoldItem);
NewCursor(player.HoldItem._iCurs + CURSOR_FIRSTITEM);
}
void control_set_gold_curs(int pnum)
void control_remove_gold(int pnum, int goldIndex)
{
SetPlrHandGoldCurs(&plr[pnum].HoldItem);
NewCursor(plr[pnum].HoldItem._iCurs + CURSOR_FIRSTITEM);
auto &player = plr[pnum];
int gi = goldIndex - INVITEM_INV_FIRST;
player.InvList[gi]._ivalue -= dropGoldValue;
if (player.InvList[gi]._ivalue > 0)
SetPlrHandGoldCurs(&player.InvList[gi]);
else
player.RemoveInvItem(gi);
SetPlrHandItem(&player.HoldItem, IDI_GOLD);
GetGoldSeed(pnum, &player.HoldItem);
player.HoldItem._ivalue = dropGoldValue;
player.HoldItem._iStatFlag = true;
control_set_gold_curs(player);
player._pGold = CalculateGold(player);
dropGoldValue = 0;
}
void DrawTalkPan(const CelOutputBuffer &out)
@ -1810,8 +1836,9 @@ void DrawTalkPan(const CelOutputBuffer &out)
nCel += 4;
CelDrawTo(out, 172 + PANEL_X, 84 + 18 * talkBtn + PANEL_Y, *pTalkBtns, nCel);
}
if (plr[i].plractive) {
DrawString(out, plr[i]._pName, { x, y + 60 + talkBtn * 18, 204, 0 }, color);
auto &player = plr[i];
if (player.plractive) {
DrawString(out, player._pName, { x, y + 60 + talkBtn * 18, 204, 0 }, color);
}
talkBtn++;

1
Source/control.h

@ -133,7 +133,6 @@ void CheckSBook();
void DrawGoldSplit(const CelOutputBuffer &out, int amount);
void control_drop_gold(char vkey);
void control_remove_gold(int pnum, int goldIndex);
void control_set_gold_curs(int pnum);
void DrawTalkPan(const CelOutputBuffer &out);
bool control_check_talk_btn();
void control_release_talk_btn();

112
Source/controls/plrctrls.cpp

@ -54,15 +54,15 @@ int slot = SLOTXY_INV_FIRST;
*/
int GetRotaryDistance(int x, int y)
{
int d, d1, d2;
auto &myPlayer = plr[myplr];
if (plr[myplr].position.future.x == x && plr[myplr].position.future.y == y)
if (myPlayer.position.future.x == x && myPlayer.position.future.y == y)
return -1;
d1 = plr[myplr]._pdir;
d2 = GetDirection(plr[myplr].position.future, { x, y });
int d1 = myPlayer._pdir;
int d2 = GetDirection(myPlayer.position.future, { x, y });
d = abs(d1 - d2);
int d = abs(d1 - d2);
if (d > 4)
return 4 - (d % 4);
@ -76,7 +76,9 @@ int GetRotaryDistance(int x, int y)
*/
int GetMinDistance(int dx, int dy)
{
return std::max(abs(plr[myplr].position.future.x - dx), abs(plr[myplr].position.future.y - dy));
auto &myPlayer = plr[myplr];
return std::max(abs(myPlayer.position.future.x - dx), abs(myPlayer.position.future.y - dy));
}
/**
@ -326,21 +328,24 @@ void CheckPlayerNearby()
if (pcursmonst != -1)
return;
int spl = plr[myplr]._pRSpell;
auto &myPlayer = plr[myplr];
int spl = myPlayer._pRSpell;
if (gbFriendlyMode && spl != SPL_RESURRECT && spl != SPL_HEALOTHER)
return;
for (int i = 0; i < MAX_PLRS; i++) {
if (i == myplr)
continue;
const int mx = plr[i].position.future.x;
const int my = plr[i].position.future.y;
auto &player = plr[i];
const int mx = player.position.future.x;
const int my = player.position.future.y;
if (dPlayer[mx][my] == 0
|| (dFlags[mx][my] & BFLAG_LIT) == 0
|| (plr[i]._pHitPoints == 0 && spl != SPL_RESURRECT))
|| (player._pHitPoints == 0 && spl != SPL_RESURRECT))
continue;
if (plr[myplr]._pwtype == WT_RANGED || HasRangedSpell() || spl == SPL_HEALOTHER) {
if (myPlayer._pwtype == WT_RANGED || HasRangedSpell() || spl == SPL_HEALOTHER) {
newDdistance = GetDistanceRanged(mx, my);
} else {
newDdistance = GetDistance(mx, my, distance);
@ -582,14 +587,15 @@ std::pair<int, int> GetItemSizeOnSlot(int slot, char &itemInvId)
{
if (slot >= SLOTXY_INV_FIRST && slot <= SLOTXY_INV_LAST) {
int ig = slot - SLOTXY_INV_FIRST;
char ii = plr[myplr].InvGrid[ig];
auto &myPlayer = plr[myplr];
char ii = myPlayer.InvGrid[ig];
if (ii != 0) {
int iv = ii;
if (ii <= 0) {
iv = -ii;
}
ItemStruct &item = plr[myplr].InvList[iv - 1];
ItemStruct &item = myPlayer.InvList[iv - 1];
if (!item.isEmpty()) {
std::pair<int, int> size = GetInvItemSize(item._iCurs + CURSOR_FIRSTITEM);
size.first /= INV_SLOT_SIZE_PX;
@ -679,6 +685,7 @@ void InvMove(AxisDirection dir)
slot = SLOTXY_BELT_LAST;
const int initialSlot = slot;
auto &myPlayer = plr[myplr];
// when item is on cursor (pcurs > 1), this is the real cursor XY
if (dir.x == AxisDirectionX_LEFT) {
@ -693,10 +700,10 @@ void InvMove(AxisDirection dir)
} else if (slot > SLOTXY_BELT_FIRST && slot <= SLOTXY_BELT_LAST) {
slot -= 1;
mousePos = BeltGetSlotCoord(slot);
} else if (plr[myplr].HoldItem._itype == ITYPE_RING) {
} else if (myPlayer.HoldItem._itype == ITYPE_RING) {
slot = SLOTXY_RING_LEFT;
mousePos = InvGetEquipSlotCoord(INVLOC_RING_LEFT);
} else if (plr[myplr].HoldItem.isWeapon() || plr[myplr].HoldItem.isShield()) {
} else if (myPlayer.HoldItem.isWeapon() || myPlayer.HoldItem.isShield()) {
if (slot == SLOTXY_HAND_LEFT_FIRST) {
slot = SLOTXY_HAND_RIGHT_FIRST;
mousePos = InvGetEquipSlotCoord(INVLOC_HAND_RIGHT);
@ -743,10 +750,10 @@ void InvMove(AxisDirection dir)
} else if (slot >= SLOTXY_BELT_FIRST && slot < SLOTXY_BELT_LAST) {
slot += 1;
mousePos = BeltGetSlotCoord(slot);
} else if (plr[myplr].HoldItem._itype == ITYPE_RING) {
} else if (myPlayer.HoldItem._itype == ITYPE_RING) {
slot = SLOTXY_RING_RIGHT;
mousePos = InvGetEquipSlotCoord(INVLOC_RING_RIGHT);
} else if (plr[myplr].HoldItem.isWeapon() || plr[myplr].HoldItem.isShield()) {
} else if (myPlayer.HoldItem.isWeapon() || myPlayer.HoldItem.isShield()) {
if (slot == SLOTXY_HAND_LEFT_FIRST) {
slot = SLOTXY_HAND_RIGHT_FIRST;
mousePos = InvGetEquipSlotCoord(INVLOC_HAND_RIGHT);
@ -788,7 +795,7 @@ void InvMove(AxisDirection dir)
slot -= INV_ROW_SLOT_SIZE;
mousePos = InvGetSlotCoord(slot);
} else if (slot >= SLOTXY_INV_FIRST) {
if (plr[myplr].HoldItem._itype == ITYPE_RING) {
if (myPlayer.HoldItem._itype == ITYPE_RING) {
if (slot >= SLOTXY_INV_ROW1_FIRST && slot <= SLOTXY_INV_ROW1_FIRST + (INV_ROW_SLOT_SIZE / 2) - 1) {
slot = SLOTXY_RING_LEFT;
mousePos = InvGetEquipSlotCoord(INVLOC_RING_LEFT);
@ -796,19 +803,19 @@ void InvMove(AxisDirection dir)
slot = SLOTXY_RING_RIGHT;
mousePos = InvGetEquipSlotCoord(INVLOC_RING_RIGHT);
}
} else if (plr[myplr].HoldItem.isWeapon()) {
} else if (myPlayer.HoldItem.isWeapon()) {
slot = SLOTXY_HAND_LEFT_FIRST;
mousePos = InvGetEquipSlotCoord(INVLOC_HAND_LEFT);
} else if (plr[myplr].HoldItem.isShield()) {
} else if (myPlayer.HoldItem.isShield()) {
slot = SLOTXY_HAND_RIGHT_FIRST;
mousePos = InvGetEquipSlotCoord(INVLOC_HAND_RIGHT);
} else if (plr[myplr].HoldItem.isHelm()) {
} else if (myPlayer.HoldItem.isHelm()) {
slot = SLOTXY_HEAD_FIRST;
mousePos = InvGetEquipSlotCoord(INVLOC_HEAD);
} else if (plr[myplr].HoldItem.isArmor()) {
} else if (myPlayer.HoldItem.isArmor()) {
slot = SLOTXY_CHEST_FIRST;
mousePos = InvGetEquipSlotCoord(INVLOC_CHEST);
} else if (plr[myplr].HoldItem._itype == ITYPE_AMULET) {
} else if (myPlayer.HoldItem._itype == ITYPE_AMULET) {
slot = SLOTXY_AMULET;
mousePos = InvGetEquipSlotCoord(INVLOC_AMULET);
}
@ -854,7 +861,7 @@ void InvMove(AxisDirection dir)
} else if (slot <= (SLOTXY_INV_ROW4_LAST - (icursH28 * INV_ROW_SLOT_SIZE))) {
slot += INV_ROW_SLOT_SIZE;
mousePos = InvGetSlotCoord(slot);
} else if (slot <= SLOTXY_INV_LAST && plr[myplr].HoldItem._itype == ITYPE_MISC && icursW28 == 1 && icursH28 == 1) { // forcing only 1x1 misc items
} else if (slot <= SLOTXY_INV_LAST && myPlayer.HoldItem._itype == ITYPE_MISC && icursW28 == 1 && icursH28 == 1) { // forcing only 1x1 misc items
slot += INV_ROW_SLOT_SIZE;
if (slot > SLOTXY_BELT_LAST)
slot = SLOTXY_BELT_LAST;
@ -905,7 +912,7 @@ void InvMove(AxisDirection dir)
// search the 'first slot' for that item in the inventory, it should have the positive number of that same InvId
if (itemInvId < 0) {
for (int s = 0; s < SLOTXY_INV_LAST - SLOTXY_INV_FIRST; ++s) {
if (plr[myplr].InvGrid[s] == -itemInvId) {
if (myPlayer.InvGrid[s] == -itemInvId) {
slot = SLOTXY_INV_FIRST + s;
break;
}
@ -1093,11 +1100,13 @@ bool CanChangeDirection(const PlayerStruct &player)
void WalkInDir(int playerId, AxisDirection dir)
{
const int x = plr[playerId].position.future.x;
const int y = plr[playerId].position.future.y;
auto &player = plr[playerId];
const int x = player.position.future.x;
const int y = player.position.future.y;
if (dir.x == AxisDirectionX_NONE && dir.y == AxisDirectionY_NONE) {
if (sgbControllerActive && plr[playerId].walkpath[0] != WALK_NONE && plr[playerId].destAction == ACTION_NONE)
if (sgbControllerActive && player.walkpath[0] != WALK_NONE && player.destAction == ACTION_NONE)
NetSendCmdLoc(playerId, true, CMD_WALKXY, { x, y }); // Stop walking
return;
}
@ -1106,8 +1115,8 @@ void WalkInDir(int playerId, AxisDirection dir)
const int dx = x + Offsets[pdir][0];
const int dy = y + Offsets[pdir][1];
if (CanChangeDirection(plr[playerId]))
plr[playerId]._pdir = pdir;
if (CanChangeDirection(player))
player._pdir = pdir;
if (PosOkPlayer(playerId, dx, dy) && IsPathBlocked(x, y, pdir))
return; // Don't start backtrack around obstacles
@ -1227,18 +1236,19 @@ void StoreSpellCoords()
int yo = endY;
for (int i = RSPLTYPE_SKILL; i <= RSPLTYPE_CHARGES; i++) {
std::uint64_t spells;
auto &myPlayer = plr[myplr];
switch (i) {
case RSPLTYPE_SKILL:
spells = plr[myplr]._pAblSpells;
spells = myPlayer._pAblSpells;
break;
case RSPLTYPE_SPELL:
spells = plr[myplr]._pMemSpells;
spells = myPlayer._pMemSpells;
break;
case RSPLTYPE_SCROLL:
spells = plr[myplr]._pScrlSpells;
spells = myPlayer._pScrlSpells;
break;
case RSPLTYPE_CHARGES:
spells = plr[myplr]._pISpells;
spells = myPlayer._pISpells;
break;
}
std::uint64_t spell = 1;
@ -1363,12 +1373,13 @@ void plrctrls_after_game_logic()
void UseBeltItem(int type)
{
for (int i = 0; i < MAXBELTITEMS; i++) {
const int id = AllItemsList[plr[myplr].SpdList[i].IDidx].iMiscId;
const int spellId = AllItemsList[plr[myplr].SpdList[i].IDidx].iSpell;
auto &myPlayer = plr[myplr];
const int id = AllItemsList[myPlayer.SpdList[i].IDidx].iMiscId;
const int spellId = AllItemsList[myPlayer.SpdList[i].IDidx].iSpell;
if ((type == BLT_HEALING && (id == IMISC_HEAL || id == IMISC_FULLHEAL || (id == IMISC_SCROLL && spellId == SPL_HEAL)))
|| (type == BLT_MANA && (id == IMISC_MANA || id == IMISC_FULLMANA))
|| id == IMISC_REJUV || id == IMISC_FULLREJUV) {
if (plr[myplr].SpdList[i]._itype > -1) {
if (myPlayer.SpdList[i]._itype > -1) {
UseInvItem(myplr, INVITEM_BELT_FIRST + i);
break;
}
@ -1433,14 +1444,12 @@ void UpdateSpellTarget()
pcursplr = -1;
pcursmonst = -1;
const PlayerStruct &player = plr[myplr];
int range = 1;
if (plr[myplr]._pRSpell == SPL_TELEPORT)
range = 4;
cursmx = player.position.future.x + Offsets[player._pdir][0] * range;
cursmy = player.position.future.y + Offsets[player._pdir][1] * range;
cursmx = plr[myplr].position.future.x + Offsets[plr[myplr]._pdir][0] * range;
cursmy = plr[myplr].position.future.y + Offsets[plr[myplr]._pdir][1] * range;
}
/**
@ -1448,12 +1457,14 @@ void UpdateSpellTarget()
*/
bool TryDropItem()
{
cursmx = plr[myplr].position.future.x + 1;
cursmy = plr[myplr].position.future.y;
const auto &myPlayer = plr[myplr];
cursmx = myPlayer.position.future.x + 1;
cursmy = myPlayer.position.future.y;
if (!DropItemBeforeTrig()) {
// Try to drop on the other side
cursmx = plr[myplr].position.future.x;
cursmy = plr[myplr].position.future.y + 1;
cursmx = myPlayer.position.future.x;
cursmy = myPlayer.position.future.y + 1;
DropItemBeforeTrig();
}
@ -1488,10 +1499,11 @@ void PerformSpellAction()
return;
}
int spl = plr[myplr]._pRSpell;
const auto &myPlayer = plr[myplr];
int spl = myPlayer._pRSpell;
if ((pcursplr == -1 && (spl == SPL_RESURRECT || spl == SPL_HEALOTHER))
|| (pcursobj == -1 && spl == SPL_DISARM)) {
plr[myplr].Say(HeroSpeech::ICantCastThatHere);
myPlayer.Say(HeroSpeech::ICantCastThatHere);
return;
}
@ -1506,10 +1518,12 @@ void CtrlUseInvItem()
if (pcursinvitem == -1)
return;
auto &myPlayer = plr[myplr];
if (pcursinvitem <= INVITEM_INV_LAST)
item = &plr[myplr].InvList[pcursinvitem - INVITEM_INV_FIRST];
item = &myPlayer.InvList[pcursinvitem - INVITEM_INV_FIRST];
else
item = &plr[myplr].SpdList[pcursinvitem - INVITEM_BELT_FIRST];
item = &myPlayer.SpdList[pcursinvitem - INVITEM_BELT_FIRST];
if ((item->_iMiscId == IMISC_SCROLLT || item->_iMiscId == IMISC_SCROLL) && spelldata[item->_iSpell].sTargeted) {
return;

16
Source/cursor.cpp

@ -278,18 +278,18 @@ void CheckCursMove()
// Adjust by player offset and tile grid alignment
CalcTileOffset(&xo, &yo);
PlayerStruct *pPlayer = &plr[myplr];
const auto &myPlayer = plr[myplr];
Point offset = ScrollInfo.offset;
if (pPlayer->IsWalking())
offset = GetOffsetForWalking(pPlayer->AnimInfo, pPlayer->_pdir, true);
if (myPlayer.IsWalking())
offset = GetOffsetForWalking(myPlayer.AnimInfo, myPlayer._pdir, true);
sx -= offset.x - xo;
sy -= offset.y - yo;
// Predict the next frame when walking to avoid input jitter
fx = plr[myplr].position.offset2.x / 256;
fy = plr[myplr].position.offset2.y / 256;
fx -= (plr[myplr].position.offset2.x + plr[myplr].position.velocity.x) / 256;
fy -= (plr[myplr].position.offset2.y + plr[myplr].position.velocity.y) / 256;
fx = myPlayer.position.offset2.x / 256;
fy = myPlayer.position.offset2.y / 256;
fx -= (myPlayer.position.offset2.x + myPlayer.position.velocity.x) / 256;
fy -= (myPlayer.position.offset2.y + myPlayer.position.velocity.y) / 256;
if (ScrollInfo._sdir != SDIR_NONE) {
sx -= fx;
sy -= fy;
@ -364,7 +364,7 @@ void CheckCursMove()
panelflag = false;
trigflag = false;
if (plr[myplr]._pInvincible) {
if (myPlayer._pInvincible) {
return;
}
if (pcurs >= CURSOR_FIRSTITEM || spselflag) {

71
Source/debug.cpp

@ -53,54 +53,57 @@ void CheckDungeonClear()
void GiveGoldCheat()
{
int i, ni;
for (i = 0; i < NUM_INV_GRID_ELEM; i++) {
if (plr[myplr].InvGrid[i] == 0) {
ni = plr[myplr]._pNumInv++;
SetPlrHandItem(&plr[myplr].InvList[ni], IDI_GOLD);
GetPlrHandSeed(&plr[myplr].InvList[ni]);
plr[myplr].InvList[ni]._ivalue = GOLD_MAX_LIMIT;
plr[myplr].InvList[ni]._iCurs = ICURS_GOLD_LARGE;
plr[myplr]._pGold += GOLD_MAX_LIMIT;
plr[myplr].InvGrid[i] = plr[myplr]._pNumInv;
auto &myPlayer = plr[myplr];
for (int i = 0; i < NUM_INV_GRID_ELEM; i++) {
if (myPlayer.InvGrid[i] == 0) {
int ni = myPlayer._pNumInv++;
SetPlrHandItem(&myPlayer.InvList[ni], IDI_GOLD);
GetPlrHandSeed(&myPlayer.InvList[ni]);
myPlayer.InvList[ni]._ivalue = GOLD_MAX_LIMIT;
myPlayer.InvList[ni]._iCurs = ICURS_GOLD_LARGE;
myPlayer._pGold += GOLD_MAX_LIMIT;
myPlayer.InvGrid[i] = myPlayer._pNumInv;
}
}
}
void TakeGoldCheat()
{
int i;
char ig;
auto &myPlayer = plr[myplr];
for (i = 0; i < NUM_INV_GRID_ELEM; i++) {
ig = plr[myplr].InvGrid[i];
if (ig > 0 && plr[myplr].InvList[ig - 1]._itype == ITYPE_GOLD)
plr[myplr].RemoveInvItem(ig - 1);
for (int i = 0; i < NUM_INV_GRID_ELEM; i++) {
int8_t ig = myPlayer.InvGrid[i];
if (ig > 0 && myPlayer.InvList[ig - 1]._itype == ITYPE_GOLD)
myPlayer.RemoveInvItem(ig - 1);
}
for (i = 0; i < MAXBELTITEMS; i++) {
if (plr[myplr].SpdList[i]._itype == ITYPE_GOLD)
plr[myplr].SpdList[i]._itype = ITYPE_NONE;
for (int i = 0; i < MAXBELTITEMS; i++) {
if (myPlayer.SpdList[i]._itype == ITYPE_GOLD)
myPlayer.SpdList[i]._itype = ITYPE_NONE;
}
plr[myplr]._pGold = 0;
myPlayer._pGold = 0;
}
void MaxSpellsCheat()
{
auto &myPlayer = plr[myplr];
for (int i = SPL_FIREBOLT; i < MAX_SPELLS; i++) {
if (GetSpellBookLevel((spell_id)i) != -1) {
plr[myplr]._pMemSpells |= GetSpellBitmask(i);
plr[myplr]._pSplLvl[i] = 10;
myPlayer._pMemSpells |= GetSpellBitmask(i);
myPlayer._pSplLvl[i] = 10;
}
}
}
void SetSpellLevelCheat(spell_id spl, int spllvl)
{
plr[myplr]._pMemSpells |= GetSpellBitmask(spl);
plr[myplr]._pSplLvl[spl] = spllvl;
auto &myPlayer = plr[myplr];
myPlayer._pMemSpells |= GetSpellBitmask(spl);
myPlayer._pSplLvl[spl] = spllvl;
}
void SetAllSpellsCheat()
@ -138,20 +141,22 @@ void PrintDebugPlayer(bool bNextPlayer)
if (bNextPlayer)
dbgplr = ((BYTE)dbgplr + 1) & 3;
sprintf(dstr, "Plr %i : Active = %i", dbgplr, plr[dbgplr].plractive);
auto &player = plr[dbgplr];
sprintf(dstr, "Plr %i : Active = %i", dbgplr, player.plractive);
NetSendCmdString(1 << myplr, dstr);
if (plr[dbgplr].plractive) {
sprintf(dstr, " Plr %i is %s", dbgplr, plr[dbgplr]._pName);
if (player.plractive) {
sprintf(dstr, " Plr %i is %s", dbgplr, player._pName);
NetSendCmdString(1 << myplr, dstr);
sprintf(dstr, " Lvl = %i : Change = %i", plr[dbgplr].plrlevel, plr[dbgplr]._pLvlChanging);
sprintf(dstr, " Lvl = %i : Change = %i", player.plrlevel, player._pLvlChanging);
NetSendCmdString(1 << myplr, dstr);
const Point target = plr[dbgplr].GetTargetPosition();
sprintf(dstr, " x = %i, y = %i : tx = %i, ty = %i", plr[dbgplr].position.tile.x, plr[dbgplr].position.tile.y, target.x, target.y);
const Point target = player.GetTargetPosition();
sprintf(dstr, " x = %i, y = %i : tx = %i, ty = %i", player.position.tile.x, player.position.tile.y, target.x, target.y);
NetSendCmdString(1 << myplr, dstr);
sprintf(dstr, " mode = %i : daction = %i : walk[0] = %i", plr[dbgplr]._pmode, plr[dbgplr].destAction, plr[dbgplr].walkpath[0]);
sprintf(dstr, " mode = %i : daction = %i : walk[0] = %i", player._pmode, player.destAction, player.walkpath[0]);
NetSendCmdString(1 << myplr, dstr);
sprintf(dstr, " inv = %i : hp = %i", plr[dbgplr]._pInvincible, plr[dbgplr]._pHitPoints);
sprintf(dstr, " inv = %i : hp = %i", player._pInvincible, player._pHitPoints);
NetSendCmdString(1 << myplr, dstr);
}
}

117
Source/diablo.cpp

@ -805,12 +805,13 @@ static bool LeftMouseCmd(bool bShift)
if (pcursitem == -1 && pcursmonst == -1 && pcursplr == -1)
return true;
} else {
bNear = abs(plr[myplr].position.tile.x - cursmx) < 2 && abs(plr[myplr].position.tile.y - cursmy) < 2;
auto &myPlayer = plr[myplr];
bNear = abs(myPlayer.position.tile.x - cursmx) < 2 && abs(myPlayer.position.tile.y - cursmy) < 2;
if (pcursitem != -1 && pcurs == CURSOR_HAND && !bShift) {
NetSendCmdLocParam1(true, invflag ? CMD_GOTOGETITEM : CMD_GOTOAGETITEM, { cursmx, cursmy }, pcursitem);
} else if (pcursobj != -1 && (!objectIsDisabled(pcursobj)) && (!bShift || (bNear && object[pcursobj]._oBreak == 1))) {
NetSendCmdLocParam1(true, pcurs == CURSOR_DISARM ? CMD_DISARMXY : CMD_OPOBJXY, { cursmx, cursmy }, pcursobj);
} else if (plr[myplr]._pwtype == WT_RANGED) {
} else if (myPlayer._pwtype == WT_RANGED) {
if (bShift) {
NetSendCmdLoc(myplr, true, CMD_RATTACKXY, { cursmx, cursmy });
} else if (pcursmonst != -1) {
@ -896,12 +897,13 @@ bool TryIconCurs()
}
if (pcurs == CURSOR_TELEPORT) {
auto &myPlayer = plr[myplr];
if (pcursmonst != -1)
NetSendCmdParam3(true, CMD_TSPELLID, pcursmonst, plr[myplr]._pTSpell, GetSpellLevel(myplr, plr[myplr]._pTSpell));
NetSendCmdParam3(true, CMD_TSPELLID, pcursmonst, myPlayer._pTSpell, GetSpellLevel(myplr, myPlayer._pTSpell));
else if (pcursplr != -1)
NetSendCmdParam3(true, CMD_TSPELLPID, pcursplr, plr[myplr]._pTSpell, GetSpellLevel(myplr, plr[myplr]._pTSpell));
NetSendCmdParam3(true, CMD_TSPELLPID, pcursplr, myPlayer._pTSpell, GetSpellLevel(myplr, myPlayer._pTSpell));
else
NetSendCmdLocParam2(true, CMD_TSPELLXY, { cursmx, cursmy }, plr[myplr]._pTSpell, GetSpellLevel(myplr, plr[myplr]._pTSpell));
NetSendCmdLocParam2(true, CMD_TSPELLXY, { cursmx, cursmy }, myPlayer._pTSpell, GetSpellLevel(myplr, myPlayer._pTSpell));
NewCursor(CURSOR_HAND);
return true;
}
@ -1004,25 +1006,29 @@ static void LeftMouseUp(int wParam)
static void RightMouseDown()
{
if (!gmenu_is_active() && sgnTimeoutCurs == CURSOR_NONE && PauseMode != 2 && !plr[myplr]._pInvincible) {
if (DoomFlag) {
doom_close();
return;
}
if (stextflag != STORE_NONE)
return;
if (spselflag) {
SetSpell();
} else if (MouseY >= SPANEL_HEIGHT
|| ((!sbookflag || MouseX <= RIGHT_PANEL)
&& !TryIconCurs()
&& (pcursinvitem == -1 || !UseInvItem(myplr, pcursinvitem)))) {
if (pcurs == CURSOR_HAND) {
if (pcursinvitem == -1 || !UseInvItem(myplr, pcursinvitem))
CheckPlrSpell();
} else if (pcurs > CURSOR_HAND && pcurs < CURSOR_FIRSTITEM) {
NewCursor(CURSOR_HAND);
}
if (gmenu_is_active() || sgnTimeoutCurs != CURSOR_NONE || PauseMode == 2 || plr[myplr]._pInvincible) {
return;
}
if (DoomFlag) {
doom_close();
return;
}
if (stextflag != STORE_NONE)
return;
if (spselflag) {
SetSpell();
return;
}
if (MouseY >= SPANEL_HEIGHT
|| ((!sbookflag || MouseX <= RIGHT_PANEL)
&& !TryIconCurs()
&& (pcursinvitem == -1 || !UseInvItem(myplr, pcursinvitem)))) {
if (pcurs == CURSOR_HAND) {
if (pcursinvitem == -1 || !UseInvItem(myplr, pcursinvitem))
CheckPlrSpell();
} else if (pcurs > CURSOR_HAND && pcurs < CURSOR_FIRSTITEM) {
NewCursor(CURSOR_HAND);
}
}
}
@ -1285,15 +1291,16 @@ static void PressChar(int32_t vkey)
if (arrowdebug > 2) {
arrowdebug = 0;
}
auto &myPlayer = plr[myplr];
if (arrowdebug == 0) {
plr[myplr]._pIFlags &= ~ISPL_FIRE_ARROWS;
plr[myplr]._pIFlags &= ~ISPL_LIGHT_ARROWS;
myPlayer._pIFlags &= ~ISPL_FIRE_ARROWS;
myPlayer._pIFlags &= ~ISPL_LIGHT_ARROWS;
}
if (arrowdebug == 1) {
plr[myplr]._pIFlags |= ISPL_FIRE_ARROWS;
myPlayer._pIFlags |= ISPL_FIRE_ARROWS;
}
if (arrowdebug == 2) {
plr[myplr]._pIFlags |= ISPL_LIGHT_ARROWS;
myPlayer._pIFlags |= ISPL_LIGHT_ARROWS;
}
arrowdebug++;
}
@ -1316,7 +1323,8 @@ static void PressChar(int32_t vkey)
case 'a':
if (debug_mode_key_inverted_v) {
spelldata[SPL_TELEPORT].sTownSpell = true;
plr[myplr]._pSplLvl[plr[myplr]._pSpell]++;
auto &myPlayer = plr[myplr];
myPlayer._pSplLvl[myPlayer._pSpell]++;
}
return;
case 'D':
@ -1349,7 +1357,8 @@ static void PressChar(int32_t vkey)
case 'T':
case 't':
if (debug_mode_key_inverted_v) {
sprintf(tempstr, "PX = %i PY = %i", plr[myplr].position.tile.x, plr[myplr].position.tile.y);
auto &myPlayer = plr[myplr];
sprintf(tempstr, "PX = %i PY = %i", myPlayer.position.tile.x, myPlayer.position.tile.y);
NetSendCmdString(1 << myplr, tempstr);
sprintf(tempstr, "CX = %i CY = %i DP = %i", cursmx, cursmy, dungeon[cursmx][cursmy]);
NetSendCmdString(1 << myplr, tempstr);
@ -1637,9 +1646,6 @@ static void UpdateMonsterLights()
void LoadGameLevel(bool firstflag, lvl_entry lvldir)
{
int i, j;
bool visited;
if (setseed != 0)
glSeedTbl[currlevel] = setseed;
@ -1678,6 +1684,8 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir)
InitLevelMonsters();
IncProgress();
auto &myPlayer = plr[myplr];
if (!setlevel) {
CreateLevel(lvldir);
IncProgress();
@ -1705,8 +1713,9 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir)
IncProgress();
for (i = 0; i < MAX_PLRS; i++) {
if (plr[i].plractive && currlevel == plr[i].plrlevel) {
for (int i = 0; i < MAX_PLRS; i++) {
auto &player = plr[i];
if (player.plractive && currlevel == player.plrlevel) {
InitPlayerGFX(i);
if (lvldir != ENTRY_LOAD)
InitPlayer(i, firstflag);
@ -1717,17 +1726,18 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir)
InitMultiView();
IncProgress();
visited = false;
bool visited = false;
int players = gbIsMultiplayer ? MAX_PLRS : 1;
for (i = 0; i < players; i++) {
if (plr[i].plractive)
visited = visited || plr[i]._pLvlVisited[currlevel];
for (int i = 0; i < players; i++) {
auto &player = plr[i];
if (player.plractive)
visited = visited || player._pLvlVisited[currlevel];
}
SetRndSeed(glSeedTbl[currlevel]);
if (leveltype != DTYPE_TOWN) {
if (firstflag || lvldir == ENTRY_LOAD || !plr[myplr]._pLvlVisited[currlevel] || gbIsMultiplayer) {
if (firstflag || lvldir == ENTRY_LOAD || !myPlayer._pLvlVisited[currlevel] || gbIsMultiplayer) {
HoldThemeRooms();
glMid1Seed[currlevel] = GetRndSeed();
InitMonsters();
@ -1758,8 +1768,8 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir)
IncProgress();
}
} else {
for (i = 0; i < MAXDUNX; i++) {
for (j = 0; j < MAXDUNY; j++)
for (int i = 0; i < MAXDUNX; i++) {
for (int j = 0; j < MAXDUNY; j++)
dFlags[i][j] |= BFLAG_LIT;
}
@ -1768,7 +1778,7 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir)
InitMissiles();
IncProgress();
if (!firstflag && lvldir != ENTRY_LOAD && plr[myplr]._pLvlVisited[currlevel] && !gbIsMultiplayer)
if (!firstflag && lvldir != ENTRY_LOAD && myPlayer._pLvlVisited[currlevel] && !gbIsMultiplayer)
LoadLevel();
if (gbIsMultiplayer)
DeltaLoadLevel();
@ -1797,8 +1807,9 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir)
GetPortalLvlPos();
IncProgress();
for (i = 0; i < MAX_PLRS; i++) {
if (plr[i].plractive && currlevel == plr[i].plrlevel) {
for (int i = 0; i < MAX_PLRS; i++) {
auto &player = plr[i];
if (player.plractive && currlevel == player.plrlevel) {
InitPlayerGFX(i);
if (lvldir != ENTRY_LOAD)
InitPlayer(i, firstflag);
@ -1809,7 +1820,7 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir)
InitMultiView();
IncProgress();
if (firstflag || lvldir == ENTRY_LOAD || !plr[myplr]._pSLvlVisited[setlvlnum]) {
if (firstflag || lvldir == ENTRY_LOAD || !myPlayer._pSLvlVisited[setlvlnum]) {
InitItems();
SavePreLighting();
} else {
@ -1822,15 +1833,16 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir)
SyncPortals();
for (i = 0; i < MAX_PLRS; i++) {
if (plr[i].plractive && plr[i].plrlevel == currlevel && (!plr[i]._pLvlChanging || i == myplr)) {
if (plr[i]._pHitPoints > 0) {
for (int i = 0; i < MAX_PLRS; i++) {
auto &player = plr[i];
if (player.plractive && player.plrlevel == currlevel && (!player._pLvlChanging || i == myplr)) {
if (player._pHitPoints > 0) {
if (!gbIsMultiplayer)
dPlayer[plr[i].position.tile.x][plr[i].position.tile.y] = i + 1;
dPlayer[player.position.tile.x][player.position.tile.y] = i + 1;
else
SyncInitPlrPos(i);
} else {
dFlags[plr[i].position.tile.x][plr[i].position.tile.y] |= BFLAG_DEAD_PLAYER;
dFlags[player.position.tile.x][player.position.tile.y] |= BFLAG_DEAD_PLAYER;
}
}
}
@ -2212,7 +2224,8 @@ void initKeymapActions()
std::string("BeltItem") + std::to_string(i + 1),
'1' + i,
[i] {
if (!plr[myplr].SpdList[i].isEmpty() && plr[myplr].SpdList[i]._itype != ITYPE_GOLD) {
auto &myPlayer = plr[myplr];
if (!myPlayer.SpdList[i].isEmpty() && myPlayer.SpdList[i]._itype != ITYPE_GOLD) {
UseInvItem(myplr, INVITEM_BELT_FIRST + i);
}
},

29
Source/effects.cpp

@ -1340,20 +1340,23 @@ void sound_init()
mask |= (sfx_ROGUE | sfx_SORCERER);
if (gbIsHellfire)
mask |= sfx_MONK;
} else if (plr[myplr]._pClass == HeroClass::Warrior) {
mask |= sfx_WARRIOR;
} else if (plr[myplr]._pClass == HeroClass::Rogue) {
mask |= sfx_ROGUE;
} else if (plr[myplr]._pClass == HeroClass::Sorcerer) {
mask |= sfx_SORCERER;
} else if (plr[myplr]._pClass == HeroClass::Monk) {
mask |= sfx_MONK;
} else if (plr[myplr]._pClass == HeroClass::Bard) {
mask |= sfx_ROGUE;
} else if (plr[myplr]._pClass == HeroClass::Barbarian) {
mask |= sfx_WARRIOR;
} else {
app_fatal("effects:1");
auto &myPlayer = plr[myplr];
if (myPlayer._pClass == HeroClass::Warrior) {
mask |= sfx_WARRIOR;
} else if (myPlayer._pClass == HeroClass::Rogue) {
mask |= sfx_ROGUE;
} else if (myPlayer._pClass == HeroClass::Sorcerer) {
mask |= sfx_SORCERER;
} else if (myPlayer._pClass == HeroClass::Monk) {
mask |= sfx_MONK;
} else if (myPlayer._pClass == HeroClass::Bard) {
mask |= sfx_ROGUE;
} else if (myPlayer._pClass == HeroClass::Barbarian) {
mask |= sfx_WARRIOR;
} else {
app_fatal("effects:1");
}
}
priv_sound_init(mask);

14
Source/gamemenu.cpp

@ -78,13 +78,9 @@ const char *const sound_toggle_names[] = {
void gamemenu_update_single()
{
bool enable;
gmenu_enable(&sgSingleMenu[3], gbValidSaveFile);
enable = false;
if (plr[myplr]._pmode != PM_DEATH && !deathflag)
enable = true;
bool enable = plr[myplr]._pmode != PM_DEATH && !deathflag;
gmenu_enable(&sgSingleMenu[0], enable);
}
@ -101,11 +97,9 @@ void gamemenu_previous(bool bActivate)
void gamemenu_new_game(bool bActivate)
{
int i;
for (i = 0; i < MAX_PLRS; i++) {
plr[i]._pmode = PM_QUIT;
plr[i]._pInvincible = true;
for (auto &player : plr) {
player._pmode = PM_QUIT;
player._pInvincible = true;
}
deathflag = false;

21
Source/interfac.cpp

@ -237,6 +237,8 @@ void ShowProgress(interface_mode uMsg)
sound_init();
IncProgress();
auto &myPlayer = plr[myplr];
switch (uMsg) {
case WM_DIABLOADGAME:
IncProgress();
@ -246,7 +248,7 @@ void ShowProgress(interface_mode uMsg)
IncProgress();
break;
case WM_DIABNEWGAME:
plr[myplr].pOriginalCathedral = !gbIsHellfire;
myPlayer.pOriginalCathedral = !gbIsHellfire;
IncProgress();
FreeGameMem();
IncProgress();
@ -266,7 +268,7 @@ void ShowProgress(interface_mode uMsg)
FreeGameMem();
currlevel++;
leveltype = gnLevelTypeTbl[currlevel];
assert(plr[myplr].plrlevel == currlevel);
assert(myPlayer.plrlevel == currlevel);
IncProgress();
LoadGameLevel(false, ENTRY_MAIN);
IncProgress();
@ -282,7 +284,7 @@ void ShowProgress(interface_mode uMsg)
FreeGameMem();
currlevel--;
leveltype = gnLevelTypeTbl[currlevel];
assert(plr[myplr].plrlevel == currlevel);
assert(myPlayer.plrlevel == currlevel);
IncProgress();
LoadGameLevel(false, ENTRY_PREV);
IncProgress();
@ -341,9 +343,8 @@ void ShowProgress(interface_mode uMsg)
}
IncProgress();
FreeGameMem();
currlevel = plr[myplr].plrlevel;
currlevel = myPlayer.plrlevel;
leveltype = gnLevelTypeTbl[currlevel];
assert(plr[myplr].plrlevel == currlevel);
IncProgress();
LoadGameLevel(false, ENTRY_TWARPDN);
IncProgress();
@ -357,9 +358,8 @@ void ShowProgress(interface_mode uMsg)
}
IncProgress();
FreeGameMem();
currlevel = plr[myplr].plrlevel;
currlevel = myPlayer.plrlevel;
leveltype = gnLevelTypeTbl[currlevel];
assert(plr[myplr].plrlevel == currlevel);
IncProgress();
LoadGameLevel(false, ENTRY_TWARPUP);
IncProgress();
@ -373,9 +373,8 @@ void ShowProgress(interface_mode uMsg)
}
IncProgress();
FreeGameMem();
currlevel = plr[myplr].plrlevel;
currlevel = myPlayer.plrlevel;
leveltype = gnLevelTypeTbl[currlevel];
assert(plr[myplr].plrlevel == currlevel);
IncProgress();
LoadGameLevel(false, ENTRY_MAIN);
IncProgress();
@ -390,11 +389,11 @@ void ShowProgress(interface_mode uMsg)
saveProc = SetWindowProc(saveProc);
assert(saveProc == DisableInputWndProc);
NetSendCmdLocParam1(true, CMD_PLAYER_JOINLEVEL, plr[myplr].position.tile, plr[myplr].plrlevel);
NetSendCmdLocParam1(true, CMD_PLAYER_JOINLEVEL, myPlayer.position.tile, myPlayer.plrlevel);
plrmsg_delay(false);
ResetPal();
if (gbSomebodyWonGameKludge && plr[myplr].plrlevel == 16) {
if (gbSomebodyWonGameKludge && myPlayer.plrlevel == 16) {
PrepDoEnding();
}

603
Source/inv.cpp

File diff suppressed because it is too large Load Diff

9
Source/inv.h

@ -97,15 +97,14 @@ void DrawInv(const CelOutputBuffer &out);
void DrawInvBelt(const CelOutputBuffer &out);
bool AutoEquipEnabled(const PlayerStruct &player, const ItemStruct &item);
bool AutoEquip(int playerNumber, const ItemStruct &item, bool persistItem = true);
bool AutoEquip(int playerId, const ItemStruct &item, bool persistItem = true);
bool AutoPlaceItemInInventory(PlayerStruct &player, const ItemStruct &item, bool persistItem = false);
bool AutoPlaceItemInInventorySlot(PlayerStruct &player, int slotIndex, const ItemStruct &item, bool persistItem);
bool AutoPlaceItemInBelt(int playerNumber, const ItemStruct &item, bool persistItem = false);
bool AutoPlaceItemInBelt(PlayerStruct &player, const ItemStruct &item, bool persistItem = false);
bool GoldAutoPlace(PlayerStruct &player);
bool GoldAutoPlaceInInventorySlot(PlayerStruct &player, int slotIndex);
void CheckInvSwap(int pnum, BYTE bLoc, int idx, uint16_t wCI, int seed, bool bId, uint32_t dwBuff);
void inv_update_rem_item(int pnum, BYTE iv);
void RemoveSpdBarItem(int pnum, int iv);
void CheckInvItem(bool isShiftHeld = false);
void CheckInvScrn(bool isShiftHeld);
void CheckItemStats(PlayerStruct &player);
@ -116,8 +115,8 @@ void SyncGetItem(int x, int y, int idx, uint16_t ci, int iseed);
bool CanPut(int x, int y);
bool TryInvPut();
void DrawInvMsg(const char *msg);
int InvPutItem(int pnum, Point position);
int SyncPutItem(int pnum, 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);
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);
bool UseScroll();

30
Source/items.cpp

@ -3082,19 +3082,19 @@ static void RepairItem(ItemStruct *i, int lvl)
void DoRepair(int pnum, int cii)
{
PlayerStruct *p;
ItemStruct *pi;
p = &plr[pnum];
PlaySfxLoc(IS_REPAIR, p->position.tile.x, p->position.tile.y);
auto &player = plr[pnum];
PlaySfxLoc(IS_REPAIR, player.position.tile.x, player.position.tile.y);
if (cii >= NUM_INVLOC) {
pi = &p->InvList[cii - NUM_INVLOC];
pi = &player.InvList[cii - NUM_INVLOC];
} else {
pi = &p->InvBody[cii];
pi = &player.InvBody[cii];
}
RepairItem(pi, p->_pLevel);
RepairItem(pi, player._pLevel);
CalcPlrInv(pnum, true);
if (pnum == myplr)
@ -3121,15 +3121,15 @@ void DoRecharge(int pnum, int cii)
{
ItemStruct *pi;
PlayerStruct *p = &plr[pnum];
auto &player = plr[pnum];
if (cii >= NUM_INVLOC) {
pi = &p->InvList[cii - NUM_INVLOC];
pi = &player.InvList[cii - NUM_INVLOC];
} else {
pi = &p->InvBody[cii];
pi = &player.InvBody[cii];
}
if (pi->_itype == ITYPE_STAFF && pi->_iSpell != SPL_NULL) {
int r = GetSpellBookLevel(pi->_iSpell);
r = GenerateRnd(p->_pLevel / r) + 1;
r = GenerateRnd(player._pLevel / r) + 1;
RechargeItem(pi, r);
CalcPlrInv(pnum, true);
}
@ -3138,7 +3138,7 @@ void DoRecharge(int pnum, int cii)
NewCursor(CURSOR_HAND);
}
static bool OilItem(ItemStruct *x, PlayerStruct *p)
static bool OilItem(ItemStruct *x, PlayerStruct &player)
{
int r;
@ -3152,7 +3152,7 @@ static bool OilItem(ItemStruct *x, PlayerStruct *p)
return false;
}
switch (p->_pOilType) {
switch (player._pOilType) {
case IMISC_OILACC:
case IMISC_OILMAST:
case IMISC_OILSHARP:
@ -3178,7 +3178,7 @@ static bool OilItem(ItemStruct *x, PlayerStruct *p)
break;
}
switch (p->_pOilType) {
switch (player._pOilType) {
case IMISC_OILACC:
if (x->_iPLToHit < 50) {
x->_iPLToHit += GenerateRnd(2) + 1;
@ -3251,8 +3251,8 @@ void DoOil(int pnum, int cii)
{
if (cii < NUM_INVLOC && cii != INVLOC_HEAD && (cii <= INVLOC_AMULET || cii > INVLOC_CHEST))
return;
PlayerStruct *p = &plr[pnum];
if (!OilItem(&p->InvBody[cii], p))
auto &player = plr[pnum];
if (!OilItem(&player.InvBody[cii], player))
return;
CalcPlrInv(pnum, true);
if (pnum == myplr) {

656
Source/loadsave.cpp

@ -302,226 +302,214 @@ static void LoadItems(LoadHelper *file, const int n, ItemStruct *pItem)
static void LoadPlayer(LoadHelper *file, int p)
{
PlayerStruct *pPlayer = &plr[p];
auto &player = plr[p];
pPlayer->_pmode = static_cast<PLR_MODE>(file->nextLE<int32_t>());
player._pmode = static_cast<PLR_MODE>(file->nextLE<int32_t>());
for (int8_t &step : pPlayer->walkpath) {
for (int8_t &step : player.walkpath) {
step = file->nextLE<int8_t>();
}
pPlayer->plractive = file->nextBool8();
player.plractive = file->nextBool8();
file->skip(2); // Alignment
pPlayer->destAction = static_cast<action_id>(file->nextLE<int32_t>());
pPlayer->destParam1 = file->nextLE<int32_t>();
pPlayer->destParam2 = file->nextLE<int32_t>();
pPlayer->destParam3 = static_cast<Direction>(file->nextLE<int32_t>());
pPlayer->destParam4 = file->nextLE<int32_t>();
pPlayer->plrlevel = file->nextLE<int32_t>();
pPlayer->position.tile.x = file->nextLE<int32_t>();
pPlayer->position.tile.y = file->nextLE<int32_t>();
pPlayer->position.future.x = file->nextLE<int32_t>();
pPlayer->position.future.y = file->nextLE<int32_t>();
player.destAction = static_cast<action_id>(file->nextLE<int32_t>());
player.destParam1 = file->nextLE<int32_t>();
player.destParam2 = file->nextLE<int32_t>();
player.destParam3 = static_cast<Direction>(file->nextLE<int32_t>());
player.destParam4 = file->nextLE<int32_t>();
player.plrlevel = file->nextLE<int32_t>();
player.position.tile.x = file->nextLE<int32_t>();
player.position.tile.y = file->nextLE<int32_t>();
player.position.future.x = file->nextLE<int32_t>();
player.position.future.y = file->nextLE<int32_t>();
file->skip(8); // Skip _ptargx and _ptargy
pPlayer->position.last.x = file->nextLE<int32_t>();
pPlayer->position.last.y = file->nextLE<int32_t>();
pPlayer->position.old.x = file->nextLE<int32_t>();
pPlayer->position.old.y = file->nextLE<int32_t>();
pPlayer->position.offset.x = file->nextLE<int32_t>();
pPlayer->position.offset.y = file->nextLE<int32_t>();
pPlayer->position.velocity.x = file->nextLE<int32_t>();
pPlayer->position.velocity.y = file->nextLE<int32_t>();
pPlayer->_pdir = static_cast<Direction>(file->nextLE<int32_t>());
player.position.last.x = file->nextLE<int32_t>();
player.position.last.y = file->nextLE<int32_t>();
player.position.old.x = file->nextLE<int32_t>();
player.position.old.y = file->nextLE<int32_t>();
player.position.offset.x = file->nextLE<int32_t>();
player.position.offset.y = file->nextLE<int32_t>();
player.position.velocity.x = file->nextLE<int32_t>();
player.position.velocity.y = file->nextLE<int32_t>();
player._pdir = static_cast<Direction>(file->nextLE<int32_t>());
file->skip(4); // Unused
pPlayer->_pgfxnum = file->nextLE<int32_t>();
player._pgfxnum = file->nextLE<int32_t>();
file->skip(4); // Skip pointer pData
pPlayer->AnimInfo.DelayLen = file->nextLE<int32_t>();
pPlayer->AnimInfo.DelayCounter = file->nextLE<int32_t>();
pPlayer->AnimInfo.NumberOfFrames = file->nextLE<int32_t>();
pPlayer->AnimInfo.CurrentFrame = file->nextLE<int32_t>();
// Skip _pAnimWidth
file->skip(4);
// Skip _pAnimWidth2
file->skip(4);
player.AnimInfo.DelayLen = file->nextLE<int32_t>();
player.AnimInfo.DelayCounter = file->nextLE<int32_t>();
player.AnimInfo.NumberOfFrames = file->nextLE<int32_t>();
player.AnimInfo.CurrentFrame = file->nextLE<int32_t>();
file->skip(4); // Skip _pAnimWidth
file->skip(4); // Skip _pAnimWidth2
file->skip(4); // Skip _peflag
pPlayer->_plid = file->nextLE<int32_t>();
pPlayer->_pvid = file->nextLE<int32_t>();
player._plid = file->nextLE<int32_t>();
player._pvid = file->nextLE<int32_t>();
pPlayer->_pSpell = static_cast<spell_id>(file->nextLE<int32_t>());
pPlayer->_pSplType = static_cast<spell_type>(file->nextLE<int8_t>());
pPlayer->_pSplFrom = file->nextLE<int8_t>();
player._pSpell = static_cast<spell_id>(file->nextLE<int32_t>());
player._pSplType = static_cast<spell_type>(file->nextLE<int8_t>());
player._pSplFrom = file->nextLE<int8_t>();
file->skip(2); // Alignment
pPlayer->_pTSpell = static_cast<spell_id>(file->nextLE<int32_t>());
pPlayer->_pTSplType = static_cast<spell_type>(file->nextLE<int8_t>());
player._pTSpell = static_cast<spell_id>(file->nextLE<int32_t>());
player._pTSplType = static_cast<spell_type>(file->nextLE<int8_t>());
file->skip(3); // Alignment
pPlayer->_pRSpell = static_cast<spell_id>(file->nextLE<int32_t>());
pPlayer->_pRSplType = static_cast<spell_type>(file->nextLE<int8_t>());
player._pRSpell = static_cast<spell_id>(file->nextLE<int32_t>());
player._pRSplType = static_cast<spell_type>(file->nextLE<int8_t>());
file->skip(3); // Alignment
pPlayer->_pSBkSpell = static_cast<spell_id>(file->nextLE<int32_t>());
pPlayer->_pSBkSplType = static_cast<spell_type>(file->nextLE<int8_t>());
for (int8_t &spellLevel : pPlayer->_pSplLvl)
player._pSBkSpell = static_cast<spell_id>(file->nextLE<int32_t>());
player._pSBkSplType = static_cast<spell_type>(file->nextLE<int8_t>());
for (int8_t &spellLevel : player._pSplLvl)
spellLevel = file->nextLE<int8_t>();
file->skip(7); // Alignment
pPlayer->_pMemSpells = file->nextLE<uint64_t>();
pPlayer->_pAblSpells = file->nextLE<uint64_t>();
pPlayer->_pScrlSpells = file->nextLE<uint64_t>();
pPlayer->_pSpellFlags = file->nextLE<uint8_t>();
player._pMemSpells = file->nextLE<uint64_t>();
player._pAblSpells = file->nextLE<uint64_t>();
player._pScrlSpells = file->nextLE<uint64_t>();
player._pSpellFlags = file->nextLE<uint8_t>();
file->skip(3); // Alignment
for (auto &spell : pPlayer->_pSplHotKey)
for (auto &spell : player._pSplHotKey)
spell = static_cast<spell_id>(file->nextLE<int32_t>());
for (auto &spellType : pPlayer->_pSplTHotKey)
for (auto &spellType : player._pSplTHotKey)
spellType = static_cast<spell_type>(file->nextLE<int8_t>());
pPlayer->_pwtype = static_cast<player_weapon_type>(file->nextLE<int32_t>());
pPlayer->_pBlockFlag = file->nextBool8();
pPlayer->_pInvincible = file->nextBool8();
pPlayer->_pLightRad = file->nextLE<int8_t>();
pPlayer->_pLvlChanging = file->nextBool8();
player._pwtype = static_cast<player_weapon_type>(file->nextLE<int32_t>());
player._pBlockFlag = file->nextBool8();
player._pInvincible = file->nextBool8();
player._pLightRad = file->nextLE<int8_t>();
player._pLvlChanging = file->nextBool8();
file->nextBytes(pPlayer->_pName, PLR_NAME_LEN);
pPlayer->_pClass = static_cast<HeroClass>(file->nextLE<int8_t>());
file->nextBytes(player._pName, PLR_NAME_LEN);
player._pClass = static_cast<HeroClass>(file->nextLE<int8_t>());
file->skip(3); // Alignment
pPlayer->_pStrength = file->nextLE<int32_t>();
pPlayer->_pBaseStr = file->nextLE<int32_t>();
pPlayer->_pMagic = file->nextLE<int32_t>();
pPlayer->_pBaseMag = file->nextLE<int32_t>();
pPlayer->_pDexterity = file->nextLE<int32_t>();
pPlayer->_pBaseDex = file->nextLE<int32_t>();
pPlayer->_pVitality = file->nextLE<int32_t>();
pPlayer->_pBaseVit = file->nextLE<int32_t>();
pPlayer->_pStatPts = file->nextLE<int32_t>();
pPlayer->_pDamageMod = file->nextLE<int32_t>();
pPlayer->_pBaseToBlk = file->nextLE<int32_t>();
if (pPlayer->_pBaseToBlk == 0)
pPlayer->_pBaseToBlk = ToBlkTbl[static_cast<std::size_t>(pPlayer->_pClass)];
pPlayer->_pHPBase = file->nextLE<int32_t>();
pPlayer->_pMaxHPBase = file->nextLE<int32_t>();
pPlayer->_pHitPoints = file->nextLE<int32_t>();
pPlayer->_pMaxHP = file->nextLE<int32_t>();
pPlayer->_pHPPer = file->nextLE<int32_t>();
pPlayer->_pManaBase = file->nextLE<int32_t>();
pPlayer->_pMaxManaBase = file->nextLE<int32_t>();
pPlayer->_pMana = file->nextLE<int32_t>();
pPlayer->_pMaxMana = file->nextLE<int32_t>();
pPlayer->_pManaPer = file->nextLE<int32_t>();
pPlayer->_pLevel = file->nextLE<int8_t>();
pPlayer->_pMaxLvl = file->nextLE<int8_t>();
player._pStrength = file->nextLE<int32_t>();
player._pBaseStr = file->nextLE<int32_t>();
player._pMagic = file->nextLE<int32_t>();
player._pBaseMag = file->nextLE<int32_t>();
player._pDexterity = file->nextLE<int32_t>();
player._pBaseDex = file->nextLE<int32_t>();
player._pVitality = file->nextLE<int32_t>();
player._pBaseVit = file->nextLE<int32_t>();
player._pStatPts = file->nextLE<int32_t>();
player._pDamageMod = file->nextLE<int32_t>();
player._pBaseToBlk = file->nextLE<int32_t>();
if (player._pBaseToBlk == 0)
player._pBaseToBlk = ToBlkTbl[static_cast<std::size_t>(player._pClass)];
player._pHPBase = file->nextLE<int32_t>();
player._pMaxHPBase = file->nextLE<int32_t>();
player._pHitPoints = file->nextLE<int32_t>();
player._pMaxHP = file->nextLE<int32_t>();
player._pHPPer = file->nextLE<int32_t>();
player._pManaBase = file->nextLE<int32_t>();
player._pMaxManaBase = file->nextLE<int32_t>();
player._pMana = file->nextLE<int32_t>();
player._pMaxMana = file->nextLE<int32_t>();
player._pManaPer = file->nextLE<int32_t>();
player._pLevel = file->nextLE<int8_t>();
player._pMaxLvl = file->nextLE<int8_t>();
file->skip(2); // Alignment
pPlayer->_pExperience = file->nextLE<int32_t>();
pPlayer->_pMaxExp = file->nextLE<int32_t>();
pPlayer->_pNextExper = file->nextLE<int32_t>();
pPlayer->_pArmorClass = file->nextLE<int8_t>();
pPlayer->_pMagResist = file->nextLE<int8_t>();
pPlayer->_pFireResist = file->nextLE<int8_t>();
pPlayer->_pLghtResist = file->nextLE<int8_t>();
pPlayer->_pGold = file->nextLE<int32_t>();
pPlayer->_pInfraFlag = file->nextBool32();
pPlayer->position.temp.x = file->nextLE<int32_t>();
pPlayer->position.temp.y = file->nextLE<int32_t>();
pPlayer->tempDirection = static_cast<Direction>(file->nextLE<int32_t>());
pPlayer->_pVar4 = file->nextLE<int32_t>();
pPlayer->_pVar5 = file->nextLE<int32_t>();
pPlayer->position.offset2.x = file->nextLE<int32_t>();
pPlayer->position.offset2.y = file->nextLE<int32_t>();
// Skip actionFrame
file->skip(4);
player._pExperience = file->nextLE<int32_t>();
player._pMaxExp = file->nextLE<int32_t>();
player._pNextExper = file->nextLE<int32_t>();
player._pArmorClass = file->nextLE<int8_t>();
player._pMagResist = file->nextLE<int8_t>();
player._pFireResist = file->nextLE<int8_t>();
player._pLghtResist = file->nextLE<int8_t>();
player._pGold = file->nextLE<int32_t>();
player._pInfraFlag = file->nextBool32();
player.position.temp.x = file->nextLE<int32_t>();
player.position.temp.y = file->nextLE<int32_t>();
player.tempDirection = static_cast<Direction>(file->nextLE<int32_t>());
player._pVar4 = file->nextLE<int32_t>();
player._pVar5 = file->nextLE<int32_t>();
player.position.offset2.x = file->nextLE<int32_t>();
player.position.offset2.y = file->nextLE<int32_t>();
file->skip(4); // Skip actionFrame
for (uint8_t i = 0; i < giNumberOfLevels; i++)
pPlayer->_pLvlVisited[i] = file->nextBool8();
player._pLvlVisited[i] = file->nextBool8();
for (uint8_t i = 0; i < giNumberOfLevels; i++)
pPlayer->_pSLvlVisited[i] = file->nextBool8();
player._pSLvlVisited[i] = file->nextBool8();
file->skip(2); // Alignment
// skip _pGFXLoad
file->skip(4);
file->skip(2); // Alignment
file->skip(4); // skip _pGFXLoad
file->skip(4 * 8); // Skip pointers _pNAnim
pPlayer->_pNFrames = file->nextLE<int32_t>();
// skip _pNWidth
file->skip(4);
player._pNFrames = file->nextLE<int32_t>();
file->skip(4); // skip _pNWidth
file->skip(4 * 8); // Skip pointers _pWAnim
pPlayer->_pWFrames = file->nextLE<int32_t>();
// skip _pWWidth
file->skip(4);
player._pWFrames = file->nextLE<int32_t>();
file->skip(4); // skip _pWWidth
file->skip(4 * 8); // Skip pointers _pAAnim
pPlayer->_pAFrames = file->nextLE<int32_t>();
// skip _pAWidth
file->skip(4);
pPlayer->_pAFNum = file->nextLE<int32_t>();
player._pAFrames = file->nextLE<int32_t>();
file->skip(4); // skip _pAWidth
player._pAFNum = file->nextLE<int32_t>();
file->skip(4 * 8); // Skip pointers _pLAnim
file->skip(4 * 8); // Skip pointers _pFAnim
file->skip(4 * 8); // Skip pointers _pTAnim
pPlayer->_pSFrames = file->nextLE<int32_t>();
// skip _pSWidth
file->skip(4);
pPlayer->_pSFNum = file->nextLE<int32_t>();
player._pSFrames = file->nextLE<int32_t>();
file->skip(4); // skip _pSWidth
player._pSFNum = file->nextLE<int32_t>();
file->skip(4 * 8); // Skip pointers _pHAnim
pPlayer->_pHFrames = file->nextLE<int32_t>();
// skip _pHWidth
file->skip(4);
player._pHFrames = file->nextLE<int32_t>();
file->skip(4); // skip _pHWidth
file->skip(4 * 8); // Skip pointers _pDAnim
pPlayer->_pDFrames = file->nextLE<int32_t>();
// skip _pDWidth
file->skip(4);
player._pDFrames = file->nextLE<int32_t>();
file->skip(4); // skip _pDWidth
file->skip(4 * 8); // Skip pointers _pBAnim
pPlayer->_pBFrames = file->nextLE<int32_t>();
// skip _pBWidth
file->skip(4);
LoadItems(file, NUM_INVLOC, pPlayer->InvBody);
LoadItems(file, NUM_INV_GRID_ELEM, pPlayer->InvList);
pPlayer->_pNumInv = file->nextLE<int32_t>();
for (int8_t &cell : pPlayer->InvGrid)
player._pBFrames = file->nextLE<int32_t>();
file->skip(4); // skip _pBWidth
LoadItems(file, NUM_INVLOC, player.InvBody);
LoadItems(file, NUM_INV_GRID_ELEM, player.InvList);
player._pNumInv = file->nextLE<int32_t>();
for (int8_t &cell : player.InvGrid)
cell = file->nextLE<int8_t>();
LoadItems(file, MAXBELTITEMS, pPlayer->SpdList);
LoadItemData(file, &pPlayer->HoldItem);
pPlayer->_pIMinDam = file->nextLE<int32_t>();
pPlayer->_pIMaxDam = file->nextLE<int32_t>();
pPlayer->_pIAC = file->nextLE<int32_t>();
pPlayer->_pIBonusDam = file->nextLE<int32_t>();
pPlayer->_pIBonusToHit = file->nextLE<int32_t>();
pPlayer->_pIBonusAC = file->nextLE<int32_t>();
pPlayer->_pIBonusDamMod = file->nextLE<int32_t>();
LoadItems(file, MAXBELTITEMS, player.SpdList);
LoadItemData(file, &player.HoldItem);
player._pIMinDam = file->nextLE<int32_t>();
player._pIMaxDam = file->nextLE<int32_t>();
player._pIAC = file->nextLE<int32_t>();
player._pIBonusDam = file->nextLE<int32_t>();
player._pIBonusToHit = file->nextLE<int32_t>();
player._pIBonusAC = file->nextLE<int32_t>();
player._pIBonusDamMod = file->nextLE<int32_t>();
file->skip(4); // Alignment
pPlayer->_pISpells = file->nextLE<uint64_t>();
pPlayer->_pIFlags = file->nextLE<int32_t>();
pPlayer->_pIGetHit = file->nextLE<int32_t>();
pPlayer->_pISplLvlAdd = file->nextLE<int8_t>();
player._pISpells = file->nextLE<uint64_t>();
player._pIFlags = file->nextLE<int32_t>();
player._pIGetHit = file->nextLE<int32_t>();
player._pISplLvlAdd = file->nextLE<int8_t>();
file->skip(1); // Unused
file->skip(2); // Alignment
pPlayer->_pISplDur = file->nextLE<int32_t>();
pPlayer->_pIEnAc = file->nextLE<int32_t>();
pPlayer->_pIFMinDam = file->nextLE<int32_t>();
pPlayer->_pIFMaxDam = file->nextLE<int32_t>();
pPlayer->_pILMinDam = file->nextLE<int32_t>();
pPlayer->_pILMaxDam = file->nextLE<int32_t>();
pPlayer->_pOilType = static_cast<item_misc_id>(file->nextLE<int32_t>());
pPlayer->pTownWarps = file->nextLE<uint8_t>();
pPlayer->pDungMsgs = file->nextLE<uint8_t>();
pPlayer->pLvlLoad = file->nextLE<uint8_t>();
player._pISplDur = file->nextLE<int32_t>();
player._pIEnAc = file->nextLE<int32_t>();
player._pIFMinDam = file->nextLE<int32_t>();
player._pIFMaxDam = file->nextLE<int32_t>();
player._pILMinDam = file->nextLE<int32_t>();
player._pILMaxDam = file->nextLE<int32_t>();
player._pOilType = static_cast<item_misc_id>(file->nextLE<int32_t>());
player.pTownWarps = file->nextLE<uint8_t>();
player.pDungMsgs = file->nextLE<uint8_t>();
player.pLvlLoad = file->nextLE<uint8_t>();
if (gbIsHellfireSaveGame) {
pPlayer->pDungMsgs2 = file->nextLE<uint8_t>();
pPlayer->pBattleNet = false;
player.pDungMsgs2 = file->nextLE<uint8_t>();
player.pBattleNet = false;
} else {
pPlayer->pDungMsgs2 = 0;
pPlayer->pBattleNet = file->nextBool8();
player.pDungMsgs2 = 0;
player.pBattleNet = file->nextBool8();
}
pPlayer->pManaShield = file->nextBool8();
player.pManaShield = file->nextBool8();
if (gbIsHellfireSaveGame) {
pPlayer->pOriginalCathedral = file->nextBool8();
player.pOriginalCathedral = file->nextBool8();
} else {
file->skip(1);
pPlayer->pOriginalCathedral = true;
player.pOriginalCathedral = true;
}
file->skip(2); // Available bytes
pPlayer->wReflections = file->nextLE<uint16_t>();
player.wReflections = file->nextLE<uint16_t>();
file->skip(14); // Available bytes
pPlayer->pDiabloKillLevel = file->nextLE<uint32_t>();
pPlayer->pDifficulty = static_cast<_difficulty>(file->nextLE<uint32_t>());
pPlayer->pDamAcFlags = file->nextLE<uint32_t>();
player.pDiabloKillLevel = file->nextLE<uint32_t>();
player.pDifficulty = static_cast<_difficulty>(file->nextLE<uint32_t>());
player.pDamAcFlags = file->nextLE<uint32_t>();
file->skip(20); // Available bytes
CalcPlrItemVals(p, false);
@ -709,8 +697,7 @@ static void LoadObject(LoadHelper *file, int i)
pObject->_oAnimLen = file->nextLE<uint32_t>();
pObject->_oAnimFrame = file->nextLE<uint32_t>();
pObject->_oAnimWidth = file->nextLE<int32_t>();
// Skip _oAnimWidth2
file->skip(4);
file->skip(4); // Skip _oAnimWidth2
pObject->_oDelFlag = file->nextBool32();
pObject->_oBreak = file->nextLE<int8_t>();
file->skip(3); // Alignment
@ -958,7 +945,7 @@ static void LoadMatchingItems(LoadHelper *file, const int n, ItemStruct *pItem)
}
}
void LoadHeroItems(PlayerStruct *pPlayer)
void LoadHeroItems(PlayerStruct &player)
{
LoadHelper file("heroitems");
if (!file.isValid())
@ -966,9 +953,9 @@ void LoadHeroItems(PlayerStruct *pPlayer)
gbIsHellfireSaveGame = file.nextBool8();
LoadMatchingItems(&file, NUM_INVLOC, pPlayer->InvBody);
LoadMatchingItems(&file, NUM_INV_GRID_ELEM, pPlayer->InvList);
LoadMatchingItems(&file, MAXBELTITEMS, pPlayer->SpdList);
LoadMatchingItems(&file, NUM_INVLOC, player.InvBody);
LoadMatchingItems(&file, NUM_INV_GRID_ELEM, player.InvList);
LoadMatchingItems(&file, MAXBELTITEMS, player.SpdList);
gbIsHellfireSaveGame = gbIsHellfire;
}
@ -1296,221 +1283,214 @@ static void SaveItems(SaveHelper *file, ItemStruct *pItem, const int n)
static void SavePlayer(SaveHelper *file, int p)
{
PlayerStruct *pPlayer = &plr[p];
auto &player = plr[p];
file->writeLE<int32_t>(pPlayer->_pmode);
for (int8_t step : pPlayer->walkpath)
file->writeLE<int32_t>(player._pmode);
for (int8_t step : player.walkpath)
file->writeLE<int8_t>(step);
file->writeLE<uint8_t>(pPlayer->plractive);
file->writeLE<uint8_t>(player.plractive);
file->skip(2); // Alignment
file->writeLE<int32_t>(pPlayer->destAction);
file->writeLE<int32_t>(pPlayer->destParam1);
file->writeLE<int32_t>(pPlayer->destParam2);
file->writeLE<int32_t>(pPlayer->destParam3);
file->writeLE<int32_t>(pPlayer->destParam4);
file->writeLE<int32_t>(pPlayer->plrlevel);
file->writeLE<int32_t>(pPlayer->position.tile.x);
file->writeLE<int32_t>(pPlayer->position.tile.y);
file->writeLE<int32_t>(pPlayer->position.future.x);
file->writeLE<int32_t>(pPlayer->position.future.y);
file->writeLE<int32_t>(player.destAction);
file->writeLE<int32_t>(player.destParam1);
file->writeLE<int32_t>(player.destParam2);
file->writeLE<int32_t>(player.destParam3);
file->writeLE<int32_t>(player.destParam4);
file->writeLE<int32_t>(player.plrlevel);
file->writeLE<int32_t>(player.position.tile.x);
file->writeLE<int32_t>(player.position.tile.y);
file->writeLE<int32_t>(player.position.future.x);
file->writeLE<int32_t>(player.position.future.y);
// For backwards compatibility
const Point target = pPlayer->GetTargetPosition();
const Point target = player.GetTargetPosition();
file->writeLE<int32_t>(target.x);
file->writeLE<int32_t>(target.y);
file->writeLE<int32_t>(pPlayer->position.last.x);
file->writeLE<int32_t>(pPlayer->position.last.y);
file->writeLE<int32_t>(pPlayer->position.old.x);
file->writeLE<int32_t>(pPlayer->position.old.y);
file->writeLE<int32_t>(pPlayer->position.offset.x);
file->writeLE<int32_t>(pPlayer->position.offset.y);
file->writeLE<int32_t>(pPlayer->position.velocity.x);
file->writeLE<int32_t>(pPlayer->position.velocity.y);
file->writeLE<int32_t>(pPlayer->_pdir);
file->writeLE<int32_t>(player.position.last.x);
file->writeLE<int32_t>(player.position.last.y);
file->writeLE<int32_t>(player.position.old.x);
file->writeLE<int32_t>(player.position.old.y);
file->writeLE<int32_t>(player.position.offset.x);
file->writeLE<int32_t>(player.position.offset.y);
file->writeLE<int32_t>(player.position.velocity.x);
file->writeLE<int32_t>(player.position.velocity.y);
file->writeLE<int32_t>(player._pdir);
file->skip(4); // Unused
file->writeLE<int32_t>(pPlayer->_pgfxnum);
file->writeLE<int32_t>(player._pgfxnum);
file->skip(4); // Skip pointer _pAnimData
file->writeLE<int32_t>(pPlayer->AnimInfo.DelayLen);
file->writeLE<int32_t>(pPlayer->AnimInfo.DelayCounter);
file->writeLE<int32_t>(pPlayer->AnimInfo.NumberOfFrames);
file->writeLE<int32_t>(pPlayer->AnimInfo.CurrentFrame);
file->writeLE<int32_t>(player.AnimInfo.DelayLen);
file->writeLE<int32_t>(player.AnimInfo.DelayCounter);
file->writeLE<int32_t>(player.AnimInfo.NumberOfFrames);
file->writeLE<int32_t>(player.AnimInfo.CurrentFrame);
// write _pAnimWidth for vanilla compatibility
int animWidth = pPlayer->AnimInfo.pCelSprite == nullptr ? 96 : pPlayer->AnimInfo.pCelSprite->Width();
int animWidth = player.AnimInfo.pCelSprite == nullptr ? 96 : player.AnimInfo.pCelSprite->Width();
file->writeLE<int32_t>(animWidth);
// write _pAnimWidth2 for vanilla compatibility
file->writeLE<int32_t>(CalculateWidth2(animWidth));
file->skip(4); // Skip _peflag
file->writeLE<int32_t>(pPlayer->_plid);
file->writeLE<int32_t>(pPlayer->_pvid);
file->writeLE<int32_t>(player._plid);
file->writeLE<int32_t>(player._pvid);
file->writeLE<int32_t>(pPlayer->_pSpell);
file->writeLE<int8_t>(pPlayer->_pSplType);
file->writeLE<int8_t>(pPlayer->_pSplFrom);
file->writeLE<int32_t>(player._pSpell);
file->writeLE<int8_t>(player._pSplType);
file->writeLE<int8_t>(player._pSplFrom);
file->skip(2); // Alignment
file->writeLE<int32_t>(pPlayer->_pTSpell);
file->writeLE<int8_t>(pPlayer->_pTSplType);
file->writeLE<int32_t>(player._pTSpell);
file->writeLE<int8_t>(player._pTSplType);
file->skip(3); // Alignment
file->writeLE<int32_t>(pPlayer->_pRSpell);
file->writeLE<int8_t>(pPlayer->_pRSplType);
file->writeLE<int32_t>(player._pRSpell);
file->writeLE<int8_t>(player._pRSplType);
file->skip(3); // Alignment
file->writeLE<int32_t>(pPlayer->_pSBkSpell);
file->writeLE<int8_t>(pPlayer->_pSBkSplType);
for (int8_t spellLevel : pPlayer->_pSplLvl)
file->writeLE<int32_t>(player._pSBkSpell);
file->writeLE<int8_t>(player._pSBkSplType);
for (int8_t spellLevel : player._pSplLvl)
file->writeLE<int8_t>(spellLevel);
file->skip(7); // Alignment
file->writeLE<uint64_t>(pPlayer->_pMemSpells);
file->writeLE<uint64_t>(pPlayer->_pAblSpells);
file->writeLE<uint64_t>(pPlayer->_pScrlSpells);
file->writeLE<uint8_t>(pPlayer->_pSpellFlags);
file->writeLE<uint64_t>(player._pMemSpells);
file->writeLE<uint64_t>(player._pAblSpells);
file->writeLE<uint64_t>(player._pScrlSpells);
file->writeLE<uint8_t>(player._pSpellFlags);
file->skip(3); // Alignment
for (auto &spellId : pPlayer->_pSplHotKey)
for (auto &spellId : player._pSplHotKey)
file->writeLE<int32_t>(spellId);
for (auto &spellType : pPlayer->_pSplTHotKey)
for (auto &spellType : player._pSplTHotKey)
file->writeLE<int8_t>(spellType);
file->writeLE<int32_t>(pPlayer->_pwtype);
file->writeLE<uint8_t>(pPlayer->_pBlockFlag);
file->writeLE<uint8_t>(pPlayer->_pInvincible);
file->writeLE<int8_t>(pPlayer->_pLightRad);
file->writeLE<uint8_t>(pPlayer->_pLvlChanging);
file->writeLE<int32_t>(player._pwtype);
file->writeLE<uint8_t>(player._pBlockFlag);
file->writeLE<uint8_t>(player._pInvincible);
file->writeLE<int8_t>(player._pLightRad);
file->writeLE<uint8_t>(player._pLvlChanging);
file->writeBytes(pPlayer->_pName, PLR_NAME_LEN);
file->writeLE<int8_t>(static_cast<int8_t>(pPlayer->_pClass));
file->writeBytes(player._pName, PLR_NAME_LEN);
file->writeLE<int8_t>(static_cast<int8_t>(player._pClass));
file->skip(3); // Alignment
file->writeLE<int32_t>(pPlayer->_pStrength);
file->writeLE<int32_t>(pPlayer->_pBaseStr);
file->writeLE<int32_t>(pPlayer->_pMagic);
file->writeLE<int32_t>(pPlayer->_pBaseMag);
file->writeLE<int32_t>(pPlayer->_pDexterity);
file->writeLE<int32_t>(pPlayer->_pBaseDex);
file->writeLE<int32_t>(pPlayer->_pVitality);
file->writeLE<int32_t>(pPlayer->_pBaseVit);
file->writeLE<int32_t>(pPlayer->_pStatPts);
file->writeLE<int32_t>(pPlayer->_pDamageMod);
file->writeLE<int32_t>(pPlayer->_pBaseToBlk);
file->writeLE<int32_t>(pPlayer->_pHPBase);
file->writeLE<int32_t>(pPlayer->_pMaxHPBase);
file->writeLE<int32_t>(pPlayer->_pHitPoints);
file->writeLE<int32_t>(pPlayer->_pMaxHP);
file->writeLE<int32_t>(pPlayer->_pHPPer);
file->writeLE<int32_t>(pPlayer->_pManaBase);
file->writeLE<int32_t>(pPlayer->_pMaxManaBase);
file->writeLE<int32_t>(pPlayer->_pMana);
file->writeLE<int32_t>(pPlayer->_pMaxMana);
file->writeLE<int32_t>(pPlayer->_pManaPer);
file->writeLE<int8_t>(pPlayer->_pLevel);
file->writeLE<int8_t>(pPlayer->_pMaxLvl);
file->writeLE<int32_t>(player._pStrength);
file->writeLE<int32_t>(player._pBaseStr);
file->writeLE<int32_t>(player._pMagic);
file->writeLE<int32_t>(player._pBaseMag);
file->writeLE<int32_t>(player._pDexterity);
file->writeLE<int32_t>(player._pBaseDex);
file->writeLE<int32_t>(player._pVitality);
file->writeLE<int32_t>(player._pBaseVit);
file->writeLE<int32_t>(player._pStatPts);
file->writeLE<int32_t>(player._pDamageMod);
file->writeLE<int32_t>(player._pBaseToBlk);
file->writeLE<int32_t>(player._pHPBase);
file->writeLE<int32_t>(player._pMaxHPBase);
file->writeLE<int32_t>(player._pHitPoints);
file->writeLE<int32_t>(player._pMaxHP);
file->writeLE<int32_t>(player._pHPPer);
file->writeLE<int32_t>(player._pManaBase);
file->writeLE<int32_t>(player._pMaxManaBase);
file->writeLE<int32_t>(player._pMana);
file->writeLE<int32_t>(player._pMaxMana);
file->writeLE<int32_t>(player._pManaPer);
file->writeLE<int8_t>(player._pLevel);
file->writeLE<int8_t>(player._pMaxLvl);
file->skip(2); // Alignment
file->writeLE<int32_t>(pPlayer->_pExperience);
file->writeLE<int32_t>(pPlayer->_pMaxExp);
file->writeLE<int32_t>(pPlayer->_pNextExper);
file->writeLE<int8_t>(pPlayer->_pArmorClass);
file->writeLE<int8_t>(pPlayer->_pMagResist);
file->writeLE<int8_t>(pPlayer->_pFireResist);
file->writeLE<int8_t>(pPlayer->_pLghtResist);
file->writeLE<int32_t>(pPlayer->_pGold);
file->writeLE<uint32_t>(pPlayer->_pInfraFlag);
file->writeLE<int32_t>(pPlayer->position.temp.x);
file->writeLE<int32_t>(pPlayer->position.temp.y);
file->writeLE<int32_t>(pPlayer->tempDirection);
file->writeLE<int32_t>(pPlayer->_pVar4);
file->writeLE<int32_t>(pPlayer->_pVar5);
file->writeLE<int32_t>(pPlayer->position.offset2.x);
file->writeLE<int32_t>(pPlayer->position.offset2.y);
file->writeLE<int32_t>(player._pExperience);
file->writeLE<int32_t>(player._pMaxExp);
file->writeLE<int32_t>(player._pNextExper);
file->writeLE<int8_t>(player._pArmorClass);
file->writeLE<int8_t>(player._pMagResist);
file->writeLE<int8_t>(player._pFireResist);
file->writeLE<int8_t>(player._pLghtResist);
file->writeLE<int32_t>(player._pGold);
file->writeLE<uint32_t>(player._pInfraFlag);
file->writeLE<int32_t>(player.position.temp.x);
file->writeLE<int32_t>(player.position.temp.y);
file->writeLE<int32_t>(player.tempDirection);
file->writeLE<int32_t>(player._pVar4);
file->writeLE<int32_t>(player._pVar5);
file->writeLE<int32_t>(player.position.offset2.x);
file->writeLE<int32_t>(player.position.offset2.y);
// Write actionFrame for vanilla compatibility
file->writeLE<int32_t>(0);
for (uint8_t i = 0; i < giNumberOfLevels; i++)
file->writeLE<uint8_t>(pPlayer->_pLvlVisited[i]);
file->writeLE<uint8_t>(player._pLvlVisited[i]);
for (uint8_t i = 0; i < giNumberOfLevels; i++)
file->writeLE<uint8_t>(pPlayer->_pSLvlVisited[i]); // only 10 used
file->writeLE<uint8_t>(player._pSLvlVisited[i]); // only 10 used
file->skip(2); // Alignment
// Write _pGFXLoad for vanilla compatibility
file->writeLE<int32_t>(0);
file->skip(4 * 8); // Skip pointers _pNAnim
file->writeLE<int32_t>(pPlayer->_pNFrames);
// Skip _pNWidth
file->skip(4);
file->writeLE<int32_t>(player._pNFrames);
file->skip(4); // Skip _pNWidth
file->skip(4 * 8); // Skip pointers _pWAnim
file->writeLE<int32_t>(pPlayer->_pWFrames);
// Skip _pWWidth
file->skip(4);
file->writeLE<int32_t>(player._pWFrames);
file->skip(4); // Skip _pWWidth
file->skip(4 * 8); // Skip pointers _pAAnim
file->writeLE<int32_t>(pPlayer->_pAFrames);
// Skip _pAWidth
file->skip(4);
file->writeLE<int32_t>(pPlayer->_pAFNum);
file->writeLE<int32_t>(player._pAFrames);
file->skip(4); // Skip _pAWidth
file->writeLE<int32_t>(player._pAFNum);
file->skip(4 * 8); // Skip pointers _pLAnim
file->skip(4 * 8); // Skip pointers _pFAnim
file->skip(4 * 8); // Skip pointers _pTAnim
file->writeLE<int32_t>(pPlayer->_pSFrames);
// Skip _pSWidth
file->skip(4);
file->writeLE<int32_t>(pPlayer->_pSFNum);
file->writeLE<int32_t>(player._pSFrames);
file->skip(4); // Skip _pSWidth
file->writeLE<int32_t>(player._pSFNum);
file->skip(4 * 8); // Skip pointers _pHAnim
file->writeLE<int32_t>(pPlayer->_pHFrames);
// Skip _pHWidth
file->skip(4);
file->writeLE<int32_t>(player._pHFrames);
file->skip(4); // Skip _pHWidth
file->skip(4 * 8); // Skip pointers _pDAnim
file->writeLE<int32_t>(pPlayer->_pDFrames);
// Skip _pDWidth
file->skip(4);
file->writeLE<int32_t>(player._pDFrames);
file->skip(4); // Skip _pDWidth
file->skip(4 * 8); // Skip pointers _pBAnim
file->writeLE<int32_t>(pPlayer->_pBFrames);
// Skip _pBWidth
file->skip(4);
SaveItems(file, pPlayer->InvBody, NUM_INVLOC);
SaveItems(file, pPlayer->InvList, NUM_INV_GRID_ELEM);
file->writeLE<int32_t>(pPlayer->_pNumInv);
for (int8_t cell : pPlayer->InvGrid)
file->writeLE<int32_t>(player._pBFrames);
file->skip(4); // Skip _pBWidth
SaveItems(file, player.InvBody, NUM_INVLOC);
SaveItems(file, player.InvList, NUM_INV_GRID_ELEM);
file->writeLE<int32_t>(player._pNumInv);
for (int8_t cell : player.InvGrid)
file->writeLE<int8_t>(cell);
SaveItems(file, pPlayer->SpdList, MAXBELTITEMS);
SaveItem(file, &pPlayer->HoldItem);
file->writeLE<int32_t>(pPlayer->_pIMinDam);
file->writeLE<int32_t>(pPlayer->_pIMaxDam);
file->writeLE<int32_t>(pPlayer->_pIAC);
file->writeLE<int32_t>(pPlayer->_pIBonusDam);
file->writeLE<int32_t>(pPlayer->_pIBonusToHit);
file->writeLE<int32_t>(pPlayer->_pIBonusAC);
file->writeLE<int32_t>(pPlayer->_pIBonusDamMod);
SaveItems(file, player.SpdList, MAXBELTITEMS);
SaveItem(file, &player.HoldItem);
file->writeLE<int32_t>(player._pIMinDam);
file->writeLE<int32_t>(player._pIMaxDam);
file->writeLE<int32_t>(player._pIAC);
file->writeLE<int32_t>(player._pIBonusDam);
file->writeLE<int32_t>(player._pIBonusToHit);
file->writeLE<int32_t>(player._pIBonusAC);
file->writeLE<int32_t>(player._pIBonusDamMod);
file->skip(4); // Alignment
file->writeLE<uint64_t>(pPlayer->_pISpells);
file->writeLE<int32_t>(pPlayer->_pIFlags);
file->writeLE<int32_t>(pPlayer->_pIGetHit);
file->writeLE<uint64_t>(player._pISpells);
file->writeLE<int32_t>(player._pIFlags);
file->writeLE<int32_t>(player._pIGetHit);
file->writeLE<int8_t>(pPlayer->_pISplLvlAdd);
file->writeLE<int8_t>(player._pISplLvlAdd);
file->skip(1); // Unused
file->skip(2); // Alignment
file->writeLE<int32_t>(pPlayer->_pISplDur);
file->writeLE<int32_t>(pPlayer->_pIEnAc);
file->writeLE<int32_t>(pPlayer->_pIFMinDam);
file->writeLE<int32_t>(pPlayer->_pIFMaxDam);
file->writeLE<int32_t>(pPlayer->_pILMinDam);
file->writeLE<int32_t>(pPlayer->_pILMaxDam);
file->writeLE<int32_t>(pPlayer->_pOilType);
file->writeLE<uint8_t>(pPlayer->pTownWarps);
file->writeLE<uint8_t>(pPlayer->pDungMsgs);
file->writeLE<uint8_t>(pPlayer->pLvlLoad);
file->writeLE<int32_t>(player._pISplDur);
file->writeLE<int32_t>(player._pIEnAc);
file->writeLE<int32_t>(player._pIFMinDam);
file->writeLE<int32_t>(player._pIFMaxDam);
file->writeLE<int32_t>(player._pILMinDam);
file->writeLE<int32_t>(player._pILMaxDam);
file->writeLE<int32_t>(player._pOilType);
file->writeLE<uint8_t>(player.pTownWarps);
file->writeLE<uint8_t>(player.pDungMsgs);
file->writeLE<uint8_t>(player.pLvlLoad);
if (gbIsHellfire)
file->writeLE<uint8_t>(pPlayer->pDungMsgs2);
file->writeLE<uint8_t>(player.pDungMsgs2);
else
file->writeLE<uint8_t>(pPlayer->pBattleNet);
file->writeLE<uint8_t>(pPlayer->pManaShield);
file->writeLE<uint8_t>(pPlayer->pOriginalCathedral);
file->writeLE<uint8_t>(player.pBattleNet);
file->writeLE<uint8_t>(player.pManaShield);
file->writeLE<uint8_t>(player.pOriginalCathedral);
file->skip(2); // Available bytes
file->writeLE<uint16_t>(pPlayer->wReflections);
file->writeLE<uint16_t>(player.wReflections);
file->skip(14); // Available bytes
file->writeLE<uint32_t>(pPlayer->pDiabloKillLevel);
file->writeLE<uint32_t>(pPlayer->pDifficulty);
file->writeLE<uint32_t>(pPlayer->pDamAcFlags);
file->writeLE<uint32_t>(player.pDiabloKillLevel);
file->writeLE<uint32_t>(player.pDifficulty);
file->writeLE<uint32_t>(player.pDamAcFlags);
file->skip(20); // Available bytes
// Omit pointer _pNData
@ -1777,16 +1757,16 @@ static void SavePortal(SaveHelper *file, int i)
const int DiabloItemSaveSize = 368;
const int HellfireItemSaveSize = 372;
void SaveHeroItems(PlayerStruct *pPlayer)
void SaveHeroItems(PlayerStruct &player)
{
size_t items = NUM_INVLOC + NUM_INV_GRID_ELEM + MAXBELTITEMS;
SaveHelper file("heroitems", items * (gbIsHellfire ? HellfireItemSaveSize : DiabloItemSaveSize) + sizeof(uint8_t));
file.writeLE<uint8_t>(gbIsHellfire);
SaveItems(&file, pPlayer->InvBody, NUM_INVLOC);
SaveItems(&file, pPlayer->InvList, NUM_INV_GRID_ELEM);
SaveItems(&file, pPlayer->SpdList, MAXBELTITEMS);
SaveItems(&file, player.InvBody, NUM_INVLOC);
SaveItems(&file, player.InvList, NUM_INV_GRID_ELEM);
SaveItems(&file, player.SpdList, MAXBELTITEMS);
}
// 256 kilobytes + 3 bytes (demo leftover) for file magic (262147)

4
Source/loadsave.h

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

2
Source/missiles.cpp

@ -1526,7 +1526,7 @@ void AddStealPotions(int mi, int sx, int sy, int dx, int dy, int midir, int8_t m
break;
case IMISC_HEAL:
case IMISC_MANA:
RemoveSpdBarItem(pnum, si);
plr[pnum].RemoveSpdBarItem(si);
break;
case IMISC_FULLMANA:
ii = ItemMiscIdIdx(IMISC_MANA);

12
Source/msg.cpp

@ -1446,7 +1446,7 @@ static DWORD On_GETITEM(TCmd *pCmd, int pnum)
if ((currlevel == p->bLevel || p->bPnum == myplr) && p->bMaster != myplr) {
if (p->bPnum == myplr) {
if (currlevel != p->bLevel) {
ii = SyncPutItem(myplr, plr[myplr].position.tile, p->wIndx, p->wCI, p->dwSeed, p->bId, p->bDur, p->bMDur, p->bCh, p->bMCh, p->wValue, p->dwBuff, p->wToHit, p->wMaxDam, p->bMinStr, p->bMinMag, p->bMinDex, p->bAC);
ii = SyncPutItem(plr[myplr], plr[myplr].position.tile, p->wIndx, p->wCI, p->dwSeed, p->bId, p->bDur, p->bMDur, p->bCh, p->bMCh, p->wValue, p->dwBuff, p->wToHit, p->wMaxDam, p->bMinStr, p->bMinMag, p->bMinDex, p->bAC);
if (ii != -1)
InvGetItem(myplr, &items[ii], ii);
} else
@ -1508,7 +1508,7 @@ static DWORD On_AGETITEM(TCmd *pCmd, int pnum)
if ((currlevel == p->bLevel || p->bPnum == myplr) && p->bMaster != myplr) {
if (p->bPnum == myplr) {
if (currlevel != p->bLevel) {
int ii = SyncPutItem(myplr, plr[myplr].position.tile, p->wIndx, p->wCI, p->dwSeed, p->bId, p->bDur, p->bMDur, p->bCh, p->bMCh, p->wValue, p->dwBuff, p->wToHit, p->wMaxDam, p->bMinStr, p->bMinMag, p->bMinDex, p->bAC);
int ii = SyncPutItem(plr[myplr], plr[myplr].position.tile, p->wIndx, p->wCI, p->dwSeed, p->bId, p->bDur, p->bMDur, p->bCh, p->bMCh, p->wValue, p->dwBuff, p->wToHit, p->wMaxDam, p->bMinStr, p->bMinMag, p->bMinDex, p->bAC);
if (ii != -1)
AutoGetItem(myplr, &items[ii], ii);
} else
@ -1547,9 +1547,9 @@ static DWORD On_PUTITEM(TCmd *pCmd, int pnum)
else if (currlevel == plr[pnum].plrlevel) {
int ii;
if (pnum == myplr)
ii = InvPutItem(pnum, { p->x, p->y });
ii = InvPutItem(plr[pnum], { p->x, p->y });
else
ii = SyncPutItem(pnum, { p->x, p->y }, p->wIndx, p->wCI, p->dwSeed, p->bId, p->bDur, p->bMDur, p->bCh, p->bMCh, p->wValue, p->dwBuff, p->wToHit, p->wMaxDam, p->bMinStr, p->bMinMag, p->bMinDex, p->bAC);
ii = SyncPutItem(plr[pnum], { p->x, p->y }, p->wIndx, p->wCI, p->dwSeed, p->bId, p->bDur, p->bMDur, p->bCh, p->bMCh, p->wValue, p->dwBuff, p->wToHit, p->wMaxDam, p->bMinStr, p->bMinMag, p->bMinDex, p->bAC);
if (ii != -1) {
PutItemRecord(p->dwSeed, p->wCI, p->wIndx);
delta_put_item(p, items[ii].position.x, items[ii].position.y, plr[pnum].plrlevel);
@ -1572,7 +1572,7 @@ static DWORD On_SYNCPUTITEM(TCmd *pCmd, int pnum)
if (gbBufferMsgs == 1)
msg_send_packet(pnum, p, sizeof(*p));
else if (currlevel == plr[pnum].plrlevel) {
int ii = SyncPutItem(pnum, { p->x, p->y }, p->wIndx, p->wCI, p->dwSeed, p->bId, p->bDur, p->bMDur, p->bCh, p->bMCh, p->wValue, p->dwBuff, p->wToHit, p->wMaxDam, p->bMinStr, p->bMinMag, p->bMinDex, p->bAC);
int ii = SyncPutItem(plr[pnum], { p->x, p->y }, p->wIndx, p->wCI, p->dwSeed, p->bId, p->bDur, p->bMDur, p->bCh, p->bMCh, p->wValue, p->dwBuff, p->wToHit, p->wMaxDam, p->bMinStr, p->bMinMag, p->bMinDex, p->bAC);
if (ii != -1) {
PutItemRecord(p->dwSeed, p->wCI, p->wIndx);
delta_put_item(p, items[ii].position.x, items[ii].position.y, plr[pnum].plrlevel);
@ -1596,7 +1596,7 @@ static DWORD On_RESPAWNITEM(TCmd *pCmd, int pnum)
msg_send_packet(pnum, p, sizeof(*p));
else {
if (currlevel == plr[pnum].plrlevel && pnum != myplr) {
SyncPutItem(pnum, { p->x, p->y }, p->wIndx, p->wCI, p->dwSeed, p->bId, p->bDur, p->bMDur, p->bCh, p->bMCh, p->wValue, p->dwBuff, p->wToHit, p->wMaxDam, p->bMinStr, p->bMinMag, p->bMinDex, p->bAC);
SyncPutItem(plr[pnum], { p->x, p->y }, p->wIndx, p->wCI, p->dwSeed, p->bId, p->bDur, p->bMDur, p->bCh, p->bMCh, p->wValue, p->dwBuff, p->wToHit, p->wMaxDam, p->bMinStr, p->bMinMag, p->bMinDex, p->bAC);
}
PutItemRecord(p->dwSeed, p->wCI, p->wIndx);
delta_put_item(p, p->x, p->y, plr[pnum].plrlevel);

2
Source/objects.cpp

@ -3902,7 +3902,7 @@ bool OperateShrineSpiritual(int pnum)
gridItem = plr[pnum]._pNumInv;
plr[pnum].InvList[t]._ivalue = r;
plr[pnum]._pGold += r;
SetGoldCurs(pnum, t);
SetPlrHandGoldCurs(&plr[pnum].InvList[t]);
}
}

30
Source/pfile.cpp

@ -236,23 +236,23 @@ void pfile_write_hero(bool write_game_data, bool clear_tables)
pfile_encode_hero(&pkplr);
if (!gbVanilla) {
SaveHotkeys();
SaveHeroItems(&plr[myplr]);
SaveHeroItems(plr[myplr]);
}
}
static void game_2_ui_player(const PlayerStruct *p, _uiheroinfo *heroinfo, bool bHasSaveFile)
static void game_2_ui_player(const PlayerStruct &player, _uiheroinfo *heroinfo, bool bHasSaveFile)
{
memset(heroinfo, 0, sizeof(*heroinfo));
strncpy(heroinfo->name, p->_pName, sizeof(heroinfo->name) - 1);
strncpy(heroinfo->name, player._pName, sizeof(heroinfo->name) - 1);
heroinfo->name[sizeof(heroinfo->name) - 1] = '\0';
heroinfo->level = p->_pLevel;
heroinfo->heroclass = p->_pClass;
heroinfo->strength = p->_pStrength;
heroinfo->magic = p->_pMagic;
heroinfo->dexterity = p->_pDexterity;
heroinfo->vitality = p->_pVitality;
heroinfo->level = player._pLevel;
heroinfo->heroclass = player._pClass;
heroinfo->strength = player._pStrength;
heroinfo->magic = player._pMagic;
heroinfo->dexterity = player._pDexterity;
heroinfo->vitality = player._pVitality;
heroinfo->hassaved = bHasSaveFile;
heroinfo->herorank = p->pDiabloKillLevel;
heroinfo->herorank = player.pDiabloKillLevel;
heroinfo->spawned = gbIsSpawn;
}
@ -274,11 +274,11 @@ bool pfile_ui_set_hero_infos(bool (*ui_add_hero_info)(_uiheroinfo *))
UnPackPlayer(&pkplr, 0, false);
pfile_SFileCloseArchive(&archive);
LoadHeroItems(&plr[0]);
LoadHeroItems(plr[0]);
RemoveEmptyInventory(0);
CalcPlrInv(0, false);
game_2_ui_player(&plr[0], &uihero, hasSaveGame);
game_2_ui_player(plr[0], &uihero, hasSaveGame);
ui_add_hero_info(&uihero);
}
pfile_SFileCloseArchive(&archive);
@ -335,10 +335,10 @@ bool pfile_ui_save_create(_uiheroinfo *heroinfo)
player._pName[PLR_NAME_LEN - 1] = '\0';
PackPlayer(&pkplr, player, true);
pfile_encode_hero(&pkplr);
game_2_ui_player(&player, heroinfo, false);
game_2_ui_player(player, heroinfo, false);
if (!gbVanilla) {
SaveHotkeys();
SaveHeroItems(&player);
SaveHeroItems(player);
}
mpqapi_flush_and_close(true);
@ -400,7 +400,7 @@ void pfile_read_player_from_save(char name[16], int playerId)
UnPackPlayer(&pkplr, playerId, false);
LoadHeroItems(&plr[playerId]);
LoadHeroItems(plr[playerId]);
RemoveEmptyInventory(playerId);
CalcPlrInv(playerId, false);
}

152
Source/player.cpp

@ -265,6 +265,14 @@ void PlayerStruct::RemoveInvItem(int iv, bool calcScrolls)
CalcScrolls();
}
void PlayerStruct::RemoveSpdBarItem(int iv)
{
SpdList[iv]._itype = ITYPE_NONE;
CalcScrolls();
force_redraw = 255;
}
int PlayerStruct::GetBaseAttributeValue(CharacterAttribute attribute) const
{
switch (attribute) {
@ -1781,116 +1789,53 @@ StartPlayerKill(int pnum, int earflag)
SetPlayerHitPoints(pnum, 0);
}
void DropHalfPlayersGold(int pnum)
static int DropGold(int pnum, int amount, bool skipFullStacks)
{
int i, hGold;
auto &player = plr[pnum];
for (int i = 0; i < player._pNumInv && amount > 0; i++) {
auto &item = player.InvList[i];
if (item._itype != ITYPE_GOLD || (skipFullStacks && item._ivalue == MaxGold))
continue;
if (amount < item._ivalue) {
item._ivalue -= amount;
SetPlrHandItem(&player.HoldItem, IDI_GOLD);
GetGoldSeed(pnum, &player.HoldItem);
SetPlrHandGoldCurs(&player.HoldItem);
player.HoldItem._ivalue = amount;
PlrDeadItem(player, &player.HoldItem, 0, 0);
return 0;
}
amount -= item._ivalue;
player.RemoveInvItem(i);
SetPlrHandItem(&player.HoldItem, IDI_GOLD);
GetGoldSeed(pnum, &player.HoldItem);
SetPlrHandGoldCurs(&player.HoldItem);
player.HoldItem._ivalue = item._ivalue;
PlrDeadItem(player, &player.HoldItem, 0, 0);
i = -1;
}
return amount;
}
void DropHalfPlayersGold(int pnum)
{
if ((DWORD)pnum >= MAX_PLRS) {
app_fatal("DropHalfPlayersGold: illegal player %i", pnum);
}
auto &player = plr[pnum];
hGold = player._pGold / 2;
for (i = 0; i < MAXBELTITEMS && hGold > 0; i++) {
if (player.SpdList[i]._itype == ITYPE_GOLD && player.SpdList[i]._ivalue != MaxGold) {
if (hGold < player.SpdList[i]._ivalue) {
player.SpdList[i]._ivalue -= hGold;
SetSpdbarGoldCurs(pnum, i);
SetPlrHandItem(&player.HoldItem, IDI_GOLD);
GetGoldSeed(pnum, &player.HoldItem);
SetPlrHandGoldCurs(&player.HoldItem);
player.HoldItem._ivalue = hGold;
PlrDeadItem(player, &player.HoldItem, 0, 0);
hGold = 0;
} else {
hGold -= player.SpdList[i]._ivalue;
RemoveSpdBarItem(pnum, i);
SetPlrHandItem(&player.HoldItem, IDI_GOLD);
GetGoldSeed(pnum, &player.HoldItem);
SetPlrHandGoldCurs(&player.HoldItem);
player.HoldItem._ivalue = player.SpdList[i]._ivalue;
PlrDeadItem(player, &player.HoldItem, 0, 0);
i = -1;
}
}
}
if (hGold > 0) {
for (i = 0; i < MAXBELTITEMS && hGold > 0; i++) {
if (player.SpdList[i]._itype == ITYPE_GOLD) {
if (hGold < player.SpdList[i]._ivalue) {
player.SpdList[i]._ivalue -= hGold;
SetSpdbarGoldCurs(pnum, i);
SetPlrHandItem(&player.HoldItem, IDI_GOLD);
GetGoldSeed(pnum, &player.HoldItem);
SetPlrHandGoldCurs(&player.HoldItem);
player.HoldItem._ivalue = hGold;
PlrDeadItem(player, &player.HoldItem, 0, 0);
hGold = 0;
} else {
hGold -= player.SpdList[i]._ivalue;
RemoveSpdBarItem(pnum, i);
SetPlrHandItem(&player.HoldItem, IDI_GOLD);
GetGoldSeed(pnum, &player.HoldItem);
SetPlrHandGoldCurs(&player.HoldItem);
player.HoldItem._ivalue = player.SpdList[i]._ivalue;
PlrDeadItem(player, &player.HoldItem, 0, 0);
i = -1;
}
}
}
}
force_redraw = 255;
if (hGold > 0) {
for (i = 0; i < player._pNumInv && hGold > 0; i++) {
if (player.InvList[i]._itype == ITYPE_GOLD && player.InvList[i]._ivalue != MaxGold) {
if (hGold < player.InvList[i]._ivalue) {
player.InvList[i]._ivalue -= hGold;
SetGoldCurs(pnum, i);
SetPlrHandItem(&player.HoldItem, IDI_GOLD);
GetGoldSeed(pnum, &player.HoldItem);
SetPlrHandGoldCurs(&player.HoldItem);
player.HoldItem._ivalue = hGold;
PlrDeadItem(player, &player.HoldItem, 0, 0);
hGold = 0;
} else {
hGold -= player.InvList[i]._ivalue;
player.RemoveInvItem(i);
SetPlrHandItem(&player.HoldItem, IDI_GOLD);
GetGoldSeed(pnum, &player.HoldItem);
SetPlrHandGoldCurs(&player.HoldItem);
player.HoldItem._ivalue = player.InvList[i]._ivalue;
PlrDeadItem(player, &player.HoldItem, 0, 0);
i = -1;
}
}
}
}
if (hGold > 0) {
for (i = 0; i < player._pNumInv && hGold > 0; i++) {
if (player.InvList[i]._itype == ITYPE_GOLD) {
if (hGold < player.InvList[i]._ivalue) {
player.InvList[i]._ivalue -= hGold;
SetGoldCurs(pnum, i);
SetPlrHandItem(&player.HoldItem, IDI_GOLD);
GetGoldSeed(pnum, &player.HoldItem);
SetPlrHandGoldCurs(&player.HoldItem);
player.HoldItem._ivalue = hGold;
PlrDeadItem(player, &player.HoldItem, 0, 0);
hGold = 0;
} else {
hGold -= player.InvList[i]._ivalue;
player.RemoveInvItem(i);
SetPlrHandItem(&player.HoldItem, IDI_GOLD);
GetGoldSeed(pnum, &player.HoldItem);
SetPlrHandGoldCurs(&player.HoldItem);
player.HoldItem._ivalue = player.InvList[i]._ivalue;
PlrDeadItem(player, &player.HoldItem, 0, 0);
i = -1;
}
}
}
}
player._pGold = CalculateGold(player);
int hGold = player._pGold / 2;
hGold = DropGold(pnum, hGold, true);
if (hGold > 0)
DropGold(pnum, hGold, false);
player._pGold -= hGold;
}
void StripTopGold(int pnum)
@ -1910,7 +1855,6 @@ void StripTopGold(int pnum)
if (player.InvList[i]._ivalue > MaxGold) {
val = player.InvList[i]._ivalue - MaxGold;
player.InvList[i]._ivalue = MaxGold;
SetGoldCurs(pnum, i);
SetPlrHandItem(&player.HoldItem, 0);
GetGoldSeed(pnum, &player.HoldItem);
player.HoldItem._ivalue = val;

2
Source/player.h

@ -312,6 +312,8 @@ struct PlayerStruct {
*/
void RemoveInvItem(int iv, bool calcScrolls = true);
void RemoveSpdBarItem(int iv);
/**
* @brief Gets the most valuable item out of all the player's items that match the given predicate.
* @param itemPredicate The predicate used to match the items.

34
Source/portal.cpp

@ -140,23 +140,25 @@ void GetPortalLevel()
currlevel = 0;
plr[myplr].plrlevel = 0;
leveltype = DTYPE_TOWN;
return;
}
if (portal[portalindex].setlvl) {
setlevel = true;
setlvlnum = (_setlevels)portal[portalindex].level;
currlevel = portal[portalindex].level;
plr[myplr].plrlevel = setlvlnum;
leveltype = portal[portalindex].ltype;
} else {
if (portal[portalindex].setlvl) {
setlevel = true;
setlvlnum = (_setlevels)portal[portalindex].level;
currlevel = portal[portalindex].level;
plr[myplr].plrlevel = setlvlnum;
leveltype = portal[portalindex].ltype;
} else {
setlevel = false;
currlevel = portal[portalindex].level;
plr[myplr].plrlevel = currlevel;
leveltype = portal[portalindex].ltype;
}
if (portalindex == myplr) {
NetSendCmd(true, CMD_DEACTIVATEPORTAL);
DeactivatePortal(portalindex);
}
setlevel = false;
currlevel = portal[portalindex].level;
plr[myplr].plrlevel = currlevel;
leveltype = portal[portalindex].ltype;
}
if (portalindex == myplr) {
NetSendCmd(true, CMD_DEACTIVATEPORTAL);
DeactivatePortal(portalindex);
}
}

4
Source/qol/xpbar.cpp

@ -68,7 +68,7 @@ void DrawXPBar(const CelOutputBuffer &out)
if (!sgOptions.Gameplay.bExperienceBar)
return;
const PlayerStruct &player = plr[myplr];
const auto &player = plr[myplr];
const int backX = PANEL_LEFT + PANEL_WIDTH / 2 - 155;
const int backY = PANEL_TOP + PANEL_HEIGHT - 11;
@ -119,7 +119,7 @@ bool CheckXPBarInfo()
if (MouseX < backX || MouseX >= backX + BACK_WIDTH || MouseY < backY || MouseY >= backY + BACK_HEIGHT)
return false;
const PlayerStruct &player = plr[myplr];
const auto &player = plr[myplr];
const int charLevel = player._pLevel;

35
Source/scrollrt.cpp

@ -408,10 +408,10 @@ static void DrawPlayer(const CelOutputBuffer &out, int pnum, int x, int y, int p
return;
}
PlayerStruct *pPlayer = &plr[pnum];
auto &player = plr[pnum];
auto *pCelSprite = pPlayer->AnimInfo.pCelSprite;
int nCel = pPlayer->AnimInfo.GetFrameToUseForRendering();
auto *pCelSprite = player.AnimInfo.pCelSprite;
int nCel = player.AnimInfo.GetFrameToUseForRendering();
if (pCelSprite == nullptr) {
Log("Drawing player {} \"{}\": NULL CelSprite", pnum, plr[pnum]._pName);
@ -471,17 +471,14 @@ static void DrawPlayer(const CelOutputBuffer &out, int pnum, int x, int y, int p
*/
void DrawDeadPlayer(const CelOutputBuffer &out, int x, int y, int sx, int sy)
{
int i, px, py;
PlayerStruct *p;
dFlags[x][y] &= ~BFLAG_DEAD_PLAYER;
for (i = 0; i < MAX_PLRS; i++) {
p = &plr[i];
if (p->plractive && p->_pHitPoints == 0 && p->plrlevel == (BYTE)currlevel && p->position.tile.x == x && p->position.tile.y == y) {
for (int i = 0; i < MAX_PLRS; i++) {
auto &player = plr[i];
if (player.plractive && player._pHitPoints == 0 && player.plrlevel == (BYTE)currlevel && player.position.tile.x == x && player.position.tile.y == y) {
dFlags[x][y] |= BFLAG_DEAD_PLAYER;
px = sx + p->position.offset.x - CalculateWidth2(p->AnimInfo.pCelSprite == nullptr ? 96 : p->AnimInfo.pCelSprite->Width());
py = sy + p->position.offset.y;
int px = sx + player.position.offset.x - CalculateWidth2(player.AnimInfo.pCelSprite == nullptr ? 96 : player.AnimInfo.pCelSprite->Width());
int py = sy + player.position.offset.y;
DrawPlayer(out, i, x, y, px, py);
}
}
@ -711,13 +708,13 @@ static void DrawPlayerHelper(const CelOutputBuffer &out, int x, int y, int sx, i
Log("draw player: tried to draw illegal player {}", p);
return;
}
auto &player = plr[p];
PlayerStruct *pPlayer = &plr[p];
Point offset = pPlayer->position.offset;
if (pPlayer->IsWalking()) {
offset = GetOffsetForWalking(pPlayer->AnimInfo, pPlayer->_pdir);
Point offset = player.position.offset;
if (player.IsWalking()) {
offset = GetOffsetForWalking(player.AnimInfo, player._pdir);
}
int px = sx + offset.x - CalculateWidth2(pPlayer->AnimInfo.pCelSprite == nullptr ? 96 : pPlayer->AnimInfo.pCelSprite->Width());
int px = sx + offset.x - CalculateWidth2(player.AnimInfo.pCelSprite == nullptr ? 96 : player.AnimInfo.pCelSprite->Width());
int py = sy + offset.y;
DrawPlayer(out, p, x, y, px, py);
@ -1147,10 +1144,10 @@ static void DrawGame(const CelOutputBuffer &full_out, int x, int y)
: full_out.subregionY(0, (gnViewportHeight + 1) / 2);
// Adjust by player offset and tile grid alignment
PlayerStruct *pPlayer = &plr[myplr];
auto &myPlayer = plr[myplr];
Point offset = ScrollInfo.offset;
if (pPlayer->IsWalking())
offset = GetOffsetForWalking(pPlayer->AnimInfo, pPlayer->_pdir, true);
if (myPlayer.IsWalking())
offset = GetOffsetForWalking(myPlayer.AnimInfo, myPlayer._pdir, true);
sx = offset.x + tileOffsetX;
sy = offset.y + tileOffsetY;

822
Source/stores.cpp

File diff suppressed because it is too large Load Diff

2
Source/stores.h

@ -108,8 +108,6 @@ void STextUp();
void STextDown();
void STextPrior();
void STextNext();
void SetGoldCurs(int pnum, int i);
void SetSpdbarGoldCurs(int pnum, int i);
void TakePlrsMoney(int cost);
void STextEnter();
void CheckStoreBtn();

1
Source/towners.h

@ -59,7 +59,6 @@ struct TownerStruct {
/** Specifies the animation frame sequence. */
const uint8_t *animOrder; // unowned
std::size_t animOrderSize;
PlayerStruct *_tTalkingToPlayer;
void (*talk)(PlayerStruct &player, TownerStruct &barOwner);
bool _tbtcnt;
_talker_id _ttype;

26
Source/trigs.cpp

@ -76,7 +76,9 @@ void InitTownTriggers()
townwarp = gbIsMultiplayer && !gbIsSpawn;
}
if (!gbIsSpawn) {
if (gbIsMultiplayer || plr[myplr].pTownWarps & 1 || (gbIsHellfire && plr[myplr]._pLevel >= 10)) {
auto &myPlayer = plr[myplr];
if (gbIsMultiplayer || myPlayer.pTownWarps & 1 || (gbIsHellfire && myPlayer._pLevel >= 10)) {
townwarps[0] = true;
trigs[numtrigs].position = { 49, 21 };
trigs[numtrigs]._tmsg = WM_DIABTOWNWARP;
@ -87,14 +89,14 @@ void InitTownTriggers()
#endif
numtrigs++;
}
if (gbIsMultiplayer || plr[myplr].pTownWarps & 2 || (gbIsHellfire && plr[myplr]._pLevel >= 15)) {
if (gbIsMultiplayer || myPlayer.pTownWarps & 2 || (gbIsHellfire && myPlayer._pLevel >= 15)) {
townwarps[1] = true;
trigs[numtrigs].position = { 17, 69 };
trigs[numtrigs]._tmsg = WM_DIABTOWNWARP;
trigs[numtrigs]._tlvl = 9;
numtrigs++;
}
if (gbIsMultiplayer || plr[myplr].pTownWarps & 4 || (gbIsHellfire && plr[myplr]._pLevel >= 20)) {
if (gbIsMultiplayer || myPlayer.pTownWarps & 4 || (gbIsHellfire && myPlayer._pLevel >= 20)) {
townwarps[2] = true;
trigs[numtrigs].position = { 41, 80 };
trigs[numtrigs]._tmsg = WM_DIABTOWNWARP;
@ -816,18 +818,20 @@ void CheckTrigForce()
void CheckTriggers()
{
if (plr[myplr]._pmode != PM_STAND)
auto &myPlayer = plr[myplr];
if (myPlayer._pmode != PM_STAND)
return;
for (int i = 0; i < numtrigs; i++) {
if (plr[myplr].position.tile != trigs[i].position) {
if (myPlayer.position.tile != trigs[i].position) {
continue;
}
switch (trigs[i]._tmsg) {
case WM_DIABNEXTLVL:
if (gbIsSpawn && currlevel >= 2) {
NetSendCmdLoc(myplr, true, CMD_WALKXY, { plr[myplr].position.tile.x, plr[myplr].position.tile.y + 1 });
NetSendCmdLoc(myplr, true, CMD_WALKXY, { myPlayer.position.tile.x, myPlayer.position.tile.y + 1 });
PlaySFX(PS_WARR18);
InitDiabloMsg(EMSG_NOT_IN_SHAREWARE);
} else {
@ -845,27 +849,27 @@ void CheckTriggers()
bool abort = false;
diablo_message abortflag;
auto position = plr[myplr].position.tile;
if (trigs[i]._tlvl == 5 && plr[myplr]._pLevel < 8) {
auto position = myPlayer.position.tile;
if (trigs[i]._tlvl == 5 && myPlayer._pLevel < 8) {
abort = true;
position.y += 1;
abortflag = EMSG_REQUIRES_LVL_8;
}
if (trigs[i]._tlvl == 9 && plr[myplr]._pLevel < 13) {
if (trigs[i]._tlvl == 9 && myPlayer._pLevel < 13) {
abort = true;
position.x += 1;
abortflag = EMSG_REQUIRES_LVL_13;
}
if (trigs[i]._tlvl == 13 && plr[myplr]._pLevel < 17) {
if (trigs[i]._tlvl == 13 && myPlayer._pLevel < 17) {
abort = true;
position.y += 1;
abortflag = EMSG_REQUIRES_LVL_17;
}
if (abort) {
plr[myplr].Say(HeroSpeech::ICantGetThereFromHere);
myPlayer.Say(HeroSpeech::ICantGetThereFromHere);
InitDiabloMsg(abortflag);
NetSendCmdLoc(myplr, true, CMD_WALKXY, position);

5
test/control_test.cpp

@ -10,10 +10,11 @@ TEST(Control, SetSpell)
pinfoflag = true;
pSpell = SPL_FIREBOLT;
pSplType = RSPLTYPE_CHARGES;
auto &myPlayer = plr[myplr];
SetSpell();
EXPECT_EQ(spselflag, false);
EXPECT_EQ(plr[myplr]._pRSpell, SPL_FIREBOLT);
EXPECT_EQ(plr[myplr]._pRSplType, RSPLTYPE_CHARGES);
EXPECT_EQ(myPlayer._pRSpell, SPL_FIREBOLT);
EXPECT_EQ(myPlayer._pRSplType, RSPLTYPE_CHARGES);
EXPECT_EQ(pnumlines, 0);
EXPECT_EQ(pinfoflag, false);
EXPECT_EQ(force_redraw, 255);

12
test/inv_test.cpp

@ -102,14 +102,14 @@ TEST(Inv, UseScroll_from_belt_invalid_conditions)
TEST(Inv, CalculateGold)
{
plr[myplr]._pNumInv = 10;
// Set up two slots of gold both in the belt and inventory
plr[myplr].SpdList[1]._itype = ITYPE_GOLD;
plr[myplr].SpdList[5]._itype = ITYPE_GOLD;
// Set up 4 slots of gold in the inventory
plr[myplr].InvList[1]._itype = ITYPE_GOLD;
plr[myplr].InvList[5]._itype = ITYPE_GOLD;
plr[myplr].InvList[2]._itype = ITYPE_GOLD;
plr[myplr].InvList[3]._itype = ITYPE_GOLD;
// Set the gold amount to arbitrary values
plr[myplr].SpdList[1]._ivalue = 100;
plr[myplr].SpdList[5]._ivalue = 200;
plr[myplr].InvList[1]._ivalue = 100;
plr[myplr].InvList[5]._ivalue = 200;
plr[myplr].InvList[2]._ivalue = 3;
plr[myplr].InvList[3]._ivalue = 30;
@ -187,7 +187,7 @@ TEST(Inv, RemoveSpdBarItem)
// Put an item in the belt: | x | x | item | x | x | x | x | x |
plr[myplr].SpdList[3]._itype = ITYPE_MISC;
RemoveSpdBarItem(myplr, 3);
plr[myplr].RemoveSpdBarItem(3);
EXPECT_EQ(plr[myplr].SpdList[3]._itype, ITYPE_NONE);
}

10
test/player_test.cpp

@ -11,16 +11,18 @@ extern bool PM_DoGotHit(int pnum);
int RunBlockTest(int frames, int flags)
{
int pnum = 0;
plr[pnum]._pHFrames = frames;
plr[pnum]._pIFlags = flags;
auto &player = plr[pnum];
player._pHFrames = frames;
player._pIFlags = flags;
StartPlrHit(pnum, 5, Direction::DIR_S);
int i = 1;
for (; i < 100; i++) {
PM_DoGotHit(pnum);
if (plr[pnum]._pmode != PM_GOTHIT)
if (player._pmode != PM_GOTHIT)
break;
plr[pnum].AnimInfo.CurrentFrame++;
player.AnimInfo.CurrentFrame++;
}
return i;

210
test/writehero_test.cpp

@ -242,113 +242,113 @@ static int CountBool(bool *bools, int n)
return count;
}
static void AssertPlayer(PlayerStruct *pPlayer)
static void AssertPlayer(PlayerStruct &player)
{
ASSERT_EQ(Count8(pPlayer->_pSplLvl, 64), 23);
ASSERT_EQ(Count8(pPlayer->InvGrid, NUM_INV_GRID_ELEM), 9);
ASSERT_EQ(CountItems(pPlayer->InvBody, NUM_INVLOC), 6);
ASSERT_EQ(CountItems(pPlayer->InvList, NUM_INV_GRID_ELEM), 2);
ASSERT_EQ(CountItems(pPlayer->SpdList, MAXBELTITEMS), 8);
ASSERT_EQ(CountItems(&pPlayer->HoldItem, 1), 1);
ASSERT_EQ(Count8(player._pSplLvl, 64), 23);
ASSERT_EQ(Count8(player.InvGrid, NUM_INV_GRID_ELEM), 9);
ASSERT_EQ(CountItems(player.InvBody, NUM_INVLOC), 6);
ASSERT_EQ(CountItems(player.InvList, NUM_INV_GRID_ELEM), 2);
ASSERT_EQ(CountItems(player.SpdList, MAXBELTITEMS), 8);
ASSERT_EQ(CountItems(&player.HoldItem, 1), 1);
ASSERT_EQ(pPlayer->position.tile.x, 75);
ASSERT_EQ(pPlayer->position.tile.y, 68);
ASSERT_EQ(pPlayer->position.future.x, 75);
ASSERT_EQ(pPlayer->position.future.y, 68);
ASSERT_EQ(pPlayer->plrlevel, 0);
ASSERT_EQ(pPlayer->destAction, -1);
ASSERT_STREQ(pPlayer->_pName, "TestPlayer");
ASSERT_EQ(pPlayer->_pClass, HeroClass::Rogue);
ASSERT_EQ(pPlayer->_pBaseStr, 55);
ASSERT_EQ(pPlayer->_pStrength, 124);
ASSERT_EQ(pPlayer->_pBaseMag, 70);
ASSERT_EQ(pPlayer->_pMagic, 80);
ASSERT_EQ(pPlayer->_pBaseDex, 250);
ASSERT_EQ(pPlayer->_pDexterity, 281);
ASSERT_EQ(pPlayer->_pBaseVit, 80);
ASSERT_EQ(pPlayer->_pVitality, 90);
ASSERT_EQ(pPlayer->_pLevel, 50);
ASSERT_EQ(pPlayer->_pStatPts, 0);
ASSERT_EQ(pPlayer->_pExperience, 1583495809);
ASSERT_EQ(pPlayer->_pGold, 0);
ASSERT_EQ(pPlayer->_pMaxHPBase, 12864);
ASSERT_EQ(pPlayer->_pHPBase, 12864);
ASSERT_EQ(pPlayer->_pBaseToBlk, 20);
ASSERT_EQ(pPlayer->_pMaxManaBase, 11104);
ASSERT_EQ(pPlayer->_pManaBase, 11104);
ASSERT_EQ(pPlayer->_pMemSpells, 66309357295);
ASSERT_EQ(pPlayer->_pNumInv, 2);
ASSERT_EQ(pPlayer->wReflections, 0);
ASSERT_EQ(pPlayer->pTownWarps, 0);
ASSERT_EQ(pPlayer->pDungMsgs, 0);
ASSERT_EQ(pPlayer->pDungMsgs2, 0);
ASSERT_EQ(pPlayer->pLvlLoad, 0);
ASSERT_EQ(pPlayer->pDiabloKillLevel, 3);
ASSERT_EQ(pPlayer->pBattleNet, 0);
ASSERT_EQ(pPlayer->pManaShield, 0);
ASSERT_EQ(pPlayer->pDifficulty, 0);
ASSERT_EQ(pPlayer->pDamAcFlags, 0);
ASSERT_EQ(player.position.tile.x, 75);
ASSERT_EQ(player.position.tile.y, 68);
ASSERT_EQ(player.position.future.x, 75);
ASSERT_EQ(player.position.future.y, 68);
ASSERT_EQ(player.plrlevel, 0);
ASSERT_EQ(player.destAction, -1);
ASSERT_STREQ(player._pName, "TestPlayer");
ASSERT_EQ(player._pClass, HeroClass::Rogue);
ASSERT_EQ(player._pBaseStr, 55);
ASSERT_EQ(player._pStrength, 124);
ASSERT_EQ(player._pBaseMag, 70);
ASSERT_EQ(player._pMagic, 80);
ASSERT_EQ(player._pBaseDex, 250);
ASSERT_EQ(player._pDexterity, 281);
ASSERT_EQ(player._pBaseVit, 80);
ASSERT_EQ(player._pVitality, 90);
ASSERT_EQ(player._pLevel, 50);
ASSERT_EQ(player._pStatPts, 0);
ASSERT_EQ(player._pExperience, 1583495809);
ASSERT_EQ(player._pGold, 0);
ASSERT_EQ(player._pMaxHPBase, 12864);
ASSERT_EQ(player._pHPBase, 12864);
ASSERT_EQ(player._pBaseToBlk, 20);
ASSERT_EQ(player._pMaxManaBase, 11104);
ASSERT_EQ(player._pManaBase, 11104);
ASSERT_EQ(player._pMemSpells, 66309357295);
ASSERT_EQ(player._pNumInv, 2);
ASSERT_EQ(player.wReflections, 0);
ASSERT_EQ(player.pTownWarps, 0);
ASSERT_EQ(player.pDungMsgs, 0);
ASSERT_EQ(player.pDungMsgs2, 0);
ASSERT_EQ(player.pLvlLoad, 0);
ASSERT_EQ(player.pDiabloKillLevel, 3);
ASSERT_EQ(player.pBattleNet, 0);
ASSERT_EQ(player.pManaShield, 0);
ASSERT_EQ(player.pDifficulty, 0);
ASSERT_EQ(player.pDamAcFlags, 0);
ASSERT_EQ(pPlayer->_pmode, 0);
ASSERT_EQ(Count8(pPlayer->walkpath, MAX_PATH_LENGTH), 25);
ASSERT_EQ(pPlayer->_pgfxnum, 36);
ASSERT_EQ(pPlayer->AnimInfo.DelayLen, 3);
ASSERT_EQ(pPlayer->AnimInfo.DelayCounter, 1);
ASSERT_EQ(pPlayer->AnimInfo.NumberOfFrames, 20);
ASSERT_EQ(pPlayer->AnimInfo.CurrentFrame, 1);
ASSERT_EQ(pPlayer->_pSpell, -1);
ASSERT_EQ(pPlayer->_pSplType, 4);
ASSERT_EQ(pPlayer->_pSplFrom, 0);
ASSERT_EQ(pPlayer->_pTSpell, 0);
ASSERT_EQ(pPlayer->_pTSplType, 0);
ASSERT_EQ(pPlayer->_pRSpell, -1);
ASSERT_EQ(pPlayer->_pRSplType, 4);
ASSERT_EQ(pPlayer->_pSBkSpell, -1);
ASSERT_EQ(pPlayer->_pSBkSplType, 0);
ASSERT_EQ(pPlayer->_pAblSpells, 134217728);
ASSERT_EQ(pPlayer->_pScrlSpells, 0);
ASSERT_EQ(pPlayer->_pSpellFlags, 0);
ASSERT_EQ(pPlayer->_pwtype, 1);
ASSERT_EQ(pPlayer->_pBlockFlag, 0);
ASSERT_EQ(pPlayer->_pLightRad, 11);
ASSERT_EQ(pPlayer->_pDamageMod, 101);
ASSERT_EQ(pPlayer->_pHitPoints, 16640);
ASSERT_EQ(pPlayer->_pMaxHP, 16640);
ASSERT_EQ(pPlayer->_pMana, 14624);
ASSERT_EQ(pPlayer->_pMaxMana, 14624);
ASSERT_EQ(pPlayer->_pNextExper, 2000);
ASSERT_EQ(pPlayer->_pMagResist, 75);
ASSERT_EQ(pPlayer->_pFireResist, 16);
ASSERT_EQ(pPlayer->_pLghtResist, 75);
ASSERT_EQ(CountBool(pPlayer->_pLvlVisited, NUMLEVELS), 0);
ASSERT_EQ(CountBool(pPlayer->_pSLvlVisited, NUMLEVELS), 0);
ASSERT_EQ(pPlayer->_pNFrames, 20);
ASSERT_EQ(pPlayer->_pWFrames, 8);
ASSERT_EQ(pPlayer->_pAFrames, 0);
ASSERT_EQ(pPlayer->_pAFNum, 0);
ASSERT_EQ(pPlayer->_pSFrames, 16);
ASSERT_EQ(pPlayer->_pSFNum, 12);
ASSERT_EQ(pPlayer->_pHFrames, 0);
ASSERT_EQ(pPlayer->_pDFrames, 20);
ASSERT_EQ(pPlayer->_pBFrames, 0);
ASSERT_EQ(pPlayer->_pIMinDam, 1);
ASSERT_EQ(pPlayer->_pIMaxDam, 14);
ASSERT_EQ(pPlayer->_pIAC, 115);
ASSERT_EQ(pPlayer->_pIBonusDam, 0);
ASSERT_EQ(pPlayer->_pIBonusToHit, 0);
ASSERT_EQ(pPlayer->_pIBonusAC, 0);
ASSERT_EQ(pPlayer->_pIBonusDamMod, 0);
ASSERT_EQ(pPlayer->_pISpells, 0);
ASSERT_EQ(pPlayer->_pIFlags, 0);
ASSERT_EQ(pPlayer->_pIGetHit, 0);
ASSERT_EQ(pPlayer->_pISplLvlAdd, 0);
ASSERT_EQ(pPlayer->_pISplDur, 0);
ASSERT_EQ(pPlayer->_pIEnAc, 0);
ASSERT_EQ(pPlayer->_pIFMinDam, 0);
ASSERT_EQ(pPlayer->_pIFMaxDam, 0);
ASSERT_EQ(pPlayer->_pILMinDam, 0);
ASSERT_EQ(pPlayer->_pILMaxDam, 0);
ASSERT_EQ(pPlayer->pOriginalCathedral, 0);
ASSERT_EQ(player._pmode, 0);
ASSERT_EQ(Count8(player.walkpath, MAX_PATH_LENGTH), 25);
ASSERT_EQ(player._pgfxnum, 36);
ASSERT_EQ(player.AnimInfo.DelayLen, 3);
ASSERT_EQ(player.AnimInfo.DelayCounter, 1);
ASSERT_EQ(player.AnimInfo.NumberOfFrames, 20);
ASSERT_EQ(player.AnimInfo.CurrentFrame, 1);
ASSERT_EQ(player._pSpell, -1);
ASSERT_EQ(player._pSplType, 4);
ASSERT_EQ(player._pSplFrom, 0);
ASSERT_EQ(player._pTSpell, 0);
ASSERT_EQ(player._pTSplType, 0);
ASSERT_EQ(player._pRSpell, -1);
ASSERT_EQ(player._pRSplType, 4);
ASSERT_EQ(player._pSBkSpell, -1);
ASSERT_EQ(player._pSBkSplType, 0);
ASSERT_EQ(player._pAblSpells, 134217728);
ASSERT_EQ(player._pScrlSpells, 0);
ASSERT_EQ(player._pSpellFlags, 0);
ASSERT_EQ(player._pwtype, 1);
ASSERT_EQ(player._pBlockFlag, 0);
ASSERT_EQ(player._pLightRad, 11);
ASSERT_EQ(player._pDamageMod, 101);
ASSERT_EQ(player._pHitPoints, 16640);
ASSERT_EQ(player._pMaxHP, 16640);
ASSERT_EQ(player._pMana, 14624);
ASSERT_EQ(player._pMaxMana, 14624);
ASSERT_EQ(player._pNextExper, 2000);
ASSERT_EQ(player._pMagResist, 75);
ASSERT_EQ(player._pFireResist, 16);
ASSERT_EQ(player._pLghtResist, 75);
ASSERT_EQ(CountBool(player._pLvlVisited, NUMLEVELS), 0);
ASSERT_EQ(CountBool(player._pSLvlVisited, NUMLEVELS), 0);
ASSERT_EQ(player._pNFrames, 20);
ASSERT_EQ(player._pWFrames, 8);
ASSERT_EQ(player._pAFrames, 0);
ASSERT_EQ(player._pAFNum, 0);
ASSERT_EQ(player._pSFrames, 16);
ASSERT_EQ(player._pSFNum, 12);
ASSERT_EQ(player._pHFrames, 0);
ASSERT_EQ(player._pDFrames, 20);
ASSERT_EQ(player._pBFrames, 0);
ASSERT_EQ(player._pIMinDam, 1);
ASSERT_EQ(player._pIMaxDam, 14);
ASSERT_EQ(player._pIAC, 115);
ASSERT_EQ(player._pIBonusDam, 0);
ASSERT_EQ(player._pIBonusToHit, 0);
ASSERT_EQ(player._pIBonusAC, 0);
ASSERT_EQ(player._pIBonusDamMod, 0);
ASSERT_EQ(player._pISpells, 0);
ASSERT_EQ(player._pIFlags, 0);
ASSERT_EQ(player._pIGetHit, 0);
ASSERT_EQ(player._pISplLvlAdd, 0);
ASSERT_EQ(player._pISplDur, 0);
ASSERT_EQ(player._pIEnAc, 0);
ASSERT_EQ(player._pIFMinDam, 0);
ASSERT_EQ(player._pIFMaxDam, 0);
ASSERT_EQ(player._pILMinDam, 0);
ASSERT_EQ(player._pILMaxDam, 0);
ASSERT_EQ(player.pOriginalCathedral, 0);
}
TEST(Writehero, pfile_write_hero)
@ -370,7 +370,7 @@ TEST(Writehero, pfile_write_hero)
PkPlayerStruct pks;
PackPlayerTest(&pks);
UnPackPlayer(&pks, myplr, true);
AssertPlayer(&plr[0]);
AssertPlayer(plr[0]);
pfile_write_hero();
std::ifstream f("multi_0.sv", std::ios::binary);

Loading…
Cancel
Save