Some more work done on the gamemodes. Team modes + standard hunt is now implemented but not quite tested. Still needs 'changeteam' cmd etc.
This commit is contained in:
parent
eda8140127
commit
fbb2df4b6e
8 changed files with 265 additions and 42 deletions
31
src/client/cmds.qc
Normal file
31
src/client/cmds.qc
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 Marco Cawthorne <marco@icculus.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
int
|
||||
ClientGame_ConsoleCommand(void)
|
||||
{
|
||||
switch(argv(0)) {
|
||||
case "+sciboard":
|
||||
g_sciboard = true;
|
||||
break;
|
||||
case "-sciboard":
|
||||
g_sciboard = false;
|
||||
break;
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
63
src/client/draw.qc
Normal file
63
src/client/draw.qc
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2022 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
var bool g_sciboard = false;
|
||||
|
||||
void
|
||||
ClientGame_PreDraw(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
SH_DrawSciBoard(void)
|
||||
{
|
||||
string line;
|
||||
vector pos;
|
||||
|
||||
line = "^xFA0Scientist round score info:";
|
||||
pos = (video_res / 2);
|
||||
pos[0] -= (Font_StringWidth(line, FALSE, FONT_CON) / 2);
|
||||
pos[1] -= 64;
|
||||
Font_DrawText(pos, line, FONT_CON);
|
||||
|
||||
|
||||
line = sprintf("^xFA0Team Red: %d kills", serverkeyfloat("teamkills_1"));
|
||||
pos = (video_res / 2);
|
||||
pos[0] -= (Font_StringWidth(line, FALSE, FONT_CON) / 2);
|
||||
pos[1] -= 36;
|
||||
Font_DrawText(pos, line, FONT_CON);
|
||||
|
||||
|
||||
line = sprintf("^xFA0Team Blue: %d kills", serverkeyfloat("teamkills_2"));
|
||||
pos = (video_res / 2);
|
||||
pos[0] -= (Font_StringWidth(line, FALSE, FONT_CON) / 2);
|
||||
pos[1] -= 24;
|
||||
Font_DrawText(pos, line, FONT_CON);
|
||||
|
||||
|
||||
line = sprintf("^xFA0Scientists left: %d", serverkeyfloat("sci_count"));
|
||||
pos = (video_res / 2);
|
||||
pos[0] -= (Font_StringWidth(line, FALSE, FONT_CON) / 2);
|
||||
Font_DrawText(pos, line, FONT_CON);
|
||||
}
|
||||
|
||||
void
|
||||
ClientGame_PostDraw(void)
|
||||
{
|
||||
if (g_sciboard)
|
||||
SH_DrawSciBoard();
|
||||
}
|
|
@ -19,12 +19,12 @@
|
|||
../shared/include.src
|
||||
|
||||
../../../valve/src/client/damage.qc
|
||||
../../../base/src/client/draw.qc
|
||||
draw.qc
|
||||
../../../valve/src/client/init.qc
|
||||
../../../valve/src/client/flashlight.qc
|
||||
../../../valve/src/client/player.qc
|
||||
../../../valve/src/client/entities.qc
|
||||
../../../valve/src/client/cmds.qc
|
||||
cmds.qc
|
||||
../../../valve/src/client/game_event.qc
|
||||
../../../valve/src/client/camera.qc
|
||||
../../../valve/src/client/viewmodel.qc
|
||||
|
|
|
@ -18,32 +18,45 @@
|
|||
|
||||
class HLGameRules:CGameRules
|
||||
{
|
||||
int m_iScientistsAlive;
|
||||
|
||||
float m_flRestockTimer;
|
||||
float m_flBreakRespawnTimer;
|
||||
|
||||
/* client */
|
||||
virtual void(NSClientPlayer) PlayerSpawn;
|
||||
virtual void(NSClientPlayer) PlayerConnect;
|
||||
virtual void(NSClientPlayer) PlayerDisconnect;
|
||||
virtual void(NSClientPlayer) PlayerKill;
|
||||
virtual void(NSClientPlayer) PlayerDeath;
|
||||
virtual void(NSClientPlayer) PlayerPostFrame;
|
||||
virtual void(NSClientPlayer, entity) ScientistKill;
|
||||
virtual void(void) RegisterSciDeath;
|
||||
|
||||
virtual void(NSClientPlayer) LevelDecodeParms;
|
||||
virtual void(NSClientPlayer) LevelChangeParms;
|
||||
virtual void(void) LevelNewParms;
|
||||
virtual void(void) FrameStart;
|
||||
virtual bool(void) IsMultiplayer;
|
||||
virtual void(void) RestartRound;
|
||||
|
||||
virtual void(void) CountScientists;
|
||||
|
||||
void(void) HLGameRules;
|
||||
};
|
||||
|
||||
class SHTeamRules:HLGameRules
|
||||
{
|
||||
int m_iKillsTeam1;
|
||||
int m_iKillsTeam2;
|
||||
|
||||
int m_iScoreTeam1;
|
||||
int m_iScoreTeam2;
|
||||
|
||||
void(void) SHTeamRules;
|
||||
|
||||
virtual void(NSClientPlayer) PlayerSpawn;
|
||||
virtual bool(void) IsTeamPlay;
|
||||
virtual void(void) AddTeam1Kill;
|
||||
virtual void(void) AddTeam2Kill;
|
||||
virtual void(NSClientPlayer, entity) ScientistKill;
|
||||
};
|
||||
|
||||
/* Standard Hunting (0):
|
||||
|
@ -51,8 +64,9 @@ class SHTeamRules:HLGameRules
|
|||
*/
|
||||
class SHGameHunt:SHTeamRules
|
||||
{
|
||||
|
||||
void(void) SHGameHunt;
|
||||
|
||||
virtual void(void) RegisterSciDeath;
|
||||
};
|
||||
|
||||
/* Stealth Hunting (1):
|
||||
|
@ -74,7 +88,7 @@ class SHGameSlaughter:HLGameRules
|
|||
};
|
||||
|
||||
/* Live in Fear (3):
|
||||
Unique round-based gamemode where players have to only kill an evil randomly selected player controlled scientist causing chaos. Those who kill good scientists are punished with lost points. The evil scientist gains one point from every kill (NPC or Players). Scientists respawn. This is the only gamemode where there are no teams.
|
||||
Unique round-based gamemode where players have to only kill an evil randomly selected player controlled scientist causing chaos. Those who kill good scientists are punished with lost points. The evil scientist gains one point from every kill (NPC or Players). Scientists respawn.
|
||||
*/
|
||||
class SHGameFear:HLGameRules
|
||||
{
|
||||
|
@ -83,7 +97,7 @@ class SHGameFear:HLGameRules
|
|||
};
|
||||
|
||||
/* Madness (4):
|
||||
Unique gamemode where scientists attack themselves and the players. Scientists inject players and NPCs only once with a poison that slowly drains their health to 0. The scientists also play a sound (sh/hide_laugh.wav) when they get a sucessful kill and are still alive. Scientists respawn. We use to have something similar, still in the logic?
|
||||
Unique gamemode where scientists attack themselves and the players. Scientists inject players and NPCs only once with a poison that slowly drains their health to 0. The scientists also play a sound (sh/hide_laugh.wav) when they get a sucessful kill and are still alive. Scientists respawn.
|
||||
*/
|
||||
class SHGameMadness:HLGameRules
|
||||
{
|
||||
|
@ -91,7 +105,6 @@ class SHGameMadness:HLGameRules
|
|||
void(void) SHGameMadness;
|
||||
};
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SHMODE_STANDARD = 0,
|
||||
|
@ -101,5 +114,5 @@ typedef enum
|
|||
SHMODE_MADNESS
|
||||
} shmode_e;
|
||||
|
||||
|
||||
var shmode_e autocvar_sv_realistic = SHMODE_SLAUGHTER;
|
||||
var shmode_e g_chosen_mode;
|
||||
|
|
|
@ -17,6 +17,26 @@
|
|||
var int autocvar_sh_insanity = 10;
|
||||
var int autocvar_sv_playerkeepalive = TRUE;
|
||||
|
||||
void
|
||||
HLGameRules::RestartRound(void)
|
||||
{
|
||||
/* respawn all players and scientists */
|
||||
for (entity e = world; (e = find( e, ::classname, "player"));) {
|
||||
PlayerSpawn((NSClientPlayer)e);
|
||||
}
|
||||
for (entity e = world; (e = find( e, ::classname, "monster_scientist"));) {
|
||||
NSEntity sci = (NSEntity)e;
|
||||
sci.Respawn();
|
||||
}
|
||||
env_message_broadcast("New round, let's go!");
|
||||
}
|
||||
|
||||
void
|
||||
HLGameRules::RegisterSciDeath(void)
|
||||
{
|
||||
CountScientists();
|
||||
}
|
||||
|
||||
bool
|
||||
HLGameRules::IsMultiplayer(void)
|
||||
{
|
||||
|
@ -232,31 +252,15 @@ HLGameRules::PlayerPostFrame(NSClientPlayer pp)
|
|||
}
|
||||
|
||||
void
|
||||
HLGameRules::PlayerConnect(NSClientPlayer pl)
|
||||
HLGameRules::CountScientists(void)
|
||||
{
|
||||
if (Plugin_PlayerConnect(pl) == FALSE)
|
||||
bprint(PRINT_HIGH, sprintf("%s connected\n", pl.netname));
|
||||
}
|
||||
m_iScientistsAlive = 0;
|
||||
for (entity s = world; (s = find(s, ::classname, "monster_scientist"));) {
|
||||
if (s.solid == SOLID_BBOX || s.solid == SOLID_SLIDEBOX)
|
||||
m_iScientistsAlive++;
|
||||
}
|
||||
|
||||
void
|
||||
HLGameRules::PlayerDisconnect(NSClientPlayer pl)
|
||||
{
|
||||
bprint(PRINT_HIGH, sprintf("%s disconnected\n", pl.netname));
|
||||
|
||||
/* Make this unusable */
|
||||
pl.solid = SOLID_NOT;
|
||||
pl.movetype = MOVETYPE_NONE;
|
||||
pl.modelindex = 0;
|
||||
pl.health = 0;
|
||||
pl.takedamage = 0;
|
||||
pl.SendFlags = PLAYER_MODELINDEX;
|
||||
}
|
||||
|
||||
void
|
||||
HLGameRules::PlayerKill(NSClientPlayer pp)
|
||||
{
|
||||
player pl = (player)pp;
|
||||
Damage_Apply(pl, pl, pl.health, WEAPON_NONE, DMG_SKIP_ARMOR);
|
||||
forceinfokey(world, "sci_count", sprintf("%i", m_iScientistsAlive));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -334,7 +338,13 @@ HLGameRules::FrameStart(void)
|
|||
void
|
||||
HLGameRules::HLGameRules(void)
|
||||
{
|
||||
CGameRules::CGameRules();
|
||||
forceinfokey(world, "teams", "0");
|
||||
forceinfokey(world, "team_1", "");
|
||||
forceinfokey(world, "team_2", "");
|
||||
forceinfokey(world, "teamscore_1", "0");
|
||||
forceinfokey(world, "teamscore_2", "0");
|
||||
forceinfokey(world, "teamkills_1", "0");
|
||||
forceinfokey(world, "teamkills_2", "0");
|
||||
}
|
||||
|
||||
/* TEAMPLAY ONLY LOGIC */
|
||||
|
@ -344,8 +354,71 @@ SHTeamRules::IsTeamPlay(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SHTeamRules::PlayerSpawn(NSClientPlayer cl)
|
||||
{
|
||||
int red = 0;
|
||||
int blue = 0;
|
||||
|
||||
super::PlayerSpawn(cl);
|
||||
|
||||
/* remove this if you want an auto-balance upon every death */
|
||||
if (cl.team != 0)
|
||||
return;
|
||||
|
||||
for (entity e = world; (e = find( e, ::classname, "player"));) {
|
||||
if (e == cl)
|
||||
continue;
|
||||
if (e.team == 1)
|
||||
red++;
|
||||
if (e.team == 2)
|
||||
blue++;
|
||||
}
|
||||
|
||||
/* assign to whatever team has fewer players */
|
||||
if (red > blue)
|
||||
cl.team = 2;
|
||||
else
|
||||
cl.team = 1;
|
||||
|
||||
forceinfokey(cl, "*team", sprintf("%d", cl.team));
|
||||
}
|
||||
|
||||
void
|
||||
SHTeamRules::ScientistKill(NSClientPlayer cl, entity sci)
|
||||
{
|
||||
super::ScientistKill(cl, sci);
|
||||
|
||||
if (cl.team == 2)
|
||||
AddTeam2Kill();
|
||||
else if (cl.team == 1)
|
||||
AddTeam1Kill();
|
||||
}
|
||||
|
||||
void
|
||||
SHTeamRules::AddTeam1Kill(void)
|
||||
{
|
||||
m_iKillsTeam1++;
|
||||
forceinfokey(world, "teamkills_1", sprintf("%i", m_iKillsTeam1));
|
||||
}
|
||||
|
||||
void
|
||||
SHTeamRules::AddTeam2Kill(void)
|
||||
{
|
||||
m_iKillsTeam2++;
|
||||
forceinfokey(world, "teamkills_2", sprintf("%i", m_iKillsTeam2));
|
||||
}
|
||||
|
||||
void
|
||||
SHTeamRules::SHTeamRules(void)
|
||||
{
|
||||
|
||||
m_iKillsTeam1 = 0;
|
||||
m_iKillsTeam2 = 0;
|
||||
forceinfokey(world, "teamkills_1", sprintf("%i", m_iKillsTeam1));
|
||||
forceinfokey(world, "teamkills_2", sprintf("%i", m_iKillsTeam2));
|
||||
forceinfokey(world, "teams", "2");
|
||||
forceinfokey(world, "team_1", "Red");
|
||||
forceinfokey(world, "teamscore_1", "0");
|
||||
forceinfokey(world, "team_2", "Blue");
|
||||
forceinfokey(world, "teamscore_2", "0");
|
||||
}
|
||||
|
|
|
@ -1,3 +1,31 @@
|
|||
void
|
||||
SHGameHunt::RegisterSciDeath(void)
|
||||
{
|
||||
super::RegisterSciDeath();
|
||||
|
||||
if (m_iScientistsAlive > 0)
|
||||
return;
|
||||
|
||||
switch (g_chosen_mode) {
|
||||
case SHMODE_STANDARD:
|
||||
if (m_iKillsTeam1 > m_iKillsTeam2) {
|
||||
m_iScoreTeam1++;
|
||||
env_message_broadcast("Red team has won!");
|
||||
} else if (m_iKillsTeam1 > m_iKillsTeam2) {
|
||||
m_iScoreTeam2++;
|
||||
env_message_broadcast("Blue team has won!");
|
||||
} else {
|
||||
env_message_broadcast("Both teams are tied!");
|
||||
}
|
||||
|
||||
forceinfokey(world, "teamscore_1", sprintf("%i", m_iScoreTeam1));
|
||||
forceinfokey(world, "teamscore_2", sprintf("%i", m_iScoreTeam2));
|
||||
think = RestartRound;
|
||||
nextthink = time + 5.0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SHGameHunt::SHGameHunt(void)
|
||||
{
|
||||
|
|
|
@ -235,22 +235,31 @@ monster_scientist::Pain(void)
|
|||
void
|
||||
monster_scientist::Death(void)
|
||||
{
|
||||
bool deathcheck = false;
|
||||
HLGameRules rules = (HLGameRules)g_grMode;
|
||||
|
||||
StartleAllies();
|
||||
|
||||
if (style != MONSTER_DEAD) {
|
||||
HLGameRules rules = (HLGameRules)g_grMode;
|
||||
|
||||
if (g_dmg_eAttacker.flags & FL_CLIENT)
|
||||
rules.ScientistKill((player)g_dmg_eAttacker, (entity)this);
|
||||
|
||||
Plugin_PlayerObituary(g_dmg_eAttacker, this, g_dmg_iWeapon, g_dmg_iHitBody, g_dmg_iDamage);
|
||||
|
||||
SetFrame(SCIA_DIE_SIMPLE + floor(random(0, 6)));
|
||||
Sound_Speak(this, "monster_scientist.die");
|
||||
deathcheck = true;
|
||||
}
|
||||
|
||||
/* now mark our state as 'dead' */
|
||||
super::Death();
|
||||
|
||||
/* now we'll tell our kill function about it, since we're now legally dead */
|
||||
if (deathcheck == true) {
|
||||
rules.RegisterSciDeath();
|
||||
}
|
||||
|
||||
/* will not respawn by themselves in this mode */
|
||||
if (g_chosen_mode == SHMODE_STANDARD)
|
||||
return;
|
||||
|
||||
think = Respawn;
|
||||
nextthink = time + 10.0f;
|
||||
}
|
||||
|
@ -267,13 +276,15 @@ monster_scientist::OnPlayerUse(void)
|
|||
void
|
||||
monster_scientist::Respawn(void)
|
||||
{
|
||||
HLGameRules rules = (HLGameRules)g_grMode;
|
||||
|
||||
super::Respawn();
|
||||
m_iFlags |= MONSTER_CANFOLLOW;
|
||||
PlayerUse = OnPlayerUse;
|
||||
health = base_health = Skill_GetValue("scientist_health", 20);
|
||||
takedamage = DAMAGE_YES;
|
||||
|
||||
if (autocvar_sh_scialert) {
|
||||
if (autocvar_sh_scialert || g_chosen_mode == SHMODE_STANDARD) {
|
||||
m_iFlags |= MONSTER_FEAR;
|
||||
}
|
||||
|
||||
|
@ -299,6 +310,8 @@ monster_scientist::Respawn(void)
|
|||
m_flPitch = 100;
|
||||
netname = "Slick";
|
||||
}
|
||||
|
||||
rules.CountScientists();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
void
|
||||
Game_InitRules(void)
|
||||
{
|
||||
g_chosen_mode = autocvar_sv_realistic;
|
||||
|
||||
switch (autocvar_sv_realistic) {
|
||||
case SHMODE_STANDARD:
|
||||
g_grMode = spawn(SHGameHunt);
|
||||
|
|
Loading…
Reference in a new issue