From d546b3954679adea39d8ca52c292ff39b3305062 Mon Sep 17 00:00:00 2001 From: Xylemon Date: Mon, 17 Jul 2023 16:46:25 -0700 Subject: [PATCH] - Add (early) bot support - Add support for all common types of spawns - Attempt at supporting mp_forcerespawn - Shoddy attempt at making some legacy cvars (gamemode and levelexec) work --- src/server/gamerules.h | 15 ++++-- src/server/gamerules.qc | 117 ++++++++++++++++++++++++++++++++++++---- src/server/progs.src | 4 +- 3 files changed, 118 insertions(+), 18 deletions(-) diff --git a/src/server/gamerules.h b/src/server/gamerules.h index 8c62094..6bba5a4 100644 --- a/src/server/gamerules.h +++ b/src/server/gamerules.h @@ -28,6 +28,7 @@ class HLGameRules:CGameRules virtual void(NSClientPlayer, entity) ScientistKill; virtual void(void) RegisterSciDeath; + virtual bool(NSClientPlayer, string) ConsoleCommand; virtual void(NSClientPlayer) LevelDecodeParms; virtual void(NSClientPlayer) LevelChangeParms; virtual void(void) LevelNewParms; @@ -63,9 +64,9 @@ class SHTeamRules:HLGameRules virtual void(void) InitPostEnts; }; -class SHRules:HLGameRules +class SHInvasionRules:HLGameRules { - void(void) SHRules; + void(void) SHInvasionRules; virtual void(void) RegisterSciDeath; }; @@ -112,7 +113,7 @@ class SHGameMadness:HLGameRules /* Invasion (5): Unique new round-based gamemode where scientists attack similar to madness but work together to kill everyone else. If players eleminate all scientists, then they win the round and have to do it all over again. Heavy WIP. Scientists and players don't respawn. */ -class SHGameInvasion:SHRules +class SHGameInvasion:SHInvasionRules { void(void) SHGameInvasion; }; @@ -131,14 +132,18 @@ typedef enum var shmode_e autocvar_sh_realistic = SHMODE_SLAUGHTER; var shmode_e g_chosen_mode; +/* enable forcerespawn */ +var int autocvar_mp_forcerespawn = 1; + /* enable team changing */ var int autocvar_sh_allowteamchange = 1; +/* enable map configs */ +var int autocvar_sh_levelexec = 1; + /* limit the amount of scientists that can spawn by default */ var int autocvar_sh_scimax = 5; -var int autocvar_sh_scialert = FALSE; - /* default speed for scientists */ var int autocvar_sh_scispeed = 40; diff --git a/src/server/gamerules.qc b/src/server/gamerules.qc index e4c03ac..814c3a1 100644 --- a/src/server/gamerules.qc +++ b/src/server/gamerules.qc @@ -333,7 +333,9 @@ HLGameRules::PlayerDeath(NSClientPlayer pl) Sound_Play(pl, CHAN_AUTO, "player.die"); /* force respawn */ - pl.ScheduleThink(PutClientInServer, 4.0f); + if (cvar("mp_forcerespawn") == 1) { + pl.ScheduleThink(PutClientInServer, 4.0f); + } /* have we gone over the fraglimit? */ CheckRules(); @@ -374,15 +376,50 @@ HLGameRules::PlayerSpawn(NSClientPlayer pp) forceinfokey(pl, "*spec", "0"); forceinfokey(pl, "*deaths", ftos(pl.deaths)); + + /* if we have team flags set, then join a team spawn + * search for the entity though in case we're on a non scihunt map */ if (pl.team == 1) { - spot = Spawn_SelectRandom("info_player_team1"); + for (entity e = world; (e = find( e, ::classname, "info_player_team1"));) { + spot = Spawn_SelectRandom("info_player_team1"); + } + } else if (pl.team == 2) { - spot = Spawn_SelectRandom("info_player_team2"); + for (entity e = world; (e = find( e, ::classname, "info_player_team2"));) { + spot = Spawn_SelectRandom("info_player_team2"); + } } - if (!spot) { - spot = Spawn_SelectRandom("info_player_deathmatch"); + /* while different behaviour from original, this could be better for other gamemodes */ + for (entity e = world; (e = find( e, ::classname, "info_player_deathmatch"));) { + spot = Spawn_SelectRandom("info_player_deathmatch"); } + + + /* all gamemodes use scihunt team spawns by default */ + if (!spot) { + int r = floor(random(0,1)); + switch (r) { + case 0: + for (entity e = world; (e = find( e, ::classname, "info_player_team1"));) { + spot = Spawn_SelectRandom("info_player_team1"); + } + break; + case 1: + for (entity e = world; (e = find( e, ::classname, "info_player_team2"));) { + spot = Spawn_SelectRandom("info_player_team2"); + } + break; + } + } + + /* if nothing else is found, then look for standard half-life spawns (compat) */ + if (!spot) { + for (entity e = world; (e = find( e, ::classname, "info_player_start"));) { + spot = Spawn_SelectRandom("info_player_start"); + } + } + setorigin(pl, spot.origin); @@ -422,20 +459,68 @@ HLGameRules::HLGameRules(void) * have a race condition */ forceinfokey(world, "sci_count", "0"); + /* realistic is an odd name, allow people to use sv_gamemode as an alias */ + if (cvar("sv_gamemode")) { + cvar_set("sh_realistic",cvar_string("sv_gamemode")); + } else { + cvar_set("sv_gamemode",cvar_string("sh_realistic")); + } + /* if the previous map set this value but the current doesn't * then set the default */ cvar_set("sh_scispeed","40"); - /* just re-read this to prevent race conditions */ - readcmd(sprintf("exec maps/%s.cfg\n", mapname)); + cvar_set("fraglimit",cvar_string("mp_fraglimit")); + + cvar_set("timelimit",cvar_string("mp_timelimit")); + + /* this is in the settings.scr, leftover? */ + cvar_set("sh_levelexec",cvar_string("lvlconfig")); + + /* since Nuclide adopted levelexec, let's just set it like this for compat */ + cvar_set("sv_levelexec",cvar_string("sh_levelexec")); + + if (cvar("sh_levelexec") != 0) { + /* just re-read this to prevent race conditions */ + readcmd(sprintf("exec maps/%s.cfg\n", mapname)); + } /* always broadcast how many max scientists the server has set * but allow an override for server admins */ - if (cvar("sh_scimax_override") > 0) { + if (cvar("sh_scimax_override") != 0) { forceinfokey(world, "sv_scimax", cvar_string("sh_scimax_override")); } else { forceinfokey(world, "sv_scimax", cvar_string("sh_scimax")); } + +} + +bool +HLGameRules::ConsoleCommand(NSClientPlayer pp, string cmd) +{ + tokenize(cmd); + + switch (argv(0)) { + case "bot_add": + bot pete = (bot)Bot_AddQuick(); + Bot_RandomColormap(pete); + searchhandle pm = search_begin("models/player/*/*.mdl", TRUE, TRUE); + int r = floor(random(0, search_getsize(pm))); + string mdl = substring(search_getfilename(pm, r), 0, -5); + tokenizebyseparator(mdl, "/"); + forceinfokey(pete, "model", argv(2)); + search_end(pm); + break; + case "jumptest": + makevectors(pp.v_angle); + traceline(pp.origin + pp.view_ofs, pp.origin + pp.view_ofs + v_forward * 1024, FALSE, pp); + pp.velocity = Route_GetJumpVelocity(pp.origin, trace_endpos, pp.gravity); + break; + default: + return (false); + } + + return (true); } /* TEAMPLAY ONLY LOGIC */ @@ -468,7 +553,6 @@ SHTeamRules::PlayerTeamSpawn(NSClientPlayer pl) super::PlayerSpawn(pl); } - void SHTeamRules::ScientistKill(NSClientPlayer cl, entity sci) { @@ -555,7 +639,7 @@ SHTeamRules::SHTeamRules(void) /* invasion scientist death tracking */ void -SHRules::RegisterSciDeath(void) +SHInvasionRules::RegisterSciDeath(void) { super::RegisterSciDeath(); @@ -570,7 +654,18 @@ SHRules::RegisterSciDeath(void) } void -SHRules::SHRules(void) +SHInvasionRules::PlayerDeath(NSClientPlayer pl) +{ + pl = (player)pl; + + super::PlayerDeath(pl); + + pl.MakeTempSpectator(); + +} + +void +SHInvasionRules::SHInvasionRules(void) { } diff --git a/src/server/progs.src b/src/server/progs.src index 2b6df36..e2cd2e4 100644 --- a/src/server/progs.src +++ b/src/server/progs.src @@ -70,6 +70,8 @@ monster_scientist.qc ../../../valve/src/server/xen_plantlight.qc ../../../valve/src/server/ammo.qc +../../../src/botlib/include.src + shdata_parse.qc gamerules.qc gamerules_fear.qc @@ -84,8 +86,6 @@ server.qc ../../../valve/src/server/flashlight.qc ../../../valve/src/server/modelevent.qc -../../../src/botlib/include.src - ../../../valve/src/server/spawn.qc ../../../src/server/include.src