- 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
This commit is contained in:
Xylemon 2023-07-17 16:46:25 -07:00
parent 19c86f9807
commit d546b39546
3 changed files with 118 additions and 18 deletions

View file

@ -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;

View file

@ -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,17 +376,52 @@ 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);
pl.angles = spot.angles;
@ -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)
{
}

View file

@ -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