diff --git a/Source/items.cpp b/Source/items.cpp index bb2046369..27e06cc5a 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -3347,7 +3347,7 @@ void SpawnQuestItem(int itemid, Point position, int randarea, int selflag) } } -void SpawnRewardItem(int itemid, Point position) +void SpawnRewardItem(int itemid, Point position, bool sendmsg) { if (ActiveItemCount >= MAXITEMS) return; @@ -3363,25 +3363,26 @@ void SpawnRewardItem(int itemid, Point position) item._iSelFlag = 2; item._iPostDraw = true; item._iIdentified = true; + GenerateNewSeed(item); - if (gbIsMultiplayer) { - NetSendCmdPItem(false, CMD_DROPITEM, item.position, item); + if (sendmsg) { + NetSendCmdPItem(true, CMD_SPAWNITEM, item.position, item); } } -void SpawnMapOfDoom(Point position) +void SpawnMapOfDoom(Point position, bool sendmsg) { - SpawnRewardItem(IDI_MAPOFDOOM, position); + SpawnRewardItem(IDI_MAPOFDOOM, position, sendmsg); } -void SpawnRuneBomb(Point position) +void SpawnRuneBomb(Point position, bool sendmsg) { - SpawnRewardItem(IDI_RUNEBOMB, position); + SpawnRewardItem(IDI_RUNEBOMB, position, sendmsg); } -void SpawnTheodore(Point position) +void SpawnTheodore(Point position, bool sendmsg) { - SpawnRewardItem(IDI_THEODORE, position); + SpawnRewardItem(IDI_THEODORE, position, sendmsg); } void RespawnItem(Item &item, bool flipFlag) @@ -3390,14 +3391,14 @@ void RespawnItem(Item &item, bool flipFlag) item.SetNewAnimation(flipFlag); item._iRequest = false; - if (item._iCurs == ICURS_MAGIC_ROCK) { + if (IsAnyOf(item._iCurs, ICURS_MAGIC_ROCK, ICURS_TAVERN_SIGN, ICURS_ANVIL_OF_FURY)) item._iSelFlag = 1; + else if (IsAnyOf(item._iCurs, ICURS_MAP_OF_THE_STARS, ICURS_RUNE_BOMB, ICURS_THEODORE, ICURS_AURIC_AMULET)) + item._iSelFlag = 2; + + if (item._iCurs == ICURS_MAGIC_ROCK) { PlaySfxLoc(ItemDropSnds[it], item.position); } - 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 26f0c6f5a..d72fc71a3 100644 --- a/Source/items.h +++ b/Source/items.h @@ -461,10 +461,10 @@ void RecreateEar(Item &item, uint16_t ic, int iseed, int Id, int dur, int mdur, void CornerstoneSave(); void CornerstoneLoad(Point position); void SpawnQuestItem(int itemid, Point position, int randarea, int selflag); -void SpawnRewardItem(int itemid, Point position); -void SpawnMapOfDoom(Point position); -void SpawnRuneBomb(Point position); -void SpawnTheodore(Point position); +void SpawnRewardItem(int itemid, Point position, bool sendmsg); +void SpawnMapOfDoom(Point position, bool sendmsg); +void SpawnRuneBomb(Point position, bool sendmsg); +void SpawnTheodore(Point position, bool sendmsg); void RespawnItem(Item &item, bool FlipFlag); void DeleteItem(int i); void ProcessItems(); diff --git a/Source/monster.cpp b/Source/monster.cpp index d72e3e549..0baa1b79a 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -987,15 +987,15 @@ void DiabloDeath(Monster &diablo, bool sendmsg) void SpawnLoot(Monster &monster, bool sendmsg) { if (Quests[Q_GARBUD].IsAvailable() && monster._uniqtype - 1 == UMT_GARBUD) { - CreateTypeItem(monster.position.tile + Displacement { 1, 1 }, true, ItemType::Mace, IMISC_NONE, true, false); + CreateTypeItem(monster.position.tile + Displacement { 1, 1 }, true, ItemType::Mace, IMISC_NONE, sendmsg, false); } else if (monster._uniqtype - 1 == UMT_DEFILER) { if (effect_is_playing(USFX_DEFILER8)) stream_stop(); Quests[Q_DEFILER]._qlog = false; - SpawnMapOfDoom(monster.position.tile); + SpawnMapOfDoom(monster.position.tile, sendmsg); } else if (monster._uniqtype - 1 == UMT_HORKDMN) { if (sgGameInitInfo.bTheoQuest != 0) { - SpawnTheodore(monster.position.tile); + SpawnTheodore(monster.position.tile, sendmsg); } else { CreateAmulet(monster.position.tile, 13, sendmsg, false); } diff --git a/Source/msg.cpp b/Source/msg.cpp index c41887b37..7378dc95a 100644 --- a/Source/msg.cpp +++ b/Source/msg.cpp @@ -1615,6 +1615,19 @@ DWORD OnDropItem(const TCmd *pCmd, int pnum) { const auto &message = *reinterpret_cast(pCmd); + if (gbBufferMsgs == 1) { + SendPacket(pnum, &message, sizeof(message)); + } else if (IsPItemValid(message)) { + DeltaPutItem(message, { message.x, message.y }, Players[pnum].plrlevel); + } + + return sizeof(message); +} + +DWORD OnSpawnItem(const TCmd *pCmd, int pnum) +{ + const auto &message = *reinterpret_cast(pCmd); + if (gbBufferMsgs == 1) { SendPacket(pnum, &message, sizeof(message)); } else if (IsPItemValid(message)) { @@ -2710,6 +2723,8 @@ uint32_t ParseCmd(int pnum, const TCmd *pCmd) return OnPutItem(pCmd, pnum); case CMD_SYNCPUTITEM: return OnSyncPutItem(pCmd, pnum); + case CMD_SPAWNITEM: + return OnSpawnItem(pCmd, pnum); case CMD_RESPAWNITEM: return OnRespawnItem(pCmd, pnum); case CMD_ATTACKXY: diff --git a/Source/msg.h b/Source/msg.h index 9d157ab64..c58dbb9e5 100644 --- a/Source/msg.h +++ b/Source/msg.h @@ -64,6 +64,10 @@ enum _cmd_id : uint8_t { // // body (TCmdPItem) CMD_PUTITEM, + // Spawn item on ground (place quest items). + // + // body (TCmdPItem) + CMD_SPAWNITEM, // Respawn item on ground (drop dead player item, or drop attempted loot item // when inventory is full). // diff --git a/Source/towners.cpp b/Source/towners.cpp index 4174b461c..a714b8ad5 100644 --- a/Source/towners.cpp +++ b/Source/towners.cpp @@ -612,7 +612,7 @@ void TalkToFarmer(Player &player, Towner &farmer) quest._qvar1 = 1; quest._qlog = true; quest._qmsg = TEXT_FARMER1; - SpawnRuneBomb(farmer.position + Displacement { 1, 0 }); + SpawnRuneBomb(farmer.position + Displacement { 1, 0 }, true); if (gbIsMultiplayer) NetSendCmdQuest(true, quest); break; @@ -621,7 +621,7 @@ void TalkToFarmer(Player &player, Towner &farmer) break; case QUEST_DONE: InitQTextMsg(TEXT_FARMER4); - SpawnRewardItem(IDI_AURIC, farmer.position + Displacement { 1, 0 }); + SpawnRewardItem(IDI_AURIC, farmer.position + Displacement { 1, 0 }, true); quest._qactive = QUEST_HIVE_DONE; quest._qlog = false; if (gbIsMultiplayer) @@ -712,7 +712,7 @@ void TalkToCowFarmer(Player &player, Towner &cowFarmer) quest._qvar1 = 1; quest._qmsg = TEXT_JERSEY4; quest._qlog = true; - SpawnRuneBomb(cowFarmer.position + Displacement { 1, 0 }); + SpawnRuneBomb(cowFarmer.position + Displacement { 1, 0 }, true); if (gbIsMultiplayer) NetSendCmdQuest(true, quest); break;