From 40bb3aeb459f5cf80b0fab591998a5f9473b665e Mon Sep 17 00:00:00 2001 From: obligaron Date: Fri, 14 Apr 2023 21:36:50 +0200 Subject: [PATCH] Replace earflag with DeathReason --- Source/debug.cpp | 2 +- Source/missiles.cpp | 12 ++++++------ Source/missiles.h | 2 +- Source/msg.cpp | 6 +++--- Source/objects.cpp | 4 ++-- Source/player.cpp | 36 ++++++++++++++++++------------------ Source/player.h | 16 +++++++++++++--- 7 files changed, 44 insertions(+), 34 deletions(-) diff --git a/Source/debug.cpp b/Source/debug.cpp index b8065bb78..fd7caab29 100644 --- a/Source/debug.cpp +++ b/Source/debug.cpp @@ -580,7 +580,7 @@ std::string DebugCmdChangeHealth(const string_view parameter) int newHealth = myPlayer._pHitPoints + (change * 64); SetPlayerHitPoints(myPlayer, newHealth); if (newHealth <= 0) - SyncPlrKill(myPlayer, 0); + SyncPlrKill(myPlayer, DeathReason::MonsterOrTrap); return "Health has changed."; } diff --git a/Source/missiles.cpp b/Source/missiles.cpp index 9818ce250..57e0144ca 100644 --- a/Source/missiles.cpp +++ b/Source/missiles.cpp @@ -442,11 +442,11 @@ void CheckMissileCol(Missile &missile, DamageType damageType, int minDamage, int isPlayerHit = Plr2PlrMHit(Players[missile._misource], pid - 1, minDamage, maxDamage, missile._midist, missile._mitype, damageType, isDamageShifted, &blocked); } else { Monster &monster = Monsters[missile._misource]; - isPlayerHit = PlayerMHit(pid - 1, &monster, missile._midist, minDamage, maxDamage, missile._mitype, damageType, isDamageShifted, 0, &blocked); + isPlayerHit = PlayerMHit(pid - 1, &monster, missile._midist, minDamage, maxDamage, missile._mitype, damageType, isDamageShifted, DeathReason::MonsterOrTrap, &blocked); } } else { - int earflag = (!missile.IsTrap() && (missile._miAnimType == MissileGraphicID::FireWall || missile._miAnimType == MissileGraphicID::Lightning)) ? 1 : 0; - isPlayerHit = PlayerMHit(pid - 1, nullptr, missile._midist, minDamage, maxDamage, missile._mitype, damageType, isDamageShifted, earflag, &blocked); + DeathReason deathReason = (!missile.IsTrap() && (missile._miAnimType == MissileGraphicID::FireWall || missile._miAnimType == MissileGraphicID::Lightning)) ? DeathReason::Player : DeathReason::MonsterOrTrap; + isPlayerHit = PlayerMHit(pid - 1, nullptr, missile._midist, minDamage, maxDamage, missile._mitype, damageType, isDamageShifted, deathReason, &blocked); } } @@ -968,7 +968,7 @@ bool MonsterTrapHit(int monsterId, int mindam, int maxdam, int dist, MissileID t return true; } -bool PlayerMHit(int pnum, Monster *monster, int dist, int mind, int maxd, MissileID mtype, DamageType damageType, bool shift, int earflag, bool *blocked) +bool PlayerMHit(int pnum, Monster *monster, int dist, int mind, int maxd, MissileID mtype, DamageType damageType, bool shift, DeathReason deathReason, bool *blocked) { *blocked = false; @@ -1087,7 +1087,7 @@ bool PlayerMHit(int pnum, Monster *monster, int dist, int mind, int maxd, Missil if (resper > 0) { dam -= dam * resper / 100; if (&player == MyPlayer) { - ApplyPlrDamage(damageType, player, 0, 0, dam, earflag); + ApplyPlrDamage(damageType, player, 0, 0, dam, deathReason); } if (player._pHitPoints >> 6 > 0) { @@ -1097,7 +1097,7 @@ bool PlayerMHit(int pnum, Monster *monster, int dist, int mind, int maxd, Missil } if (&player == MyPlayer) { - ApplyPlrDamage(damageType, player, 0, 0, dam, earflag); + ApplyPlrDamage(damageType, player, 0, 0, dam, deathReason); } if (player._pHitPoints >> 6 > 0) { diff --git a/Source/missiles.h b/Source/missiles.h index 2ca03c9f7..cec648b72 100644 --- a/Source/missiles.h +++ b/Source/missiles.h @@ -199,7 +199,7 @@ void GetDamageAmt(SpellID i, int *mind, int *maxd); */ Direction16 GetDirection16(Point p1, Point p2); bool MonsterTrapHit(int monsterId, int mindam, int maxdam, int dist, MissileID t, DamageType damageType, bool shift); -bool PlayerMHit(int pnum, Monster *monster, int dist, int mind, int maxd, MissileID mtype, DamageType damageType, bool shift, int earflag, bool *blocked); +bool PlayerMHit(int pnum, Monster *monster, int dist, int mind, int maxd, MissileID mtype, DamageType damageType, bool shift, DeathReason deathReason, bool *blocked); /** * @brief Could the missile collide with solid objects? (like walls or closed doors) diff --git a/Source/msg.cpp b/Source/msg.cpp index a1aff2ca7..2ebeea8e0 100644 --- a/Source/msg.cpp +++ b/Source/msg.cpp @@ -1971,12 +1971,12 @@ size_t OnMonstDamage(const TCmd *pCmd, size_t pnum) size_t OnPlayerDeath(const TCmd *pCmd, size_t pnum) { const auto &message = *reinterpret_cast(pCmd); - const uint16_t earFlag = SDL_SwapLE16(message.wParam1); + const DeathReason deathReason = static_cast(SDL_SwapLE16(message.wParam1)); if (gbBufferMsgs != 1) { Player &player = Players[pnum]; if (&player != MyPlayer) - StartPlayerKill(player, earFlag); + StartPlayerKill(player, deathReason); else pfile_update(true); } else { @@ -1994,7 +1994,7 @@ size_t OnPlayerDamage(const TCmd *pCmd, Player &player) Player &target = Players[message.bPlr]; if (&target == MyPlayer && leveltype != DTYPE_TOWN && gbBufferMsgs != 1) { if (player.isOnActiveLevel() && damage <= 192000 && target._pHitPoints >> 6 > 0) { - ApplyPlrDamage(message.damageType, target, 0, 0, damage, 1); + ApplyPlrDamage(message.damageType, target, 0, 0, damage, DeathReason::Player); } } diff --git a/Source/objects.cpp b/Source/objects.cpp index a41817e40..43c1c05c3 100644 --- a/Source/objects.cpp +++ b/Source/objects.cpp @@ -1699,7 +1699,7 @@ void UpdateFlameTrap(Object &trap) MonsterTrapHit(dMonster[x][y] - 1, mindam / 2, maxdam / 2, 0, TrapMissile, GetMissileData(TrapMissile).damageType(), false); if (dPlayer[x][y] > 0) { bool unused; - PlayerMHit(dPlayer[x][y] - 1, nullptr, 0, mindam, maxdam, TrapMissile, GetMissileData(TrapMissile).damageType(), false, 0, &unused); + PlayerMHit(dPlayer[x][y] - 1, nullptr, 0, mindam, maxdam, TrapMissile, GetMissileData(TrapMissile).damageType(), false, DeathReason::MonsterOrTrap, &unused); } if (trap._oAnimFrame == trap._oAnimLen) @@ -3517,7 +3517,7 @@ void BreakBarrel(const Player &player, Object &barrel, bool forcebreak, bool sen } if (dPlayer[xp][yp] > 0) { bool unused; - PlayerMHit(dPlayer[xp][yp] - 1, nullptr, 0, 8, 16, TrapMissile, GetMissileData(TrapMissile).damageType(), false, 0, &unused); + PlayerMHit(dPlayer[xp][yp] - 1, nullptr, 0, 8, 16, TrapMissile, GetMissileData(TrapMissile).damageType(), false, DeathReason::MonsterOrTrap, &unused); } // don't really need to exclude large objects as explosive barrels are single tile objects, but using considerLargeObjects == false as this matches the old logic. Object *adjacentObject = FindObjectAtPosition({ xp, yp }, false); diff --git a/Source/player.cpp b/Source/player.cpp index fc7cbf353..6f91b54e3 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -198,7 +198,7 @@ void StartWalkAnimation(Player &player, Direction dir, bool pmWillBeCalled) void StartWalk(Player &player, Direction dir, bool pmWillBeCalled) { if (player._pInvincible && player._pHitPoints == 0 && &player == MyPlayer) { - SyncPlrKill(player, -1); + SyncPlrKill(player, DeathReason::Unknown); return; } @@ -231,7 +231,7 @@ void ChangeOffset(Player &player) void StartAttack(Player &player, Direction d, bool includesFirstFrame) { if (player._pInvincible && player._pHitPoints == 0 && &player == MyPlayer) { - SyncPlrKill(player, -1); + SyncPlrKill(player, DeathReason::Unknown); return; } @@ -274,7 +274,7 @@ void StartAttack(Player &player, Direction d, bool includesFirstFrame) void StartRangeAttack(Player &player, Direction d, WorldTileCoord cx, WorldTileCoord cy, bool includesFirstFrame) { if (player._pInvincible && player._pHitPoints == 0 && &player == MyPlayer) { - SyncPlrKill(player, -1); + SyncPlrKill(player, DeathReason::Unknown); return; } @@ -314,7 +314,7 @@ player_graphic GetPlayerGraphicForSpell(SpellID spellId) void StartSpell(Player &player, Direction d, WorldTileCoord cx, WorldTileCoord cy) { if (player._pInvincible && player._pHitPoints == 0 && &player == MyPlayer) { - SyncPlrKill(player, -1); + SyncPlrKill(player, DeathReason::Unknown); return; } @@ -2661,7 +2661,7 @@ void FixPlayerLocation(Player &player, Direction bDir) void StartStand(Player &player, Direction dir) { if (player._pInvincible && player._pHitPoints == 0 && &player == MyPlayer) { - SyncPlrKill(player, -1); + SyncPlrKill(player, DeathReason::Unknown); return; } @@ -2676,7 +2676,7 @@ void StartStand(Player &player, Direction dir) void StartPlrBlock(Player &player, Direction dir) { if (player._pInvincible && player._pHitPoints == 0 && &player == MyPlayer) { - SyncPlrKill(player, -1); + SyncPlrKill(player, DeathReason::Unknown); return; } @@ -2706,7 +2706,7 @@ void FixPlrWalkTags(const Player &player) void StartPlrHit(Player &player, int dam, bool forcehit) { if (player._pInvincible && player._pHitPoints == 0 && &player == MyPlayer) { - SyncPlrKill(player, -1); + SyncPlrKill(player, DeathReason::Unknown); return; } @@ -2747,14 +2747,14 @@ void StartPlrHit(Player &player, int dam, bool forcehit) __attribute__((no_sanitize("shift-base"))) #endif void -StartPlayerKill(Player &player, int earflag) +StartPlayerKill(Player &player, DeathReason deathReason) { if (player._pHitPoints <= 0 && player._pmode == PM_DEATH) { return; } if (&player == MyPlayer) { - NetSendCmdParam1(true, CMD_PLRDEAD, earflag); + NetSendCmdParam1(true, CMD_PLRDEAD, static_cast(deathReason)); } bool diablolevel = gbIsMultiplayer && (player.isOnLevel(16) || player.isOnArenaLevel()); @@ -2762,7 +2762,7 @@ StartPlayerKill(Player &player, int earflag) player.Say(HeroSpeech::AuughUh); if (player._pgfxnum != 0) { - if (diablolevel || earflag != 0) + if (diablolevel || deathReason != DeathReason::MonsterOrTrap) player._pgfxnum &= ~0xFU; else player._pgfxnum = 0; @@ -2777,7 +2777,7 @@ StartPlayerKill(Player &player, int earflag) player._pInvincible = true; SetPlayerHitPoints(player, 0); - if (&player != MyPlayer && earflag == 0 && !diablolevel) { + if (&player != MyPlayer && deathReason == DeathReason::MonsterOrTrap && !diablolevel) { for (auto &item : player.InvBody) { item.clear(); } @@ -2800,8 +2800,8 @@ StartPlayerKill(Player &player, int earflag) if (!diablolevel) { DropHalfPlayersGold(player); - if (earflag != -1) { - if (earflag != 0) { + 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)); @@ -2862,7 +2862,7 @@ void StripTopGold(Player &player) player._pGold = CalculateGold(player); } -void ApplyPlrDamage(DamageType damageType, Player &player, int dam, int minHP /*= 0*/, int frac /*= 0*/, int earflag /*= 0*/) +void ApplyPlrDamage(DamageType damageType, Player &player, int dam, int minHP /*= 0*/, int frac /*= 0*/, DeathReason deathReason /*= DeathReason::MonsterOrTrap*/) { int totalDamage = (dam << 6) + frac; if (&player == MyPlayer) { @@ -2906,11 +2906,11 @@ void ApplyPlrDamage(DamageType damageType, Player &player, int dam, int minHP /* SetPlayerHitPoints(player, minHitPoints); } if (player._pHitPoints >> 6 <= 0) { - SyncPlrKill(player, earflag); + SyncPlrKill(player, deathReason); } } -void SyncPlrKill(Player &player, int earflag) +void SyncPlrKill(Player &player, DeathReason deathReason) { if (player._pHitPoints <= 0 && leveltype == DTYPE_TOWN) { SetPlayerHitPoints(player, 64); @@ -2918,7 +2918,7 @@ void SyncPlrKill(Player &player, int earflag) } SetPlayerHitPoints(player, 0); - StartPlayerKill(player, earflag); + StartPlayerKill(player, deathReason); } void RemovePlrMissiles(const Player &player) @@ -3072,7 +3072,7 @@ void ProcessPlayers() CheckCheatStats(player); if (!PlrDeathModeOK(player) && (player._pHitPoints >> 6) <= 0) { - SyncPlrKill(player, -1); + SyncPlrKill(player, DeathReason::Unknown); } if (&player == MyPlayer) { diff --git a/Source/player.h b/Source/player.h index c23bbc869..319004aec 100644 --- a/Source/player.h +++ b/Source/player.h @@ -162,6 +162,16 @@ enum class SpellFlag : uint8_t { }; use_enum_as_flags(SpellFlag); +/* @brief When the player dies, what is the reason/source why? */ +enum class DeathReason { + /* @brief Monster or Trap (dungeon) */ + MonsterOrTrap, + /* @brief Other player or selfkill (for example firewall) */ + Player, + /* @brief HP is zero but we don't know when or where this happend */ + Unknown, +}; + /** Maps from armor animation to letter used in graphic files. */ constexpr std::array ArmourChar = { 'l', // light @@ -797,7 +807,7 @@ void NextPlrLevel(Player &player); #endif void AddPlrExperience(Player &player, int lvl, int exp); void AddPlrMonstExper(int lvl, int exp, char pmask); -void ApplyPlrDamage(DamageType damageType, Player &player, int dam, int minHP = 0, int frac = 0, int earflag = 0); +void ApplyPlrDamage(DamageType damageType, Player &player, int dam, int minHP = 0, int frac = 0, DeathReason deathReason = DeathReason::MonsterOrTrap); void InitPlayer(Player &player, bool FirstTime); void InitMultiView(); void PlrClrTrans(Point position); @@ -808,12 +818,12 @@ void StartStand(Player &player, Direction dir); void StartPlrBlock(Player &player, Direction dir); void FixPlrWalkTags(const Player &player); void StartPlrHit(Player &player, int dam, bool forcehit); -void StartPlayerKill(Player &player, int earflag); +void StartPlayerKill(Player &player, DeathReason deathReason); /** * @brief Strip the top off gold piles that are larger than MaxGold */ void StripTopGold(Player &player); -void SyncPlrKill(Player &player, int earflag); +void SyncPlrKill(Player &player, DeathReason deathReason); void RemovePlrMissiles(const Player &player); void StartNewLvl(Player &player, interface_mode fom, int lvl); void RestartTownLvl(Player &player);