From f6aae56a2847bbf6c3989eb290c102245dd99792 Mon Sep 17 00:00:00 2001 From: obligaron Date: Fri, 14 Apr 2023 22:24:20 +0200 Subject: [PATCH] Refactor StartPlayerKill --- Source/player.cpp | 92 +++++++++++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 42 deletions(-) diff --git a/Source/player.cpp b/Source/player.cpp index 6f91b54e3..a088eb19b 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -2757,15 +2757,21 @@ StartPlayerKill(Player &player, DeathReason deathReason) NetSendCmdParam1(true, CMD_PLRDEAD, static_cast(deathReason)); } - bool diablolevel = gbIsMultiplayer && (player.isOnLevel(16) || player.isOnArenaLevel()); + const bool dropGold = !gbIsMultiplayer || !(player.isOnLevel(16) || player.isOnArenaLevel()); + const bool dropItems = dropGold && deathReason == DeathReason::MonsterOrTrap; + const bool dropEar = dropGold && deathReason == DeathReason::Player; player.Say(HeroSpeech::AuughUh); + // Are the current animations item dependend? if (player._pgfxnum != 0) { - if (diablolevel || deathReason != DeathReason::MonsterOrTrap) - player._pgfxnum &= ~0xFU; - else + if (dropItems) { + // Ensure death animation show the player without weapon and armor, because they drop on death player._pgfxnum = 0; + } else { + // Death animation aren't weapon specific, so always use the unarmed animations + player._pgfxnum &= ~0xFU; + } ResetPlayerGFX(player); SetPlrAnims(player); } @@ -2777,7 +2783,9 @@ StartPlayerKill(Player &player, DeathReason deathReason) player._pInvincible = true; SetPlayerHitPoints(player, 0); - if (&player != MyPlayer && deathReason == DeathReason::MonsterOrTrap && !diablolevel) { + if (&player != MyPlayer && dropItems) { + // Ensure that items are removed for remote players + // The dropped items will be synced seperatly (by the remote client) for (auto &item : player.InvBody) { item.clear(); } @@ -2790,6 +2798,8 @@ StartPlayerKill(Player &player, DeathReason deathReason) dFlags[player.position.tile.x][player.position.tile.y] |= DungeonFlag::DeadPlayer; SetPlayerOld(player); + // Only generate drops once (for the local player) + // For remote players we get seperated sync messages (by the remote client) if (&player == MyPlayer) { RedrawComponent(PanelDrawComponent::Health); @@ -2797,48 +2807,46 @@ StartPlayerKill(Player &player, DeathReason deathReason) DeadItem(player, std::move(player.HoldItem), { 0, 0 }); NewCursor(CURSOR_HAND); } - - if (!diablolevel) { + if (dropGold) { DropHalfPlayersGold(player); - if (deathReason != DeathReason::Unknown) { - if (deathReason == DeathReason::Player) { - Item ear; - InitializeItem(ear, IDI_EAR); - CopyUtf8(ear._iName, fmt::format(fmt::runtime(_("Ear of {:s}")), player._pName), sizeof(ear._iName)); - CopyUtf8(ear._iIName, player._pName, sizeof(ear._iIName)); - switch (player._pClass) { - case HeroClass::Sorcerer: - ear._iCurs = ICURS_EAR_SORCERER; - break; - case HeroClass::Warrior: - ear._iCurs = ICURS_EAR_WARRIOR; - break; - case HeroClass::Rogue: - case HeroClass::Monk: - case HeroClass::Bard: - case HeroClass::Barbarian: - ear._iCurs = ICURS_EAR_ROGUE; - break; - } - - ear._iCreateInfo = player._pName[0] << 8 | player._pName[1]; - ear._iSeed = player._pName[2] << 24 | player._pName[3] << 16 | player._pName[4] << 8 | player._pName[5]; - ear._ivalue = player._pLevel; + } + if (dropEar) { + Item ear; + InitializeItem(ear, IDI_EAR); + CopyUtf8(ear._iName, fmt::format(fmt::runtime("Ear of {:s}"), player._pName), sizeof(ear._iName)); + CopyUtf8(ear._iIName, player._pName, sizeof(ear._iIName)); + switch (player._pClass) { + case HeroClass::Sorcerer: + ear._iCurs = ICURS_EAR_SORCERER; + break; + case HeroClass::Warrior: + ear._iCurs = ICURS_EAR_WARRIOR; + break; + case HeroClass::Rogue: + case HeroClass::Monk: + case HeroClass::Bard: + case HeroClass::Barbarian: + ear._iCurs = ICURS_EAR_ROGUE; + break; + } - if (FindGetItem(ear._iSeed, IDI_EAR, ear._iCreateInfo) == -1) { - DeadItem(player, std::move(ear), { 0, 0 }); - } - } else { - Direction pdd = player._pdir; - for (auto &item : player.InvBody) { - pdd = Left(pdd); - DeadItem(player, item.pop(), Displacement(pdd)); - } + ear._iCreateInfo = player._pName[0] << 8 | player._pName[1]; + ear._iSeed = player._pName[2] << 24 | player._pName[3] << 16 | player._pName[4] << 8 | player._pName[5]; + ear._ivalue = player._pLevel; - CalcPlrInv(player, false); - } + if (FindGetItem(ear._iSeed, IDI_EAR, ear._iCreateInfo) == -1) { + DeadItem(player, std::move(ear), { 0, 0 }); } } + if (dropItems) { + Direction pdd = player._pdir; + for (auto &item : player.InvBody) { + pdd = Left(pdd); + DeadItem(player, item.pop(), Displacement(pdd)); + } + + CalcPlrInv(player, false); + } } } SetPlayerHitPoints(player, 0);