From f0fdfb48b93576093bea2bc490b000a8ca4e3a2e Mon Sep 17 00:00:00 2001 From: UnreallyHard <UnreallyHard@gmail.com> Date: Sat, 24 Feb 2024 01:33:29 +0700 Subject: [PATCH] Added Multiplayer Things Spawn Type option Option is available for all netgame types Added Multiplayer Things Spawn Type to setup menu Added Cmd Line Parameter mpspawntype Added netgame functionality Added mobjtype_weapons array is_weapon function Closes https://github.com/fabiangreffrath/crispy-doom/issues/681 --- src/doom/d_main.c | 16 +++++++++++++++ src/doom/d_net.c | 2 ++ src/doom/doomstat.h | 4 ++-- src/doom/p_mobj.c | 43 ++++++++++++++++++++++++++++++++++++++++- src/net_defs.h | 13 ++++++++++++- src/net_structrw.c | 4 +++- src/setup/multiplayer.c | 34 ++++++++++++++++++++++++++++++++ 7 files changed, 111 insertions(+), 5 deletions(-) diff --git a/src/doom/d_main.c b/src/doom/d_main.c index 736a1fee1f..8cfa332a50 100644 --- a/src/doom/d_main.c +++ b/src/doom/d_main.c @@ -108,6 +108,7 @@ boolean nomonsters; // checkparm of -nomonsters boolean respawnparm; // checkparm of -respawn boolean fastparm; // checkparm of -fast boolean coop_spawns = false; // [crispy] checkparm of -coop_spawns +int mp_things_spawn_type; // [crispy] checkparm of -mpspawntype @@ -1577,6 +1578,21 @@ void D_DoomMain (void) if (M_CheckParm ("-dm3")) deathmatch = 3; + //! + // @arg <n> + // @category net + // [crispy] + // Types of multiplayer things to be spawned in a netgame + // + + p = M_CheckParmWithArgs("-mpspawntype", 1); + mp_things_spawn_type = atoi(myargv[p+1]); + + if (mp_things_spawn_type > MP_THINGS_SPAWN_TYPES_NUM || mp_things_spawn_type < 0) + { + mp_things_spawn_type = 0; + } + if (devparm) DEH_printf(D_DEVSTR); diff --git a/src/doom/d_net.c b/src/doom/d_net.c index 4da8004aa3..8cba767554 100644 --- a/src/doom/d_net.c +++ b/src/doom/d_net.c @@ -119,6 +119,7 @@ static void LoadGameSettings(net_gamesettings_t *settings) respawnparm = settings->respawn_monsters; timelimit = settings->timelimit; consoleplayer = settings->consoleplayer; + mp_things_spawn_type = settings->mp_things_spawn_type; // [crispy] if (lowres_turn) { @@ -150,6 +151,7 @@ static void SaveGameSettings(net_gamesettings_t *settings) settings->fast_monsters = fastparm; settings->respawn_monsters = respawnparm; settings->timelimit = timelimit; + settings->mp_things_spawn_type = mp_things_spawn_type; // [crispy] settings->lowres_turn = (M_ParmExists("-record") && !M_ParmExists("-longtics")) diff --git a/src/doom/doomstat.h b/src/doom/doomstat.h index 262e6c4e59..80089ec264 100644 --- a/src/doom/doomstat.h +++ b/src/doom/doomstat.h @@ -48,7 +48,7 @@ extern boolean nomonsters; // checkparm of -nomonsters extern boolean respawnparm; // checkparm of -respawn extern boolean fastparm; // checkparm of -fast extern boolean coop_spawns; // [crispy] checkparm of -coop_spawns - +extern int mp_things_spawn_type; // [crispy] checkparm of -mpspawntype extern boolean devparm; // DEBUG: launched with -devparm @@ -103,7 +103,7 @@ extern boolean respawnmonsters; // Netgame? Only true if >1 player. extern boolean netgame; -// 0=Cooperative; 1=Deathmatch; 2=Altdeath +// 0=Cooperative; 1=Deathmatch; 2=Altdeath; 3=dm3; extern int deathmatch; // ------------------------- diff --git a/src/doom/p_mobj.c b/src/doom/p_mobj.c index e3348d3398..74a61b0b11 100644 --- a/src/doom/p_mobj.c +++ b/src/doom/p_mobj.c @@ -41,6 +41,27 @@ void G_PlayerReborn (int player); void P_SpawnMapThing (mapthing_t* mthing); +// [crispy] mobjtype weapons +const mobjtype_t mobjtype_weapons[] = { + MT_MISC25, + MT_CHAINGUN, + MT_MISC26, + MT_MISC27, + MT_MISC28, + MT_SHOTGUN, + MT_SUPERSHOTGUN, +}; + +#define MOBJTYPE_WEAPONS_COUNT (sizeof(mobjtype_weapons) / sizeof(mobjtype_t)) + +boolean is_weapon(mobjtype_t value) { + for (int i = 0; i < MOBJTYPE_WEAPONS_COUNT; ++i) { + if (value == mobjtype_weapons[i]) { + return true; + } + } + return false; +} // // P_SetMobjState @@ -1006,7 +1027,13 @@ void P_SpawnMapThing (mapthing_t* mthing) // check for appropriate skill level if (!coop_spawns && !netgame && (mthing->options & 16) ) return; - + + // [crispy] Don't spawn mp-only things in the netgame + if (netgame && (mthing->options & 16) && mp_things_spawn_type == MP_THINGS_SPAWN_NONE) + { + return; + } + if (gameskill == sk_baby) bit = 1; else if (gameskill == sk_nightmare) @@ -1057,6 +1084,20 @@ void P_SpawnMapThing (mapthing_t* mthing) return; } + if (netgame && (mthing->options & 16)) + { + // [crispy] Don't spawn any mp-only things except monsters in the netgame + if (mp_things_spawn_type == MP_THINGS_SPAWN_ONLY_MONSTERS && !(i == MT_SKULL || (mobjinfo[i].flags & MF_COUNTKILL))) + { + return; + } + // [crispy] Don't spawn mp-only weapons in the netgame + if (mp_things_spawn_type == MP_THINGS_SPAWN_ALL_BUT_WEAPONS && is_weapon(i)) + { + return; + } + } + // spawn it x = mthing->x << FRACBITS; y = mthing->y << FRACBITS; diff --git a/src/net_defs.h b/src/net_defs.h index ab852c08ee..47fa5249df 100644 --- a/src/net_defs.h +++ b/src/net_defs.h @@ -169,6 +169,16 @@ typedef enum NET_MASTER_PACKET_TYPE_NAT_HOLE_PUNCH_ALL, } net_master_packet_type_t; +typedef enum // [crispy] +{ + MP_THINGS_SPAWN_ALL, + MP_THINGS_SPAWN_ALL_BUT_WEAPONS, + MP_THINGS_SPAWN_ONLY_MONSTERS, + MP_THINGS_SPAWN_NONE, + + MP_THINGS_SPAWN_TYPES_NUM, +} net_mp_things_spawn_t; + // Settings specified when the client connects to the server. typedef struct @@ -210,7 +220,8 @@ typedef struct int num_players; int consoleplayer; - + int mp_things_spawn_type; // [crispy] + // Hexen player classes: int player_classes[NET_MAXPLAYERS]; diff --git a/src/net_structrw.c b/src/net_structrw.c index 2dbd2740a1..878990249f 100644 --- a/src/net_structrw.c +++ b/src/net_structrw.c @@ -81,6 +81,7 @@ void NET_WriteSettings(net_packet_t *packet, net_gamesettings_t *settings) NET_WriteInt8(packet, settings->random); NET_WriteInt8(packet, settings->num_players); NET_WriteInt8(packet, settings->consoleplayer); + NET_WriteInt8(packet, settings->mp_things_spawn_type); // [crispy] for (i = 0; i < settings->num_players; ++i) { @@ -109,7 +110,8 @@ boolean NET_ReadSettings(net_packet_t *packet, net_gamesettings_t *settings) && NET_ReadSInt8(packet, (signed int *) &settings->loadgame) && NET_ReadInt8(packet, (unsigned int *) &settings->random) && NET_ReadInt8(packet, (unsigned int *) &settings->num_players) - && NET_ReadSInt8(packet, (signed int *) &settings->consoleplayer); + && NET_ReadSInt8(packet, (signed int *) &settings->consoleplayer) + && NET_ReadSInt8(packet, (signed int *) &settings->mp_things_spawn_type); // [crispy] if (!success) { diff --git a/src/setup/multiplayer.c b/src/setup/multiplayer.c index 24517519db..d8af870e43 100644 --- a/src/setup/multiplayer.c +++ b/src/setup/multiplayer.c @@ -133,6 +133,7 @@ static int deathmatch = 0; static int strife_altdeath = 0; static int fast = 0; static int respawn = 0; +static int mp_things_spawn_type = 0; // [crispy] static int udpport = 2342; static int timer = 0; static int privateserver = 0; @@ -282,6 +283,11 @@ static void StartGame(int multiplayer) { AddCmdLineParameter(exec, "-privateserver"); } + + if (mp_things_spawn_type) // [crispy] + { + AddCmdLineParameter(exec, "-mpspawntype %i", mp_things_spawn_type); + } } AddWADs(exec); @@ -708,6 +714,25 @@ static txt_dropdown_list_t *GameTypeDropdown(void) } } +static void MultiplayerFlags(void) // [crispy] +{ + txt_window_t *window; + + // Build the window + window = TXT_NewWindow("Multiplayer Flags"); + TXT_SetColumnWidths(window, 40); + TXT_SetWindowPosition(window, TXT_HORIZ_CENTER, TXT_VERT_TOP, TXT_SCREEN_W / 2, 3); + + TXT_AddWidgets(window, + TXT_NewSeparator("Multiplayer Things Spawn Type"), + TXT_NewRadioButton("All", &mp_things_spawn_type, MP_THINGS_SPAWN_ALL), + TXT_NewRadioButton("All except weapons", &mp_things_spawn_type, MP_THINGS_SPAWN_ALL_BUT_WEAPONS), + TXT_NewRadioButton("Only monsters", &mp_things_spawn_type, MP_THINGS_SPAWN_ONLY_MONSTERS), + TXT_NewRadioButton("None", &mp_things_spawn_type, MP_THINGS_SPAWN_NONE), + NULL + ); +} + // "Start game" menu. This is used for the start server window // and the single player warp menu. The parameters specify // the window title and whether to display multiplayer options. @@ -769,6 +794,15 @@ static void StartGameMenu(const char *window_title, int multiplayer) TXT_NewLabel("minutes"), NULL), NULL); + if (gamemission == doom) // [crispy] Multiplayer Flags + { + TXT_AddWidgets(window, + TXT_NewLabel("Flags"), + TXT_NewButton2("Set", + (TxtWidgetSignalFunc) MultiplayerFlags, NULL), + NULL + ); + } } TXT_AddWidgets(window,