From d1189388f5e2700692bc8c6aa04ffcc2abecf36c Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sun, 17 Jul 2022 16:46:31 +0200 Subject: [PATCH] Use user by reference --- Source/automap.cpp | 2 +- Source/controls/plrctrls.cpp | 4 +- Source/debug.cpp | 8 +- Source/diablo.cpp | 7 +- Source/levels/trigs.cpp | 10 +- Source/loadsave.cpp | 2 +- Source/missiles.cpp | 18 +-- Source/monster.cpp | 133 +++++++++++----------- Source/monster.h | 12 +- Source/msg.cpp | 54 ++++----- Source/multi.cpp | 4 +- Source/objects.cpp | 25 +++-- Source/objects.h | 5 +- Source/player.cpp | 207 ++++++++++++----------------------- Source/player.h | 19 ++-- Source/quests.cpp | 2 +- Source/spells.cpp | 2 +- test/player_test.cpp | 9 +- 18 files changed, 232 insertions(+), 291 deletions(-) diff --git a/Source/automap.cpp b/Source/automap.cpp index 433151f0f..0a62da1d9 100644 --- a/Source/automap.cpp +++ b/Source/automap.cpp @@ -737,7 +737,7 @@ void DrawAutomap(const Surface &out) for (int playerId = 0; playerId < MAX_PLRS; playerId++) { Player &player = Players[playerId]; - if (player.isOnActiveLevel() && player.plractive && !player._pLvlChanging && (&player == &myPlayer || player.friendlyMode)) { + if (player.isOnActiveLevel() && player.plractive && !player._pLvlChanging && (&player == MyPlayer || player.friendlyMode)) { DrawAutomapPlr(out, myPlayerOffset, playerId); } } diff --git a/Source/controls/plrctrls.cpp b/Source/controls/plrctrls.cpp index 73777131c..9973a9a39 100644 --- a/Source/controls/plrctrls.cpp +++ b/Source/controls/plrctrls.cpp @@ -1283,7 +1283,7 @@ void WalkInDir(int playerId, AxisDirection dir) if (ControlMode == ControlTypes::VirtualGamepad) { if (VirtualGamepadState.standButton.isHeld) { if (player._pmode == PM_STAND) - StartStand(playerId, pdir); + StartStand(player, pdir); return; } } @@ -1291,7 +1291,7 @@ void WalkInDir(int playerId, AxisDirection dir) if (PosOkPlayer(player, delta) && IsPathBlocked(player.position.future, pdir)) { if (player._pmode == PM_STAND) - StartStand(playerId, pdir); + StartStand(player, pdir); return; // Don't start backtrack around obstacles } diff --git a/Source/debug.cpp b/Source/debug.cpp index 8cdb2a355..3322a3321 100644 --- a/Source/debug.cpp +++ b/Source/debug.cpp @@ -207,7 +207,7 @@ std::string DebugCmdWarpToLevel(const string_view parameter) if (!setlevel && myPlayer.isOnLevel(level)) return StrCat("I did nothing but fulfilled your wish. You are already at level ", level, "."); - StartNewLvl(MyPlayerId, (level != 21) ? interface_mode::WM_DIABNEXTLVL : interface_mode::WM_DIABTOWNWARP, level); + StartNewLvl(myPlayer, (level != 21) ? interface_mode::WM_DIABNEXTLVL : interface_mode::WM_DIABTOWNWARP, level); return StrCat("Welcome to level ", level, "."); } @@ -234,12 +234,12 @@ std::string DebugCmdLoadQuestMap(const string_view parameter) continue; if (!MyPlayer->isOnLevel(quest._qlevel)) { - StartNewLvl(MyPlayerId, (quest._qlevel != 21) ? interface_mode::WM_DIABNEXTLVL : interface_mode::WM_DIABTOWNWARP, quest._qlevel); + StartNewLvl(*MyPlayer, (quest._qlevel != 21) ? interface_mode::WM_DIABNEXTLVL : interface_mode::WM_DIABTOWNWARP, quest._qlevel); ProcessMessages(); } setlvltype = quest._qlvltype; - StartNewLvl(MyPlayerId, WM_DIABSETLVL, level); + StartNewLvl(*MyPlayer, WM_DIABSETLVL, level); return StrCat("Welcome to ", QuestLevelNames[level], "."); } @@ -283,7 +283,7 @@ std::string DebugCmdLoadMap(const string_view parameter) setlvltype = static_cast(mapType); ViewPosition = spawn; - StartNewLvl(MyPlayerId, WM_DIABSETLVL, SL_NONE); + StartNewLvl(*MyPlayer, WM_DIABSETLVL, SL_NONE); return "Welcome to this unique place."; } diff --git a/Source/diablo.cpp b/Source/diablo.cpp index b45e5c20f..da7d685df 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -2264,14 +2264,13 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir) SyncPortals(); - for (int i = 0; i < MAX_PLRS; i++) { - Player &player = Players[i]; + for (Player &player : Players) { if (player.plractive && player.isOnActiveLevel() && (!player._pLvlChanging || &player == MyPlayer)) { if (player._pHitPoints > 0) { if (!gbIsMultiplayer) - dPlayer[player.position.tile.x][player.position.tile.y] = i + 1; + dPlayer[player.position.tile.x][player.position.tile.y] = player.getId() + 1; else - SyncInitPlrPos(i); + SyncInitPlrPos(player); } else { dFlags[player.position.tile.x][player.position.tile.y] |= DungeonFlag::DeadPlayer; } diff --git a/Source/levels/trigs.cpp b/Source/levels/trigs.cpp index d1ab41519..98ed4fc02 100644 --- a/Source/levels/trigs.cpp +++ b/Source/levels/trigs.cpp @@ -835,14 +835,14 @@ void CheckTriggers() myPlayer.Say(HeroSpeech::NotAChance); InitDiabloMsg(EMSG_NOT_IN_SHAREWARE); } else { - StartNewLvl(MyPlayerId, trigs[i]._tmsg, currlevel + 1); + StartNewLvl(myPlayer, trigs[i]._tmsg, currlevel + 1); } break; case WM_DIABPREVLVL: - StartNewLvl(MyPlayerId, trigs[i]._tmsg, currlevel - 1); + StartNewLvl(myPlayer, trigs[i]._tmsg, currlevel - 1); break; case WM_DIABRTNLVL: - StartNewLvl(MyPlayerId, trigs[i]._tmsg, ReturnLevel); + StartNewLvl(myPlayer, trigs[i]._tmsg, ReturnLevel); break; case WM_DIABTOWNWARP: if (gbIsMultiplayer) { @@ -877,11 +877,11 @@ void CheckTriggers() } } - StartNewLvl(MyPlayerId, trigs[i]._tmsg, trigs[i]._tlvl); + StartNewLvl(myPlayer, trigs[i]._tmsg, trigs[i]._tlvl); break; case WM_DIABTWARPUP: TWarpFrom = currlevel; - StartNewLvl(MyPlayerId, trigs[i]._tmsg, 0); + StartNewLvl(myPlayer, trigs[i]._tmsg, 0); break; default: app_fatal("Unknown trigger msg"); diff --git a/Source/loadsave.cpp b/Source/loadsave.cpp index fd8bd0343..b61a84ccc 100644 --- a/Source/loadsave.cpp +++ b/Source/loadsave.cpp @@ -2078,7 +2078,7 @@ void LoadGame(bool firstflag) } LoadGameLevel(firstflag, ENTRY_LOAD); - SyncInitPlr(MyPlayerId); + SyncInitPlr(myPlayer); SyncPlrAnim(myPlayer); ViewPosition = { viewX, viewY }; diff --git a/Source/missiles.cpp b/Source/missiles.cpp index 1a290bc83..a3a686c2a 100644 --- a/Source/missiles.cpp +++ b/Source/missiles.cpp @@ -245,14 +245,14 @@ bool MonsterMHit(int pnum, int monsterId, int mindam, int maxdam, int dist, miss monster.flags |= MFLAG_NOHEAL; if (monster.hitPoints >> 6 <= 0) { - M_StartKill(monster, pnum); + M_StartKill(monster, player); } else if (resist) { PlayEffect(monster, 1); } else { if (monster.mode != MonsterMode::Petrified && MissilesData[t].mType == 0 && HasAnyOf(player._pIFlags, ItemSpecialEffect::Knockback)) M_GetKnockback(monster); if (monster.type().type != MT_GOLEM) - M_StartHit(monster, pnum, dam); + M_StartHit(monster, player, dam); } if (monster.activeForTicks == 0) { @@ -354,7 +354,7 @@ bool Plr2PlrMHit(const Player &player, int p, int mindam, int maxdam, int dist, } else { if (&player == MyPlayer) NetSendCmdDamage(true, p, dam); - StartPlrHit(p, dam, false); + StartPlrHit(target, dam, false); } return true; @@ -438,7 +438,7 @@ void CheckMissileCol(Missile &missile, int minDamage, int maxDamage, bool isDama if (IsMissileBlockedByTile({ mx, my })) { Object *object = ObjectAtPosition({ mx, my }); if (object != nullptr && object->IsBreakable()) { - BreakObject(-1, *object); + BreakObjectMissile(*object); } if (!dontDeleteOnCollision) @@ -683,7 +683,7 @@ bool IsMissileBlockedByTile(Point tile) void GetDamageAmt(spell_id i, int *mind, int *maxd) { - assert(MyPlayerId >= 0 && MyPlayerId < MAX_PLRS); + assert(MyPlayer != nullptr); assert(i >= 0 && i < 64); Player &myPlayer = *MyPlayer; @@ -873,7 +873,7 @@ bool MonsterTrapHit(int monsterId, int mindam, int maxdam, int dist, missile_id monster.hitPoints = 0; #endif if (monster.hitPoints >> 6 <= 0) { - StartMonsterDeath(monster, -1, true); + MonsterDeath(monster, monster.direction, true); } else if (resist) { PlayEffect(monster, 1); } else { @@ -1014,7 +1014,7 @@ bool PlayerMHit(int pnum, Monster *monster, int dist, int mind, int maxd, missil } if (player._pHitPoints >> 6 > 0) { - StartPlrHit(pnum, dam, false); + StartPlrHit(player, dam, false); } return true; @@ -2159,7 +2159,7 @@ void AddGolem(Missile &missile, const AddMissileParameter ¶meter) Monster &golem = Monsters[playerId]; if (golem.position.tile != GolemHoldingCell && &player == MyPlayer) - M_StartKill(golem, playerId); + M_StartKill(golem, player); UseMana(player, SPL_GOLEM); @@ -2171,7 +2171,7 @@ void AddGolem(Missile &missile, const AddMissileParameter ¶meter) parameter.dst, 0, 5); if (spawnPosition) { - SpawnGolem(playerId, *spawnPosition, missile); + SpawnGolem(player, golem, *spawnPosition, missile); } } } diff --git a/Source/monster.cpp b/Source/monster.cpp index b7eee7b99..6a7ce9df7 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -1067,45 +1067,6 @@ void MonsterHitMonster(Monster &monster, int i, int dam) HitMonster(monster, dam); } -void MonsterDeath(Monster &monster, int pnum, Direction md, bool sendmsg) -{ - if (pnum < MAX_PLRS) { - if (pnum >= 0) - monster.whoHit |= 1 << pnum; - if (monster.type().type != MT_GOLEM) - AddPlrMonstExper(monster.level, monster.exp, monster.whoHit); - } - - MonsterKillCounts[monster.type().type]++; - monster.hitPoints = 0; - SetRndSeed(monster.rndItemSeed); - - SpawnLoot(monster, sendmsg); - - if (monster.type().type == MT_DIABLO) - DiabloDeath(monster, true); - else - PlayEffect(monster, 2); - - if (monster.mode != MonsterMode::Petrified) { - if (monster.type().type == MT_GOLEM) - md = Direction::South; - NewMonsterAnim(monster, MonsterGraphic::Death, md, gGameLogicStep < GameLogicStep::ProcessMonsters ? AnimationDistributionFlags::ProcessAnimationPending : AnimationDistributionFlags::None); - monster.mode = MonsterMode::Death; - } - monster.goal = MonsterGoal::None; - monster.var1 = 0; - monster.position.offset = { 0, 0 }; - monster.position.tile = monster.position.old; - monster.position.future = monster.position.old; - M_ClearSquares(monster); - dMonster[monster.position.tile.x][monster.position.tile.y] = monster.getId() + 1; - CheckQuestKill(monster, sendmsg); - M_FallenFear(monster.position.tile); - if (IsAnyOf(monster.type().type, MT_NACID, MT_RACID, MT_BACID, MT_XACID, MT_SPIDLORD)) - AddMissile(monster.position.tile, { 0, 0 }, Direction::South, MIS_ACIDPUD, TARGET_PLAYERS, monster.getId(), monster.intelligence + 1, 0); -} - void StartDeathFromMonster(int i, int mid) { assert(static_cast(i) < MaxMonsters); @@ -1116,8 +1077,12 @@ void StartDeathFromMonster(int i, int mid) delta_kill_monster(monster, monster.position.tile, *MyPlayer); NetSendCmdLocParam1(false, CMD_MONSTDEATH, monster.position.tile, mid); + if (killer.type().type == MT_GOLEM) + monster.whoHit |= 1 << i; + Direction md = GetDirection(monster.position.tile, killer.position.tile); - MonsterDeath(monster, i, md, true); + MonsterDeath(monster, md, true); + if (gbIsHellfire) M_StartStand(killer, killer.direction); } @@ -1279,9 +1244,9 @@ void CheckReflect(int monsterId, int pnum, int dam) monster.hitPoints -= mdam; dam = std::max(dam - mdam, 0); if (monster.hitPoints >> 6 <= 0) - M_StartKill(monster, pnum); + M_StartKill(monster, player); else - M_StartHit(monster, pnum, mdam); + M_StartHit(monster, player, mdam); } void MonsterAttackPlayer(int monsterId, int pnum, int hit, int minDam, int maxDam) @@ -1367,9 +1332,9 @@ void MonsterAttackPlayer(int monsterId, int pnum, int hit, int minDam, int maxDa int mdam = (GenerateRnd(3) + 1) << 6; monster.hitPoints -= mdam; if (monster.hitPoints >> 6 <= 0) - M_StartKill(monster, pnum); + M_StartKill(monster, player); else - M_StartHit(monster, pnum, mdam); + M_StartHit(monster, player, mdam); } if ((monster.flags & MFLAG_NOLIFESTEAL) == 0 && monster.type().type == MT_SKING && gbIsMultiplayer) @@ -1379,10 +1344,10 @@ void MonsterAttackPlayer(int monsterId, int pnum, int hit, int minDam, int maxDa M_StartStand(monster, monster.direction); return; } - StartPlrHit(pnum, dam, false); + StartPlrHit(player, dam, false); if ((monster.flags & MFLAG_KNOCKBACK) != 0) { if (player._pmode != PM_GOTHIT) - StartPlrHit(pnum, 0, true); + StartPlrHit(player, 0, true); Point newPosition = player.position.tile + monster.direction; if (PosOkPlayer(player, newPosition)) { @@ -3115,7 +3080,7 @@ void LachdananAi(int monsterId) if (!effect_is_playing(USFX_LACH3) && monster.goal == MonsterGoal::Talking) { monster.talkMsg = TEXT_NONE; Quests[Q_VEIL]._qactive = QUEST_DONE; - StartMonsterDeath(monster, -1, true); + MonsterDeath(monster, monster.direction, true); } } } @@ -3907,16 +3872,15 @@ void M_StartHit(Monster &monster, int dam) } } -void M_StartHit(Monster &monster, int pnum, int dam) +void M_StartHit(Monster &monster, const Player &player, int dam) { - monster.whoHit |= 1 << pnum; - Player &player = Players[pnum]; + monster.whoHit |= 1 << player.getId(); if (&player == MyPlayer) { delta_monster_hp(monster, *MyPlayer); NetSendCmdMonDmg(false, monster.getId(), dam); } if (IsAnyOf(monster.type().type, MT_SNEAK, MT_STALKER, MT_UNSEEN, MT_ILLWEAV) || dam >> 6 >= monster.level + 3) { - monster.enemy = pnum; + monster.enemy = player.getId(); monster.enemyPosition = player.position.future; monster.flags &= ~MFLAG_TARGETS_MONSTER; monster.direction = GetMonsterDirection(monster); @@ -3925,27 +3889,64 @@ void M_StartHit(Monster &monster, int pnum, int dam) M_StartHit(monster, dam); } -void StartMonsterDeath(Monster &monster, int pnum, bool sendmsg) +void MonsterDeath(Monster &monster, Direction md, bool sendmsg) +{ + if (monster.type().type != MT_GOLEM) + AddPlrMonstExper(monster.level, monster.exp, monster.whoHit); + + MonsterKillCounts[monster.type().type]++; + monster.hitPoints = 0; + SetRndSeed(monster.rndItemSeed); + + SpawnLoot(monster, sendmsg); + + if (monster.type().type == MT_DIABLO) + DiabloDeath(monster, true); + else + PlayEffect(monster, 2); + + if (monster.mode != MonsterMode::Petrified) { + if (monster.type().type == MT_GOLEM) + md = Direction::South; + NewMonsterAnim(monster, MonsterGraphic::Death, md, gGameLogicStep < GameLogicStep::ProcessMonsters ? AnimationDistributionFlags::ProcessAnimationPending : AnimationDistributionFlags::None); + monster.mode = MonsterMode::Death; + } + monster.goal = MonsterGoal::None; + monster.var1 = 0; + monster.position.offset = { 0, 0 }; + monster.position.tile = monster.position.old; + monster.position.future = monster.position.old; + M_ClearSquares(monster); + dMonster[monster.position.tile.x][monster.position.tile.y] = monster.getId() + 1; + CheckQuestKill(monster, sendmsg); + M_FallenFear(monster.position.tile); + if (IsAnyOf(monster.type().type, MT_NACID, MT_RACID, MT_BACID, MT_XACID, MT_SPIDLORD)) + AddMissile(monster.position.tile, { 0, 0 }, Direction::South, MIS_ACIDPUD, TARGET_PLAYERS, monster.getId(), monster.intelligence + 1, 0); +} + +void StartMonsterDeath(Monster &monster, const Player &player, bool sendmsg) { - Direction md = pnum >= 0 ? GetDirection(monster.position.tile, Players[pnum].position.tile) : monster.direction; - MonsterDeath(monster, pnum, md, sendmsg); + monster.whoHit |= 1 << player.getId(); + Direction md = GetDirection(monster.position.tile, player.position.tile); + MonsterDeath(monster, md, sendmsg); } -void M_StartKill(Monster &monster, int pnum) +void M_StartKill(Monster &monster, const Player &player) { - if (pnum == MyPlayerId) { + if (&player == MyPlayer) { delta_kill_monster(monster, monster.position.tile, *MyPlayer); - if (&monster != &Monsters[pnum]) { - NetSendCmdLocParam1(false, CMD_MONSTDEATH, monster.position.tile, monster.getId()); + size_t monsterId = monster.getId(); + if (monsterId != player.getId()) { + NetSendCmdLocParam1(false, CMD_MONSTDEATH, monster.position.tile, monsterId); } else { NetSendCmdLoc(MyPlayerId, false, CMD_KILLGOLEM, monster.position.tile); } } - StartMonsterDeath(monster, pnum, true); + StartMonsterDeath(monster, player, true); } -void M_SyncStartKill(int monsterId, Point position, int pnum) +void M_SyncStartKill(int monsterId, Point position, const Player &player) { assert(static_cast(monsterId) < MaxMonsters); auto &monster = Monsters[monsterId]; @@ -3960,7 +3961,7 @@ void M_SyncStartKill(int monsterId, Point position, int pnum) monster.position.old = position; } - StartMonsterDeath(monster, pnum, false); + StartMonsterDeath(monster, player, false); } void M_UpdateRelations(const Monster &monster) @@ -4584,7 +4585,7 @@ void MissToMonst(Missile &missile, Point position) Player &player = Players[pnum]; if (player._pmode != PM_GOTHIT && player._pmode != PM_DEATH) - StartPlrHit(pnum, 0, true); + StartPlrHit(player, 0, true); Point newPosition = oldPosition + monster.direction; if (PosOkPlayer(player, newPosition)) { player.position.tile = newPosition; @@ -4736,13 +4737,9 @@ void TalktoMonster(Monster &monster) } } -void SpawnGolem(int id, Point position, Missile &missile) +void SpawnGolem(Player &player, Monster &golem, Point position, Missile &missile) { - assert(id >= 0 && id < MAX_PLRS); - Player &player = Players[id]; - auto &golem = Monsters[id]; - - dMonster[position.x][position.y] = id + 1; + dMonster[position.x][position.y] = golem.getId() + 1; golem.position.tile = position; golem.position.future = position; golem.position.old = position; diff --git a/Source/monster.h b/Source/monster.h index 5763e175d..4598a4a31 100644 --- a/Source/monster.h +++ b/Source/monster.h @@ -26,6 +26,7 @@ namespace devilution { struct Missile; +struct Player; constexpr size_t MaxMonsters = 200; constexpr size_t MaxLvlMTypes = 24; @@ -370,10 +371,11 @@ void M_StartStand(Monster &monster, Direction md); void M_ClearSquares(const Monster &monster); void M_GetKnockback(Monster &monster); void M_StartHit(Monster &monster, int dam); -void M_StartHit(Monster &monster, int pnum, int dam); -void StartMonsterDeath(Monster &monster, int pnum, bool sendmsg); -void M_StartKill(Monster &monster, int pnum); -void M_SyncStartKill(int monsterId, Point position, int pnum); +void M_StartHit(Monster &monster, const Player &player, int dam); +void StartMonsterDeath(Monster &monster, const Player &player, bool sendmsg); +void MonsterDeath(Monster &monster, Direction md, bool sendmsg); +void M_StartKill(Monster &monster, const Player &player); +void M_SyncStartKill(int monsterId, Point position, const Player &player); void M_UpdateRelations(const Monster &monster); void DoEnding(); void PrepDoEnding(); @@ -404,7 +406,7 @@ bool IsGoat(_monster_id mt); bool SpawnSkeleton(Monster *monster, Point position); Monster *PreSpawnSkeleton(); void TalktoMonster(Monster &monster); -void SpawnGolem(int id, Point position, Missile &missile); +void SpawnGolem(Player &player, Monster &golem, Point position, Missile &missile); bool CanTalkToMonst(const Monster &monster); int encode_enemy(Monster &monster); void decode_enemy(Monster &monster, int enemyId); diff --git a/Source/msg.cpp b/Source/msg.cpp index 3cc8218dd..b1440f631 100644 --- a/Source/msg.cpp +++ b/Source/msg.cpp @@ -665,12 +665,6 @@ void DeltaOpenPortal(int pnum, Point position, uint8_t bLevel, dungeon_type bLTy sgJunk.portal[pnum].setlvl = bSetLvl ? 1 : 0; } -void CheckUpdatePlayer(int pnum) -{ - if (gbIsMultiplayer && pnum == MyPlayerId) - pfile_update(true); -} - void NetSendCmdGItem2(bool usonly, _cmd_id bCmd, uint8_t mast, uint8_t pnum, const TCmdGItem &item) { TCmdGItem cmd; @@ -995,22 +989,25 @@ size_t OnPutItem(const TCmd *pCmd, int pnum) } else if (IsPItemValid(message)) { const Point position { message.x, message.y }; Player &player = Players[pnum]; + bool isSelf = &player == MyPlayer; if (player.isOnActiveLevel()) { int ii; - if (&player == MyPlayer) + if (isSelf) ii = InvPutItem(player, position, ItemLimbo); else ii = SyncPutItem(player, position, message.wIndx, message.wCI, message.dwSeed, message.bId, message.bDur, message.bMDur, message.bCh, message.bMCh, message.wValue, message.dwBuff, message.wToHit, message.wMaxDam, message.bMinStr, message.bMinMag, message.bMinDex, message.bAC); if (ii != -1) { PutItemRecord(message.dwSeed, message.wCI, message.wIndx); DeltaPutItem(message, Items[ii].position, player); - CheckUpdatePlayer(pnum); + if (isSelf) + pfile_update(true); } return sizeof(message); } else { PutItemRecord(message.dwSeed, message.wCI, message.wIndx); DeltaPutItem(message, position, player); - CheckUpdatePlayer(pnum); + if (isSelf) + pfile_update(true); } } @@ -1031,13 +1028,15 @@ size_t OnSyncPutItem(const TCmd *pCmd, int pnum) if (ii != -1) { PutItemRecord(message.dwSeed, message.wCI, message.wIndx); DeltaPutItem(message, Items[ii].position, player); - CheckUpdatePlayer(pnum); + if (&player == MyPlayer) + pfile_update(true); } return sizeof(message); } else { PutItemRecord(message.dwSeed, message.wCI, message.wIndx); DeltaPutItem(message, position, player); - CheckUpdatePlayer(pnum); + if (&player == MyPlayer) + pfile_update(true); } } @@ -1448,10 +1447,12 @@ size_t OnKnockback(const TCmd *pCmd, int pnum) { const auto &message = *reinterpret_cast(pCmd); - if (gbBufferMsgs != 1 && Players[pnum].isOnActiveLevel() && message.wParam1 < MaxMonsters) { + Player &player = Players[pnum]; + + if (gbBufferMsgs != 1 && player.isOnActiveLevel() && message.wParam1 < MaxMonsters) { Monster &monster = Monsters[message.wParam1]; M_GetKnockback(monster); - M_StartHit(monster, pnum, 0); + M_StartHit(monster, player, 0); } return sizeof(message); @@ -1465,7 +1466,8 @@ size_t OnResurrect(const TCmd *pCmd, int pnum) SendPacket(pnum, &message, sizeof(message)); } else if (message.wParam1 < MAX_PLRS) { DoResurrect(pnum, message.wParam1); - CheckUpdatePlayer(pnum); + if (pnum == MyPlayerId) + pfile_update(true); } return sizeof(message); @@ -1515,7 +1517,7 @@ size_t OnNewLevel(const TCmd *pCmd, int pnum) return sizeof(message); } - StartNewLvl(pnum, mode, levelId); + StartNewLvl(Players[pnum], mode, levelId); } return sizeof(message); @@ -1528,7 +1530,7 @@ size_t OnWarp(const TCmd *pCmd, int pnum) if (gbBufferMsgs == 1) { SendPacket(pnum, &message, sizeof(message)); } else if (message.wParam1 < MAXPORTAL) { - StartWarpLvl(pnum, message.wParam1); + StartWarpLvl(Players[pnum], message.wParam1); } return sizeof(message); @@ -1544,7 +1546,7 @@ size_t OnMonstDeath(const TCmd *pCmd, int pnum) if (&player != MyPlayer && InDungeonBounds(position) && message.wParam1 < MaxMonsters) { Monster &monster = Monsters[message.wParam1]; if (player.isOnActiveLevel()) - M_SyncStartKill(message.wParam1, position, pnum); + M_SyncStartKill(message.wParam1, position, player); delta_kill_monster(monster, position, player); } } else { @@ -1564,7 +1566,7 @@ size_t OnKillGolem(const TCmd *pCmd, int pnum) if (&player != MyPlayer && InDungeonBounds(position)) { Monster &monster = Monsters[pnum]; if (player.isOnActiveLevel()) - M_SyncStartKill(pnum, position, pnum); + M_SyncStartKill(pnum, position, player); delta_kill_monster(monster, position, player); } } else { @@ -1634,7 +1636,7 @@ size_t OnPlayerDeath(const TCmd *pCmd, int pnum) if (&player != MyPlayer) StartPlayerKill(player, message.wParam1); else - CheckUpdatePlayer(pnum); + pfile_update(true); } else { SendPacket(pnum, &message, sizeof(message)); } @@ -1722,16 +1724,16 @@ size_t OnPlayerOperateObject(const TCmd *pCmd, int pnum) size_t OnBreakObject(const TCmd *pCmd, int pnum) { - const auto &message = *reinterpret_cast(pCmd); + const auto &message = *reinterpret_cast(pCmd); if (gbBufferMsgs == 1) { SendPacket(pnum, &message, sizeof(message)); - } else if (message.wParam1 < MAX_PLRS && message.wParam2 < MAXOBJECTS) { + } else if (message.wParam1 < MAXOBJECTS) { Player &player = Players[pnum]; if (player.isOnActiveLevel()) { - SyncBreakObj(message.wParam1, Objects[message.wParam2]); + SyncBreakObj(player, Objects[message.wParam1]); } - DeltaSyncObject(message.wParam2, CMD_BREAKOBJ, player); + DeltaSyncObject(message.wParam1, CMD_BREAKOBJ, player); } return sizeof(message); @@ -1866,9 +1868,9 @@ size_t OnPlayerJoinLevel(const TCmd *pCmd, int pnum) player.setLevel(playerLevel); ResetPlayerGFX(player); if (player.isOnActiveLevel()) { - SyncInitPlr(pnum); + SyncInitPlr(player); if ((player._pHitPoints >> 6) > 0) { - StartStand(pnum, Direction::South); + StartStand(player, Direction::South); } else { player._pgfxnum &= ~0xF; player._pmode = PM_DEATH; @@ -1945,7 +1947,7 @@ size_t OnRestartTown(const TCmd *pCmd, int pnum) MyPlayerIsDead = false; gamemenu_off(); } - RestartTownLvl(pnum); + RestartTownLvl(Players[pnum]); } return sizeof(*pCmd); diff --git a/Source/multi.cpp b/Source/multi.cpp index 6f49c066b..831757e92 100644 --- a/Source/multi.cpp +++ b/Source/multi.cpp @@ -826,14 +826,14 @@ void recv_plrinfo(int pnum, const TCmdPlrInfoHdr &header, bool recv) } EventPlrMsg(fmt::format(fmt::runtime(szEvent), player._pName, player._pLevel)); - SyncInitPlr(pnum); + SyncInitPlr(player); if (!player.isOnActiveLevel()) { return; } if (player._pHitPoints >> 6 > 0) { - StartStand(pnum, Direction::South); + StartStand(player, Direction::South); return; } diff --git a/Source/objects.cpp b/Source/objects.cpp index f64053ac4..08e7a7cea 100644 --- a/Source/objects.cpp +++ b/Source/objects.cpp @@ -1408,7 +1408,7 @@ void UpdateCircle(Object &circle) LastMouseButtonAction = MouseActionType::None; sgbMouseDown = CLICK_NONE; ClrPlrPath(myPlayer); - StartStand(MyPlayerId, Direction::South); + StartStand(myPlayer, Direction::South); } } @@ -3815,11 +3815,11 @@ void BreakCrux(Object &crux) ObjChangeMap(crux._oVar1, crux._oVar2, crux._oVar3, crux._oVar4); } -void BreakBarrel(int pnum, Object &barrel, bool forcebreak, bool sendmsg) +void BreakBarrel(const Player &player, Object &barrel, bool forcebreak, bool sendmsg) { if (barrel._oSelFlag == 0) return; - if (!forcebreak && pnum != MyPlayerId) { + if (!forcebreak && &player != MyPlayer) { return; } @@ -3851,7 +3851,7 @@ void BreakBarrel(int pnum, Object &barrel, bool forcebreak, bool sendmsg) // 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 = ObjectAtPosition({ xp, yp }, false); if (adjacentObject != nullptr && adjacentObject->isExplosive() && !adjacentObject->IsBroken()) { - BreakBarrel(pnum, *adjacentObject, true, sendmsg); + BreakBarrel(player, *adjacentObject, true, sendmsg); } } } @@ -3872,8 +3872,8 @@ void BreakBarrel(int pnum, Object &barrel, bool forcebreak, bool sendmsg) if (barrel._oVar2 >= 8 && barrel._oVar4 >= 0) SpawnSkeleton(&Monsters[barrel._oVar4], barrel.position); } - if (pnum == MyPlayerId) { - NetSendCmdParam2(false, CMD_BREAKOBJ, pnum, static_cast(barrel.GetId())); + if (&player == MyPlayer) { + NetSendCmdParam1(false, CMD_BREAKOBJ, static_cast(barrel.GetId())); } } @@ -5144,10 +5144,15 @@ void SyncOpObject(int pnum, int cmd, int i) } } -void BreakObject(int pnum, Object &object) +void BreakObjectMissile(Object &object) +{ + if (object.IsCrux()) + BreakCrux(object); +} +void BreakObject(const Player &player, Object &object) { if (object.IsBarrel()) { - BreakBarrel(pnum, object, false, true); + BreakBarrel(player, object, false, true); } else if (object.IsCrux()) { BreakCrux(object); } @@ -5167,10 +5172,10 @@ void DeltaSyncBreakObj(Object &object) object._oAnimFrame = object._oAnimLen; } -void SyncBreakObj(int pnum, Object &object) +void SyncBreakObj(const Player &player, Object &object) { if (object.IsBarrel()) { - BreakBarrel(pnum, object, true, false); + BreakBarrel(player, object, true, false); } } diff --git a/Source/objects.h b/Source/objects.h index 84d1cea5d..9921984f9 100644 --- a/Source/objects.h +++ b/Source/objects.h @@ -307,10 +307,11 @@ void ObjChangeMapResync(int x1, int y1, int x2, int y2); int ItemMiscIdIdx(item_misc_id imiscid); void OperateObject(int pnum, int i, bool TeleFlag); void SyncOpObject(int pnum, int cmd, int i); -void BreakObject(int pnum, Object &object); +void BreakObjectMissile(Object &object); +void BreakObject(const Player &player, Object &object); void DeltaSyncOpObject(int cmd, int i); void DeltaSyncBreakObj(Object &object); -void SyncBreakObj(int pnum, Object &object); +void SyncBreakObj(const Player &player, Object &object); void SyncObjectAnim(Object &object); /** * @brief Updates the text drawn in the info box to describe the given object diff --git a/Source/player.cpp b/Source/player.cpp index 328d440ed..2cff03367 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -595,9 +595,8 @@ void DropHalfPlayersGold(Player &player) player._pGold /= 2; } -void InitLevelChange(int pnum) +void InitLevelChange(Player &player) { - Player &player = Players[pnum]; Player &myPlayer = *MyPlayer; RemovePlrMissiles(player); @@ -617,7 +616,7 @@ void InitLevelChange(int pnum) FixPlrWalkTags(player); SetPlayerOld(player); if (&player == MyPlayer) { - dPlayer[player.position.tile.x][player.position.tile.y] = pnum + 1; + dPlayer[player.position.tile.x][player.position.tile.y] = player.getId() + 1; } else { player._pLvlVisited[player.plrlevel] = true; } @@ -684,7 +683,7 @@ bool DoWalk(int pnum, int variant) if (player.walkpath[0] != WALK_NONE) { StartWalkStand(player); } else { - StartStand(pnum, player.tempDirection); + StartStand(player, player.tempDirection); } ClearStateVariables(player); @@ -785,17 +784,12 @@ bool DamageWeapon(Player &player, unsigned damageFrequency) return false; } -bool PlrHitMonst(int pnum, size_t monsterId, bool adjacentDamage = false) +bool PlrHitMonst(Player &player, size_t monsterId, bool adjacentDamage = false) { int hper = 0; Monster &monster = Monsters[monsterId]; - if (pnum < 0 || pnum >= MAX_PLRS) { - app_fatal(StrCat("PlrHitMonst: illegal player ", pnum)); - } - Player &player = Players[pnum]; - if (!monster.isPossibleToHit()) return false; @@ -826,7 +820,7 @@ bool PlrHitMonst(int pnum, size_t monsterId, bool adjacentDamage = false) if (gbIsHellfire && HasAllOf(player._pIFlags, ItemSpecialEffect::FireDamage | ItemSpecialEffect::LightningDamage)) { int midam = player._pIFMinDam + GenerateRnd(player._pIFMaxDam - player._pIFMinDam); - AddMissile(player.position.tile, player.position.temp, player._pdir, MIS_SPECARROW, TARGET_MONSTERS, pnum, midam, 0); + AddMissile(player.position.tile, player.position.temp, player._pdir, MIS_SPECARROW, TARGET_MONSTERS, player.getId(), midam, 0); } int mind = player._pIMinDam; int maxd = player._pIMaxDam; @@ -957,22 +951,17 @@ bool PlrHitMonst(int pnum, size_t monsterId, bool adjacentDamage = false) } #endif if ((monster.hitPoints >> 6) <= 0) { - M_StartKill(monster, pnum); + M_StartKill(monster, player); } else { if (monster.mode != MonsterMode::Petrified && HasAnyOf(player._pIFlags, ItemSpecialEffect::Knockback)) M_GetKnockback(monster); - M_StartHit(monster, pnum, dam); + M_StartHit(monster, player, dam); } return true; } -bool PlrHitPlr(Player &attacker, int8_t p) +bool PlrHitPlr(Player &attacker, Player &target) { - if (p < 0 || p >= MAX_PLRS) { - app_fatal(StrCat("PlrHitPlr: illegal target player ", p)); - } - Player &target = Players[p]; - if (target._pInvincible) { return false; } @@ -1029,17 +1018,17 @@ bool PlrHitPlr(Player &attacker, int8_t p) drawhpflag = true; } if (&attacker == MyPlayer) { - NetSendCmdDamage(true, p, skdam); + NetSendCmdDamage(true, target.getId(), skdam); } - StartPlrHit(p, skdam, false); + StartPlrHit(target, skdam, false); return true; } -bool PlrHitObj(int pnum, Object &targetObject) +bool PlrHitObj(const Player &player, Object &targetObject) { if (targetObject.IsBreakable()) { - BreakObject(pnum, targetObject); + BreakObject(player, targetObject); return true; } @@ -1081,13 +1070,13 @@ bool DoAttack(int pnum) } if (dMonster[dx][dy] != 0) { - didhit = PlrHitMonst(pnum, abs(dMonster[dx][dy]) - 1); + didhit = PlrHitMonst(player, abs(dMonster[dx][dy]) - 1); } else if (dPlayer[dx][dy] != 0 && !player.friendlyMode) { - didhit = PlrHitPlr(player, abs(dPlayer[dx][dy]) - 1); + didhit = PlrHitPlr(player, Players[abs(dPlayer[dx][dy]) - 1]); } else { Object *object = ObjectAtPosition(position, false); if (object != nullptr) { - didhit = PlrHitObj(pnum, *object); + didhit = PlrHitObj(player, *object); } } if ((player._pClass == HeroClass::Monk @@ -1107,7 +1096,7 @@ bool DoAttack(int pnum) int m = abs(dMonster[position.x][position.y]) - 1; auto &monster = Monsters[m]; if (!CanTalkToMonst(monster) && monster.position.old == position) { - if (PlrHitMonst(pnum, m, true)) + if (PlrHitMonst(player, m, true)) didhit = true; } } @@ -1116,21 +1105,21 @@ bool DoAttack(int pnum) int m = abs(dMonster[position.x][position.y]) - 1; auto &monster = Monsters[m]; if (!CanTalkToMonst(monster) && monster.position.old == position) { - if (PlrHitMonst(pnum, m, true)) + if (PlrHitMonst(player, m, true)) didhit = true; } } } if (didhit && DamageWeapon(player, 30)) { - StartStand(pnum, player._pdir); + StartStand(player, player._pdir); ClearStateVariables(player); return true; } } if (player.AnimInfo.currentFrame == player._pAFrames - 1) { - StartStand(pnum, player._pdir); + StartStand(player, player._pdir); ClearStateVariables(player); return true; } @@ -1138,13 +1127,8 @@ bool DoAttack(int pnum) return false; } -bool DoRangeAttack(int pnum) +bool DoRangeAttack(Player &player) { - if (pnum < 0 || pnum >= MAX_PLRS) { - app_fatal(StrCat("PM_DoRangeAttack: illegal player ", pnum)); - } - Player &player = Players[pnum]; - int arrows = 0; if (player.AnimInfo.currentFrame == player._pAFNum - 1) { arrows = 1; @@ -1186,7 +1170,7 @@ bool DoRangeAttack(int pnum) player._pdir, mistype, TARGET_MONSTERS, - pnum, + player.getId(), dmg, 0); @@ -1195,14 +1179,14 @@ bool DoRangeAttack(int pnum) } if (DamageWeapon(player, 40)) { - StartStand(pnum, player._pdir); + StartStand(player, player._pdir); ClearStateVariables(player); return true; } } if (player.AnimInfo.currentFrame >= player._pAFrames - 1) { - StartStand(pnum, player._pdir); + StartStand(player, player._pdir); ClearStateVariables(player); return true; } @@ -1238,15 +1222,10 @@ void DamageParryItem(Player &player) } } -bool DoBlock(int pnum) +bool DoBlock(Player &player) { - if (pnum < 0 || pnum >= MAX_PLRS) { - app_fatal(StrCat("PM_DoBlock: illegal player ", pnum)); - } - Player &player = Players[pnum]; - if (player.AnimInfo.currentFrame >= player._pBFrames - 1) { - StartStand(pnum, player._pdir); + StartStand(player, player._pdir); ClearStateVariables(player); if (FlipCoin(10)) { @@ -1299,16 +1278,11 @@ void DamageArmor(Player &player) CalcPlrInv(player, true); } -bool DoSpell(int pnum) +bool DoSpell(Player &player) { - if (pnum < 0 || pnum >= MAX_PLRS) { - app_fatal(StrCat("PM_DoSpell: illegal player ", pnum)); - } - Player &player = Players[pnum]; - if (player.AnimInfo.currentFrame == player._pSFNum) { CastSpell( - pnum, + player.getId(), player._pSpell, player.position.tile.x, player.position.tile.y, @@ -1322,7 +1296,7 @@ bool DoSpell(int pnum) } if (player.AnimInfo.currentFrame >= player._pSFrames - 1) { - StartStand(pnum, player._pdir); + StartStand(player, player._pdir); ClearStateVariables(player); return true; } @@ -1330,15 +1304,10 @@ bool DoSpell(int pnum) return false; } -bool DoGotHit(int pnum) +bool DoGotHit(Player &player) { - if (pnum < 0 || pnum >= MAX_PLRS) { - app_fatal(StrCat("PM_DoGotHit: illegal player ", pnum)); - } - Player &player = Players[pnum]; - if (player.AnimInfo.currentFrame >= player._pHFrames - 1) { - StartStand(pnum, player._pdir); + StartStand(player, player._pdir); ClearStateVariables(player); if (!FlipCoin(4)) { DamageArmor(player); @@ -1524,7 +1493,7 @@ void CheckNewPath(int pnum, bool pmWillBeCalled) player.walkpath[MaxPathLength - 1] = WALK_NONE; if (player._pmode == PM_STAND) { - StartStand(pnum, player._pdir); + StartStand(player, player._pdir); player.destAction = ACTION_NONE; } } @@ -1741,9 +1710,7 @@ bool PlrDeathModeOK(Player &player) void ValidatePlayer() { - if (MyPlayerId < 0 || MyPlayerId >= MAX_PLRS) { - app_fatal(StrCat("ValidatePlayer: illegal player ", MyPlayerId)); - } + assert(MyPlayer != nullptr); Player &myPlayer = *MyPlayer; if (myPlayer._pLevel > MaxCharacterLevel) @@ -1876,6 +1843,11 @@ void Player::RemoveSpdBarItem(int iv) force_redraw = 255; } +[[nodiscard]] size_t Player::getId() const +{ + return std::distance(&Players[0], this); +} + int Player::GetBaseAttributeValue(CharacterAttribute attribute) const { switch (attribute) { @@ -2730,12 +2702,10 @@ void AddPlrMonstExper(int lvl, int exp, char pmask) void InitPlayer(Player &player, bool firstTime) { - Player &myPlayer = *MyPlayer; - if (firstTime) { player._pRSplType = RSPLTYPE_INVALID; player._pRSpell = SPL_INVALID; - if (&player == &myPlayer) + if (&player == MyPlayer) LoadHotkeys(); player._pSBkSpell = SPL_INVALID; player._pSpell = player._pRSpell; @@ -2766,7 +2736,7 @@ void InitPlayer(Player &player, bool firstTime) player._pdir = Direction::South; - if (&player == &myPlayer) { + if (&player == MyPlayer) { if (!firstTime || leveltype != DTYPE_TOWN) { player.position.tile = ViewPosition; } @@ -2782,13 +2752,13 @@ void InitPlayer(Player &player, bool firstTime) player.walkpath[0] = WALK_NONE; player.destAction = ACTION_NONE; - if (&player == &myPlayer) { + if (&player == MyPlayer) { player._plid = AddLight(player.position.tile, player._pLightRad); ChangeLightXY(player._plid, player.position.tile); // fix for a bug where old light is still visible at the entrance after reentering level } else { player._plid = NO_LIGHT; } - player._pvid = AddVision(player.position.tile, player._pLightRad, &player == &myPlayer); + player._pvid = AddVision(player.position.tile, player._pLightRad, &player == MyPlayer); } if (player._pClass == HeroClass::Warrior) { @@ -2808,7 +2778,7 @@ void InitPlayer(Player &player, bool firstTime) player._pNextExper = ExpLvlsTbl[player._pLevel]; player._pInvincible = false; - if (&player == &myPlayer) { + if (&player == MyPlayer) { MyPlayerIsDead = false; ScrollInfo.offset = { 0, 0 }; ScrollInfo._sdir = ScrollDirection::None; @@ -2817,12 +2787,8 @@ void InitPlayer(Player &player, bool firstTime) void InitMultiView() { - if (MyPlayerId < 0 || MyPlayerId >= MAX_PLRS) { - app_fatal(StrCat("InitPlayer: illegal player ", MyPlayerId)); - } - Player &myPlayer = *MyPlayer; - - ViewPosition = myPlayer.position.tile; + assert(MyPlayer != nullptr); + ViewPosition = MyPlayer->position.tile; } void PlrClrTrans(Point position) @@ -2869,13 +2835,8 @@ void FixPlayerLocation(Player &player, Direction bDir) ChangeVisionXY(player._pvid, player.position.tile); } -void StartStand(int pnum, Direction dir) +void StartStand(Player &player, Direction dir) { - if (pnum < 0 || pnum >= MAX_PLRS) { - app_fatal(StrCat("StartStand: illegal player ", pnum)); - } - Player &player = Players[pnum]; - if (player._pInvincible && player._pHitPoints == 0 && &player == MyPlayer) { SyncPlrKill(player, -1); return; @@ -2885,7 +2846,7 @@ void StartStand(int pnum, Direction dir) player._pmode = PM_STAND; FixPlayerLocation(player, dir); FixPlrWalkTags(player); - dPlayer[player.position.tile.x][player.position.tile.y] = pnum + 1; + dPlayer[player.position.tile.x][player.position.tile.y] = player.getId() + 1; SetPlayerOld(player); } @@ -2919,13 +2880,8 @@ void FixPlrWalkTags(const Player &player) } } -void StartPlrHit(int pnum, int dam, bool forcehit) +void StartPlrHit(Player &player, int dam, bool forcehit) { - if (pnum < 0 || pnum >= MAX_PLRS) { - app_fatal(StrCat("StartPlrHit: illegal player ", pnum)); - } - Player &player = Players[pnum]; - if (player._pInvincible && player._pHitPoints == 0 && &player == MyPlayer) { SyncPlrKill(player, -1); return; @@ -2963,7 +2919,7 @@ void StartPlrHit(int pnum, int dam, bool forcehit) player._pmode = PM_GOTHIT; FixPlayerLocation(player, pd); FixPlrWalkTags(player); - dPlayer[player.position.tile.x][player.position.tile.y] = pnum + 1; + dPlayer[player.position.tile.x][player.position.tile.y] = player.getId() + 1; SetPlayerOld(player); } @@ -3147,7 +3103,7 @@ void RemovePlrMissiles(const Player &player) if (leveltype != DTYPE_TOWN && &player == MyPlayer) { Monster &golem = Monsters[MyPlayerId]; if (golem.position.tile.x != 1 || golem.position.tile.y != 0) { - M_StartKill(golem, MyPlayerId); + M_StartKill(golem, player); AddCorpse(golem.position.tile, golem.type().corpseId, golem.direction); int mx = golem.position.tile.x; int my = golem.position.tile.y; @@ -3168,15 +3124,9 @@ void RemovePlrMissiles(const Player &player) __attribute__((no_sanitize("shift-base"))) #endif void -StartNewLvl(int pnum, interface_mode fom, int lvl) +StartNewLvl(Player &player, interface_mode fom, int lvl) { - InitLevelChange(pnum); - - if (pnum < 0 || pnum >= MAX_PLRS) { - app_fatal(StrCat("StartNewLvl: illegal player ", pnum)); - } - Player &player = Players[pnum]; - Player &myPlayer = *MyPlayer; + InitLevelChange(player); switch (fom) { case WM_DIABNEXTLVL: @@ -3190,7 +3140,7 @@ StartNewLvl(int pnum, interface_mode fom, int lvl) player.setLevel(setlvlnum); break; case WM_DIABTWARPUP: - myPlayer.pTownWarps |= 1 << (leveltype - 2); + MyPlayer->pTownWarps |= 1 << (leveltype - 2); player.setLevel(lvl); break; case WM_DIABRETOWN: @@ -3209,13 +3159,9 @@ StartNewLvl(int pnum, interface_mode fom, int lvl) } } -void RestartTownLvl(int pnum) +void RestartTownLvl(Player &player) { - InitLevelChange(pnum); - if (pnum < 0 || pnum >= MAX_PLRS) { - app_fatal(StrCat("RestartTownLvl: illegal player ", pnum)); - } - Player &player = Players[pnum]; + InitLevelChange(player); player.setLevel(0); player._pInvincible = false; @@ -3234,11 +3180,9 @@ void RestartTownLvl(int pnum) } } -void StartWarpLvl(int pnum, int pidx) +void StartWarpLvl(Player &player, int pidx) { - Player &player = Players[pnum]; - - InitLevelChange(pnum); + InitLevelChange(player); if (gbIsMultiplayer) { if (!player.isOnLevel(0)) { @@ -3261,9 +3205,7 @@ void StartWarpLvl(int pnum, int pidx) void ProcessPlayers() { - if (MyPlayerId < 0 || MyPlayerId >= MAX_PLRS) { - app_fatal(StrCat("ProcessPlayers: illegal player ", MyPlayerId)); - } + assert(MyPlayer != nullptr); Player &myPlayer = *MyPlayer; if (myPlayer.pLvlLoad > 0) { @@ -3331,16 +3273,16 @@ void ProcessPlayers() tplayer = DoAttack(pnum); break; case PM_RATTACK: - tplayer = DoRangeAttack(pnum); + tplayer = DoRangeAttack(player); break; case PM_BLOCK: - tplayer = DoBlock(pnum); + tplayer = DoBlock(player); break; case PM_SPELL: - tplayer = DoSpell(pnum); + tplayer = DoSpell(player); break; case PM_GOTHIT: - tplayer = DoGotHit(pnum); + tplayer = DoGotHit(player); break; case PM_DEATH: tplayer = DoDeath(player); @@ -3430,9 +3372,7 @@ void CheckPlrSpell(bool isShiftHeld, spell_id spellID, spell_type spellType) { bool addflag = false; - if (MyPlayerId < 0 || MyPlayerId >= MAX_PLRS) { - app_fatal(StrCat("CheckPlrSpell: illegal player ", MyPlayerId)); - } + assert(MyPlayer != nullptr); Player &myPlayer = *MyPlayer; if (!IsValidSpell(spellID)) { @@ -3569,10 +3509,8 @@ void SyncPlrAnim(Player &player) ScrollViewPort(player, WalkSettings[static_cast(player._pdir)].scrollDir); } -void SyncInitPlrPos(int pnum) +void SyncInitPlrPos(Player &player) { - Player &player = Players[pnum]; - if (!gbIsMultiplayer || !player.isOnActiveLevel()) { return; } @@ -3596,7 +3534,7 @@ void SyncInitPlrPos(int pnum) }(); player.position.tile = position; - dPlayer[position.x][position.y] = pnum + 1; + dPlayer[position.x][position.y] = player.getId() + 1; if (&player == MyPlayer) { player.position.future = position; @@ -3604,15 +3542,10 @@ void SyncInitPlrPos(int pnum) } } -void SyncInitPlr(int pnum) +void SyncInitPlr(Player &player) { - if (pnum < 0 || pnum >= MAX_PLRS) { - app_fatal(StrCat("SyncInitPlr: illegal player ", pnum)); - } - Player &player = Players[pnum]; - SetPlrAnims(player); - SyncInitPlrPos(pnum); + SyncInitPlrPos(player); if (&player != MyPlayer) player._plid = NO_LIGHT; } @@ -3787,9 +3720,7 @@ enum { void PlayDungMsgs() { - if (MyPlayerId < 0 || MyPlayerId >= MAX_PLRS) { - app_fatal(StrCat("PlayDungMsgs: illegal player ", MyPlayerId)); - } + assert(MyPlayer != nullptr); Player &myPlayer = *MyPlayer; if (currlevel == 1 && !myPlayer._pLvlVisited[1] && (myPlayer.pDungMsgs & DungMsgCathedral) == 0) { @@ -3828,9 +3759,9 @@ void PlayDungMsgs() } #ifdef BUILD_TESTING -bool TestPlayerDoGotHit(int pnum) +bool TestPlayerDoGotHit(Player &player) { - return DoGotHit(pnum); + return DoGotHit(player); } #endif diff --git a/Source/player.h b/Source/player.h index 25c5436d2..484f39e95 100644 --- a/Source/player.h +++ b/Source/player.h @@ -368,6 +368,11 @@ struct Player { */ void RemoveInvItem(int iv, bool calcScrolls = true); + /** + * @brief Returns the network identifier for this player + */ + [[nodiscard]] size_t getId() const; + void RemoveSpdBarItem(int iv); /** @@ -771,10 +776,10 @@ void PlrClrTrans(Point position); void PlrDoTrans(Point position); void SetPlayerOld(Player &player); void FixPlayerLocation(Player &player, Direction bDir); -void StartStand(int pnum, Direction dir); +void StartStand(Player &player, Direction dir); void StartPlrBlock(Player &player, Direction dir); void FixPlrWalkTags(const Player &player); -void StartPlrHit(int pnum, int dam, bool forcehit); +void StartPlrHit(Player &player, int dam, bool forcehit); void StartPlayerKill(Player &player, int earflag); /** * @brief Strip the top off gold piles that are larger than MaxGold @@ -782,9 +787,9 @@ void StartPlayerKill(Player &player, int earflag); void StripTopGold(Player &player); void SyncPlrKill(Player &player, int earflag); void RemovePlrMissiles(const Player &player); -void StartNewLvl(int pnum, interface_mode fom, int lvl); -void RestartTownLvl(int pnum); -void StartWarpLvl(int pnum, int pidx); +void StartNewLvl(Player &player, interface_mode fom, int lvl); +void RestartTownLvl(Player &player); +void StartWarpLvl(Player &player, int pidx); void ProcessPlayers(); void ClrPlrPath(Player &player); bool PosOkPlayer(const Player &player, Point position); @@ -792,8 +797,8 @@ void MakePlrPath(Player &player, Point targetPosition, bool endspace); void CalcPlrStaff(Player &player); void CheckPlrSpell(bool isShiftHeld, spell_id spellID = MyPlayer->_pRSpell, spell_type spellType = MyPlayer->_pRSplType); void SyncPlrAnim(Player &player); -void SyncInitPlrPos(int pnum); -void SyncInitPlr(int pnum); +void SyncInitPlrPos(Player &player); +void SyncInitPlr(Player &player); void CheckStats(Player &player); void ModifyPlrStr(Player &player, int l); void ModifyPlrMag(Player &player, int l); diff --git a/Source/quests.cpp b/Source/quests.cpp index fccb121e3..75d39ec9f 100644 --- a/Source/quests.cpp +++ b/Source/quests.cpp @@ -365,7 +365,7 @@ void CheckQuests() if (quest._qlvltype != DTYPE_NONE) { setlvltype = quest._qlvltype; } - StartNewLvl(MyPlayerId, WM_DIABSETLVL, quest._qslvl); + StartNewLvl(*MyPlayer, WM_DIABSETLVL, quest._qslvl); } } } diff --git a/Source/spells.cpp b/Source/spells.cpp index 1a163ec8b..1cd52c5f8 100644 --- a/Source/spells.cpp +++ b/Source/spells.cpp @@ -295,7 +295,7 @@ void DoResurrect(int pnum, uint16_t rid) CalcPlrInv(target, true); if (target.isOnActiveLevel()) { - StartStand(rid, target._pdir); + StartStand(target, target._pdir); } else { target._pmode = PM_STAND; } diff --git a/test/player_test.cpp b/test/player_test.cpp index a98b09cc7..64e2cc70f 100644 --- a/test/player_test.cpp +++ b/test/player_test.cpp @@ -5,21 +5,20 @@ using namespace devilution; namespace devilution { -extern bool TestPlayerDoGotHit(int pnum); +extern bool TestPlayerDoGotHit(Player &player); } int RunBlockTest(int frames, ItemSpecialEffect flags) { - int pnum = 0; - Player &player = Players[pnum]; + Player &player = Players[0]; player._pHFrames = frames; player._pIFlags = flags; - StartPlrHit(pnum, 5, false); + StartPlrHit(player, 5, false); int i = 1; for (; i < 100; i++) { - TestPlayerDoGotHit(pnum); + TestPlayerDoGotHit(player); if (player._pmode != PM_GOTHIT) break; player.AnimInfo.currentFrame++;