Skip to content

Commit

Permalink
fix: multiplayer game ending if host is defeated
Browse files Browse the repository at this point in the history
now host will lose all units/structures, become observer and will be kicked to lobby, once other players finish the game.
  • Loading branch information
codeflorist committed May 13, 2023
1 parent 9e3f08e commit 01d549d
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 7 deletions.
20 changes: 20 additions & 0 deletions src/house.c
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,26 @@ House_Server_ReassignToAI(enum HouseType houseID)
}
}

void
House_Server_Eliminate(enum HouseType houseID)
{
House *h = House_Get_ByIndex(houseID);

PoolFindStruct find;

for (Structure *s = Structure_FindFirst(&find, houseID, STRUCTURE_INVALID);
s != NULL;
s = Structure_FindNext(&find)) {
Structure_Damage(s, s->o.hitpoints * 2, 0);
}

for (Unit *u = Unit_FindFirst(&find, houseID, UNIT_INVALID);
u != NULL;
u = Unit_FindNext(&find)) {
Unit_Damage(u, u->o.hitpoints * 2, 0);
}
}

void
House_Client_UpdateRadarState(void)
{
Expand Down
11 changes: 11 additions & 0 deletions src/mods/multiplayer.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,17 @@ Multiplayer_Prepare(void)
}
}

bool Multiplayer_IsAnyHouseLeftPlaying(void)
{
bool houseLeft = false;
for (enum HouseType h = HOUSE_HARKONNEN; h < HOUSE_MAX; h++) {
if (g_multiplayer.state[h] == MP_HOUSE_PLAYING)
houseLeft = true;
}

return houseLeft;
}

enum MapGeneratorMode
Multiplayer_GenerateMap(enum MapGeneratorMode mode)
{
Expand Down
1 change: 1 addition & 0 deletions src/mods/multiplayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,6 @@ extern void Multiplayer_Init(void);
extern bool Multiplayer_IsHouseAvailable(enum HouseType houseID);
extern bool Multiplayer_GenHouses(struct SkirmishData *sd);
extern enum MapGeneratorMode Multiplayer_GenerateMap(enum MapGeneratorMode mode);
extern bool Multiplayer_IsAnyHouseLeftPlaying(void);

#endif
14 changes: 12 additions & 2 deletions src/net/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -710,13 +710,14 @@ Server_Send_WinLose(enum HouseType houseID, bool win)
g_client_houses &= ~(1 << houseID);

if (!win) {
House_Server_ReassignToAI(houseID);
// this is not working: House_Server_ReassignToAI(houseID);
// so we blow up everything instead.
House_Server_Eliminate(houseID);
}
}

if (houseID == g_playerHouseID) {
MenuBar_DisplayWinLose(win);
Server_ReturnToLobbyNow(win);
} else {
unsigned char src[2];
unsigned char *buf = src;
Expand All @@ -726,6 +727,15 @@ Server_Send_WinLose(enum HouseType houseID, bool win)

assert(buf - src == sizeof(src));
Server_BufferGameEvent(1 << houseID, sizeof(src), src);

// If no other houses are left playing,
// the host might have lost earlier and might
// still be waiting for the game to end.
// So we send him back to the lobby.
if (!Multiplayer_IsAnyHouseLeftPlaying() && g_gameOverlay == GAMEOVERLAY_NONE) {
g_gameMode = GM_LOSE;
GUI_ChangeSelectionType(SELECTIONTYPE_MENTAT);
}
}
}

Expand Down
34 changes: 29 additions & 5 deletions src/newui/menubar.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "../tools/random_xorshift.h"
#include "../video/video.h"
#include "../wsa.h"
#include "../mods/multiplayer.h"

static enum {
RADAR_ANIMATION_NONE,
Expand Down Expand Up @@ -362,18 +363,41 @@ MenuBar_DisplayWinLose(bool win)
Video_UngrabCursor();

Audio_PlayVoice(voiceID);
snprintf(s_modal_message_buf, sizeof(s_modal_message_buf), "%s",
String_Get_ByIndex(stringID));

if (!win && g_campaign_selected == CAMPAIGNID_MULTIPLAYER && Net_HasServerRole() && Multiplayer_IsAnyHouseLeftPlaying()) {
snprintf(
s_modal_message_buf,
sizeof(s_modal_message_buf), "%s %s",
String_Get_ByIndex(stringID),
"As host you will become observer until the other players finish the game."
);
}
else {
snprintf(s_modal_message_buf, sizeof(s_modal_message_buf), "%s",
String_Get_ByIndex(stringID));
}
MenuBar_PrepareModalMessage(SHAPE_INVALID);
}

void
MenuBar_TickWinLoseOverlay(void)
{
if (MenuBar_TickModalMessage()) {
g_gameMode = (g_gameOverlay == GAMEOVERLAY_WIN) ? GM_WIN : GM_LOSE;
g_gameOverlay = GAMEOVERLAY_NONE;
GUI_ChangeSelectionType(SELECTIONTYPE_MENTAT);
bool finishMap = true;

// Multiplayer host can only end map, if all houses have either won or lost.
if (g_campaign_selected == CAMPAIGNID_MULTIPLAYER && Net_HasServerRole() && Multiplayer_IsAnyHouseLeftPlaying()) {
finishMap = false;
}

if (finishMap) {
g_gameMode = (g_gameOverlay == GAMEOVERLAY_WIN) ? GM_WIN : GM_LOSE;
g_gameOverlay = GAMEOVERLAY_NONE;
GUI_ChangeSelectionType(SELECTIONTYPE_MENTAT);
}
else {
g_gameOverlay = GAMEOVERLAY_NONE;
}
}
}

Expand Down

0 comments on commit 01d549d

Please sign in to comment.