From 4480bd0bbba64d4ba01d3d8f12ae5bf6b9052fcf Mon Sep 17 00:00:00 2001 From: obligaron Date: Fri, 16 Dec 2022 22:32:27 +0100 Subject: [PATCH] In multiplayer randomly drop unique quest reward or magic item of same type --- Source/items.cpp | 20 +++++++++++++++----- Source/items.h | 2 +- Source/towners.cpp | 10 +++++----- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/Source/items.cpp b/Source/items.cpp index 9bf5d230d512..a2a1f888866a 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -3202,7 +3202,7 @@ void SetupItem(Item &item) item._iIdentified = false; } -Item *SpawnUnique(_unique_items uid, Point position, bool sendmsg /*= true*/) +Item *SpawnUnique(_unique_items uid, Point position, std::optional level /*= std::nullopt*/, bool sendmsg /*= true*/) { if (ActiveItemCount >= MAXITEMS) return nullptr; @@ -3216,9 +3216,19 @@ Item *SpawnUnique(_unique_items uid, Point position, bool sendmsg /*= true*/) while (AllItemsList[idx].iItemId != UniqueItems[uid].UIItemId) idx++; - GetItemAttrs(item, static_cast<_item_indexes>(idx), curlv); - GetUniqueItem(*MyPlayer, item, uid); - SetupItem(item); + if (!gbIsMultiplayer || FlipCoin(4)) { + GetItemAttrs(item, static_cast<_item_indexes>(idx), curlv); + GetUniqueItem(*MyPlayer, item, uid); + SetupItem(item); + } else { + if (level) + curlv = *level; + const ItemData &uniqueItemData = AllItemsList[idx]; + _item_indexes idx = GetItemIndexForDroppableItem(false, [&uniqueItemData](const ItemData &item) { + return item.itype == uniqueItemData.itype; + }); + SetupAllItems(*MyPlayer, item, idx, AdvanceRndSeed(), curlv * 2, 15, true, false, false); + } if (sendmsg) NetSendCmdPItem(false, CMD_SPAWNITEM, item.position, item); @@ -3235,7 +3245,7 @@ void SpawnItem(Monster &monster, Point position, bool sendmsg) bool dropBrain = Quests[Q_MUSHROOM]._qactive == QUEST_ACTIVE && Quests[Q_MUSHROOM]._qvar1 == QS_MUSHGIVEN; if (dropsSpecialTreasure && !gbIsMultiplayer) { - Item *uniqueItem = SpawnUnique(static_cast<_unique_items>(monster.data().treasure & T_MASK), position, false); + Item *uniqueItem = SpawnUnique(static_cast<_unique_items>(monster.data().treasure & T_MASK), position, std::nullopt, false); if (uniqueItem != nullptr && sendmsg) NetSendCmdPItem(false, CMD_DROPITEM, uniqueItem->position, *uniqueItem); return; diff --git a/Source/items.h b/Source/items.h index 00396c083690..d93ec257767b 100644 --- a/Source/items.h +++ b/Source/items.h @@ -509,7 +509,7 @@ uint8_t PlaceItemInWorld(Item &&item, WorldTilePosition position); Point GetSuperItemLoc(Point position); void GetItemAttrs(Item &item, _item_indexes itemData, int lvl); void SetupItem(Item &item); -Item *SpawnUnique(_unique_items uid, Point position, bool sendmsg = true); +Item *SpawnUnique(_unique_items uid, Point position, std::optional level = std::nullopt, bool sendmsg = true); void SpawnItem(Monster &monster, Point position, bool sendmsg); void CreateRndItem(Point position, bool onlygood, bool sendmsg, bool delta); void CreateRndUseful(Point position, bool sendmsg); diff --git a/Source/towners.cpp b/Source/towners.cpp index 414bbe2b3bac..59af29d97c50 100644 --- a/Source/towners.cpp +++ b/Source/towners.cpp @@ -344,7 +344,7 @@ void TalkToBarOwner(Player &player, Towner &barOwner) bannerQuest._qactive = QUEST_DONE; bannerQuest._qvar1 = 3; NetSendCmdQuest(true, bannerQuest); - SpawnUnique(UITEM_HARCREST, barOwner.position + Direction::SouthWest); + SpawnUnique(UITEM_HARCREST, barOwner.position + Direction::SouthWest, bannerQuest._qlevel); InitQTextMsg(TEXT_BANNER3); return; } @@ -392,7 +392,7 @@ void TalkToBlackSmith(Player &player, Towner &blackSmith) if (Quests[Q_ROCK]._qvar2 == 1 && RemoveInventoryItemById(player, IDI_ROCK)) { Quests[Q_ROCK]._qactive = QUEST_DONE; NetSendCmdQuest(true, Quests[Q_ROCK]); - SpawnUnique(UITEM_INFRARING, blackSmith.position + Direction::SouthWest); + SpawnUnique(UITEM_INFRARING, blackSmith.position + Direction::SouthWest, Quests[Q_ROCK]._qlevel); InitQTextMsg(TEXT_INFRA7); return; } @@ -413,7 +413,7 @@ void TalkToBlackSmith(Player &player, Towner &blackSmith) if (Quests[Q_ANVIL]._qvar2 == 1 && RemoveInventoryItemById(player, IDI_ANVIL)) { Quests[Q_ANVIL]._qactive = QUEST_DONE; NetSendCmdQuest(true, Quests[Q_ANVIL]); - SpawnUnique(UITEM_GRISWOLD, blackSmith.position + Direction::SouthWest); + SpawnUnique(UITEM_GRISWOLD, blackSmith.position + Direction::SouthWest, Quests[Q_ANVIL]._qlevel); InitQTextMsg(TEXT_ANVIL7); return; } @@ -510,7 +510,7 @@ void TalkToHealer(Player &player, Towner &healer) if (poisonWater._qactive == QUEST_DONE && poisonWater._qvar1 != 2) { poisonWater._qvar1 = 2; InitQTextMsg(TEXT_POISON5); - SpawnUnique(UITEM_TRING, healer.position + Direction::SouthWest); + SpawnUnique(UITEM_TRING, healer.position + Direction::SouthWest, poisonWater._qlevel); NetSendCmdQuest(true, poisonWater); return; } @@ -670,7 +670,7 @@ void TalkToCowFarmer(Player &player, Towner &cowFarmer) auto &quest = Quests[Q_JERSEY]; if (RemoveInventoryItemById(player, IDI_BROWNSUIT)) { - SpawnUnique(UITEM_BOVINE, cowFarmer.position + Direction::SouthEast); + SpawnUnique(UITEM_BOVINE, cowFarmer.position + Direction::SouthEast, quest._qlevel); InitQTextMsg(TEXT_JERSEY8); quest._qactive = QUEST_DONE; auto curFrame = cowFarmer._tAnimFrame;