Skip to content
16 changes: 16 additions & 0 deletions src/doom/d_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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



Expand Down Expand Up @@ -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);

Expand Down
2 changes: 2 additions & 0 deletions src/doom/d_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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"))
Expand Down
3 changes: 2 additions & 1 deletion src/doom/doomstat.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +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

Expand Down Expand Up @@ -103,7 +104,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;

// -------------------------
Expand Down
41 changes: 41 additions & 0 deletions src/doom/p_mobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1007,6 +1028,12 @@ void P_SpawnMapThing (mapthing_t* mthing)
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)
Expand Down Expand Up @@ -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;
Expand Down
11 changes: 11 additions & 0 deletions src/net_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -210,6 +220,7 @@ typedef struct

int num_players;
int consoleplayer;
int mp_things_spawn_type; // [crispy]
Comment thread
UnreallyHard marked this conversation as resolved.
Outdated

// Hexen player classes:

Expand Down
4 changes: 3 additions & 1 deletion src/net_structrw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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, (unsigned int *) &settings->mp_things_spawn_type); // [crispy]

if (!success)
{
Expand Down
34 changes: 34 additions & 0 deletions src/setup/multiplayer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand Down