diff --git a/Source/automap.cpp b/Source/automap.cpp index 0a62da1d9..edcd3b0ee 100644 --- a/Source/automap.cpp +++ b/Source/automap.cpp @@ -735,7 +735,7 @@ void DrawAutomap(const Surface &out) screen.y += AmLine32; } - 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 6aa458a41..20c84b02d 100644 --- a/Source/control.cpp +++ b/Source/control.cpp @@ -329,7 +329,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; } @@ -1151,7 +1151,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; @@ -1219,13 +1219,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 9973a9a39..1f93dcd5d 100644 --- a/Source/controls/plrctrls.cpp +++ b/Source/controls/plrctrls.cpp @@ -370,7 +370,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 853c3e5e3..6212340ff 100644 --- a/Source/cursor.cpp +++ b/Source/cursor.cpp @@ -404,52 +404,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) { @@ -464,52 +464,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) { @@ -540,34 +540,34 @@ 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 (size_t playerId = 0; playerId < Players.size(); ++playerId) { + const Player &player = Players[playerId]; if (player.position.tile == Point { mx, my } && &player != MyPlayer) { cursPosition = { mx, my }; - pcursplr = i; + pcursplr = static_cast(playerId); } } } @@ -575,11 +575,11 @@ 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 (size_t playerId = 0; playerId < Players.size(); ++playerId) { + const Player &player = Players[playerId]; 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(playerId); } } } @@ -587,11 +587,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); } } } @@ -621,36 +621,36 @@ void CheckCursMove() if (object != nullptr) { // found object that can be activated with the given cursor position cursPosition = testPosition; - pcursobj = object->GetId(); + pcursobj = static_cast(object->GetId()); } } if (pcursplr == -1 && pcursobj == -1 && 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 3322a3321..8bf27a060 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 5a9da6826..439b61fba 100644 --- a/Source/engine/render/scrollrt.cpp +++ b/Source/engine/render/scrollrt.cpp @@ -545,7 +545,7 @@ void DrawPlayer(const Surface &out, const Player &player, Point tilePosition, Po return; } - if (pcursplr >= 0 && pcursplr < MAX_PLRS && &player == &Players[pcursplr]) + if (pcursplr >= 0 && static_cast(pcursplr) < Players.size() && &player == &Players[pcursplr]) Cl2DrawOutline(out, 165, spriteBufferPosition.x, spriteBufferPosition.y, *sprite, nCel); if (&player == MyPlayer) { @@ -867,7 +867,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 49545adb5..9af550c5f 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -2989,7 +2989,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/missiles.cpp b/Source/missiles.cpp index 061ff2e37..6fb4347c7 100644 --- a/Source/missiles.cpp +++ b/Source/missiles.cpp @@ -1035,7 +1035,7 @@ void InitMissiles() if (myPlayer._pInfraFlag) { for (auto &missile : Missiles) { if (missile._mitype == MIS_INFRA) { - if (missile._misource == MyPlayerId) + if (missile._misource == static_cast(MyPlayerId)) CalcPlrItemVals(myPlayer, true); } } @@ -1046,7 +1046,7 @@ void InitMissiles() myPlayer._pSpellFlags &= ~SpellFlag::RageCooldown; for (auto &missile : Missiles) { if (missile._mitype == MIS_BLODBOIL) { - if (missile._misource == MyPlayerId) { + if (missile._misource == static_cast(MyPlayerId)) { int missingHP = myPlayer._pMaxHP - myPlayer._pHitPoints; CalcPlrItemVals(myPlayer, true); ApplyPlrDamage(myPlayer, 0, 1, missingHP + missile.var2); @@ -1872,7 +1872,7 @@ void AddTown(Missile &missile, const AddMissileParameter ¶meter) other._mirange = 0; } PutMissile(missile); - if (missile._misource == MyPlayerId && !missile._miDelFlag && leveltype != DTYPE_TOWN) { + if (missile._misource == static_cast(MyPlayerId) && !missile._miDelFlag && leveltype != DTYPE_TOWN) { if (!setlevel) { NetSendCmdLocParam3(true, CMD_ACTIVATEPORTAL, missile.position.tile, currlevel, leveltype, 0); } else { diff --git a/Source/monster.cpp b/Source/monster.cpp index 6a7ce9df7..7d235b89d 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -701,7 +701,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)) @@ -712,7 +712,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; @@ -3682,7 +3682,7 @@ void WeakenNaKrul() void InitGolems() { if (!setlevel) { - for (int i = 0; i < MAX_PLRS; i++) + for (size_t i = 0; i < MAX_PLRS; i++) AddMonster(GolemHoldingCell, Direction::South, 0, false); } } @@ -3750,7 +3750,7 @@ void SetMapMonsters(const uint16_t *dunData, Point startPosition) { AddMonsterType(MT_GOLEM, PLACE_SPECIAL); if (setlevel) - for (int i = 0; i < MAX_PLRS; i++) + for (size_t i = 0; i < MAX_PLRS; i++) AddMonster(GolemHoldingCell, Direction::South, 0, false); if (setlevel && setlvlnum == SL_VILEBETRAYER) { @@ -4140,7 +4140,7 @@ void GolumAi(int monsterId) void DeleteMonsterList() { - for (int i = 0; i < MAX_PLRS; i++) { + for (size_t i = 0; i < Players.size(); i++) { auto &golem = Monsters[i]; if (!golem.isInvalid) continue; diff --git a/Source/msg.cpp b/Source/msg.cpp index b1440f631..a453e1c09 100644 --- a/Source/msg.cpp +++ b/Source/msg.cpp @@ -235,7 +235,7 @@ void PrePacket() continue; } - if (playerId >= MAX_PLRS) { + if (playerId >= Players.size()) { Log("Missing source of network message"); return; } @@ -289,7 +289,7 @@ int WaitForTurns() if (gbGameDestroyed) return 100; - if (gbDeltaSender >= MAX_PLRS) { + if (gbDeltaSender >= Players.size()) { sgbDeltaChunks = 0; sgbRecvCmd = CMD_DLEVEL_END; gbDeltaSender = MyPlayerId; @@ -798,9 +798,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; @@ -1274,7 +1274,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; @@ -1300,7 +1300,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; @@ -1353,7 +1353,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); @@ -1421,7 +1421,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); @@ -1464,7 +1464,7 @@ 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, message.wParam1); if (pnum == MyPlayerId) pfile_update(true); @@ -1478,7 +1478,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]); } } @@ -1506,7 +1506,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); @@ -1712,7 +1712,7 @@ size_t OnPlayerOperateObject(const TCmd *pCmd, int pnum) if (gbBufferMsgs == 1) { SendPacket(pnum, &message, sizeof(message)); - } else if (message.wParam1 < MAX_PLRS && message.wParam2 < MAXOBJECTS) { + } else if (message.wParam1 < Players.size() && message.wParam2 < MAXOBJECTS) { Player &player = Players[pnum]; if (player.isOnActiveLevel()) SyncOpObject(message.wParam1, CMD_PLROPOBJ, message.wParam2); @@ -1943,7 +1943,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(); } @@ -2038,7 +2038,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; } @@ -2609,7 +2609,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 831757e92..4581c9094 100644 --- a/Source/multi.cpp +++ b/Source/multi.cpp @@ -150,7 +150,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; @@ -200,16 +200,16 @@ void MonsterSeeds() void HandleTurnUpperBit(int pnum) { - int i; + size_t i; - for (i = 0; i < MAX_PLRS; i++) { - if ((player_state[i] & PS_CONNECTED) != 0 && i != pnum) + for (i = 0; i < Players.size(); i++) { + if ((player_state[i] & PS_CONNECTED) != 0 && i != static_cast(pnum)) break; } if (MyPlayerId == i) { sgbSendDeltaTbl[pnum] = true; - } else if (pnum == MyPlayerId) { + } else if (pnum == static_cast(MyPlayerId)) { gbDeltaSender = i; } } @@ -262,7 +262,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 +277,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); } @@ -415,6 +415,8 @@ void UnregisterNetEventHandlers() bool InitSingle(GameData *gameData) { + Players.emplace_back(); + if (!SNetInitializeProvider(SELCONN_LOOPBACK, gameData)) { return false; } @@ -435,6 +437,8 @@ bool InitSingle(GameData *gameData) bool InitMulti(GameData *gameData) { + Players.resize(MAX_PLRS); + int playerId; while (true) { @@ -449,7 +453,7 @@ bool InitMulti(GameData *gameData) gbSelectProvider = true; } - if (playerId < 0 || playerId >= MAX_PLRS) { + if (static_cast(playerId) >= Players.size()) { return false; } MyPlayerId = playerId; @@ -515,7 +519,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"); @@ -527,10 +531,10 @@ 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]); + ParseTurn(static_cast(i), *(int32_t *)glpMsgTbl[i]); } } } @@ -555,7 +559,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); @@ -598,7 +602,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; @@ -659,7 +663,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); @@ -705,6 +709,8 @@ void NetClose() SNetLeaveGame(3); if (gbIsMultiplayer) SDL_Delay(2000); + Players.clear(); + MyPlayer = nullptr; } bool NetInit(bool bSinglePlayer) @@ -717,9 +723,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/objects.cpp b/Source/objects.cpp index 6fc55865e..b6a77651f 100644 --- a/Source/objects.cpp +++ b/Source/objects.cpp @@ -1349,16 +1349,14 @@ void UpdateObjectLight(Object &light, int lightRadius) bool turnon = false; int ox = light.position.x; int oy = light.position.y; - int tr = lightRadius + 10; + const int tr = lightRadius + 10; if (!DisableLighting) { - for (int p = 0; p < MAX_PLRS && !turnon; p++) { - if (Players[p].plractive) { - if (Players[p].isOnActiveLevel()) { - int dx = abs(Players[p].position.tile.x - ox); - int dy = abs(Players[p].position.tile.y - oy); - if (dx < tr && dy < tr) - turnon = true; - } + for (const Player &player : Players) { + if (player.plractive && player.isOnActiveLevel() + && abs(player.position.tile.x - ox) < tr + && abs(player.position.tile.y - oy) < tr) { + turnon = true; + break; } } } diff --git a/Source/player.cpp b/Source/player.cpp index 2cff03367..7b0cfabf4 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -44,9 +44,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. */ @@ -635,7 +635,7 @@ void InitLevelChange(Player &player) */ bool DoWalk(int pnum, int variant) { - if (pnum < 0 || pnum >= MAX_PLRS) { + if (static_cast(pnum) >= Players.size()) { app_fatal(StrCat("PM_DoWalk: illegal player ", pnum)); } Player &player = Players[pnum]; @@ -1037,7 +1037,7 @@ bool PlrHitObj(const Player &player, Object &targetObject) bool DoAttack(int pnum) { - if (pnum < 0 || pnum >= MAX_PLRS) { + if (static_cast(pnum) >= Players.size()) { app_fatal(StrCat("PM_DoAttack: illegal player ", pnum)); } Player &player = Players[pnum]; @@ -1372,7 +1372,7 @@ void TryDisarm(const Player &player, Object &object) void CheckNewPath(int pnum, bool pmWillBeCalled) { - if (pnum < 0 || pnum >= MAX_PLRS) { + if (static_cast(pnum) >= Players.size()) { app_fatal(StrCat("CheckNewPath: illegal player ", pnum)); } Player &player = Players[pnum]; @@ -1948,13 +1948,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; @@ -2434,7 +2427,7 @@ void SetPlrAnims(Player &player) */ void CreatePlayer(Player &player, HeroClass c) { - player.Reset(); + player = {}; SetRndSeed(SDL_GetTicks()); player._pClass = c; @@ -2687,7 +2680,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++; } @@ -3236,7 +3229,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 484f39e95..6e6456b54 100644 --- a/Source/player.h +++ b/Source/player.h @@ -6,6 +6,7 @@ #pragma once #include +#include #include #include @@ -459,11 +460,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. */ @@ -737,9 +733,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]; diff --git a/Source/portal.cpp b/Source/portal.cpp index 18ef3dda7..aac1ff4c6 100644 --- a/Source/portal.cpp +++ b/Source/portal.cpp @@ -152,7 +152,7 @@ void GetPortalLevel() leveltype = Portals[portalindex].ltype; } - if (portalindex == MyPlayerId) { + if (portalindex == static_cast(MyPlayerId)) { NetSendCmd(true, CMD_DEACTIVATEPORTAL); DeactivatePortal(portalindex); } @@ -165,7 +165,7 @@ void GetPortalLvlPos() } else { ViewPosition = Portals[portalindex].position; - if (portalindex != MyPlayerId) { + if (portalindex != static_cast(MyPlayerId)) { ViewPosition.x++; ViewPosition.y++; } diff --git a/Source/qol/monhealthbar.cpp b/Source/qol/monhealthbar.cpp index e21a97524..dfd1a7b3e 100644 --- a/Source/qol/monhealthbar.cpp +++ b/Source/qol/monhealthbar.cpp @@ -161,7 +161,7 @@ void DrawMonsterHealthBar(const Surface &out) } int tagOffset = 5; - for (int i = 0; i < MAX_PLRS; i++) { + for (size_t i = 0; i < Players.size(); i++) { if (1 << i & monster.whoHit) { DrawArt(out, position + Displacement { tagOffset, height - 31 }, &playerExpTags, i + 1); } else if (Players[i].plractive) { diff --git a/Source/spells.cpp b/Source/spells.cpp index 1cd52c5f8..39b89a992 100644 --- a/Source/spells.cpp +++ b/Source/spells.cpp @@ -259,7 +259,7 @@ void CastSpell(int id, spell_id spl, int sx, int sy, int dx, int dy, int spllvl) void DoResurrect(int pnum, uint16_t rid) { - if ((pnum < 0 && pnum >= MAX_PLRS) || rid >= MAX_PLRS) { + if (static_cast(pnum) >= Players.size() || rid >= Players.size()) { return; } 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 00ad41e4b..c5a9d86c1 100644 --- a/Source/towners.cpp +++ b/Source/towners.cpp @@ -808,7 +808,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 ca60c8993..76f344fa5 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 d2a9a42a0..7b68e7ae9 100644 --- a/test/inv_test.cpp +++ b/test/inv_test.cpp @@ -4,7 +4,17 @@ #include "inv.h" #include "player.h" -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) @@ -28,7 +38,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; @@ -36,14 +46,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(UseScroll(MyPlayer->_pRSpell)); } // 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; @@ -99,7 +109,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 @@ -117,7 +127,7 @@ TEST(Inv, CalculateGold) } // Test automatic gold placing -TEST(Inv, GoldAutoPlace) +TEST_F(InvTest, GoldAutoPlace) { // Empty the inventory clear_inventory(); @@ -139,7 +149,7 @@ TEST(Inv, GoldAutoPlace) } // Test removing an item from inventory with no other items. -TEST(Inv, RemoveInvItem) +TEST_F(InvTest, RemoveInvItem) { clear_inventory(); // Put a two-slot misc item into the inventory: @@ -156,7 +166,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) { clear_inventory(); // Put a two-slot misc item and a ring into the inventory: @@ -178,7 +188,7 @@ TEST(Inv, RemoveInvItem_other_item) } // Test removing an item from the belt -TEST(Inv, RemoveSpdBarItem) +TEST_F(InvTest, RemoveSpdBarItem) { // Clear the belt for (int i = 0; i < MaxBeltItems; i++) { @@ -192,7 +202,7 @@ TEST(Inv, RemoveSpdBarItem) } // Test removing a scroll from the inventory -TEST(Inv, RemoveCurrentSpellScroll_inventory) +TEST_F(InvTest, RemoveCurrentSpellScroll_inventory) { clear_inventory(); @@ -209,7 +219,7 @@ TEST(Inv, RemoveCurrentSpellScroll_inventory) } // Test removing a scroll from the belt -TEST(Inv, RemoveCurrentSpellScroll_belt) +TEST_F(InvTest, RemoveCurrentSpellScroll_belt) { // Clear the belt for (int i = 0; i < MaxBeltItems; i++) { @@ -225,7 +235,7 @@ TEST(Inv, RemoveCurrentSpellScroll_belt) EXPECT_TRUE(MyPlayer->SpdList[3].isEmpty()); } -TEST(Inv, ItemSize) +TEST_F(InvTest, ItemSize) { Item testItem {}; @@ -246,3 +256,6 @@ TEST(Inv, ItemSize) InitializeItem(testItem, IDI_GOLD); EXPECT_EQ(GetInventorySize(testItem), Size(1, 1)); } + +} // namespace +} // namespace devilution 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