From f64d17bfa9940855753145385b47cc87aa40c62a Mon Sep 17 00:00:00 2001 From: Andrew James Date: Sun, 6 Mar 2022 14:53:29 +1100 Subject: [PATCH] Initial clean up of code related to creating items (#2943) * Move declaration of dItems to items.cpp This array is never used in dungeon generation, it's closely related to Items so should be kept together. Ideally managing dItems can become responsibility of a container for Items, which will handle adding/removing items from the list and keeping the positions in sync. * Rename SetPlrHandItem to match purpose/use * Give more descriptive name to GetPlrHandSeed This function sets a new seed on a given item struct, not just the held item. * Don't use HoldItem as a temporary for the players initial inventory * Take Item by reference in RespawnItem * Don't use holdItem as a temporary when dropping gold on death * Update DeadItem to take item by reference, and refer to it consistently Move code which invalidates the source of dropped items to the caller Most call sites use a temporary item instance or remove the item from the container, so there's no real point invalidating the item after it's been copied to the drop list. Update DeadItem to take position instead of player references --- Source/control.cpp | 2 +- Source/debug.cpp | 4 +- Source/gendung.cpp | 2 - Source/gendung.h | 2 - Source/inv.cpp | 12 ++-- Source/items.cpp | 149 ++++++++++++++++++++++---------------------- Source/items.h | 9 ++- Source/missiles.cpp | 4 +- Source/msg.cpp | 2 +- Source/objects.cpp | 8 +-- Source/player.cpp | 69 ++++++++++---------- 11 files changed, 127 insertions(+), 136 deletions(-) diff --git a/Source/control.cpp b/Source/control.cpp index cd5c91932..96eac4d0b 100644 --- a/Source/control.cpp +++ b/Source/control.cpp @@ -374,7 +374,7 @@ void RemoveGold(Player &player, int goldIndex) SetPlrHandGoldCurs(player.InvList[gi]); else player.RemoveInvItem(gi); - SetPlrHandItem(player.HoldItem, IDI_GOLD); + InitializeItem(player.HoldItem, IDI_GOLD); SetGoldSeed(player, player.HoldItem); player.HoldItem._ivalue = dropGoldValue; player.HoldItem._iStatFlag = true; diff --git a/Source/debug.cpp b/Source/debug.cpp index 91587940b..629c2f7cb 100644 --- a/Source/debug.cpp +++ b/Source/debug.cpp @@ -174,8 +174,8 @@ std::string DebugCmdGiveGoldCheat(const string_view parameter) continue; int ni = myPlayer._pNumInv++; - SetPlrHandItem(myPlayer.InvList[ni], IDI_GOLD); - GetPlrHandSeed(&myPlayer.InvList[ni]); + InitializeItem(myPlayer.InvList[ni], IDI_GOLD); + GenerateNewSeed(myPlayer.InvList[ni]); myPlayer.InvList[ni]._ivalue = GOLD_MAX_LIMIT; myPlayer.InvList[ni]._iCurs = ICURS_GOLD_LARGE; myPlayer._pGold += GOLD_MAX_LIMIT; diff --git a/Source/gendung.cpp b/Source/gendung.cpp index ab4356830..015ee295d 100644 --- a/Source/gendung.cpp +++ b/Source/gendung.cpp @@ -56,7 +56,6 @@ int8_t dPlayer[MAXDUNX][MAXDUNY]; int16_t dMonster[MAXDUNX][MAXDUNY]; int8_t dCorpse[MAXDUNX][MAXDUNY]; int8_t dObject[MAXDUNX][MAXDUNY]; -int8_t dItem[MAXDUNX][MAXDUNY]; char dSpecial[MAXDUNX][MAXDUNY]; int themeCount; THEME_LOC themeLoc[MAXTHEMES]; @@ -622,7 +621,6 @@ void DRLG_Init_Globals() memset(dMonster, 0, sizeof(dMonster)); memset(dCorpse, 0, sizeof(dCorpse)); memset(dObject, 0, sizeof(dObject)); - memset(dItem, 0, sizeof(dItem)); memset(dSpecial, 0, sizeof(dSpecial)); int8_t c = DisableLighting ? 0 : 15; memset(dLight, c, sizeof(dLight)); diff --git a/Source/gendung.h b/Source/gendung.h index 48ecceb6b..0c392ce46 100644 --- a/Source/gendung.h +++ b/Source/gendung.h @@ -224,8 +224,6 @@ extern int16_t dMonster[MAXDUNX][MAXDUNY]; extern DVL_API_FOR_TEST int8_t dCorpse[MAXDUNX][MAXDUNY]; /** Contains the object numbers (objects array indices) of the map. */ extern DVL_API_FOR_TEST int8_t dObject[MAXDUNX][MAXDUNY]; -/** Contains the item numbers (items array indices) of the map. */ -extern int8_t dItem[MAXDUNX][MAXDUNY]; /** * Contains the arch frame numbers of the map from the special tileset * (e.g. "levels/l1data/l1s.cel"). Note, the special tileset of Tristram (i.e. diff --git a/Source/inv.cpp b/Source/inv.cpp index aa41581b1..20d654522 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -1515,7 +1515,7 @@ bool GoldAutoPlace(Player &player) SetPlrHandGoldCurs(player.HoldItem); player.InvList[i]._ivalue = MaxGold; if (gbIsHellfire) - GetPlrHandSeed(&player.HoldItem); + GenerateNewSeed(player.HoldItem); } else { player.HoldItem._ivalue = 0; done = true; @@ -1547,13 +1547,13 @@ bool GoldAutoPlaceInInventorySlot(Player &player, int slotIndex) player.InvList[ii] = player.HoldItem; player._pNumInv++; player.InvGrid[slotIndex] = player._pNumInv; - GetPlrHandSeed(&player.InvList[ii]); + GenerateNewSeed(player.InvList[ii]); int gold = player.HoldItem._ivalue; if (gold > MaxGold) { gold -= MaxGold; player.HoldItem._ivalue = gold; - GetPlrHandSeed(&player.HoldItem); + GenerateNewSeed(player.HoldItem); player.InvList[ii]._ivalue = MaxGold; return false; } @@ -1705,7 +1705,7 @@ void AutoGetItem(int pnum, Item *item, int ii) player.Say(HeroSpeech::ICantCarryAnymore); } player.HoldItem = *item; - RespawnItem(item, true); + RespawnItem(*item, true); NetSendCmdPItem(true, CMD_RESPAWNITEM, item->position, player.HoldItem); player.HoldItem._itype = ItemType::None; } @@ -1829,7 +1829,7 @@ int InvPutItem(Player &player, Point position) dItem[position.x][position.y] = ii + 1; Items[ii] = player.HoldItem; Items[ii].position = position; - RespawnItem(&Items[ii], true); + RespawnItem(Items[ii], true); if (currlevel == 21 && position == CornerStone.position) { CornerStone.item = Items[ii]; @@ -1886,7 +1886,7 @@ int SyncDropItem(Point position, int idx, uint16_t icreateinfo, int iseed, int i } item.position = position; - RespawnItem(&Items[ii], true); + RespawnItem(Items[ii], true); if (currlevel == 21 && position == CornerStone.position) { CornerStone.item = Items[ii]; diff --git a/Source/items.cpp b/Source/items.cpp index f9be560dd..01550be20 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -42,10 +42,10 @@ namespace devilution { -/** Contains the items on ground in the current game. */ Item Items[MAXITEMS + 1]; uint8_t ActiveItems[MAXITEMS]; uint8_t ActiveItemCount; +int8_t dItem[MAXDUNX][MAXDUNY]; bool ShowUniqueItemInfoBox; CornerStoneStruct CornerStone; bool UniqueItemFlags[128]; @@ -539,11 +539,6 @@ void CalcPlrBookVals(Player &player) } } -void SetPlrHandSeed(Item &item, int iseed) -{ - item._iSeed = iseed; -} - bool GetItemSpace(Point position, int8_t inum) { int xx = 0; @@ -2503,6 +2498,7 @@ void InitItems() GetItemAttrs(golditem, IDI_GOLD, 1); golditem._iStatFlag = true; ActiveItemCount = 0; + memset(dItem, 0, sizeof(dItem)); for (auto &item : Items) { item._itype = ItemType::None; @@ -2914,7 +2910,7 @@ void CalcPlrInv(Player &player, bool loadgfx) } } -void SetPlrHandItem(Item &item, int itemData) +void InitializeItem(Item &item, int itemData) { auto &pAllItem = AllItemsList[itemData]; @@ -2953,9 +2949,9 @@ void SetPlrHandItem(Item &item, int itemData) item.dwBuff |= CF_HELLFIRE; } -void GetPlrHandSeed(Item *h) +void GenerateNewSeed(Item &item) { - h->_iSeed = AdvanceRndSeed(); + item._iSeed = AdvanceRndSeed(); } void SetGoldSeed(Player &player, Item &gold) @@ -3023,87 +3019,88 @@ void CreatePlrItems(int playerId) switch (player._pClass) { case HeroClass::Warrior: - SetPlrHandItem(player.InvBody[INVLOC_HAND_LEFT], IDI_WARRIOR); - GetPlrHandSeed(&player.InvBody[INVLOC_HAND_LEFT]); + InitializeItem(player.InvBody[INVLOC_HAND_LEFT], IDI_WARRIOR); + GenerateNewSeed(player.InvBody[INVLOC_HAND_LEFT]); - SetPlrHandItem(player.InvBody[INVLOC_HAND_RIGHT], IDI_WARRSHLD); - GetPlrHandSeed(&player.InvBody[INVLOC_HAND_RIGHT]); + InitializeItem(player.InvBody[INVLOC_HAND_RIGHT], IDI_WARRSHLD); + GenerateNewSeed(player.InvBody[INVLOC_HAND_RIGHT]); - SetPlrHandItem(player.HoldItem, IDI_WARRCLUB); - GetPlrHandSeed(&player.HoldItem); + InitializeItem(player.HoldItem, IDI_WARRCLUB); + GenerateNewSeed(player.HoldItem); AutoPlaceItemInInventory(player, player.HoldItem, true); - SetPlrHandItem(player.SpdList[0], IDI_HEAL); - GetPlrHandSeed(&player.SpdList[0]); + InitializeItem(player.SpdList[0], IDI_HEAL); + GenerateNewSeed(player.SpdList[0]); - SetPlrHandItem(player.SpdList[1], IDI_HEAL); - GetPlrHandSeed(&player.SpdList[1]); + InitializeItem(player.SpdList[1], IDI_HEAL); + GenerateNewSeed(player.SpdList[1]); break; case HeroClass::Rogue: - SetPlrHandItem(player.InvBody[INVLOC_HAND_LEFT], IDI_ROGUE); - GetPlrHandSeed(&player.InvBody[INVLOC_HAND_LEFT]); + InitializeItem(player.InvBody[INVLOC_HAND_LEFT], IDI_ROGUE); + GenerateNewSeed(player.InvBody[INVLOC_HAND_LEFT]); - SetPlrHandItem(player.SpdList[0], IDI_HEAL); - GetPlrHandSeed(&player.SpdList[0]); + InitializeItem(player.SpdList[0], IDI_HEAL); + GenerateNewSeed(player.SpdList[0]); - SetPlrHandItem(player.SpdList[1], IDI_HEAL); - GetPlrHandSeed(&player.SpdList[1]); + InitializeItem(player.SpdList[1], IDI_HEAL); + GenerateNewSeed(player.SpdList[1]); break; case HeroClass::Sorcerer: - SetPlrHandItem(player.InvBody[INVLOC_HAND_LEFT], gbIsHellfire ? IDI_SORCERER : 166); - GetPlrHandSeed(&player.InvBody[INVLOC_HAND_LEFT]); + InitializeItem(player.InvBody[INVLOC_HAND_LEFT], gbIsHellfire ? IDI_SORCERER : 166); + GenerateNewSeed(player.InvBody[INVLOC_HAND_LEFT]); - SetPlrHandItem(player.SpdList[0], gbIsHellfire ? IDI_HEAL : IDI_MANA); - GetPlrHandSeed(&player.SpdList[0]); + InitializeItem(player.SpdList[0], gbIsHellfire ? IDI_HEAL : IDI_MANA); + GenerateNewSeed(player.SpdList[0]); - SetPlrHandItem(player.SpdList[1], gbIsHellfire ? IDI_HEAL : IDI_MANA); - GetPlrHandSeed(&player.SpdList[1]); + InitializeItem(player.SpdList[1], gbIsHellfire ? IDI_HEAL : IDI_MANA); + GenerateNewSeed(player.SpdList[1]); break; case HeroClass::Monk: - SetPlrHandItem(player.InvBody[INVLOC_HAND_LEFT], IDI_SHORTSTAFF); - GetPlrHandSeed(&player.InvBody[INVLOC_HAND_LEFT]); - SetPlrHandItem(player.SpdList[0], IDI_HEAL); - GetPlrHandSeed(&player.SpdList[0]); + InitializeItem(player.InvBody[INVLOC_HAND_LEFT], IDI_SHORTSTAFF); + GenerateNewSeed(player.InvBody[INVLOC_HAND_LEFT]); + InitializeItem(player.SpdList[0], IDI_HEAL); + GenerateNewSeed(player.SpdList[0]); - SetPlrHandItem(player.SpdList[1], IDI_HEAL); - GetPlrHandSeed(&player.SpdList[1]); + InitializeItem(player.SpdList[1], IDI_HEAL); + GenerateNewSeed(player.SpdList[1]); break; case HeroClass::Bard: - SetPlrHandItem(player.InvBody[INVLOC_HAND_LEFT], IDI_BARDSWORD); - GetPlrHandSeed(&player.InvBody[INVLOC_HAND_LEFT]); + InitializeItem(player.InvBody[INVLOC_HAND_LEFT], IDI_BARDSWORD); + GenerateNewSeed(player.InvBody[INVLOC_HAND_LEFT]); - SetPlrHandItem(player.InvBody[INVLOC_HAND_RIGHT], IDI_BARDDAGGER); - GetPlrHandSeed(&player.InvBody[INVLOC_HAND_RIGHT]); - SetPlrHandItem(player.SpdList[0], IDI_HEAL); - GetPlrHandSeed(&player.SpdList[0]); + InitializeItem(player.InvBody[INVLOC_HAND_RIGHT], IDI_BARDDAGGER); + GenerateNewSeed(player.InvBody[INVLOC_HAND_RIGHT]); + InitializeItem(player.SpdList[0], IDI_HEAL); + GenerateNewSeed(player.SpdList[0]); - SetPlrHandItem(player.SpdList[1], IDI_HEAL); - GetPlrHandSeed(&player.SpdList[1]); + InitializeItem(player.SpdList[1], IDI_HEAL); + GenerateNewSeed(player.SpdList[1]); break; case HeroClass::Barbarian: - SetPlrHandItem(player.InvBody[INVLOC_HAND_LEFT], 139); // TODO: add more enums to items - GetPlrHandSeed(&player.InvBody[INVLOC_HAND_LEFT]); + InitializeItem(player.InvBody[INVLOC_HAND_LEFT], 139); // TODO: add more enums to items + GenerateNewSeed(player.InvBody[INVLOC_HAND_LEFT]); - SetPlrHandItem(player.InvBody[INVLOC_HAND_RIGHT], IDI_WARRSHLD); - GetPlrHandSeed(&player.InvBody[INVLOC_HAND_RIGHT]); - SetPlrHandItem(player.SpdList[0], IDI_HEAL); - GetPlrHandSeed(&player.SpdList[0]); + InitializeItem(player.InvBody[INVLOC_HAND_RIGHT], IDI_WARRSHLD); + GenerateNewSeed(player.InvBody[INVLOC_HAND_RIGHT]); + InitializeItem(player.SpdList[0], IDI_HEAL); + GenerateNewSeed(player.SpdList[0]); - SetPlrHandItem(player.SpdList[1], IDI_HEAL); - GetPlrHandSeed(&player.SpdList[1]); + InitializeItem(player.SpdList[1], IDI_HEAL); + GenerateNewSeed(player.SpdList[1]); break; } - SetPlrHandItem(player.HoldItem, IDI_GOLD); - GetPlrHandSeed(&player.HoldItem); - - player.HoldItem._ivalue = 100; - player.HoldItem._iCurs = ICURS_GOLD_SMALL; - player._pGold = player.HoldItem._ivalue; - player.InvList[player._pNumInv++] = player.HoldItem; + auto &startingGold = player.InvList[player._pNumInv]; + player._pNumInv++; player.InvGrid[30] = player._pNumInv; + InitializeItem(startingGold, IDI_GOLD); + GenerateNewSeed(startingGold); + startingGold._ivalue = 100; + startingGold._iCurs = ICURS_GOLD_SMALL; + player._pGold = startingGold._ivalue; + CalcPlrItemVals(player, false); } @@ -3365,7 +3362,7 @@ void RecreateItem(Item &item, int idx, uint16_t icreateinfo, int iseed, int ival gbIsHellfire = isHellfire; if (idx == IDI_GOLD) { - SetPlrHandItem(item, IDI_GOLD); + InitializeItem(item, IDI_GOLD); item._iSeed = iseed; item._iCreateInfo = icreateinfo; item._ivalue = ivalue; @@ -3375,8 +3372,8 @@ void RecreateItem(Item &item, int idx, uint16_t icreateinfo, int iseed, int ival } if (icreateinfo == 0) { - SetPlrHandItem(item, idx); - SetPlrHandSeed(item, iseed); + InitializeItem(item, idx); + item._iSeed = iseed; gbIsHellfire = tmpIsHellfire; return; } @@ -3413,7 +3410,7 @@ void RecreateItem(Item &item, int idx, uint16_t icreateinfo, int iseed, int ival void RecreateEar(Item &item, uint16_t ic, int iseed, int id, int dur, int mdur, int ch, int mch, int ivalue, int ibuff) { - SetPlrHandItem(item, IDI_EAR); + InitializeItem(item, IDI_EAR); tempstr[0] = static_cast((ic >> 8) & 0x7F); tempstr[1] = static_cast(ic & 0x7F); tempstr[2] = static_cast((iseed >> 24) & 0x7F); @@ -3487,7 +3484,7 @@ void CornerstoneLoad(Point position) UnPackItem(pkSItem, item, (pkSItem.dwBuff & CF_HELLFIRE) != 0); item.position = position; - RespawnItem(&item, false); + RespawnItem(item, false); CornerStone.item = item; } @@ -3575,20 +3572,20 @@ void SpawnTheodore(Point position) SpawnRewardItem(IDI_THEODORE, position); } -void RespawnItem(Item *item, bool flipFlag) +void RespawnItem(Item &item, bool flipFlag) { - int it = ItemCAnimTbl[item->_iCurs]; - item->SetNewAnimation(flipFlag); - item->_iRequest = false; + int it = ItemCAnimTbl[item._iCurs]; + item.SetNewAnimation(flipFlag); + item._iRequest = false; - if (item->_iCurs == ICURS_MAGIC_ROCK) { - item->_iSelFlag = 1; - PlaySfxLoc(ItemDropSnds[it], item->position); + if (item._iCurs == ICURS_MAGIC_ROCK) { + item._iSelFlag = 1; + PlaySfxLoc(ItemDropSnds[it], item.position); } - if (item->_iCurs == ICURS_TAVERN_SIGN) - item->_iSelFlag = 1; - if (item->_iCurs == ICURS_ANVIL_OF_FURY) - item->_iSelFlag = 1; + if (item._iCurs == ICURS_TAVERN_SIGN) + item._iSelFlag = 1; + if (item._iCurs == ICURS_ANVIL_OF_FURY) + item._iSelFlag = 1; } void DeleteItem(int i) diff --git a/Source/items.h b/Source/items.h index aa41927e4..d837d4b74 100644 --- a/Source/items.h +++ b/Source/items.h @@ -413,9 +413,12 @@ struct CornerStoneStruct { struct Player; +/** Contains the items on ground in the current game. */ extern Item Items[MAXITEMS + 1]; extern uint8_t ActiveItems[MAXITEMS]; extern uint8_t ActiveItemCount; +/** Contains the location of dropped items. */ +extern int8_t dItem[MAXDUNX][MAXDUNY]; extern bool ShowUniqueItemInfoBox; extern CornerStoneStruct CornerStone; extern bool UniqueItemFlags[128]; @@ -427,8 +430,8 @@ void InitItemGFX(); void InitItems(); void CalcPlrItemVals(Player &player, bool Loadgfx); void CalcPlrInv(Player &player, bool Loadgfx); -void SetPlrHandItem(Item &item, int itemData); -void GetPlrHandSeed(Item *h); +void InitializeItem(Item &item, int itemData); +void GenerateNewSeed(Item &h); /** * @brief Set a new unique seed value on the given item @@ -462,7 +465,7 @@ void SpawnRewardItem(int itemid, Point position); void SpawnMapOfDoom(Point position); void SpawnRuneBomb(Point position); void SpawnTheodore(Point position); -void RespawnItem(Item *item, bool FlipFlag); +void RespawnItem(Item &item, bool FlipFlag); void DeleteItem(int i); void ProcessItems(); void FreeItemGFX(); diff --git a/Source/missiles.cpp b/Source/missiles.cpp index 654cc5126..489be633d 100644 --- a/Source/missiles.cpp +++ b/Source/missiles.cpp @@ -1420,8 +1420,8 @@ void AddStealPotions(Missile &missile, const AddMissileParameter & /*parameter*/ } } if (ii != -1) { - SetPlrHandItem(player.HoldItem, ii); - GetPlrHandSeed(&player.HoldItem); + InitializeItem(player.HoldItem, ii); + GenerateNewSeed(player.HoldItem); player.HoldItem._iStatFlag = true; player.SpdList[si] = player.HoldItem; } diff --git a/Source/msg.cpp b/Source/msg.cpp index 5d1829f41..4322dae90 100644 --- a/Source/msg.cpp +++ b/Source/msg.cpp @@ -2292,7 +2292,7 @@ void DeltaLoadLevel() int y = sgLevels[currlevel].item[i].y; item.position = GetItemPosition({ x, y }); dItem[item.position.x][item.position.y] = ii + 1; - RespawnItem(&Items[ii], false); + RespawnItem(Items[ii], false); } } diff --git a/Source/objects.cpp b/Source/objects.cpp index c923c8ddb..6f6d9e178 100644 --- a/Source/objects.cpp +++ b/Source/objects.cpp @@ -2955,15 +2955,15 @@ bool OperateShrineEldritch(int pnum) if (item._itype == ItemType::Misc) { if (item._iMiscId == IMISC_HEAL || item._iMiscId == IMISC_MANA) { - SetPlrHandItem(player.HoldItem, ItemMiscIdIdx(IMISC_REJUV)); - GetPlrHandSeed(&player.HoldItem); + InitializeItem(player.HoldItem, ItemMiscIdIdx(IMISC_REJUV)); + GenerateNewSeed(player.HoldItem); player.HoldItem._iStatFlag = true; item = player.HoldItem; } if (item._iMiscId == IMISC_FULLHEAL || item._iMiscId == IMISC_FULLMANA) { - SetPlrHandItem(player.HoldItem, ItemMiscIdIdx(IMISC_FULLREJUV)); - GetPlrHandSeed(&player.HoldItem); + InitializeItem(player.HoldItem, ItemMiscIdIdx(IMISC_FULLREJUV)); + GenerateNewSeed(player.HoldItem); player.HoldItem._iStatFlag = true; item = player.HoldItem; } diff --git a/Source/player.cpp b/Source/player.cpp index 5e34ba510..51b5ebe56 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -536,7 +536,7 @@ void StartSpell(int pnum, Direction d, int cx, int cy) player.spellLevel = GetSpellLevel(pnum, player._pSpell); } -void RespawnDeadItem(Item *itm, Point target) +void RespawnDeadItem(Item &itm, Point target) { if (ActiveItemCount >= MAXITEMS) return; @@ -545,23 +545,20 @@ void RespawnDeadItem(Item *itm, Point target) dItem[target.x][target.y] = ii + 1; - Items[ii] = *itm; + Items[ii] = itm; Items[ii].position = target; - RespawnItem(&Items[ii], true); - - itm->_itype = ItemType::None; + RespawnItem(Items[ii], true); } -void DeadItem(Player &player, Item *itm, Displacement direction) +void DeadItem(Player &player, Item &itm, Displacement direction) { - if (itm->isEmpty()) + if (itm.isEmpty()) return; Point target = player.position.tile + direction; if (direction != Displacement { 0, 0 } && ItemSpaceOk(target)) { RespawnDeadItem(itm, target); - player.HoldItem = *itm; - NetSendCmdPItem(false, CMD_RESPAWNITEM, target, player.HoldItem); + NetSendCmdPItem(false, CMD_RESPAWNITEM, target, itm); return; } @@ -571,8 +568,7 @@ void DeadItem(Player &player, Item *itm, Displacement direction) Point next = player.position.tile + Displacement { i, j }; if (ItemSpaceOk(next)) { RespawnDeadItem(itm, next); - player.HoldItem = *itm; - NetSendCmdPItem(false, CMD_RESPAWNITEM, next, player.HoldItem); + NetSendCmdPItem(false, CMD_RESPAWNITEM, next, itm); return; } } @@ -580,10 +576,8 @@ void DeadItem(Player &player, Item *itm, Displacement direction) } } -int DropGold(int pnum, int amount, bool skipFullStacks) +int DropGold(Player &player, int amount, bool skipFullStacks) { - auto &player = Players[pnum]; - for (int i = 0; i < player._pNumInv && amount > 0; i++) { auto &item = player.InvList[i]; @@ -591,22 +585,20 @@ int DropGold(int pnum, int amount, bool skipFullStacks) continue; if (amount < item._ivalue) { + Item gold {}; + InitializeItem(gold, IDI_GOLD); + SetGoldSeed(player, gold); + + gold._ivalue = amount; item._ivalue -= amount; - SetPlrHandItem(player.HoldItem, IDI_GOLD); - SetGoldSeed(player, player.HoldItem); - SetPlrHandGoldCurs(player.HoldItem); - player.HoldItem._ivalue = amount; - DeadItem(player, &player.HoldItem, { 0, 0 }); + SetPlrHandGoldCurs(gold); + DeadItem(player, gold, { 0, 0 }); return 0; } amount -= item._ivalue; + DeadItem(player, item, { 0, 0 }); player.RemoveInvItem(i); - SetPlrHandItem(player.HoldItem, IDI_GOLD); - SetGoldSeed(player, player.HoldItem); - SetPlrHandGoldCurs(player.HoldItem); - player.HoldItem._ivalue = item._ivalue; - DeadItem(player, &player.HoldItem, { 0, 0 }); i = -1; } @@ -620,13 +612,12 @@ void DropHalfPlayersGold(int pnum) } auto &player = Players[pnum]; - int hGold = player._pGold / 2; - - hGold = DropGold(pnum, hGold, true); - if (hGold > 0) - DropGold(pnum, hGold, false); + int remainingGold = DropGold(player, player._pGold / 2, true); + if (remainingGold > 0) { + DropGold(player, remainingGold, false); + } - player._pGold -= hGold; + player._pGold /= 2; } void InitLevelChange(int pnum) @@ -3152,7 +3143,8 @@ StartPlayerKill(int pnum, int earflag) drawhpflag = true; if (pcurs >= CURSOR_FIRSTITEM) { - DeadItem(player, &player.HoldItem, { 0, 0 }); + DeadItem(player, player.HoldItem, { 0, 0 }); + player.HoldItem._itype = ItemType::None; NewCursor(CURSOR_HAND); } @@ -3161,7 +3153,7 @@ StartPlayerKill(int pnum, int earflag) if (earflag != -1) { if (earflag != 0) { Item ear; - SetPlrHandItem(ear, IDI_EAR); + InitializeItem(ear, IDI_EAR); strcpy(ear._iName, fmt::format(_("Ear of {:s}"), player._pName).c_str()); switch (player._pClass) { case HeroClass::Sorcerer: @@ -3183,13 +3175,14 @@ StartPlayerKill(int pnum, int earflag) ear._ivalue = player._pLevel; if (FindGetItem(ear._iSeed, IDI_EAR, ear._iCreateInfo) == -1) { - DeadItem(player, &ear, { 0, 0 }); + DeadItem(player, ear, { 0, 0 }); } } else { Direction pdd = player._pdir; for (auto &item : player.InvBody) { pdd = Left(pdd); - DeadItem(player, &item, Displacement(pdd)); + DeadItem(player, item, Displacement(pdd)); + item._itype = ItemType::None; } CalcPlrInv(player, false); @@ -3210,12 +3203,14 @@ void StripTopGold(Player &player) if (item._ivalue > MaxGold) { int val = item._ivalue - MaxGold; item._ivalue = MaxGold; - SetPlrHandItem(player.HoldItem, 0); + InitializeItem(player.HoldItem, IDI_GOLD); SetGoldSeed(player, player.HoldItem); player.HoldItem._ivalue = val; SetPlrHandGoldCurs(player.HoldItem); - if (!GoldAutoPlace(player)) - DeadItem(player, &player.HoldItem, { 0, 0 }); + if (!GoldAutoPlace(player)) { + DeadItem(player, player.HoldItem, { 0, 0 }); + player.HoldItem._itype == ItemType::None; + } } } }