Hey,
This feature was demanded by one of the guys (klepto) on the Dretchstorm server.
It allows for the alien team to, as a last resort, spawn extra grangers for a rebuild.
Written in the tremfusion codebase; here's the diff:
diff -r d98736eddde5 src/game/g_cmds.c
--- a/src/game/g_cmds.c Wed Aug 06 11:38:23 2008 +0800
+++ b/src/game/g_cmds.c Sun Aug 10 16:53:28 2008 -0400
@@ -1830,6 +1830,86 @@ void Cmd_Class_f( gentity_t *ent )
}
}
+static void Cmd_PoopGranger_f( gentity_t *ent ) {
+ int clientNum;
+ gentity_t *granger;
+ vec3_t anus_origin;
+ vec3_t anus_vector;
+ vec3_t damage_angles;
+ vec3_t temp;
+ vec3_t up = { 0.0f, 0.0f, 1.0f };
+ extern vmCvar_t g_tyrantPoop;
+
+ // check permissions and classes etc
+ if ( g_tyrantPoop.integer == 0 )
+ return;
+
+ if( ent->client->pers.teamSelection != TEAM_ALIENS || ent->client->sess.spectatorState != SPECTATOR_NOT)
+ return;
+
+ if( ent->client->pers.classSelection != PCL_ALIEN_LEVEL4 ) {
+ trap_SendServerCommand( ent-g_entities, "print \"poop: Only tyrants can poop grangers!\n\"");
+ return;
+ }
+
+ // pick the next sucker...
+ clientNum = G_PeekSpawnQueue( &level.alienSpawnQueue );
+ if( clientNum < 0 ) {
+ trap_SendServerCommand( ent-g_entities, "print \"poop: No larvae are queued up!\n\"");
+ return;
+ }
+ granger = &g_entities[ clientNum ];
+
+ // calculate the spawn position
+ AngleVectors(ent->client->ps.viewangles, anus_vector, NULL, NULL);
+ anus_vector[PLANE_Z] = 0;
+ VectorNormalize(anus_vector);
+ VectorScale(anus_vector, -75, anus_vector);
+ VectorAdd(anus_vector, ent->s.origin, anus_origin);
+
+ // check to make sure there's room to spawn
+ VectorCopy(granger->s.origin, temp);
+ VectorCopy(anus_origin, granger->s.origin);
+ if ( G_RoomForClassChange(granger, PCL_ALIEN_BUILDER0, anus_origin) == qfalse )
+ {
+ VectorCopy(temp, granger->s.origin);
+ trap_SendServerCommand( ent-g_entities, "print \"poop: No room to poop here, fatass!\n\"");
+ return;
+ }
+
+ // make the granger face the tyrant's butt when it spawns
+ VectorCopy(ent->client->ps.viewangles, granger->client->ps.viewangles);
+ granger->client->ps.viewangles[PITCH] = -25.0f;
+ granger->client->ps.viewangles[YAW] -= 180.0f; //compensating for clientspawn code
+
+ // set health
+ granger->client->pers.maxHealth =
+ granger->client->ps.stats[ STAT_MAX_HEALTH ] =
+ granger->health =
+ BG_Class( ent->client->pers.classSelection )->health;
+
+ // dequeue from spawn queue and set flags etc
+ G_PopSpawnQueue( &level.alienSpawnQueue );
+ granger->client->sess.spectatorState = SPECTATOR_NOT;
+ granger->client->pers.classSelection = PCL_ALIEN_BUILDER0;
+ granger->client->ps.stats[ STAT_CLASS ] = PCL_ALIEN_BUILDER0;
+
+ // spawn the client
+ ClientUserinfoChanged( clientNum );
+ ClientSpawn( granger, ent, anus_origin, granger->client->ps.viewangles );
+
+ // grangers are large objects. Large, lumpy, and difficult (read: painful) to pass.
+ VectorCopy(ent->r.currentAngles, damage_angles);
+ G_Damage(granger, granger, granger, damage_angles, ent->r.currentOrigin, ABUILDER_HEALTH - 2, 0, MOD_UNKNOWN);
+ VectorScale(damage_angles, -1, damage_angles);
+ G_Damage(ent, ent, ent, damage_angles, anus_origin, LEVEL4_HEALTH - 10, 0, MOD_UNKNOWN);
+
+ // be crude. it's fun.
+ trap_SendServerCommand( granger-g_entities, "cp \"YOU HAVE BEEN ^1POOPED^7 BY A TYRANT! EIWW!\"");
+ G_AddPredictableEvent( granger, EV_ALIEN_EVOLVE, DirToByte( up ) );
+ anus_vector[PLANE_Z]=-10; // aim the tube spray down a bit
+ G_AddEvent( ent, EV_ALIEN_ACIDTUBE, DirToByte( anus_vector ) );
+}
/*
=================
@@ -3062,6 +3142,8 @@ commands_t cmds[ ] = {
{ "itemdeact", CMD_HUMAN|CMD_LIVING, Cmd_DeActivateItem_f },
{ "itemtoggle", CMD_HUMAN|CMD_LIVING, Cmd_ToggleItem_f },
{ "reload", CMD_HUMAN|CMD_LIVING, Cmd_Reload_f },
+
+ { "poop", CMD_ALIEN|CMD_LIVING, Cmd_PoopGranger_f }
};
static int numCmds = sizeof( cmds ) / sizeof( cmds[ 0 ] );
diff -r d98736eddde5 src/game/g_main.c
--- a/src/game/g_main.c Wed Aug 06 11:38:23 2008 +0800
+++ b/src/game/g_main.c Sun Aug 10 16:53:28 2008 -0400
@@ -129,6 +129,8 @@ vmCvar_t g_privateMessages;
vmCvar_t g_tag;
+vmCvar_t g_tyrantPoop;
+
static cvarTable_t gameCvarTable[ ] =
{
// don't override the cheat state set by the system
@@ -242,7 +244,8 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_privateMessages, "g_privateMessages", "1", CVAR_ARCHIVE, 0, qfalse },
- { &g_tag, "g_tag", "main", CVAR_INIT, 0, qfalse }
+ { &g_tag, "g_tag", "main", CVAR_INIT, 0, qfalse },
+ { &g_tyrantPoop, "g_tyrantPoop", "0", CVAR_ARCHIVE, 0, qfalse }
};
static int gameCvarTableSize = sizeof( gameCvarTable ) / sizeof( gameCvarTable[ 0 ] );
Originally posted here:
http://groups.obliter8.com/node/4085It's running on the dretchstorm server now...feel free to try it out.