Skip to content

Commit

Permalink
QoL: Increase playercount to 8
Browse files Browse the repository at this point in the history
Replace MAXVISION with MAX_PLRS

Update base.cpp

MAXVISION again?

Add 8 player functionality

Remove MAXPORTAL

Update

Update

Update

Update portal.cpp

Add fixed monster tags

Update automap.cpp

Adjust portal positions

Update automap.cpp

Use default 200 max monsters

Fix errors

Fix mistakes
  • Loading branch information
kphoenix137 committed Jan 19, 2025
1 parent f7603b7 commit e240051
Show file tree
Hide file tree
Showing 26 changed files with 106 additions and 79 deletions.
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
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

0 comments on commit e240051

Please sign in to comment.