Browse Source

Make `Players` a vector

dyn-players
Gleb Mazovetskiy 4 years ago committed by Anders Jenbo
parent
commit
6fd8796ef0
  1. 2
      Source/automap.cpp
  2. 14
      Source/control.cpp
  3. 4
      Source/controls/game_controls.cpp
  4. 2
      Source/controls/plrctrls.cpp
  5. 146
      Source/cursor.cpp
  6. 2
      Source/debug.cpp
  7. 12
      Source/dvlnet/base.cpp
  8. 16
      Source/dvlnet/base_protocol.h
  9. 3
      Source/dvlnet/loopback.cpp
  10. 9
      Source/dvlnet/tcp_server.cpp
  11. 4
      Source/engine/render/scrollrt.cpp
  12. 2
      Source/items.cpp
  13. 6
      Source/missiles.cpp
  14. 10
      Source/monster.cpp
  15. 30
      Source/msg.cpp
  16. 39
      Source/multi.cpp
  17. 16
      Source/objects.cpp
  18. 25
      Source/player.cpp
  19. 10
      Source/player.h
  20. 4
      Source/portal.cpp
  21. 2
      Source/qol/monhealthbar.cpp
  22. 2
      Source/spells.cpp
  23. 4
      Source/sync.cpp
  24. 2
      Source/towners.cpp
  25. 26
      test/drlg_l1_test.cpp
  26. 10
      test/effects_test.cpp
  27. 39
      test/inv_test.cpp
  28. 33
      test/pack_test.cpp
  29. 2
      test/path_test.cpp
  30. 3
      test/player_test.cpp
  31. 1
      test/writehero_test.cpp

2
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);

14
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()

4
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

2
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;

146
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<int8_t>(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<int8_t>(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<int8_t>(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<int8_t>(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<int8_t>(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<int8_t>(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<int8_t>(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<int8_t>(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<int8_t>(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<int8_t>(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<int8_t>(itemId);
}
}
if (pcursitem == -1) {

2
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<size_t>(playerId) >= Players.size())
return "My friend, we need a valid playerId.";
Player &player = Players[playerId];
if (!player.plractive)

12
Source/dvlnet/base.cpp

@ -4,6 +4,8 @@
#include <cstring>
#include <memory>
#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;
}

16
Source/dvlnet/base_protocol.h

@ -68,7 +68,7 @@ template <class P>
plr_t base_protocol<P>::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<P>::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<P>::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 <class P>
void base_protocol<P>::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<P>::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<PT_CONNECT>(PLR_MASTER, PLR_BROADCAST, i, senderinfo);
@ -297,7 +297,7 @@ void base_protocol<P>::recv_decrypted(packet &pkt, endpoint_t sender)
return;
const GameData *gameData = (const GameData *)pkt.Info().data();
std::vector<std::string> 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<P>::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<P>::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);
}

3
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;
}

9
Source/dvlnet/tcp_server.cpp

@ -6,6 +6,7 @@
#include <utility>
#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<PT_CONNECT>(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 {

4
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<size_t>(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<size_t>(playerId - 1) <= Players.size()) {
DrawPlayerHelper(out, Players[playerId - 1], tilePosition, targetBufferPosition);
}
if (dMonster[tilePosition.x][tilePosition.y] > 0) {

2
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;
}

6
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<int>(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<int>(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 &parameter)
other._mirange = 0;
}
PutMissile(missile);
if (missile._misource == MyPlayerId && !missile._miDelFlag && leveltype != DTYPE_TOWN) {
if (missile._misource == static_cast<int>(MyPlayerId) && !missile._miDelFlag && leveltype != DTYPE_TOWN) {
if (!setlevel) {
NetSendCmdLocParam3(true, CMD_ACTIVATEPORTAL, missile.position.tile, currlevel, leveltype, 0);
} else {

10
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<int>(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;

30
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<const TCmdParam1 *>(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<const TCmdParam1 *>(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<const TCmdParam1 *>(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<int>(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<int>(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<int>(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<int>(MyPlayerId) && WasPlayerCmdAlreadyRequested(bCmd, position))
return;
TCmdLoc cmd;

39
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<size_t>(pnum))
break;
}
if (MyPlayerId == i) {
sgbSendDeltaTbl[pnum] = true;
} else if (pnum == MyPlayerId) {
} else if (pnum == static_cast<int>(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<size_t>(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<uint16_t>(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<int>(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<size_t>(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<int>(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) {

16
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;
}
}
}

25
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<Player> 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<size_t>(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<size_t>(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<size_t>(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<Player>();
*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);

10
Source/player.h

@ -6,6 +6,7 @@
#pragma once
#include <cstdint>
#include <vector>
#include <algorithm>
#include <array>
@ -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<Player> Players;
extern bool MyPlayerIsDead;
extern const int BlockBonuses[enum_size<HeroClass>::value];

4
Source/portal.cpp

@ -152,7 +152,7 @@ void GetPortalLevel()
leveltype = Portals[portalindex].ltype;
}
if (portalindex == MyPlayerId) {
if (portalindex == static_cast<int>(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<int>(MyPlayerId)) {
ViewPosition.x++;
ViewPosition.y++;
}

2
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) {

2
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<size_t>(pnum) >= Players.size() || rid >= Players.size()) {
return;
}

4
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<int>(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<int>(MyPlayerId), monsterSyncs[i]);
}
delta_sync_monster(monsterSyncs[i], level);

2
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;
}

26
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;

10
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;

39
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

33
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;

2
test/path_test.cpp

@ -110,7 +110,7 @@ void CheckPath(Point startPosition, Point destinationPosition, std::vector<int8_
// Die early if the wrong path length is returned as we don't want to read oob in expectedSteps
ASSERT_LE(pathLength, expectedSteps.size()) << "Path is longer than expected.";
for (auto i = 0; i < pathLength; i++) {
for (int i = 0; i < pathLength; i++) {
EXPECT_EQ(pathSteps[i], expectedSteps[i]) << "Path step " << i << " differs from expectation for a path from "
<< startPosition << " to " << destinationPosition; // this shouldn't be a requirement but...

3
test/player_test.cpp

@ -82,6 +82,8 @@ BlockTestCase BlockData[] = {
TEST(Player, PM_DoGotHit)
{
Players.resize(1);
MyPlayer = &Players[0];
for (size_t i = 0; i < sizeof(BlockData) / sizeof(*BlockData); i++) {
EXPECT_EQ(BlockData[i].expectedRecoveryFrame, RunBlockTest(BlockData[i].maxRecoveryFrame, BlockData[i].itemFlags));
}
@ -180,6 +182,7 @@ static void AssertPlayer(Player &player)
TEST(Player, CreatePlayer)
{
Players.resize(1);
CreatePlayer(Players[0], HeroClass::Rogue);
AssertPlayer(Players[0]);
}

1
test/writehero_test.cpp

@ -333,6 +333,7 @@ TEST(Writehero, pfile_write_hero)
leveltype = DTYPE_TOWN;
giNumberOfLevels = 17;
Players.resize(1);
MyPlayerId = 0;
MyPlayer = &Players[MyPlayerId];
*MyPlayer = {};

Loading…
Cancel
Save