Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Increase Max Players to 8 #7663

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Source/DiabloUI/multi/selconn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,15 @@ void SelconnEsc()

void SelconnFocus(size_t value)
{
int players = MAX_PLRS;
int players = MaxPlayers;
switch (vecConnItems[value]->m_value) {
case SELCONN_TCP:
CopyUtf8(selconn_Description, _("All computers must be connected to a TCP-compatible network."), sizeof(selconn_Description));
players = MAX_PLRS;
players = MaxPlayers;
break;
case SELCONN_ZT:
CopyUtf8(selconn_Description, _("All computers must be connected to the internet."), sizeof(selconn_Description));
players = MAX_PLRS;
players = MaxPlayers;
break;
case SELCONN_LOOPBACK:
CopyUtf8(selconn_Description, _("Play by yourself with no network exposure."), sizeof(selconn_Description));
Expand Down
11 changes: 10 additions & 1 deletion Source/automap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ Point Automap;
enum MapColors : uint8_t {
/** color used to draw the player's arrow */
MapColorsPlayer = (PAL8_ORANGE + 1),
MapColorsPlayer2 = (PAL8_YELLOW + 1),
MapColorsPlayer3 = (PAL8_RED + 1),
MapColorsPlayer4 = (PAL8_BLUE + 1),
MapColorsPlayer5 = (PAL16_ORANGE + 1),
MapColorsPlayer6 = (PAL16_BEIGE + 1),
MapColorsPlayer7 = (PAL16_RED + 1),
MapColorsPlayer8 = (PAL16_BLUE + 1),
/** color for bright map lines (doors, stairs etc.) */
MapColorsBright = PAL8_YELLOW,
/** color for dim map lines/dots */
Expand Down Expand Up @@ -153,6 +160,8 @@ struct AutomapTile {
}
};

uint8_t playerColors[] { MapColorsPlayer, MapColorsPlayer2, MapColorsPlayer3, MapColorsPlayer4, MapColorsPlayer5, MapColorsPlayer6, MapColorsPlayer7, MapColorsPlayer8 };

/**
* Maps from tile_id to automap type.
*/
Expand Down Expand Up @@ -1319,7 +1328,7 @@ void SearchAutomapItem(const Surface &out, const Displacement &myPlayerOffset, i
*/
void DrawAutomapPlr(const Surface &out, const Displacement &myPlayerOffset, const Player &player)
{
const uint8_t playerColor = MapColorsPlayer + (8 * player.getId()) % 128;
const uint8_t playerColor = playerColors[player.getId()];

Point tile = player.position.tile;

Expand Down
2 changes: 1 addition & 1 deletion Source/control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ uint8_t NextTalkSave;
char TalkMessage[MAX_SEND_STR_LEN];
bool TalkButtonsDown[3];
int sgbPlrTalkTbl;
bool WhisperList[MAX_PLRS];
bool WhisperList[MaxPlayers];
int PanelPaddingHeight = 16;

TextInputCursorState ChatCursor;
Expand Down
6 changes: 3 additions & 3 deletions Source/dvlnet/base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ bool base::IsConnected(plr_t player) const

tl::expected<void, PacketError> base::RecvLocal(packet &pkt)
{
if (pkt.Source() < MAX_PLRS) {
if (pkt.Source() < MaxPlayers) {
if (tl::expected<void, PacketError> result = Connect(pkt.Source());
!result.has_value()) {
return result;
Expand Down Expand Up @@ -225,7 +225,7 @@ bool base::SNetReceiveMessage(uint8_t *sender, void **data, size_t *size)

bool base::SNetSendMessage(uint8_t playerId, void *data, size_t size)
{
if (playerId != SNPLAYER_OTHERS && playerId >= MAX_PLRS)
if (playerId != SNPLAYER_OTHERS && playerId >= MaxPlayers)
abort();
auto *rawMessage = reinterpret_cast<unsigned char *>(data);
buffer_t message(rawMessage, rawMessage + size);
Expand Down Expand Up @@ -420,7 +420,7 @@ void base::SNetGetProviderCaps(struct _SNETCAPS *caps)
caps->flags = 0; // unused
caps->maxmessagesize = 512; // capped to 512; underflow if < 24
caps->maxqueuesize = 0; // unused
caps->maxplayers = MAX_PLRS; // capped to 4
caps->maxplayers = MaxPlayers; // capped to 8
caps->bytessec = 1000000; // ?
caps->latencyms = 0; // unused
caps->defaultturnssec = 10; // ?
Expand Down
2 changes: 1 addition & 1 deletion Source/dvlnet/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class base : public abstract_net {
virtual bool IsGameHost() = 0;

private:
std::array<PlayerState, MAX_PLRS> playerStateTable_;
std::array<PlayerState, MaxPlayers> playerStateTable_;
bool awaitingSequenceNumber_ = true;

plr_t GetOwner();
Expand Down
18 changes: 9 additions & 9 deletions Source/dvlnet/base_protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class base_protocol : public base {
endpoint_t peer;
};
ankerl::unordered_dense::map</*name*/ std::string, GameListValue> game_list;
std::array<Peer, MAX_PLRS> peers;
std::array<Peer, MaxPlayers> peers;
bool isGameHost_;

plr_t get_master();
Expand Down Expand Up @@ -252,7 +252,7 @@ tl::expected<void, PacketError> base_protocol<P>::send(packet &pkt)
}
return {};
}
if (destination >= MAX_PLRS)
if (destination >= MaxPlayers)
return tl::make_unexpected("Invalid player ID");
if (destination == MyPlayerId)
return {};
Expand Down Expand Up @@ -319,7 +319,7 @@ tl::expected<void, PacketError> base_protocol<P>::handle_join_request(packet &in
break;
}
}
if (i >= MAX_PLRS) {
if (i >= MaxPlayers) {
// already full
return {};
}
Expand Down Expand Up @@ -358,7 +358,7 @@ template <class P>
tl::expected<void, PacketError> base_protocol<P>::recv_decrypted(packet &pkt, endpoint_t sender)
{
if (pkt.Source() == PLR_BROADCAST && pkt.Destination() == PLR_MASTER && pkt.Type() == PT_INFO_REPLY) {
size_t neededSize = sizeof(GameData) + (PlayerNameLength * MAX_PLRS);
size_t neededSize = sizeof(GameData) + (PlayerNameLength * MaxPlayers);
const tl::expected<const buffer_t *, PacketError> pktInfo = pkt.Info();
if (!pktInfo.has_value())
return tl::make_unexpected(pktInfo.error());
Expand Down Expand Up @@ -405,7 +405,7 @@ tl::expected<void, PacketError> base_protocol<P>::recv_ingame(packet &pkt, endpo
} else if (pkt.Type() == PT_INFO_REQUEST) {
if ((plr_self != PLR_BROADCAST) && (get_master() == plr_self)) {
buffer_t buf;
buf.resize(game_init_info.size() + (PlayerNameLength * MAX_PLRS) + gamename.size());
buf.resize(game_init_info.size() + (PlayerNameLength * MaxPlayers) + gamename.size());
std::memcpy(buf.data(), &game_init_info[0], game_init_info.size());
for (size_t i = 0; i < Players.size(); i++) {
if (Players[i].plractive) {
Expand All @@ -414,7 +414,7 @@ tl::expected<void, PacketError> base_protocol<P>::recv_ingame(packet &pkt, endpo
std::memset(buf.data() + game_init_info.size() + (i * PlayerNameLength), '\0', PlayerNameLength);
}
}
std::memcpy(buf.data() + game_init_info.size() + (PlayerNameLength * MAX_PLRS), &gamename[0], gamename.size());
std::memcpy(buf.data() + game_init_info.size() + (PlayerNameLength * MaxPlayers), &gamename[0], gamename.size());
tl::expected<std::unique_ptr<packet>, PacketError> reply
= pktfty->make_packet<PT_INFO_REPLY>(PLR_BROADCAST, PLR_MASTER, buf);
if (!reply.has_value()) {
Expand Down Expand Up @@ -453,9 +453,9 @@ tl::expected<void, PacketError> base_protocol<P>::recv_ingame(packet &pkt, endpo
return InitiateHandshake(*newPlayer);
return {};
}
if (pkt.Source() >= MAX_PLRS) {
if (pkt.Source() >= MaxPlayers) {
// normal packets
LogDebug("Invalid packet: packet source ({}) >= MAX_PLRS", pkt.Source());
LogDebug("Invalid packet: packet source ({}) >= MaxPlayers", pkt.Source());
return {};
}
if (sender == firstpeer && pkt.Type() == PT_JOIN_ACCEPT) {
Expand Down Expand Up @@ -523,7 +523,7 @@ bool base_protocol<P>::is_recognized(endpoint_t sender)
if (sender == firstpeer)
return true;

for (auto player = 0; player <= MAX_PLRS; player++) {
for (auto player = 0; player <= MaxPlayers; player++) {
if (sender == peers[player].endpoint)
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion Source/dvlnet/loopback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void loopback::SNetGetProviderCaps(struct _SNETCAPS *caps)
caps->flags = 0; // unused
caps->maxmessagesize = 512; // capped to 512; underflow if < 24
caps->maxqueuesize = 0; // unused
caps->maxplayers = MAX_PLRS; // capped to 4
caps->maxplayers = MaxPlayers; // capped to 8
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason this shouldn't be capped to 1?

caps->bytessec = 1000000; // ?
caps->latencyms = 0; // unused
caps->defaultturnssec = 10; // ?
Expand Down
2 changes: 1 addition & 1 deletion Source/dvlnet/tcp_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ tl::expected<void, PacketError> tcp_server::SendPacket(packet &pkt)
}
return {};
}
if (pkt.Destination() >= MAX_PLRS)
if (pkt.Destination() >= MaxPlayers)
return tl::make_unexpected(ServerError());
if (pkt.Destination() == pkt.Source() || !connections[pkt.Destination()])
return {};
Expand Down
2 changes: 1 addition & 1 deletion Source/dvlnet/tcp_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class tcp_server {
asio::io_context &ioc;
packet_factory &pktfty;
std::unique_ptr<asio::ip::tcp::acceptor> acceptor;
std::array<scc, MAX_PLRS> connections;
std::array<scc, MaxPlayers> connections;
buffer_t game_init_info;

std::optional<PacketError> ioHandlerResult;
Expand Down
2 changes: 1 addition & 1 deletion Source/engine/render/scrollrt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ void DrawDungeon(const Surface &out, Point tilePosition, Point targetBufferPosit
Player *player = PlayerAtPosition(tilePosition);
if (player != nullptr) {
uint8_t pid = player->getId();
assert(pid < MAX_PLRS);
assert(pid < MaxPlayers);
int playerId = static_cast<int>(pid) + 1;
// If sprite is moving southwards or east, we want to draw it offset from the tile it's moving to, so we need negative ID
// This respests the order that tiles are drawn. By using the negative id, we ensure that the sprite is drawn with priority
Expand Down
4 changes: 2 additions & 2 deletions Source/lighting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@

namespace devilution {

std::array<bool, MAXVISION> VisionActive;
Light VisionList[MAXVISION];
std::array<bool, MaxPlayers> VisionActive;
Light VisionList[MaxPlayers];
Light Lights[MAXLIGHTS];
std::array<uint8_t, MAXLIGHTS> ActiveLights;
int ActiveLightCount;
Expand Down
6 changes: 3 additions & 3 deletions Source/lighting.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
#include "engine/displacement.hpp"
#include "engine/point.hpp"
#include "engine/world_tile.hpp"
#include "multi.h"
#include "utils/attributes.h"

namespace devilution {

#define MAXLIGHTS 32
#define MAXVISION 4
/** @brief Number of supported light levels */
constexpr size_t NumLightingLevels = 16;
#define NO_LIGHT -1
Expand All @@ -40,8 +40,8 @@ struct Light {
bool hasChanged;
};

extern Light VisionList[MAXVISION];
extern std::array<bool, MAXVISION> VisionActive;
extern Light VisionList[MaxPlayers];
extern std::array<bool, MaxPlayers> VisionActive;
extern Light Lights[MAXLIGHTS];
extern std::array<uint8_t, MAXLIGHTS> ActiveLights;
extern int ActiveLightCount;
Expand Down
12 changes: 6 additions & 6 deletions Source/loadsave.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -421,10 +421,10 @@ void LoadPlayer(LoadHelper &file, Player &player)
file.Skip(3); // Alignment

// Extra hotkeys: to keep single player save compatibility, read only 4 hotkeys here, rely on LoadHotkeys for the rest
for (size_t i = 0; i < 4; i++) {
for (size_t i = 0; i < MaxPlayersSp; i++) {
player._pSplHotKey[i] = static_cast<SpellID>(file.NextLE<int32_t>());
}
for (size_t i = 0; i < 4; i++) {
for (size_t i = 0; i < MaxPlayersSp; i++) {
player._pSplTHotKey[i] = static_cast<SpellType>(file.NextLE<uint8_t>());
}

Expand Down Expand Up @@ -1224,10 +1224,10 @@ void SavePlayer(SaveHelper &file, const Player &player)
file.Skip(3); // Alignment

// Extra hotkeys: to keep single player save compatibility, write only 4 hotkeys here, rely on SaveHotkeys for the rest
for (size_t i = 0; i < 4; i++) {
for (size_t i = 0; i < MaxPlayersSp; i++) {
file.WriteLE<int32_t>(static_cast<int8_t>(player._pSplHotKey[i]));
}
for (size_t i = 0; i < 4; i++) {
for (size_t i = 0; i < MaxPlayersSp; i++) {
file.WriteLE<uint8_t>(static_cast<uint8_t>(player._pSplTHotKey[i]));
}

Expand Down Expand Up @@ -2400,7 +2400,7 @@ tl::expected<void, std::string> LoadGame(bool firstflag)

for (int i = 0; i < giNumberQuests; i++)
LoadQuest(&file, i);
for (int i = 0; i < MAXPORTAL; i++)
for (int i = 0; i < MaxPlayersSp; i++)
LoadPortal(&file, i);

if (gbIsHellfireSaveGame != gbIsHellfire) {
Expand Down Expand Up @@ -2678,7 +2678,7 @@ void SaveGameData(SaveWriter &saveWriter)

for (int i = 0; i < giNumberQuests; i++)
SaveQuest(&file, i);
for (int i = 0; i < MAXPORTAL; i++)
for (int i = 0; i < MaxPlayersSp; i++)
SavePortal(&file, i);
for (int monstkill : MonsterKillCounts)
file.WriteBE<int32_t>(monstkill);
Expand Down
33 changes: 24 additions & 9 deletions Source/monster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3262,6 +3262,7 @@ void InitLevelMonsters()

ClrAllMonsters();
ActiveMonsterCount = 0;

totalmonsters = MaxMonsters;

std::iota(std::begin(ActiveMonsters), std::end(ActiveMonsters), 0u);
Expand Down Expand Up @@ -3517,7 +3518,9 @@ void WeakenNaKrul()
void InitGolems()
{
if (!setlevel) {
for (int i = 0; i < MAX_PLRS; i++)
uint8_t maxPlayers = gbIsMultiplayer ? MaxPlayers : MaxPlayersSp;

for (int i = 0; i < maxPlayers; i++)
AddMonster(GolemHoldingCell, Direction::South, 0, false);
}
}
Expand Down Expand Up @@ -3551,6 +3554,7 @@ tl::expected<void, std::string> InitMonsters()
size_t numplacemonsters = na / 30;
if (gbIsMultiplayer)
numplacemonsters += numplacemonsters / 2;

if (ActiveMonsterCount + numplacemonsters > MaxMonsters - 10)
numplacemonsters = MaxMonsters - 10 - ActiveMonsterCount;
totalmonsters = ActiveMonsterCount + numplacemonsters;
Expand Down Expand Up @@ -3586,9 +3590,12 @@ tl::expected<void, std::string> InitMonsters()
tl::expected<void, std::string> SetMapMonsters(const uint16_t *dunData, Point startPosition)
{
RETURN_IF_ERROR(AddMonsterType(MT_GOLEM, PLACE_SPECIAL));
if (setlevel)
for (int i = 0; i < MAX_PLRS; i++)
if (setlevel) {
uint8_t maxPlayers = gbIsMultiplayer ? MaxPlayers : MaxPlayersSp;

for (int i = 0; i < maxPlayers; i++)
AddMonster(GolemHoldingCell, Direction::South, 0, false);
}

WorldTileSize size = GetDunSize(dunData);

Expand Down Expand Up @@ -4011,7 +4018,9 @@ void GolumAi(Monster &golem)

void DeleteMonsterList()
{
for (int i = 0; i < MAX_PLRS; i++) {
uint8_t maxPlayers = gbIsMultiplayer ? MaxPlayers : MaxPlayersSp;

for (int i = 0; i < maxPlayers; i++) {
Monster &golem = Monsters[i];
if (!golem.isInvalid)
continue;
Expand All @@ -4022,7 +4031,7 @@ void DeleteMonsterList()
golem.isInvalid = false;
}

for (size_t i = MAX_PLRS; i < ActiveMonsterCount;) {
for (size_t i = maxPlayers; i < ActiveMonsterCount;) {
if (Monsters[ActiveMonsters[i]].isInvalid) {
if (pcursmonst == static_cast<int>(ActiveMonsters[i])) // Unselect monster if player highlighted it
pcursmonst = -1;
Expand Down Expand Up @@ -4079,7 +4088,9 @@ void ProcessMonsters()
monster.position.last = Monsters[monster.enemy].position.future;
monster.enemyPosition = monster.position.last;
} else {
assert(monster.enemy >= 0 && monster.enemy < MAX_PLRS);
uint8_t maxPlayers = gbIsMultiplayer ? MaxPlayers : MaxPlayersSp;

assert(monster.enemy >= 0 && monster.enemy < maxPlayers);
Player &player = Players[monster.enemy];
monster.enemyPosition = player.position.future;
if (IsTileVisible(monster.position.tile)) {
Expand Down Expand Up @@ -4670,21 +4681,25 @@ bool CanTalkToMonst(const Monster &monster)

int encode_enemy(Monster &monster)
{
uint8_t maxPlayers = gbIsMultiplayer ? MaxPlayers : MaxPlayersSp;

if ((monster.flags & MFLAG_TARGETS_MONSTER) != 0)
return monster.enemy + MAX_PLRS;
return monster.enemy + maxPlayers;

return monster.enemy;
}

void decode_enemy(Monster &monster, int enemyId)
{
if (enemyId < MAX_PLRS) {
uint8_t maxPlayers = gbIsMultiplayer ? MaxPlayers : MaxPlayersSp;

if (enemyId < maxPlayers) {
monster.flags &= ~MFLAG_TARGETS_MONSTER;
monster.enemy = enemyId;
monster.enemyPosition = Players[enemyId].position.future;
} else {
monster.flags |= MFLAG_TARGETS_MONSTER;
enemyId -= MAX_PLRS;
enemyId -= maxPlayers;
monster.enemy = enemyId;
monster.enemyPosition = Monsters[enemyId].position.future;
}
Expand Down
Loading
Loading