From f15ee5ac6702e14a827a2643bfa893796c5659df Mon Sep 17 00:00:00 2001
From: IronClawTrem <louie.nutman@gmail.com>
Date: Sat, 29 Feb 2020 02:31:53 +0000
Subject: add !practise command

---
 src/game/g_active.c    | 17 +++++++++++++++
 src/game/g_admin.c     | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/game/g_admin.h     |  1 +
 src/game/g_buildable.c |  4 ----
 src/game/g_client.c    |  4 +++-
 src/game/g_cmds.c      | 30 +++++++++++++++++++-------
 src/game/g_combat.c    |  3 +++
 src/game/g_local.h     |  1 +
 src/game/g_main.c      | 16 +++++++++++---
 9 files changed, 117 insertions(+), 16 deletions(-)

(limited to 'src/game')

diff --git a/src/game/g_active.c b/src/game/g_active.c
index 5076873..3ef4d0b 100644
--- a/src/game/g_active.c
+++ b/src/game/g_active.c
@@ -1474,6 +1474,7 @@ void ClientThink_real( gentity_t *ent )
   int       msec;
   usercmd_t *ucmd;
   int       real_pm_type;
+  pTeam_t   team;
 
   client = ent->client;
 
@@ -1923,6 +1924,22 @@ void ClientThink_real( gentity_t *ent )
     bubble = G_TempEntity( client->ps.origin, EV_PLAYER_TELEPORT_OUT );
     bubble->s.clientNum = ent->s.clientNum;
   }
+
+  if( g_practise.integer )
+  {
+    if( team = PTE_ALIENS )
+    {
+      if( client->pers.credit < 9 )
+        G_AddCreditToClient( client, 9, qtrue );
+    }
+    if( team = PTE_HUMANS )
+    {
+      if( client->pers.credit < 2000 )
+        G_AddCreditToClient( client, 2000, qtrue );
+      else if( client->pers.credit > 2000 )
+        G_AddCreditToClient( client, -2000, qtrue );
+    }
+  }
 }
 
 /*
diff --git a/src/game/g_admin.c b/src/game/g_admin.c
index 356369c..8817432 100644
--- a/src/game/g_admin.c
+++ b/src/game/g_admin.c
@@ -451,6 +451,11 @@ g_admin_cmd_t g_admin_cmds[ ] =
     {"range", G_admin_range, "range",
       "changes a player's bite/swipe/chomp range",
       "[^3name|slot#^7] [^5range^7]"
+    },
+
+    {"practise", G_admin_practise, "practise",
+      "enables practise mode",
+      "[^3on|off^7]"
     }
 
   };
@@ -8663,3 +8668,55 @@ qboolean G_admin_range( gentity_t *ent, int skiparg )
 	return qtrue;
 
 }
+
+qboolean G_admin_practise( gentity_t *ent, int skiparg )
+{
+	int minargc;
+	char arg[ MAX_STRING_CHARS ];
+	minargc = 2 + skiparg;
+
+	if( G_SayArgc() < minargc )
+	{
+		ADMP( "^3!practise: ^7usage: !practise [on|off]\n" );
+		return qfalse;
+	}
+
+	G_SayArgv( 1 + skiparg, arg, sizeof( arg ) );
+
+	if( !Q_stricmp( arg, "on" ) )
+	{
+		if( g_practise.integer )
+		{
+			ADMP( "^3!practise: ^7practise mode is already on\n" );
+			return qfalse;
+		}
+		trap_Cvar_Set( "g_practise", "1" );
+		trap_Cvar_Set( "g_alienStage", "2" );
+		trap_Cvar_Set( "g_humanStage", "2" );
+		strcpy( arg, "^2enabled^7" );
+	}
+	else if( !Q_stricmp( arg, "off" ) )
+	{
+		if( !g_practise.integer )
+		{
+			ADMP( "^3!practise: ^7practise mode is already off\n" );
+			return qfalse;
+		}
+		trap_Cvar_Set( "g_practise", "0" );
+		strcpy( arg, "^1disabled^7" );
+	}
+	else
+	{
+		ADMP( "^3!practise: ^7usage: !practise [on|off]\n" );
+		return qfalse;
+	}
+
+	ent->flags ^= FL_NOTARGET;
+
+	AP( va( "print \"^3!practise: ^7practise mode was %s by %s\n\"",
+	arg,
+	( ent ) ? G_admin_adminPrintName( ent ) : "console" ) );
+
+	return qtrue;
+
+}
diff --git a/src/game/g_admin.h b/src/game/g_admin.h
index 9a03f2e..230d662 100644
--- a/src/game/g_admin.h
+++ b/src/game/g_admin.h
@@ -313,6 +313,7 @@ qboolean G_admin_switch( gentity_t *ent, int skiparg );
 qboolean G_admin_drug( gentity_t *ent, int skiparg );
 qboolean G_admin_god( gentity_t *ent, int skiparg );
 qboolean G_admin_range( gentity_t *ent, int skiparg );
+qboolean G_admin_practise( gentity_t *ent, int skiparg );
 
 void G_admin_print( gentity_t *ent, char *m );
 void G_admin_buffer_print( gentity_t *ent, char *m );
diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c
index 461c2d0..1117aa7 100644
--- a/src/game/g_buildable.c
+++ b/src/game/g_buildable.c
@@ -1986,9 +1986,6 @@ void HMedistat_Think( gentity_t *self )
       {
         player = &g_entities[ entityList[ i ] ];
 
-    if( player->flags & FL_NOTARGET )
-      continue; // notarget cancels even beneficial effects?
-
         if( player->client && player->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
         {
           if( player->health < player->client->ps.stats[ STAT_MAX_HEALTH ] &&
@@ -3523,7 +3520,6 @@ static gentity_t *G_Build( gentity_t *builder, buildable_t buildable, vec3_t ori
   built->splashMethodOfDeath = BG_FindMODForBuildable( buildable );
 
   built->nextthink = BG_FindNextThinkForBuildable( buildable );
-
   built->takedamage = qtrue;
   built->spawned = qfalse;
   built->buildTime = built->s.time = level.time;
diff --git a/src/game/g_client.c b/src/game/g_client.c
index 6a8bcc5..db8e895 100644
--- a/src/game/g_client.c
+++ b/src/game/g_client.c
@@ -1863,7 +1863,9 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles
   ent->watertype = 0;
   ent->flags = 0;
   if( ent->client->pers.godMode )
-    ent->flags = FL_GODMODE;
+    ent->flags += FL_GODMODE;
+  if( g_practise.integer )
+   ent->flags += FL_NOTARGET;
 
   //TA: calculate each client's acceleration
   ent->evaluateAcceleration = qtrue;
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index 4f0f919..6846a16 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -2757,14 +2757,17 @@ void Cmd_Class_f( gentity_t *ent )
 
     if( ent->client->pers.teamSelection == PTE_ALIENS )
     {
-      if( newClass != PCL_ALIEN_BUILDER0 &&
-          newClass != PCL_ALIEN_BUILDER0_UPG &&
-          newClass != PCL_ALIEN_LEVEL0 )
+      if( !g_practise.integer )
       {
-        trap_SendServerCommand( ent-g_entities,
-          va( "print \"You cannot spawn with class %s\n\"", s ) );
-        return;
-      } 
+        if( newClass != PCL_ALIEN_BUILDER0 &&
+            newClass != PCL_ALIEN_BUILDER0_UPG &&
+            newClass != PCL_ALIEN_LEVEL0 )
+        {
+          trap_SendServerCommand( ent-g_entities,
+            va( "print \"You cannot spawn with class %s\n\"", s ) );
+          return;
+        }
+      }
       
       if( !BG_ClassIsAllowed( newClass ) )
       {
@@ -2781,7 +2784,8 @@ void Cmd_Class_f( gentity_t *ent )
         return;
       }
       
-      if( ent->client->pers.denyBuild && ( newClass==PCL_ALIEN_BUILDER0 || newClass==PCL_ALIEN_BUILDER0_UPG ) )
+      if( ent->client->pers.denyBuild && ( newClass==PCL_ALIEN_BUILDER0 || newClass==PCL_ALIEN_BUILDER0_UPG )
+        || g_practise.integer && ( newClass==PCL_ALIEN_BUILDER0 || newClass==PCL_ALIEN_BUILDER0_UPG ) )
       {
         trap_SendServerCommand( ent-g_entities, "print \"Your building rights have been revoked\n\"" );
         return;
@@ -2805,12 +2809,22 @@ void Cmd_Class_f( gentity_t *ent )
       else if( !Q_stricmp( s, BG_FindNameForWeapon( WP_HBUILD ) ) &&
                BG_WeaponIsAllowed( WP_HBUILD ) )
       {
+        if( g_practise.integer )
+        {
+          trap_SendServerCommand( ent-g_entities, "print \"Your building rights have been revoked\n\"" );
+          return;
+        }
         ent->client->pers.humanItemSelection = WP_HBUILD;
       }
       else if( !Q_stricmp( s, BG_FindNameForWeapon( WP_HBUILD2 ) ) &&
                BG_WeaponIsAllowed( WP_HBUILD2 ) &&
                BG_FindStagesForWeapon( WP_HBUILD2, g_humanStage.integer ) )
       {
+        if( g_practise.integer )
+        {
+          trap_SendServerCommand( ent-g_entities, "print \"Your building rights have been revoked\n\"" );
+          return;
+        }
         ent->client->pers.humanItemSelection = WP_HBUILD2;
       }
       else
diff --git a/src/game/g_combat.c b/src/game/g_combat.c
index 5350895..85880ef 100644
--- a/src/game/g_combat.c
+++ b/src/game/g_combat.c
@@ -1336,6 +1336,9 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
     
     if(targ->s.eType == ET_BUILDABLE && g_cheats.integer && g_devmapNoStructDmg.integer)
       return;
+
+    if( targ->s.eType == ET_BUILDABLE && g_practise.integer )
+      return;
   }
 
   // add to the attacker's hit counter
diff --git a/src/game/g_local.h b/src/game/g_local.h
index e673583..a77a5d6 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -1503,6 +1503,7 @@ extern  vmCvar_t  g_schachtmeisterAutobahnMessage;
 extern  vmCvar_t  g_adminAutobahnNotify;
 extern  vmCvar_t  g_maxGhosts;
 extern  vmCvar_t  g_specNoclip;
+extern  vmCvar_t  g_practise;
 
 void      trap_Printf( const char *fmt );
 void      trap_Error( const char *fmt );
diff --git a/src/game/g_main.c b/src/game/g_main.c
index a95dd5d..b3fe4a2 100644
--- a/src/game/g_main.c
+++ b/src/game/g_main.c
@@ -245,6 +245,7 @@ vmCvar_t  g_schachtmeisterAutobahnMessage;
 vmCvar_t  g_adminAutobahnNotify;
 vmCvar_t  g_maxGhosts;
 vmCvar_t  g_specNoclip;
+vmCvar_t  g_practise;
 
 static cvarTable_t   gameCvarTable[ ] =
 {
@@ -468,7 +469,8 @@ static cvarTable_t   gameCvarTable[ ] =
   { &g_schachtmeisterAutobahnMessage, "g_schachtmeisterAutobahnMessage", "Your host is blacklisted.", CVAR_ARCHIVE, 0, qfalse },
   { &g_adminAutobahnNotify, "g_adminAutobahnNotify", "1", CVAR_ARCHIVE, 0, qfalse },
   { &g_maxGhosts, "g_maxGhosts", "0", CVAR_ARCHIVE, 0, qfalse },
-  { &g_specNoclip, "g_specNoclip", "0", CVAR_ARCHIVE, 0, qtrue }
+  { &g_specNoclip, "g_specNoclip", "0", CVAR_ARCHIVE, 0, qtrue },
+  { &g_practise, "g_practise", "0", CVAR_ARCHIVE, 0, qfalse }
 };
 
 static int gameCvarTableSize = sizeof( gameCvarTable ) / sizeof( gameCvarTable[ 0 ] );
@@ -860,8 +862,16 @@ void G_InitGame( int levelTime, int randomSeed, int restart )
     G_PrintRotations( );
 
   //reset stages
-  trap_Cvar_Set( "g_alienStage", va( "%d", S1 ) );
-  trap_Cvar_Set( "g_humanStage", va( "%d", S1 ) );
+  if( g_practise.integer )
+  {
+    trap_Cvar_Set( "g_alienStage", "2" );
+    trap_Cvar_Set( "g_humanStage", "2" );
+  }
+  else
+  {
+    trap_Cvar_Set( "g_alienStage", va( "%d", S1 ) );
+    trap_Cvar_Set( "g_humanStage", va( "%d", S1 ) );
+  }
   trap_Cvar_Set( "g_alienKills", 0 );
   trap_Cvar_Set( "g_humanKills", 0 );
   trap_Cvar_Set( "g_suddenDeath", 0 );
-- 
cgit