diff --git a/Source/automap.cpp b/Source/automap.cpp index f47a30349..de6a58a0a 100644 --- a/Source/automap.cpp +++ b/Source/automap.cpp @@ -715,7 +715,7 @@ void DrawAutomap(const Surface &out) screen.y += AmLine(32); } - for (int playerId = 0; playerId < MAX_PLRS; playerId++) { + for (size_t playerId = 0; playerId < Players.size(); playerId++) { Player &player = Players[playerId]; if (player.isOnActiveLevel() && player.plractive && !player._pLvlChanging && (&player == MyPlayer || player.friendlyMode)) { DrawAutomapPlr(out, myPlayerOffset, playerId); diff --git a/Source/control.cpp b/Source/control.cpp index 6d1c7be20..955e7f13c 100644 --- a/Source/control.cpp +++ b/Source/control.cpp @@ -328,7 +328,7 @@ void ResetTalkMsg() uint32_t pmask = 0; - for (int i = 0; i < MAX_PLRS; i++) { + for (size_t i = 0; i < Players.size(); i++) { if (WhisperList[i]) pmask |= 1 << i; } @@ -1154,7 +1154,7 @@ void DrawTalkPan(const Surface &out) x += 46; int talkBtn = 0; - for (int i = 0; i < 4; i++) { + for (size_t i = 0; i < Players.size(); i++) { Player &player = Players[i]; if (&player == MyPlayer) continue; @@ -1221,13 +1221,13 @@ void control_release_talk_btn() int off = (MousePosition.y - (69 + mainPanelPosition.y)) / 18; - int p = 0; - for (; p < MAX_PLRS && off != -1; p++) { - if (p != MyPlayerId) + size_t playerId = 0; + for (; playerId < Players.size() && off != -1; ++playerId) { + if (playerId != MyPlayerId) off--; } - if (p <= MAX_PLRS) - WhisperList[p - 1] = !WhisperList[p - 1]; + if (playerId > 0 && playerId <= Players.size()) + WhisperList[playerId - 1] = !WhisperList[playerId - 1]; } void control_type_message() diff --git a/Source/controls/game_controls.cpp b/Source/controls/game_controls.cpp index dd6c0c0b0..2c24cec1a 100644 --- a/Source/controls/game_controls.cpp +++ b/Source/controls/game_controls.cpp @@ -103,6 +103,10 @@ bool HandleStartAndSelect(const ControllerButtonEvent &ctrlEvent, GameAction *ac bool GetGameAction(const SDL_Event &event, ControllerButtonEvent ctrlEvent, GameAction *action) { + if (MyPlayer == nullptr) { + return false; + } + const bool inGameMenu = InGameMenu(); #ifndef USE_SDL1 diff --git a/Source/controls/plrctrls.cpp b/Source/controls/plrctrls.cpp index 0e2967998..228116c27 100644 --- a/Source/controls/plrctrls.cpp +++ b/Source/controls/plrctrls.cpp @@ -373,7 +373,7 @@ void CheckPlayerNearby() if (myPlayer.friendlyMode && spl != SPL_RESURRECT && spl != SPL_HEALOTHER) return; - for (int i = 0; i < MAX_PLRS; i++) { + for (size_t i = 0; i < Players.size(); i++) { const Player &player = Players[i]; if (&player == MyPlayer) continue; diff --git a/Source/cursor.cpp b/Source/cursor.cpp index d3c7eb764..f7533446d 100644 --- a/Source/cursor.cpp +++ b/Source/cursor.cpp @@ -423,52 +423,52 @@ void CheckCursMove() if (leveltype != DTYPE_TOWN) { if (pcurstemp != -1) { if (!flipflag && mx + 2 < MAXDUNX && my + 1 < MAXDUNY && dMonster[mx + 2][my + 1] != 0 && IsTileLit({ mx + 2, my + 1 })) { - int mi = abs(dMonster[mx + 2][my + 1]) - 1; - if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 4) != 0) { + const uint16_t monsterId = abs(dMonster[mx + 2][my + 1]) - 1; + if (monsterId == pcurstemp && Monsters[monsterId].hitPoints >> 6 > 0 && (Monsters[monsterId].data().selectionType & 4) != 0) { cursPosition = Point { mx, my } + Displacement { 2, 1 }; - pcursmonst = mi; + pcursmonst = monsterId; } } if (flipflag && mx + 1 < MAXDUNX && my + 2 < MAXDUNY && dMonster[mx + 1][my + 2] != 0 && IsTileLit({ mx + 1, my + 2 })) { - int mi = abs(dMonster[mx + 1][my + 2]) - 1; - if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 4) != 0) { + const uint16_t monsterId = abs(dMonster[mx + 1][my + 2]) - 1; + if (monsterId == pcurstemp && Monsters[monsterId].hitPoints >> 6 > 0 && (Monsters[monsterId].data().selectionType & 4) != 0) { cursPosition = Point { mx, my } + Displacement { 1, 2 }; - pcursmonst = mi; + pcursmonst = monsterId; } } if (mx + 2 < MAXDUNX && my + 2 < MAXDUNY && dMonster[mx + 2][my + 2] != 0 && IsTileLit({ mx + 2, my + 2 })) { - int mi = abs(dMonster[mx + 2][my + 2]) - 1; - if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 4) != 0) { + const uint16_t monsterId = abs(dMonster[mx + 2][my + 2]) - 1; + if (monsterId == pcurstemp && Monsters[monsterId].hitPoints >> 6 > 0 && (Monsters[monsterId].data().selectionType & 4) != 0) { cursPosition = Point { mx, my } + Displacement { 2, 2 }; - pcursmonst = mi; + pcursmonst = monsterId; } } if (mx + 1 < MAXDUNX && !flipflag && dMonster[mx + 1][my] != 0 && IsTileLit({ mx + 1, my })) { - int mi = abs(dMonster[mx + 1][my]) - 1; - if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 2) != 0) { + const uint16_t monsterId = abs(dMonster[mx + 1][my]) - 1; + if (monsterId == pcurstemp && Monsters[monsterId].hitPoints >> 6 > 0 && (Monsters[monsterId].data().selectionType & 2) != 0) { cursPosition = Point { mx, my } + Displacement { 1, 0 }; - pcursmonst = mi; + pcursmonst = monsterId; } } if (my + 1 < MAXDUNY && flipflag && dMonster[mx][my + 1] != 0 && IsTileLit({ mx, my + 1 })) { - int mi = abs(dMonster[mx][my + 1]) - 1; - if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 2) != 0) { + const uint16_t monsterId = abs(dMonster[mx][my + 1]) - 1; + if (monsterId == pcurstemp && Monsters[monsterId].hitPoints >> 6 > 0 && (Monsters[monsterId].data().selectionType & 2) != 0) { cursPosition = Point { mx, my } + Displacement { 0, 1 }; - pcursmonst = mi; + pcursmonst = monsterId; } } if (dMonster[mx][my] != 0 && IsTileLit({ mx, my })) { - int mi = abs(dMonster[mx][my]) - 1; - if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 1) != 0) { + const uint16_t monsterId = abs(dMonster[mx][my]) - 1; + if (monsterId == pcurstemp && Monsters[monsterId].hitPoints >> 6 > 0 && (Monsters[monsterId].data().selectionType & 1) != 0) { cursPosition = { mx, my }; - pcursmonst = mi; + pcursmonst = monsterId; } } if (mx + 1 < MAXDUNX && my + 1 < MAXDUNY && dMonster[mx + 1][my + 1] != 0 && IsTileLit({ mx + 1, my + 1 })) { - int mi = abs(dMonster[mx + 1][my + 1]) - 1; - if (mi == pcurstemp && Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 2) != 0) { + const uint16_t monsterId = abs(dMonster[mx + 1][my + 1]) - 1; + if (monsterId == pcurstemp && Monsters[monsterId].hitPoints >> 6 > 0 && (Monsters[monsterId].data().selectionType & 2) != 0) { cursPosition = Point { mx, my } + Displacement { 1, 1 }; - pcursmonst = mi; + pcursmonst = monsterId; } } if (pcursmonst != -1 && (Monsters[pcursmonst].flags & MFLAG_HIDDEN) != 0) { @@ -483,52 +483,52 @@ void CheckCursMove() } } if (!flipflag && mx + 2 < MAXDUNX && my + 1 < MAXDUNY && dMonster[mx + 2][my + 1] != 0 && IsTileLit({ mx + 2, my + 1 })) { - int mi = abs(dMonster[mx + 2][my + 1]) - 1; - if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 4) != 0) { + int monsterId = abs(dMonster[mx + 2][my + 1]) - 1; + if (Monsters[monsterId].hitPoints >> 6 > 0 && (Monsters[monsterId].data().selectionType & 4) != 0) { cursPosition = Point { mx, my } + Displacement { 2, 1 }; - pcursmonst = mi; + pcursmonst = monsterId; } } if (flipflag && mx + 1 < MAXDUNX && my + 2 < MAXDUNY && dMonster[mx + 1][my + 2] != 0 && IsTileLit({ mx + 1, my + 2 })) { - int mi = abs(dMonster[mx + 1][my + 2]) - 1; - if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 4) != 0) { + const uint16_t monsterId = abs(dMonster[mx + 1][my + 2]) - 1; + if (Monsters[monsterId].hitPoints >> 6 > 0 && (Monsters[monsterId].data().selectionType & 4) != 0) { cursPosition = Point { mx, my } + Displacement { 1, 2 }; - pcursmonst = mi; + pcursmonst = monsterId; } } if (mx + 2 < MAXDUNX && my + 2 < MAXDUNY && dMonster[mx + 2][my + 2] != 0 && IsTileLit({ mx + 2, my + 2 })) { - int mi = abs(dMonster[mx + 2][my + 2]) - 1; - if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 4) != 0) { + const uint16_t monsterId = abs(dMonster[mx + 2][my + 2]) - 1; + if (Monsters[monsterId].hitPoints >> 6 > 0 && (Monsters[monsterId].data().selectionType & 4) != 0) { cursPosition = Point { mx, my } + Displacement { 2, 2 }; - pcursmonst = mi; + pcursmonst = monsterId; } } if (!flipflag && mx + 1 < MAXDUNX && dMonster[mx + 1][my] != 0 && IsTileLit({ mx + 1, my })) { - int mi = abs(dMonster[mx + 1][my]) - 1; - if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 2) != 0) { + const uint16_t monsterId = abs(dMonster[mx + 1][my]) - 1; + if (Monsters[monsterId].hitPoints >> 6 > 0 && (Monsters[monsterId].data().selectionType & 2) != 0) { cursPosition = Point { mx, my } + Displacement { 1, 0 }; - pcursmonst = mi; + pcursmonst = monsterId; } } if (flipflag && my + 1 < MAXDUNY && dMonster[mx][my + 1] != 0 && IsTileLit({ mx, my + 1 })) { - int mi = abs(dMonster[mx][my + 1]) - 1; - if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 2) != 0) { + const uint16_t monsterId = abs(dMonster[mx][my + 1]) - 1; + if (Monsters[monsterId].hitPoints >> 6 > 0 && (Monsters[monsterId].data().selectionType & 2) != 0) { cursPosition = Point { mx, my } + Displacement { 0, 1 }; - pcursmonst = mi; + pcursmonst = monsterId; } } if (dMonster[mx][my] != 0 && IsTileLit({ mx, my })) { - int mi = abs(dMonster[mx][my]) - 1; - if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 1) != 0) { + const uint16_t monsterId = abs(dMonster[mx][my]) - 1; + if (Monsters[monsterId].hitPoints >> 6 > 0 && (Monsters[monsterId].data().selectionType & 1) != 0) { cursPosition = { mx, my }; - pcursmonst = mi; + pcursmonst = monsterId; } } if (mx + 1 < MAXDUNX && my + 1 < MAXDUNY && dMonster[mx + 1][my + 1] != 0 && IsTileLit({ mx + 1, my + 1 })) { - int mi = abs(dMonster[mx + 1][my + 1]) - 1; - if (Monsters[mi].hitPoints >> 6 > 0 && (Monsters[mi].data().selectionType & 2) != 0) { + const uint16_t monsterId = abs(dMonster[mx + 1][my + 1]) - 1; + if (Monsters[monsterId].hitPoints >> 6 > 0 && (Monsters[monsterId].data().selectionType & 2) != 0) { cursPosition = Point { mx, my } + Displacement { 1, 1 }; - pcursmonst = mi; + pcursmonst = monsterId; } } if (pcursmonst != -1 && (Monsters[pcursmonst].flags & MFLAG_HIDDEN) != 0) { @@ -559,34 +559,33 @@ void CheckCursMove() if (pcursmonst == -1) { if (!flipflag && mx + 1 < MAXDUNX && dPlayer[mx + 1][my] != 0) { - int8_t bv = abs(dPlayer[mx + 1][my]) - 1; - Player &player = Players[bv]; + const uint8_t playerId = abs(dPlayer[mx + 1][my]) - 1; + Player &player = Players[playerId]; if (&player != MyPlayer && player._pHitPoints != 0) { cursPosition = Point { mx, my } + Displacement { 1, 0 }; - pcursplr = bv; + pcursplr = static_cast(playerId); } } if (flipflag && my + 1 < MAXDUNY && dPlayer[mx][my + 1] != 0) { - int8_t bv = abs(dPlayer[mx][my + 1]) - 1; - Player &player = Players[bv]; + const uint8_t playerId = abs(dPlayer[mx][my + 1]) - 1; + Player &player = Players[playerId]; if (&player != MyPlayer && player._pHitPoints != 0) { cursPosition = Point { mx, my } + Displacement { 0, 1 }; - pcursplr = bv; + pcursplr = static_cast(playerId); } } if (dPlayer[mx][my] != 0) { - int8_t bv = abs(dPlayer[mx][my]) - 1; - if (bv != MyPlayerId) { + const uint8_t playerId = abs(dPlayer[mx][my]) - 1; + if (playerId != MyPlayerId) { cursPosition = { mx, my }; - pcursplr = bv; + pcursplr = static_cast(playerId); } } if (TileContainsDeadPlayer({ mx, my })) { - for (int i = 0; i < MAX_PLRS; i++) { - const Player &player = Players[i]; + for (const Player &player : Players) { if (player.position.tile == Point { mx, my } && &player != MyPlayer) { cursPosition = { mx, my }; - pcursplr = i; + pcursplr = static_cast(player.getId()); } } } @@ -594,11 +593,10 @@ void CheckCursMove() for (int xx = -1; xx < 2; xx++) { for (int yy = -1; yy < 2; yy++) { if (TileContainsDeadPlayer({ mx + xx, my + yy })) { - for (int i = 0; i < MAX_PLRS; i++) { - const Player &player = Players[i]; + for (const Player &player : Players) { if (player.position.tile.x == mx + xx && player.position.tile.y == my + yy && &player != MyPlayer) { cursPosition = Point { mx, my } + Displacement { xx, yy }; - pcursplr = i; + pcursplr = static_cast(player.getId()); } } } @@ -606,11 +604,11 @@ void CheckCursMove() } } if (mx + 1 < MAXDUNX && my + 1 < MAXDUNY && dPlayer[mx + 1][my + 1] != 0) { - int8_t bv = abs(dPlayer[mx + 1][my + 1]) - 1; - const Player &player = Players[bv]; + const uint8_t playerId = abs(dPlayer[mx + 1][my + 1]) - 1; + const Player &player = Players[playerId]; if (&player != MyPlayer && player._pHitPoints != 0) { cursPosition = Point { mx, my } + Displacement { 1, 1 }; - pcursplr = bv; + pcursplr = static_cast(playerId); } } } @@ -645,31 +643,31 @@ void CheckCursMove() } if (pcursplr == -1 && ObjectUnderCursor == nullptr && pcursmonst == -1) { if (!flipflag && mx + 1 < MAXDUNX && dItem[mx + 1][my] > 0) { - int8_t bv = dItem[mx + 1][my] - 1; - if (Items[bv]._iSelFlag >= 2) { + const uint8_t itemId = dItem[mx + 1][my] - 1; + if (Items[itemId]._iSelFlag >= 2) { cursPosition = Point { mx, my } + Displacement { 1, 0 }; - pcursitem = bv; + pcursitem = static_cast(itemId); } } if (flipflag && my + 1 < MAXDUNY && dItem[mx][my + 1] > 0) { - int8_t bv = dItem[mx][my + 1] - 1; - if (Items[bv]._iSelFlag >= 2) { + const uint8_t itemId = dItem[mx][my + 1] - 1; + if (Items[itemId]._iSelFlag >= 2) { cursPosition = Point { mx, my } + Displacement { 0, 1 }; - pcursitem = bv; + pcursitem = static_cast(itemId); } } if (dItem[mx][my] > 0) { - int8_t bv = dItem[mx][my] - 1; - if (Items[bv]._iSelFlag == 1 || Items[bv]._iSelFlag == 3) { + const uint8_t itemId = dItem[mx][my] - 1; + if (Items[itemId]._iSelFlag == 1 || Items[itemId]._iSelFlag == 3) { cursPosition = { mx, my }; - pcursitem = bv; + pcursitem = static_cast(itemId); } } if (mx + 1 < MAXDUNX && my + 1 < MAXDUNY && dItem[mx + 1][my + 1] > 0) { - int8_t bv = dItem[mx + 1][my + 1] - 1; - if (Items[bv]._iSelFlag >= 2) { + const uint8_t itemId = dItem[mx + 1][my + 1] - 1; + if (Items[itemId]._iSelFlag >= 2) { cursPosition = Point { mx, my } + Displacement { 1, 1 }; - pcursitem = bv; + pcursitem = static_cast(itemId); } } if (pcursitem == -1) { diff --git a/Source/debug.cpp b/Source/debug.cpp index b16f2d5e8..9d79699d7 100644 --- a/Source/debug.cpp +++ b/Source/debug.cpp @@ -935,7 +935,7 @@ std::string DebugCmdQuestInfo(const string_view parameter) std::string DebugCmdPlayerInfo(const string_view parameter) { int playerId = atoi(parameter.data()); - if (playerId < 0 || playerId >= MAX_PLRS) + if (static_cast(playerId) >= Players.size()) return "My friend, we need a valid playerId."; Player &player = Players[playerId]; if (!player.plractive) diff --git a/Source/dvlnet/base.cpp b/Source/dvlnet/base.cpp index 0c05c8de1..dcd75420e 100644 --- a/Source/dvlnet/base.cpp +++ b/Source/dvlnet/base.cpp @@ -4,6 +4,8 @@ #include #include +#include "player.h" + namespace devilution { namespace net { @@ -218,7 +220,7 @@ bool base::SNetSendMessage(int playerId, void *data, unsigned int size) bool base::AllTurnsArrived() { - for (auto i = 0; i < MAX_PLRS; ++i) { + for (size_t i = 0; i < Players.size(); ++i) { PlayerState &playerState = playerStateTable_[i]; if (!playerState.isConnected) continue; @@ -237,7 +239,7 @@ bool base::SNetReceiveTurns(char **data, size_t *size, uint32_t *status) { poll(); - for (auto i = 0; i < MAX_PLRS; ++i) { + for (size_t i = 0; i < Players.size(); ++i) { status[i] = 0; PlayerState &playerState = playerStateTable_[i]; @@ -257,7 +259,7 @@ bool base::SNetReceiveTurns(char **data, size_t *size, uint32_t *status) } if (AllTurnsArrived()) { - for (auto i = 0; i < MAX_PLRS; ++i) { + for (size_t i = 0; i < Players.size(); ++i) { PlayerState &playerState = playerStateTable_[i]; if (!playerState.isConnected) continue; @@ -284,7 +286,7 @@ bool base::SNetReceiveTurns(char **data, size_t *size, uint32_t *status) return true; } - for (auto i = 0; i < MAX_PLRS; ++i) { + for (size_t i = 0; i < Players.size(); ++i) { PlayerState &playerState = playerStateTable_[i]; if (!playerState.isConnected) continue; @@ -414,7 +416,7 @@ bool base::SNetDropPlayer(int playerid, uint32_t flags) plr_t base::GetOwner() { - for (auto i = 0; i < MAX_PLRS; ++i) { + for (size_t i = 0; i < Players.size(); ++i) { if (IsConnected(i)) { return i; } diff --git a/Source/dvlnet/base_protocol.h b/Source/dvlnet/base_protocol.h index 7757ccd08..bfbe25b77 100644 --- a/Source/dvlnet/base_protocol.h +++ b/Source/dvlnet/base_protocol.h @@ -68,7 +68,7 @@ template plr_t base_protocol

::get_master() { plr_t ret = plr_self; - for (plr_t i = 0; i < MAX_PLRS; ++i) + for (plr_t i = 0; i < Players.size(); ++i) if (peers[i].endpoint) ret = std::min(ret, i); return ret; @@ -195,7 +195,7 @@ void base_protocol

::send(packet &pkt) return; SendTo(destination, pkt); } else if (destination == PLR_BROADCAST) { - for (plr_t player = 0; player < MAX_PLRS; player++) + for (plr_t player = 0; player < Players.size(); player++) SendTo(player, pkt); } else if (destination == PLR_MASTER) { throw dvlnet_exception(); @@ -236,7 +236,7 @@ void base_protocol

::recv() } } while (proto.get_disconnected(sender)) { - for (plr_t i = 0; i < MAX_PLRS; ++i) { + for (plr_t i = 0; i < Players.size(); ++i) { if (peers[i].endpoint == sender) { DisconnectNet(i); break; @@ -253,7 +253,7 @@ template void base_protocol

::handle_join_request(packet &pkt, endpoint_t sender) { plr_t i; - for (i = 0; i < MAX_PLRS; ++i) { + for (i = 0; i < Players.size(); ++i) { Peer &peer = peers[i]; if (i != plr_self && !peer.endpoint) { peer.endpoint = sender; @@ -268,7 +268,7 @@ void base_protocol

::handle_join_request(packet &pkt, endpoint_t sender) } auto senderinfo = sender.serialize(); - for (plr_t j = 0; j < MAX_PLRS; ++j) { + for (plr_t j = 0; j < Players.size(); ++j) { endpoint_t peer = peers[j].endpoint; if ((j != plr_self) && (j != i) && peer) { auto peerpkt = pktfty->make_packet(PLR_MASTER, PLR_BROADCAST, i, senderinfo); @@ -297,7 +297,7 @@ void base_protocol

::recv_decrypted(packet &pkt, endpoint_t sender) return; const GameData *gameData = (const GameData *)pkt.Info().data(); std::vector playerNames; - for (size_t i = 0; i < MAX_PLRS; i++) { + for (size_t i = 0; i < Players.size(); i++) { std::string playerName; const char *playerNamePointer = (const char *)(pkt.Info().data() + sizeof(GameData) + (i * PlayerNameLength)); playerName.append(playerNamePointer, strnlen(playerNamePointer, PlayerNameLength)); @@ -325,7 +325,7 @@ void base_protocol

::recv_ingame(packet &pkt, endpoint_t sender) buffer_t buf; buf.resize(game_init_info.size() + (PlayerNameLength * MAX_PLRS) + gamename.size()); std::memcpy(buf.data(), &game_init_info[0], game_init_info.size()); - for (size_t i = 0; i < MAX_PLRS; i++) { + for (size_t i = 0; i < Players.size(); i++) { if (Players[i].plractive) { std::memcpy(buf.data() + game_init_info.size() + (i * PlayerNameLength), &Players[i]._pName, PlayerNameLength); } else { @@ -379,7 +379,7 @@ void base_protocol

::recv_ingame(packet &pkt, endpoint_t sender) if (plr_self != PLR_BROADCAST) { if (wasBroadcast) { // Send a handshake to everyone just after PT_JOIN_ACCEPT - for (plr_t player = 0; player < MAX_PLRS; player++) + for (plr_t player = 0; player < Players.size(); player++) InitiateHandshake(player); } diff --git a/Source/dvlnet/loopback.cpp b/Source/dvlnet/loopback.cpp index df8b32518..9c4138138 100644 --- a/Source/dvlnet/loopback.cpp +++ b/Source/dvlnet/loopback.cpp @@ -1,6 +1,7 @@ #include "dvlnet/loopback.h" #include "multi.h" +#include "player.h" #include "utils/language.h" #include "utils/stubs.h" @@ -41,7 +42,7 @@ bool loopback::SNetSendMessage(int dest, void *data, unsigned int size) bool loopback::SNetReceiveTurns(char **data, size_t *size, uint32_t * /*status*/) { - for (auto i = 0; i < MAX_PLRS; ++i) { + for (size_t i = 0; i < Players.size(); ++i) { size[i] = 0; data[i] = nullptr; } diff --git a/Source/dvlnet/tcp_server.cpp b/Source/dvlnet/tcp_server.cpp index 635f26c2b..6cdb8b1ce 100644 --- a/Source/dvlnet/tcp_server.cpp +++ b/Source/dvlnet/tcp_server.cpp @@ -6,6 +6,7 @@ #include #include "dvlnet/base.h" +#include "player.h" #include "utils/log.hpp" namespace devilution { @@ -44,7 +45,7 @@ tcp_server::scc tcp_server::MakeConnection() plr_t tcp_server::NextFree() { - for (plr_t i = 0; i < MAX_PLRS; ++i) + for (plr_t i = 0; i < Players.size(); ++i) if (!connections[i]) return i; return PLR_BROADCAST; @@ -52,7 +53,7 @@ plr_t tcp_server::NextFree() bool tcp_server::Empty() { - for (plr_t i = 0; i < MAX_PLRS; ++i) + for (plr_t i = 0; i < Players.size(); ++i) if (connections[i]) return false; return true; @@ -108,7 +109,7 @@ void tcp_server::HandleReceiveNewPlayer(const scc &con, packet &pkt) if (Empty()) game_init_info = pkt.Info(); - for (plr_t player = 0; player < MAX_PLRS; player++) { + for (plr_t player = 0; player < Players.size(); player++) { if (connections[player]) { auto playerPacket = pktfty.make_packet(PLR_MASTER, PLR_BROADCAST, newplr); StartSend(connections[player], *playerPacket); @@ -135,7 +136,7 @@ void tcp_server::HandleReceivePacket(packet &pkt) void tcp_server::SendPacket(packet &pkt) { if (pkt.Destination() == PLR_BROADCAST) { - for (auto i = 0; i < MAX_PLRS; ++i) + for (size_t i = 0; i < Players.size(); ++i) if (i != pkt.Source() && connections[i]) StartSend(connections[i], pkt); } else { diff --git a/Source/engine/render/scrollrt.cpp b/Source/engine/render/scrollrt.cpp index 21eea24bd..5b10ce5bc 100644 --- a/Source/engine/render/scrollrt.cpp +++ b/Source/engine/render/scrollrt.cpp @@ -496,7 +496,7 @@ void DrawPlayer(const Surface &out, const Player &player, Point tilePosition, Po Point spriteBufferPosition = targetBufferPosition - Displacement { CalculateWidth2(sprite.width()), 0 }; - if (pcursplr >= 0 && pcursplr < MAX_PLRS && &player == &Players[pcursplr]) + if (static_cast(pcursplr) < Players.size() && &player == &Players[pcursplr]) ClxDrawOutlineSkipColorZero(out, 165, spriteBufferPosition, sprite); if (&player == MyPlayer) { @@ -799,7 +799,7 @@ void DrawDungeon(const Surface &out, Point tilePosition, Point targetBufferPosit DrawDeadPlayer(out, tilePosition, targetBufferPosition); } int8_t playerId = dPlayer[tilePosition.x][tilePosition.y]; - if (playerId > 0 && playerId <= MAX_PLRS) { + if (static_cast(playerId - 1) < Players.size()) { DrawPlayerHelper(out, Players[playerId - 1], tilePosition, targetBufferPosition); } if (dMonster[tilePosition.x][tilePosition.y] != 0) { diff --git a/Source/items.cpp b/Source/items.cpp index dc266f113..290a940c0 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -3020,7 +3020,7 @@ void GetItemAttrs(Item &item, int itemData, int lvl) void SetupItem(Item &item) { - item.setNewAnimation(MyPlayer->pLvlLoad == 0); + item.setNewAnimation(MyPlayer != nullptr && MyPlayer->pLvlLoad == 0); item._iIdentified = false; } diff --git a/Source/monster.cpp b/Source/monster.cpp index ec4303a55..6fdb5b9ca 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -624,7 +624,7 @@ void UpdateEnemy(Monster &monster) bool bestsameroom = false; const auto &position = monster.position.tile; if ((monster.flags & MFLAG_BERSERK) != 0 || (monster.flags & MFLAG_GOLEM) == 0) { - for (int pnum = 0; pnum < MAX_PLRS; pnum++) { + for (size_t pnum = 0; pnum < Players.size(); pnum++) { Player &player = Players[pnum]; if (!player.plractive || !player.isOnActiveLevel() || player._pLvlChanging || (((player._pHitPoints >> 6) == 0) && gbIsMultiplayer)) @@ -635,7 +635,7 @@ void UpdateEnemy(Monster &monster) || ((sameroom || !bestsameroom) && dist < bestDist) || (menemy == -1)) { monster.flags &= ~MFLAG_TARGETS_MONSTER; - menemy = pnum; + menemy = static_cast(pnum); target = player.position.future; bestDist = dist; bestsameroom = sameroom; diff --git a/Source/msg.cpp b/Source/msg.cpp index 3a3294e1b..5ce434791 100644 --- a/Source/msg.cpp +++ b/Source/msg.cpp @@ -237,7 +237,7 @@ void PrePacket() continue; } - if (playerId >= MAX_PLRS) { + if (playerId >= Players.size()) { Log("Missing source of network message"); return; } @@ -291,7 +291,7 @@ int WaitForTurns() if (gbGameDestroyed) return 100; - if (gbDeltaSender >= MAX_PLRS) { + if (gbDeltaSender >= Players.size()) { sgbDeltaChunks = 0; sgbRecvCmd = CMD_DLEVEL_END; gbDeltaSender = MyPlayerId; @@ -820,9 +820,9 @@ size_t OnGotoGetItem(const TCmd *pCmd, Player &player) bool IsGItemValid(const TCmdGItem &message) { - if (message.bMaster >= MAX_PLRS) + if (message.bMaster >= Players.size()) return false; - if (message.bPnum >= MAX_PLRS) + if (message.bPnum >= Players.size()) return false; if (message.bCursitem >= MAXITEMS + 1) return false; @@ -1275,7 +1275,7 @@ size_t OnAttackPlayer(const TCmd *pCmd, Player &player) { const auto &message = *reinterpret_cast(pCmd); - if (gbBufferMsgs != 1 && player.isOnActiveLevel() && message.wParam1 < MAX_PLRS) { + if (gbBufferMsgs != 1 && player.isOnActiveLevel() && message.wParam1 < Players.size()) { MakePlrPath(player, Players[message.wParam1].position.future, false); player.destAction = ACTION_ATTACKPLR; player.destParam1 = message.wParam1; @@ -1301,7 +1301,7 @@ size_t OnRangedAttackPlayer(const TCmd *pCmd, Player &player) { const auto &message = *reinterpret_cast(pCmd); - if (gbBufferMsgs != 1 && player.isOnActiveLevel() && message.wParam1 < MAX_PLRS) { + if (gbBufferMsgs != 1 && player.isOnActiveLevel() && message.wParam1 < Players.size()) { ClrPlrPath(player); player.destAction = ACTION_RATTACKPLR; player.destParam1 = message.wParam1; @@ -1354,7 +1354,7 @@ size_t OnSpellPlayer(const TCmd *pCmd, Player &player) return sizeof(message); if (!player.isOnActiveLevel()) return sizeof(message); - if (message.wParam1 >= MAX_PLRS) + if (message.wParam1 >= Players.size()) return sizeof(message); if (message.wParam2 > SPL_LAST) return sizeof(message); @@ -1422,7 +1422,7 @@ size_t OnTargetSpellPlayer(const TCmd *pCmd, Player &player) return sizeof(message); if (!player.isOnActiveLevel()) return sizeof(message); - if (message.wParam1 >= MAX_PLRS) + if (message.wParam1 >= Players.size()) return sizeof(message); if (message.wParam2 > SPL_LAST) return sizeof(message); @@ -1467,9 +1467,9 @@ size_t OnResurrect(const TCmd *pCmd, int pnum) if (gbBufferMsgs == 1) { SendPacket(pnum, &message, sizeof(message)); - } else if (message.wParam1 < MAX_PLRS) { + } else if (message.wParam1 < Players.size()) { DoResurrect(pnum, Players[message.wParam1]); - if (pnum == MyPlayerId) + if (static_cast(pnum) == MyPlayerId) pfile_update(true); } @@ -1481,7 +1481,7 @@ size_t OnHealOther(const TCmd *pCmd, const Player &caster) const auto &message = *reinterpret_cast(pCmd); if (gbBufferMsgs != 1) { - if (caster.isOnActiveLevel() && message.wParam1 < MAX_PLRS) { + if (caster.isOnActiveLevel() && message.wParam1 < Players.size()) { DoHealOther(caster, Players[message.wParam1]); } } @@ -1509,7 +1509,7 @@ size_t OnNewLevel(const TCmd *pCmd, int pnum) if (gbBufferMsgs == 1) { SendPacket(pnum, &message, sizeof(message)); - } else if (pnum != MyPlayerId) { + } else if (pnum != static_cast(MyPlayerId)) { if (message.wParam1 < WM_FIRST || message.wParam1 > WM_LAST) return sizeof(message); @@ -1963,7 +1963,7 @@ size_t OnRestartTown(const TCmd *pCmd, int pnum) if (gbBufferMsgs == 1) { SendPacket(pnum, pCmd, sizeof(*pCmd)); } else { - if (pnum == MyPlayerId) { + if (pnum == static_cast(MyPlayerId)) { MyPlayerIsDead = false; gamemenu_off(); } @@ -2058,7 +2058,7 @@ size_t OnSyncQuest(const TCmd *pCmd, int pnum) if (gbBufferMsgs == 1) { SendPacket(pnum, &message, sizeof(message)); } else { - if (pnum != MyPlayerId && message.q < MAXQUESTS && message.qstate <= QUEST_HIVE_DONE) + if (pnum != static_cast(MyPlayerId) && message.q < MAXQUESTS && message.qstate <= QUEST_HIVE_DONE) SetMultiQuest(message.q, message.qstate, message.qlog != 0, message.qvar1); sgbDeltaChanged = true; } @@ -2642,7 +2642,7 @@ void NetSendCmdGolem(uint8_t mx, uint8_t my, Direction dir, uint8_t menemy, int void NetSendCmdLoc(int playerId, bool bHiPri, _cmd_id bCmd, Point position) { - if (playerId == MyPlayerId && WasPlayerCmdAlreadyRequested(bCmd, position)) + if (playerId == static_cast(MyPlayerId) && WasPlayerCmdAlreadyRequested(bCmd, position)) return; TCmdLoc cmd; diff --git a/Source/multi.cpp b/Source/multi.cpp index c685fcc1b..8efc9da97 100644 --- a/Source/multi.cpp +++ b/Source/multi.cpp @@ -12,6 +12,7 @@ #include "DiabloUI/diabloui.h" #include "diablo.h" +#include "engine/demomode.h" #include "engine/point.hpp" #include "engine/random.hpp" #include "engine/world_tile.hpp" @@ -150,7 +151,7 @@ bool IsNetPlayerValid(const Player &player) void CheckPlayerInfoTimeouts() { - for (int i = 0; i < MAX_PLRS; i++) { + for (size_t i = 0; i < Players.size(); i++) { Player &player = Players[i]; if (&player == MyPlayer) { continue; @@ -198,11 +199,11 @@ void MonsterSeeds() Monsters[i].aiSeed = seed + i; } -void HandleTurnUpperBit(int pnum) +void HandleTurnUpperBit(size_t pnum) { - int i; + size_t i; - for (i = 0; i < MAX_PLRS; i++) { + for (i = 0; i < Players.size(); i++) { if ((player_state[i] & PS_CONNECTED) != 0 && i != pnum) break; } @@ -214,7 +215,7 @@ void HandleTurnUpperBit(int pnum) } } -void ParseTurn(int pnum, uint32_t turn) +void ParseTurn(size_t pnum, uint32_t turn) { if ((turn & 0x80000000) != 0) HandleTurnUpperBit(pnum); @@ -262,7 +263,7 @@ void PlayerLeftMsg(int pnum, bool left) void ClearPlayerLeftState() { - for (int i = 0; i < MAX_PLRS; i++) { + for (size_t i = 0; i < Players.size(); i++) { if (sgbPlayerLeftGameTbl[i]) { if (gbBufferMsgs == 1) msg_send_drop_pkt(i, sgdwPlayerLeftReasonTbl[i]); @@ -277,7 +278,7 @@ void ClearPlayerLeftState() void CheckDropPlayer() { - for (int i = 0; i < MAX_PLRS; i++) { + for (size_t i = 0; i < Players.size(); i++) { if ((player_state[i] & PS_ACTIVE) == 0 && (player_state[i] & PS_CONNECTED) != 0) { SNetDropPlayer(i, LEAVE_DROP); } @@ -411,6 +412,8 @@ void UnregisterNetEventHandlers() bool InitSingle(GameData *gameData) { + Players.resize(1); + if (!SNetInitializeProvider(SELCONN_LOOPBACK, gameData)) { return false; } @@ -431,6 +434,8 @@ bool InitSingle(GameData *gameData) bool InitMulti(GameData *gameData) { + Players.resize(MAX_PLRS); + int playerId; while (true) { @@ -445,7 +450,7 @@ bool InitMulti(GameData *gameData) gbSelectProvider = true; } - if (playerId < 0 || playerId >= MAX_PLRS) { + if (static_cast(playerId) >= Players.size()) { return false; } MyPlayerId = playerId; @@ -511,7 +516,7 @@ void multi_send_msg_packet(uint32_t pmask, const byte *data, size_t size) pkt.hdr.wLen = static_cast(len); memcpy(pkt.body, data, size); size_t playerID = 0; - for (size_t v = 1; playerID < MAX_PLRS; playerID++, v <<= 1) { + for (size_t v = 1; playerID < Players.size(); playerID++, v <<= 1) { if ((v & pmask) != 0) { if (!SNetSendMessage(playerID, &pkt.hdr, len) && SErrGetLastError() != STORM_ERROR_INVALID_PLAYER) { nthread_terminate_game("SNetSendMessage"); @@ -523,7 +528,7 @@ void multi_send_msg_packet(uint32_t pmask, const byte *data, size_t size) void multi_msg_countdown() { - for (int i = 0; i < MAX_PLRS; i++) { + for (size_t i = 0; i < Players.size(); i++) { if ((player_state[i] & PS_TURN_ARRIVED) != 0) { if (gdwMsgLenTbl[i] == sizeof(int32_t)) ParseTurn(i, *(int32_t *)glpMsgTbl[i]); @@ -551,7 +556,7 @@ bool multi_handle_delta() return false; } - for (int i = 0; i < MAX_PLRS; i++) { + for (size_t i = 0; i < Players.size(); i++) { if (sgbSendDeltaTbl[i]) { sgbSendDeltaTbl[i] = false; DeltaExportData(i); @@ -594,7 +599,7 @@ void multi_process_network_packets() ClearPlayerLeftState(); if (dwMsgSize < sizeof(TPktHdr)) continue; - if (dwID < 0 || dwID >= MAX_PLRS) + if (static_cast(dwID) >= Players.size()) continue; if (pkt->wCheck != LoadBE32("\0\0ip")) continue; @@ -655,7 +660,7 @@ void multi_process_network_packets() void multi_send_zero_packet(int pnum, _cmd_id bCmd, const byte *data, size_t size) { - assert(pnum != MyPlayerId); + assert(pnum != static_cast(MyPlayerId)); assert(data != nullptr); assert(size <= 0x0ffff); @@ -700,6 +705,10 @@ void NetClose() SNetLeaveGame(3); if (gbIsMultiplayer) SDL_Delay(2000); + if (!demo::IsRunning()) { + Players.clear(); + MyPlayer = nullptr; + } } bool NetInit(bool bSinglePlayer) @@ -712,9 +721,8 @@ bool NetInit(bool bSinglePlayer) memset(sgbPlayerLeftGameTbl, 0, sizeof(sgbPlayerLeftGameTbl)); memset(sgdwPlayerLeftReasonTbl, 0, sizeof(sgdwPlayerLeftReasonTbl)); memset(sgbSendDeltaTbl, 0, sizeof(sgbSendDeltaTbl)); - for (Player &player : Players) { - player.Reset(); - } + Players.clear(); + MyPlayer = nullptr; memset(sgwPackPlrOffsetTbl, 0, sizeof(sgwPackPlrOffsetTbl)); SNetSetBasePlayer(0); if (bSinglePlayer) { diff --git a/Source/player.cpp b/Source/player.cpp index a5eda62ea..77b26a149 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -47,9 +47,9 @@ namespace devilution { -int MyPlayerId; -Player *MyPlayer = &Players[MyPlayerId]; -Player Players[MAX_PLRS]; +size_t MyPlayerId; +Player *MyPlayer; +std::vector Players; bool MyPlayerIsDead; /** Specifies the X-coordinate delta from the player start location in Tristram. */ @@ -1933,13 +1933,6 @@ bool Player::IsWalking() const return IsAnyOf(_pmode, PM_WALK_NORTHWARDS, PM_WALK_SOUTHWARDS, PM_WALK_SIDEWAYS); } -void Player::Reset() -{ - // Create empty default initialized Player on heap to avoid excessive stack usage - auto emptyPlayer = std::make_unique(); - *this = std::move(*emptyPlayer); -} - int Player::GetManaShieldDamageReduction() { constexpr int8_t Max = 7; @@ -2421,7 +2414,7 @@ void SetPlrAnims(Player &player) */ void CreatePlayer(Player &player, HeroClass c) { - player.Reset(); + player = {}; SetRndSeed(SDL_GetTicks()); player._pClass = c; @@ -2674,7 +2667,7 @@ void AddPlrExperience(Player &player, int lvl, int exp) void AddPlrMonstExper(int lvl, int exp, char pmask) { int totplrs = 0; - for (int i = 0; i < MAX_PLRS; i++) { + for (size_t i = 0; i < Players.size(); i++) { if (((1 << i) & pmask) != 0) { totplrs++; } @@ -3165,7 +3158,7 @@ void RestartTownLvl(Player &player) } } -void StartWarpLvl(Player &player, int pidx) +void StartWarpLvl(Player &player, size_t pidx) { InitLevelChange(player); @@ -3223,7 +3216,7 @@ void ProcessPlayers() ValidatePlayer(); - for (int pnum = 0; pnum < MAX_PLRS; pnum++) { + for (size_t pnum = 0; pnum < Players.size(); pnum++) { Player &player = Players[pnum]; if (player.plractive && player.isOnActiveLevel() && (&player == MyPlayer || !player._pLvlChanging)) { CheckCheatStats(player); diff --git a/Source/player.h b/Source/player.h index c5f54323c..5ea3451e3 100644 --- a/Source/player.h +++ b/Source/player.h @@ -6,6 +6,7 @@ #pragma once #include +#include #include #include @@ -463,11 +464,6 @@ struct Player { */ bool IsWalking() const; - /** - * @brief Resets all Data of the current Player - */ - void Reset(); - /** * @brief Returns item location taking into consideration barbarian's ability to hold two-handed maces and clubs in one hand. */ @@ -745,9 +741,9 @@ struct Player { } }; -extern DVL_API_FOR_TEST int MyPlayerId; +extern DVL_API_FOR_TEST size_t MyPlayerId; extern DVL_API_FOR_TEST Player *MyPlayer; -extern DVL_API_FOR_TEST Player Players[MAX_PLRS]; +extern DVL_API_FOR_TEST std::vector Players; extern bool MyPlayerIsDead; extern const int BlockBonuses[enum_size::value]; @@ -797,7 +793,7 @@ void SyncPlrKill(Player &player, int earflag); void RemovePlrMissiles(const Player &player); void StartNewLvl(Player &player, interface_mode fom, int lvl); void RestartTownLvl(Player &player); -void StartWarpLvl(Player &player, int pidx); +void StartWarpLvl(Player &player, size_t pidx); void ProcessPlayers(); void ClrPlrPath(Player &player); bool PosOkPlayer(const Player &player, Point position); diff --git a/Source/portal.cpp b/Source/portal.cpp index 18ef3dda7..c9eaa29f7 100644 --- a/Source/portal.cpp +++ b/Source/portal.cpp @@ -19,7 +19,7 @@ Portal Portals[MAXPORTAL]; namespace { /** Current portal number (a portal array index). */ -int portalindex; +size_t portalindex; /** Coordinate of each players portal in town. */ Point WarpDrop[MAXPORTAL] = { @@ -124,7 +124,7 @@ void RemovePortalMissile(int id) }); } -void SetCurrentPortal(int p) +void SetCurrentPortal(size_t p) { portalindex = p; } diff --git a/Source/portal.h b/Source/portal.h index 449aaf47c..46f5ee1c8 100644 --- a/Source/portal.h +++ b/Source/portal.h @@ -31,7 +31,7 @@ void ActivatePortal(int i, Point position, int lvl, dungeon_type lvltype, bool s void DeactivatePortal(int i); bool PortalOnLevel(int i); void RemovePortalMissile(int id); -void SetCurrentPortal(int p); +void SetCurrentPortal(size_t p); void GetPortalLevel(); void GetPortalLvlPos(); bool PosOkPortal(int lvl, int x, int y); diff --git a/Source/qol/monhealthbar.cpp b/Source/qol/monhealthbar.cpp index cfd28992a..29723e6ee 100644 --- a/Source/qol/monhealthbar.cpp +++ b/Source/qol/monhealthbar.cpp @@ -155,7 +155,7 @@ void DrawMonsterHealthBar(const Surface &out) } int tagOffset = 5; - for (size_t i = 0; i < MAX_PLRS; i++) { + for (size_t i = 0; i < Players.size(); i++) { if (((1U << i) & monster.whoHit) != 0) { RenderClxSprite(out, (*playerExpTags)[i + 1], position + Displacement { tagOffset, height - 31 }); } else if (Players[i].plractive) { diff --git a/Source/spells.cpp b/Source/spells.cpp index 4ba2f271e..29c32769b 100644 --- a/Source/spells.cpp +++ b/Source/spells.cpp @@ -252,8 +252,12 @@ void CastSpell(int id, spell_id spl, int sx, int sy, int dx, int dy, int spllvl) } } -void DoResurrect(int pnum, Player &target) +void DoResurrect(size_t pnum, Player &target) { + if (pnum >= Players.size()) { + return; + } + AddMissile(target.position.tile, target.position.tile, Direction::South, MIS_RESURRECTBEAM, TARGET_MONSTERS, pnum, 0, 0); if (target._pHitPoints != 0) diff --git a/Source/spells.h b/Source/spells.h index 1eef1c264..2c34d5768 100644 --- a/Source/spells.h +++ b/Source/spells.h @@ -37,7 +37,7 @@ void CastSpell(int id, spell_id spl, int sx, int sy, int dx, int dy, int spllvl) * @param pnum player index * @param rid target player index */ -void DoResurrect(int pnum, Player &target); +void DoResurrect(size_t pnum, Player &target); void DoHealOther(const Player &caster, Player &target); int GetSpellBookLevel(spell_id s); int GetSpellStaffLevel(spell_id s); diff --git a/Source/sync.cpp b/Source/sync.cpp index 37b551e29..e69af6b01 100644 --- a/Source/sync.cpp +++ b/Source/sync.cpp @@ -295,7 +295,7 @@ uint32_t OnSyncData(const TCmd *pCmd, int pnum) if (gbBufferMsgs == 1) { return header.wLen + sizeof(header); } - if (pnum == MyPlayerId) { + if (pnum == static_cast(MyPlayerId)) { return header.wLen + sizeof(header); } @@ -312,7 +312,7 @@ uint32_t OnSyncData(const TCmd *pCmd, int pnum) continue; if (GetLevelForMultiplayer(*MyPlayer) == level) { - SyncMonster(pnum > MyPlayerId, monsterSyncs[i]); + SyncMonster(pnum > static_cast(MyPlayerId), monsterSyncs[i]); } delta_sync_monster(monsterSyncs[i], level); diff --git a/Source/towners.cpp b/Source/towners.cpp index ba57b3fd8..e152e2e59 100644 --- a/Source/towners.cpp +++ b/Source/towners.cpp @@ -810,7 +810,7 @@ bool IsTownerPresent(_talker_id npc) case TOWN_COWFARM: return gbIsHellfire && sgGameInitInfo.bCowQuest != 0; case TOWN_GIRL: - return gbIsHellfire && sgGameInitInfo.bTheoQuest != 0 && Players->_pLvlVisited[17] && Quests[Q_GIRL]._qactive != QUEST_DONE; + return gbIsHellfire && sgGameInitInfo.bTheoQuest != 0 && MyPlayer->_pLvlVisited[17] && Quests[Q_GIRL]._qactive != QUEST_DONE; default: return true; } diff --git a/test/drlg_l1_test.cpp b/test/drlg_l1_test.cpp index ef7e026e1..bed42c82d 100644 --- a/test/drlg_l1_test.cpp +++ b/test/drlg_l1_test.cpp @@ -12,6 +12,8 @@ TEST(Drlg_l1, CreateL5Dungeon_diablo_1_2588) { LoadExpectedLevelData("diablo/1-2588.dun"); + Players.resize(1); + MyPlayer = &Players[0]; MyPlayer->pOriginalCathedral = true; TestCreateDungeon(1, 2588, ENTRY_MAIN); @@ -24,6 +26,8 @@ TEST(Drlg_l1, CreateL5Dungeon_diablo_1_743271966) { LoadExpectedLevelData("diablo/1-743271966.dun"); + Players.resize(1); + MyPlayer = &Players[0]; MyPlayer->pOriginalCathedral = true; TestCreateDungeon(1, 743271966, ENTRY_MAIN); @@ -36,6 +40,8 @@ TEST(Drlg_l1, CreateL5Dungeon_diablo_2_1383137027) { LoadExpectedLevelData("diablo/2-1383137027.dun"); + Players.resize(1); + MyPlayer = &Players[0]; MyPlayer->pOriginalCathedral = true; InitQuests(); @@ -54,6 +60,8 @@ TEST(Drlg_l1, CreateL5Dungeon_diablo_3_844660068) { LoadExpectedLevelData("diablo/3-844660068.dun"); + Players.resize(1); + MyPlayer = &Players[0]; MyPlayer->pOriginalCathedral = true; Quests[Q_SKELKING]._qactive = QUEST_NOTAVAIL; @@ -67,6 +75,8 @@ TEST(Drlg_l1, CreateL5Dungeon_diablo_4_609325643) { LoadExpectedLevelData("diablo/4-609325643.dun"); + Players.resize(1); + MyPlayer = &Players[0]; MyPlayer->pOriginalCathedral = true; Quests[Q_LTBANNER]._qactive = QUEST_NOTAVAIL; @@ -80,6 +90,8 @@ TEST(Drlg_l1, CreateL5Dungeon_hellfire_1_401921334) { LoadExpectedLevelData("hellfire/1-401921334.dun"); + Players.resize(1); + MyPlayer = &Players[0]; MyPlayer->pOriginalCathedral = false; TestCreateDungeon(1, 401921334, ENTRY_MAIN); @@ -92,6 +104,8 @@ TEST(Drlg_l1, CreateL5Dungeon_hellfire_1_536340718) { LoadExpectedLevelData("hellfire/1-536340718.dun"); + Players.resize(1); + MyPlayer = &Players[0]; MyPlayer->pOriginalCathedral = false; TestCreateDungeon(1, 536340718, ENTRY_MAIN); @@ -104,6 +118,8 @@ TEST(Drlg_l1, CreateL5Dungeon_hellfire_2_128964898) { LoadExpectedLevelData("hellfire/2-128964898.dun"); + Players.resize(1); + MyPlayer = &Players[0]; MyPlayer->pOriginalCathedral = false; InitQuests(); Quests[Q_PWATER]._qactive = QUEST_NOTAVAIL; @@ -119,6 +135,8 @@ TEST(Drlg_l1, CreateL5Dungeon_hellfire_2_1180526547) { LoadExpectedLevelData("hellfire/2-1180526547.dun"); + Players.resize(1); + MyPlayer = &Players[0]; MyPlayer->pOriginalCathedral = false; InitQuests(); Quests[Q_PWATER]._qactive = QUEST_NOTAVAIL; @@ -134,6 +152,8 @@ TEST(Drlg_l1, CreateL5Dungeon_hellfire_3_1799396623) { LoadExpectedLevelData("hellfire/3-1799396623.dun"); + Players.resize(1); + MyPlayer = &Players[0]; MyPlayer->pOriginalCathedral = false; InitQuests(); Quests[Q_SKELKING]._qactive = QUEST_NOTAVAIL; @@ -148,6 +168,8 @@ TEST(Drlg_l1, CreateL5Dungeon_hellfire_3_1512491184) { LoadExpectedLevelData("hellfire/3-1512491184.dun"); + Players.resize(1); + MyPlayer = &Players[0]; MyPlayer->pOriginalCathedral = false; InitQuests(); Quests[Q_SKELKING]._qactive = QUEST_INIT; @@ -162,6 +184,8 @@ TEST(Drlg_l1, CreateL5Dungeon_hellfire_4_1190318991) { LoadExpectedLevelData("hellfire/4-1190318991.dun"); + Players.resize(1); + MyPlayer = &Players[0]; MyPlayer->pOriginalCathedral = false; InitQuests(); Quests[Q_LTBANNER]._qactive = QUEST_NOTAVAIL; @@ -176,6 +200,8 @@ TEST(Drlg_l1, CreateL5Dungeon_hellfire_4_1924296259) { LoadExpectedLevelData("hellfire/4-1924296259.dun"); + Players.resize(1); + MyPlayer = &Players[0]; MyPlayer->pOriginalCathedral = false; InitQuests(); Quests[Q_LTBANNER]._qactive = QUEST_INIT; diff --git a/test/effects_test.cpp b/test/effects_test.cpp index 4b3e0bf31..36a576e62 100644 --- a/test/effects_test.cpp +++ b/test/effects_test.cpp @@ -7,6 +7,8 @@ using namespace devilution; TEST(Effects, CalculateSoundPosition_center) { + Players.resize(1); + MyPlayer = &Players[0]; MyPlayer->position.tile = { 50, 50 }; int plVolume = 0; int plPan = 0; @@ -17,6 +19,8 @@ TEST(Effects, CalculateSoundPosition_center) TEST(Effects, CalculateSoundPosition_near) { + Players.resize(1); + MyPlayer = &Players[0]; MyPlayer->position.tile = { 50, 50 }; int plVolume = 0; int plPan = 0; @@ -27,6 +31,8 @@ TEST(Effects, CalculateSoundPosition_near) TEST(Effects, CalculateSoundPosition_out_of_range) { + Players.resize(1); + MyPlayer = &Players[0]; MyPlayer->position.tile = { 12, 12 }; int plVolume = 1234; int plPan = 0; @@ -37,6 +43,8 @@ TEST(Effects, CalculateSoundPosition_out_of_range) TEST(Effects, CalculateSoundPosition_extreme_right) { + Players.resize(1); + MyPlayer = &Players[0]; MyPlayer->position.tile = { 50, 50 }; int plVolume = 0; int plPan = 0; @@ -47,6 +55,8 @@ TEST(Effects, CalculateSoundPosition_extreme_right) TEST(Effects, CalculateSoundPosition_extreme_left) { + Players.resize(1); + MyPlayer = &Players[0]; MyPlayer->position.tile = { 50, 50 }; int plVolume = 0; int plPan = 0; diff --git a/test/inv_test.cpp b/test/inv_test.cpp index d764ed974..ee9a0ee80 100644 --- a/test/inv_test.cpp +++ b/test/inv_test.cpp @@ -5,7 +5,17 @@ #include "player.h" #include "storm/storm_net.hpp" -using namespace devilution; +namespace devilution { +namespace { + +class InvTest : public ::testing::Test { +public: + void SetUp() override + { + Players.resize(1); + MyPlayer = &Players[0]; + } +}; /* Set up a given item as a spell scroll, allowing for its usage. */ void set_up_scroll(Item &item, spell_id spell) @@ -29,7 +39,7 @@ void clear_inventory() } // Test that the scroll is used in the inventory in correct conditions -TEST(Inv, UseScroll_from_inventory) +TEST_F(InvTest, UseScroll_from_inventory) { set_up_scroll(MyPlayer->InvList[2], SPL_FIREBOLT); MyPlayer->_pNumInv = 5; @@ -37,14 +47,14 @@ TEST(Inv, UseScroll_from_inventory) } // Test that the scroll is used in the belt in correct conditions -TEST(Inv, UseScroll_from_belt) +TEST_F(InvTest, UseScroll_from_belt) { set_up_scroll(MyPlayer->SpdList[2], SPL_FIREBOLT); EXPECT_TRUE(CanUseScroll(*MyPlayer, SPL_FIREBOLT)); } // Test that the scroll is not used in the inventory for each invalid condition -TEST(Inv, UseScroll_from_inventory_invalid_conditions) +TEST_F(InvTest, UseScroll_from_inventory_invalid_conditions) { // Empty the belt to prevent using a scroll from the belt for (int i = 0; i < MaxBeltItems; i++) { @@ -72,7 +82,7 @@ TEST(Inv, UseScroll_from_inventory_invalid_conditions) } // Test that the scroll is not used in the belt for each invalid condition -TEST(Inv, UseScroll_from_belt_invalid_conditions) +TEST_F(InvTest, UseScroll_from_belt_invalid_conditions) { // Disable the inventory to prevent using a scroll from the inventory MyPlayer->_pNumInv = 0; @@ -95,7 +105,7 @@ TEST(Inv, UseScroll_from_belt_invalid_conditions) } // Test gold calculation -TEST(Inv, CalculateGold) +TEST_F(InvTest, CalculateGold) { MyPlayer->_pNumInv = 10; // Set up 4 slots of gold in the inventory @@ -113,7 +123,7 @@ TEST(Inv, CalculateGold) } // Test automatic gold placing -TEST(Inv, GoldAutoPlace) +TEST_F(InvTest, GoldAutoPlace) { // Empty the inventory clear_inventory(); @@ -135,7 +145,7 @@ TEST(Inv, GoldAutoPlace) } // Test removing an item from inventory with no other items. -TEST(Inv, RemoveInvItem) +TEST_F(InvTest, RemoveInvItem) { SNetInitializeProvider(SELCONN_LOOPBACK, nullptr); @@ -154,7 +164,7 @@ TEST(Inv, RemoveInvItem) } // Test removing an item from inventory with other items in it. -TEST(Inv, RemoveInvItem_other_item) +TEST_F(InvTest, RemoveInvItem_other_item) { SNetInitializeProvider(SELCONN_LOOPBACK, nullptr); @@ -178,7 +188,7 @@ TEST(Inv, RemoveInvItem_other_item) } // Test removing an item from the belt -TEST(Inv, RemoveSpdBarItem) +TEST_F(InvTest, RemoveSpdBarItem) { SNetInitializeProvider(SELCONN_LOOPBACK, nullptr); @@ -194,7 +204,7 @@ TEST(Inv, RemoveSpdBarItem) } // Test removing a scroll from the inventory -TEST(Inv, RemoveCurrentSpellScroll_inventory) +TEST_F(InvTest, RemoveCurrentSpellScroll_inventory) { clear_inventory(); @@ -211,7 +221,7 @@ TEST(Inv, RemoveCurrentSpellScroll_inventory) } // Test removing a scroll from the belt -TEST(Inv, RemoveCurrentSpellScroll_belt) +TEST_F(InvTest, RemoveCurrentSpellScroll_belt) { SNetInitializeProvider(SELCONN_LOOPBACK, nullptr); @@ -229,7 +239,7 @@ TEST(Inv, RemoveCurrentSpellScroll_belt) EXPECT_TRUE(MyPlayer->SpdList[3].isEmpty()); } -TEST(Inv, ItemSize) +TEST_F(InvTest, ItemSize) { Item testItem {}; @@ -250,3 +260,6 @@ TEST(Inv, ItemSize) InitializeItem(testItem, IDI_GOLD); EXPECT_EQ(GetInventorySize(testItem), Size(1, 1)); } + +} // namespace +} // namespace devilution diff --git a/test/missiles_test.cpp b/test/missiles_test.cpp index afbea3652..36d564811 100644 --- a/test/missiles_test.cpp +++ b/test/missiles_test.cpp @@ -7,6 +7,11 @@ using namespace devilution; TEST(Missiles, RotateBlockedMissileArrow) { + Players.resize(1); + MyPlayerId = 0; + MyPlayer = &Players[MyPlayerId]; + *MyPlayer = {}; + Player &player = Players[0]; // missile can be a copy or a reference, there's no nullptr check and the functions that use it don't expect the instance to be part of a global structure so it doesn't really matter for this use. Missile missile = *AddMissile({ 0, 0 }, { 0, 0 }, Direction::South, MIS_ARROW, TARGET_MONSTERS, player.getId(), 0, 0); diff --git a/test/pack_test.cpp b/test/pack_test.cpp index 72834d4f5..4c5ba7ca0 100644 --- a/test/pack_test.cpp +++ b/test/pack_test.cpp @@ -332,7 +332,16 @@ const TestItemStruct DiabloItems[] = { // clang-format on }; -TEST(PackTest, UnPackItem_diablo) +class PackTest : public ::testing::Test { +public: + void SetUp() override + { + Players.resize(1); + MyPlayer = &Players[0]; + } +}; + +TEST_F(PackTest, UnPackItem_diablo) { Item id; ItemPack is; @@ -353,7 +362,7 @@ TEST(PackTest, UnPackItem_diablo) } } -TEST(PackTest, UnPackItem_diablo_unique_bug) +TEST_F(PackTest, UnPackItem_diablo_unique_bug) { ItemPack pkItemBug = { 6, 911, 14, 5, 60, 60, 0, 0, 0, 0 }; // Veil of Steel - with morph bug ItemPack pkItem = { 6, 655, 14, 5, 60, 60, 0, 0, 0, 0 }; // Veil of Steel - fixed @@ -403,7 +412,7 @@ const TestItemStruct SpawnItems[] = { // clang-format on }; -TEST(PackTest, UnPackItem_spawn) +TEST_F(PackTest, UnPackItem_spawn) { Item id; ItemPack is; @@ -447,7 +456,7 @@ const TestItemStruct DiabloMPItems[] = { // clang-format on }; -TEST(PackTest, UnPackItem_diablo_multiplayer) +TEST_F(PackTest, UnPackItem_diablo_multiplayer) { Item id; ItemPack is; @@ -660,7 +669,7 @@ const TestItemStruct HellfireItems[] = { // clang-format on }; -TEST(PackTest, UnPackItem_hellfire) +TEST_F(PackTest, UnPackItem_hellfire) { Item id; ItemPack is; @@ -682,7 +691,7 @@ TEST(PackTest, UnPackItem_hellfire) } } -TEST(PackTest, UnPackItem_diablo_strip_hellfire_items) +TEST_F(PackTest, UnPackItem_diablo_strip_hellfire_items) { ItemPack is = { 1478792102, 259, 92, 0, 0, 0, 0, 0, 0, 0 }; // Scroll of Search Item id; @@ -696,7 +705,7 @@ TEST(PackTest, UnPackItem_diablo_strip_hellfire_items) ASSERT_EQ(id._itype, ItemType::None); } -TEST(PackTest, UnPackItem_empty) +TEST_F(PackTest, UnPackItem_empty) { ItemPack is = { 0, 0, 0xFFFF, 0, 0, 0, 0, 0, 0, 0 }; Item id; @@ -706,7 +715,7 @@ TEST(PackTest, UnPackItem_empty) ASSERT_EQ(id._itype, ItemType::None); } -TEST(PackTest, PackItem_empty) +TEST_F(PackTest, PackItem_empty) { ItemPack is; Item id = {}; @@ -737,25 +746,25 @@ static void compareGold(const ItemPack &is, int iCurs) ComparePackedItems(is, is2); } -TEST(PackTest, UnPackItem_gold_small) +TEST_F(PackTest, UnPackItem_gold_small) { ItemPack is = { 0, 0, IDI_GOLD, 0, 0, 0, 0, 0, 1000, 0 }; compareGold(is, ICURS_GOLD_SMALL); } -TEST(PackTest, UnPackItem_gold_medium) +TEST_F(PackTest, UnPackItem_gold_medium) { ItemPack is = { 0, 0, IDI_GOLD, 0, 0, 0, 0, 0, 1001, 0 }; compareGold(is, ICURS_GOLD_MEDIUM); } -TEST(PackTest, UnPackItem_gold_large) +TEST_F(PackTest, UnPackItem_gold_large) { ItemPack is = { 0, 0, IDI_GOLD, 0, 0, 0, 0, 0, 2500, 0 }; compareGold(is, ICURS_GOLD_LARGE); } -TEST(PackTest, UnPackItem_ear) +TEST_F(PackTest, UnPackItem_ear) { ItemPack is = { 1633955154, 17509, 23, 111, 103, 117, 101, 68, 19843, 0 }; Item id; diff --git a/test/path_test.cpp b/test/path_test.cpp index 43eb37f7e..3ddffdd4d 100644 --- a/test/path_test.cpp +++ b/test/path_test.cpp @@ -110,7 +110,7 @@ void CheckPath(Point startPosition, Point destinationPosition, std::vector