summaryrefslogtreecommitdiff
path: root/src/game
diff options
context:
space:
mode:
Diffstat (limited to 'src/game')
-rw-r--r--src/game/bg_misc.c45
-rw-r--r--src/game/bg_public.h5
-rw-r--r--src/game/g_buildable.c37
-rw-r--r--src/game/g_client.c6
-rw-r--r--src/game/g_cmds.c272
-rw-r--r--src/game/g_local.h1
6 files changed, 269 insertions, 97 deletions
diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c
index d4d75462..3f36f2a9 100644
--- a/src/game/bg_misc.c
+++ b/src/game/bg_misc.c
@@ -238,6 +238,37 @@ buildableAttributes_t bg_buildableList[ ] =
qfalse //qboolean reactorTest;
},
{
+ BA_A_OBANK, //int buildNum;
+ "obank", //char *buildName;
+ "Organ Bank", //char *humanName;
+ "team_alien_obank", //char *entityName;
+ { "models/buildables/obank/obank.md3", 0, 0, 0 },
+ { -15, -15, -15 }, //vec3_t mins;
+ { 15, 15, 15 }, //vec3_t maxs;
+ TR_GRAVITY, //trType_t traj;
+ 0.0, //float bounce;
+ 100, //int buildPoints;
+ ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
+ 1000, //int health;
+ 50, //int damage;
+ 50, //int splashDamage;
+ 200, //int splashRadius;
+ MOD_ASPAWN, //int meansOfDeath;
+ BIT_ALIENS, //int team;
+ ( 1 << WP_ABUILD )|( 1 << WP_ABUILD2 ), //weapon_t buildWeapon;
+ BANIM_IDLE1, //int idleAnim;
+ -1, //int nextthink;
+ 0, //int turretFireSpeed;
+ 0, //int turretRange;
+ WP_NONE, //weapon_t turretProjType;
+ 0.5f, //float minNormal;
+ qtrue, //qboolean invertNormal;
+ qtrue, //qboolean creepTest;
+ 120, //int creepSize;
+ qfalse, //qboolean dccTest;
+ qfalse //qboolean reactorTest;
+ },
+ {
BA_H_SPAWN, //int buildNum;
"replicator", //char *buildName;
"Replicator", //char *humanName;
@@ -1862,10 +1893,14 @@ float BG_FindBuildDistForClass( int pclass )
BG_ClassCanEvolveFromTo
==============
*/
-qboolean BG_ClassCanEvolveFromTo( int fclass, int tclass )
+qboolean BG_ClassCanEvolveFromTo( int fclass, int tclass, int credits )
{
int i, j;
+ //base case
+ if( credits + 1 == 0 )
+ return qfalse;
+
if( tclass == PCL_NONE )
return qfalse;
@@ -1874,8 +1909,14 @@ qboolean BG_ClassCanEvolveFromTo( int fclass, int tclass )
if( bg_classList[ i ].classNum == fclass )
{
for( j = 0; j <= 3; j++ )
- if( bg_classList[ i ].children[ j ] == tclass ) return qtrue;
+ if( bg_classList[ i ].children[ j ] == tclass )
+ return qtrue;
+ for( j = 0; j <= 3; j++ )
+ if( BG_ClassCanEvolveFromTo( bg_classList[ i ].children[ j ],
+ tclass, credits - 1 ) == qtrue )
+ return qtrue;
+
return qfalse; //may as well return by this point
}
}
diff --git a/src/game/bg_public.h b/src/game/bg_public.h
index 84b313be..7d1c48f0 100644
--- a/src/game/bg_public.h
+++ b/src/game/bg_public.h
@@ -403,6 +403,7 @@ typedef enum
BA_A_BOOSTER,
BA_A_HOVEL,
+ BA_A_OBANK,
BA_H_SPAWN,
@@ -583,6 +584,8 @@ typedef enum
MN_A_NORMAL,
MN_A_HOVEL_OCCUPIED,
MN_A_HOVEL_BLOCKED,
+ MN_A_OBANK,
+ MN_A_NOFUNDS,
MN_H_SPAWN,
MN_H_BUILD,
@@ -1017,7 +1020,7 @@ float BG_FindStickyForClass( int pclass );
int BG_FindSteptimeForClass( int pclass );
qboolean BG_ClassHasAbility( int pclass, int ability );
float BG_FindBuildDistForClass( int pclass );
-qboolean BG_ClassCanEvolveFromTo( int fclass, int tclass );
+qboolean BG_ClassCanEvolveFromTo( int fclass, int tclass, int credits );
int BG_FindEvolveTimeForClass( int pclass );
int BG_FindValueOfClass( int pclass );
diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c
index 3ae84654..53f42ea2 100644
--- a/src/game/g_buildable.c
+++ b/src/game/g_buildable.c
@@ -799,10 +799,37 @@ void AHovel_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
trap_LinkEntity( self );
}
+
+
+
//==================================================================================
+
+/*
+================
+ABank_Activate
+
+Called when an alien activates an organ bank
+================
+*/
+void ABank_Activate( gentity_t *self, gentity_t *other, gentity_t *activator )
+{
+ //only aliens can activate this
+ if( activator->client->ps.stats[ STAT_PTEAM ] != PTE_ALIENS ) return;
+
+ G_AddPredictableEvent( activator, EV_MENU, MN_A_OBANK );
+}
+
+
+
+
+//==================================================================================
+
+
+
+
/*
================
ABooster_Touch
@@ -2046,6 +2073,12 @@ gentity_t *G_buildItem( gentity_t *builder, buildable_t buildable, vec3_t origin
built->pain = ASpawn_Pain;
break;
+ case BA_A_OBANK:
+ built->think = ABarricade_Think;
+ built->die = ASpawn_Die;
+ built->use = ABank_Activate;
+ break;
+
case BA_H_SPAWN:
built->die = HSpawn_Die;
built->think = HSpawn_Think;
@@ -2205,6 +2238,10 @@ void G_ValidateBuild( gentity_t *ent, buildable_t buildable )
G_AddPredictableEvent( ent, EV_MENU, MN_H_NOPOWER );
break;
+ case IBE_NODCC:
+ G_AddPredictableEvent( ent, EV_MENU, MN_H_NODCC );
+ break;
+
case IBE_SPWNWARN:
G_AddPredictableEvent( ent, EV_MENU, MN_A_SPWNWARN );
G_buildItem( ent, buildable, origin, ent->s.apos.trBase );
diff --git a/src/game/g_client.c b/src/game/g_client.c
index ef8efe0e..02fd38ec 100644
--- a/src/game/g_client.c
+++ b/src/game/g_client.c
@@ -633,7 +633,8 @@ void useBody( gentity_t *self, gentity_t *other, gentity_t *activator )
//check the client /can/ upgrade to another class
for( i = PCL_NONE + 1; i < PCL_NUM_CLASSES; i++ )
{
- if( BG_ClassCanEvolveFromTo( activator->client->ps.stats[ STAT_PCLASS ], i ) &&
+ if( BG_ClassCanEvolveFromTo( activator->client->ps.stats[ STAT_PCLASS ],
+ i, activator->client->ps.stats[ STAT_CREDIT ] ) &&
BG_FindStagesForClass( i, g_alienStage.integer ) )
break;
}
@@ -1419,6 +1420,9 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn )
client->ps.stats[ STAT_WEAPONS2 ] = 0;
client->ps.stats[ STAT_SLOTS ] = 0;
+ //no credit
+ client->ps.stats[ STAT_CREDIT ] = 0;
+
client->ps.eFlags = flags;
client->ps.clientNum = index;
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index 9eed943b..a3f5325e 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -628,6 +628,8 @@ void Cmd_Team_f( gentity_t *ent )
if( oldTeam != ent->client->pers.pteam )
{
+ level.bankCredits[ ent->client->ps.clientNum ] = 0;
+ ent->client->ps.stats[ STAT_BANK ] = 0;
ent->client->pers.pclass = 0;
ClientSpawn( ent, NULL );
}
@@ -1557,6 +1559,7 @@ void Cmd_Class_f( gentity_t *ent )
int clientNum;
gentity_t *body, *victim;
vec3_t distance;
+ vec3_t up = { 0.0f, 0.0f, 1.0f };
int length = 4096;
int i;
trace_t tr;
@@ -1590,49 +1593,62 @@ void Cmd_Class_f( gentity_t *ent )
//if a human corpse is nearby...
if( length <= 200 )
{
- ent->client->pers.pclass = BG_FindClassNumForName( s );
-
- if( ent->client->pers.pclass == PCL_NONE )
+ if( !Q_stricmp( s, "store" ) )
{
- trap_SendServerCommand( ent-g_entities, va("print \"Unknown class\n\"" ) );
- return;
+ //increment credits
+ ent->client->ps.stats[ STAT_CREDIT ]++;
+
+ //destroy body
+ G_AddEvent( victim, EV_GIB_ALIEN, DirToByte( up ) );
+ victim->freeAfterEvent = qtrue;
}
-
- //...check we can evolve to that class
- if( BG_ClassCanEvolveFromTo( ent->client->ps.stats[ STAT_PCLASS ],
- ent->client->pers.pclass ) ||
- BG_FindStagesForClass( ent->client->pers.pclass, g_alienStage.integer ) )
+ else
{
- //prevent lerping
- ent->client->ps.eFlags ^= EF_TELEPORT_BIT;
-
- //evolve
- ent->client->ps.stats[ STAT_PCLASS ] = PCL_NONE;
- ent->client->sess.sessionTeam = TEAM_FREE;
- ClientUserinfoChanged( clientNum );
- ent->client->ps.stats[ STAT_STATE ] |= SS_INFESTING;
- ent->client->lastInfestTime = level.time;
- ent->client->infestBody = victim;
+ //evolve now
+ ent->client->pers.pclass = BG_FindClassNumForName( s );
+
+ if( ent->client->pers.pclass == PCL_NONE )
+ {
+ trap_SendServerCommand( ent-g_entities, va("print \"Unknown class\n\"" ) );
+ return;
+ }
+
+ //...check we can evolve to that class
+ if( BG_ClassCanEvolveFromTo( ent->client->ps.stats[ STAT_PCLASS ],
+ ent->client->pers.pclass, ent->client->ps.stats[ STAT_CREDIT ] ) ||
+ BG_FindStagesForClass( ent->client->pers.pclass, g_alienStage.integer ) )
+ {
+ //prevent lerping
+ ent->client->ps.eFlags ^= EF_TELEPORT_BIT;
+
+ //evolve
+ ent->client->ps.stats[ STAT_PCLASS ] = PCL_NONE;
+ ent->client->sess.sessionTeam = TEAM_FREE;
+ ClientUserinfoChanged( clientNum );
+ ent->client->ps.stats[ STAT_STATE ] |= SS_INFESTING;
+ ent->client->lastInfestTime = level.time;
+ ent->client->infestBody = victim;
- VectorCopy( victim->s.pos.trBase, infestOrigin );
- infestOrigin[ 2 ] += 128;
+ VectorCopy( victim->s.pos.trBase, infestOrigin );
+ infestOrigin[ 2 ] += 128;
- VectorCopy( victim->s.angles, infestAngles );
+ VectorCopy( victim->s.angles, infestAngles );
- infestAngles[ PITCH ] = 90;
+ infestAngles[ PITCH ] = 90;
- G_SetOrigin( ent, infestOrigin );
- VectorCopy( infestOrigin, ent->client->ps.origin );
- SetClientViewAngle( ent, infestAngles );
+ G_SetOrigin( ent, infestOrigin );
+ VectorCopy( infestOrigin, ent->client->ps.origin );
+ SetClientViewAngle( ent, infestAngles );
- //so no one can claim this body as of now
- victim->killedBy = victim->s.powerups = MAX_CLIENTS;
- }
- else
- {
- ent->client->pers.pclass = PCL_NONE;
- trap_SendServerCommand( ent-g_entities, va("print \"You cannot evolve from your current class\n\"" ) );
- return;
+ //so no one can claim this body as of now
+ victim->killedBy = victim->s.powerups = MAX_CLIENTS;
+ }
+ else
+ {
+ ent->client->pers.pclass = PCL_NONE;
+ trap_SendServerCommand( ent-g_entities, va("print \"You cannot evolve from your current class\n\"" ) );
+ return;
+ }
}
}
}
@@ -2066,43 +2082,78 @@ void Cmd_Deposit_f( gentity_t *ent )
trap_Argv( 1, s, sizeof( s ) );
- //aliens don't sell stuff
- if( ent->client->pers.pteam != PTE_HUMANS )
- return;
-
- for ( i = 1, bankEntity = g_entities + i; i < level.num_entities; i++, bankEntity++ )
+ if( ent->client->pers.pteam == PTE_HUMANS )
{
- if( bankEntity->s.eType != ET_BUILDABLE )
- continue;
-
- if( bankEntity->s.modelindex == BA_H_BANK )
+ for ( i = 1, bankEntity = g_entities + i; i < level.num_entities; i++, bankEntity++ )
{
- VectorSubtract( ent->s.pos.trBase, bankEntity->s.origin, distance );
- if( VectorLength( distance ) <= 100 )
- nearBank = qtrue;
+ if( bankEntity->s.eType != ET_BUILDABLE )
+ continue;
+
+ if( bankEntity->s.modelindex == BA_H_BANK )
+ {
+ VectorSubtract( ent->s.pos.trBase, bankEntity->s.origin, distance );
+ if( VectorLength( distance ) <= 100 )
+ nearBank = qtrue;
+ }
}
- }
- if( !Q_stricmp( s, "all" ) )
- amount = ent->client->ps.stats[ STAT_CREDIT ];
- else
- amount = atoi( s );
+ if( !Q_stricmp( s, "all" ) )
+ amount = ent->client->ps.stats[ STAT_CREDIT ];
+ else
+ amount = atoi( s );
- //no Bank nearby
- if( !nearBank )
- {
- trap_SendServerCommand( ent-g_entities, va("print \"You must be near an Bank\n\"" ) );
- return;
- }
+ //no Bank nearby
+ if( !nearBank )
+ {
+ trap_SendServerCommand( ent-g_entities, va("print \"You must be near an Bank\n\"" ) );
+ return;
+ }
- if( amount <= ent->client->ps.stats[ STAT_CREDIT ] )
+ if( amount <= ent->client->ps.stats[ STAT_CREDIT ] )
+ {
+ ent->client->ps.stats[ STAT_CREDIT ] -= amount;
+ ent->client->ps.stats[ STAT_BANK ] += amount;
+ level.bankCredits[ ent->client->ps.clientNum ] += amount;
+ }
+ else
+ G_AddPredictableEvent( ent, EV_MENU, MN_H_NOFUNDS );
+ }
+ else if( ent->client->pers.pteam == PTE_ALIENS )
{
- ent->client->ps.stats[ STAT_CREDIT ] -= amount;
- ent->client->ps.stats[ STAT_BANK ] += amount;
- level.bankCredits[ ent->client->ps.clientNum ] += amount;
+ for ( i = 1, bankEntity = g_entities + i; i < level.num_entities; i++, bankEntity++ )
+ {
+ if( bankEntity->s.eType != ET_BUILDABLE )
+ continue;
+
+ if( bankEntity->s.modelindex == BA_A_OBANK )
+ {
+ VectorSubtract( ent->s.pos.trBase, bankEntity->s.origin, distance );
+ if( VectorLength( distance ) <= 100 )
+ nearBank = qtrue;
+ }
+ }
+
+ if( !Q_stricmp( s, "all" ) )
+ amount = ent->client->ps.stats[ STAT_CREDIT ];
+ else
+ amount = atoi( s );
+
+ //no Bank nearby
+ if( !nearBank )
+ {
+ trap_SendServerCommand( ent-g_entities, va("print \"You must be near an Bank\n\"" ) );
+ return;
+ }
+
+ if( amount <= ent->client->ps.stats[ STAT_CREDIT ] )
+ {
+ ent->client->ps.stats[ STAT_CREDIT ] -= amount;
+ ent->client->ps.stats[ STAT_BANK ] += amount;
+ level.bankCredits[ ent->client->ps.clientNum ] += amount;
+ }
+ else
+ G_AddPredictableEvent( ent, EV_MENU, MN_A_NOFUNDS );
}
- else
- G_AddPredictableEvent( ent, EV_MENU, MN_H_NOFUNDS );
}
@@ -2121,44 +2172,79 @@ void Cmd_Withdraw_f( gentity_t *ent )
qboolean nearBank = qfalse;
trap_Argv( 1, s, sizeof( s ) );
-
- //aliens don't sell stuff
- if( ent->client->pers.pteam != PTE_HUMANS )
- return;
- for ( i = 1, bankEntity = g_entities + i; i < level.num_entities; i++, bankEntity++ )
+ if( ent->client->pers.pteam == PTE_HUMANS )
{
- if( bankEntity->s.eType != ET_BUILDABLE )
- continue;
-
- if( bankEntity->s.modelindex == BA_H_BANK )
+ for ( i = 1, bankEntity = g_entities + i; i < level.num_entities; i++, bankEntity++ )
{
- VectorSubtract( ent->s.pos.trBase, bankEntity->s.origin, distance );
- if( VectorLength( distance ) <= 100 )
- nearBank = qtrue;
+ if( bankEntity->s.eType != ET_BUILDABLE )
+ continue;
+
+ if( bankEntity->s.modelindex == BA_H_BANK )
+ {
+ VectorSubtract( ent->s.pos.trBase, bankEntity->s.origin, distance );
+ if( VectorLength( distance ) <= 100 )
+ nearBank = qtrue;
+ }
}
- }
- if( !Q_stricmp( s, "all" ) )
- amount = level.bankCredits[ ent->client->ps.clientNum ];
- else
- amount = atoi( s );
+ if( !Q_stricmp( s, "all" ) )
+ amount = level.bankCredits[ ent->client->ps.clientNum ];
+ else
+ amount = atoi( s );
- //no Bank nearby
- if( !nearBank )
- {
- trap_SendServerCommand( ent-g_entities, va("print \"You must be near an Bank\n\"" ) );
- return;
- }
+ //no Bank nearby
+ if( !nearBank )
+ {
+ trap_SendServerCommand( ent-g_entities, va("print \"You must be near an Bank\n\"" ) );
+ return;
+ }
- if( amount <= level.bankCredits[ ent->client->ps.clientNum ] )
+ if( amount <= level.bankCredits[ ent->client->ps.clientNum ] )
+ {
+ ent->client->ps.stats[ STAT_CREDIT ] += amount;
+ ent->client->ps.stats[ STAT_BANK ] -= amount;
+ level.bankCredits[ ent->client->ps.clientNum ] -= amount;
+ }
+ else
+ G_AddPredictableEvent( ent, EV_MENU, MN_H_NOFUNDS );
+ }
+ else if( ent->client->pers.pteam == PTE_ALIENS )
{
- ent->client->ps.stats[ STAT_CREDIT ] += amount;
- ent->client->ps.stats[ STAT_BANK ] -= amount;
- level.bankCredits[ ent->client->ps.clientNum ] -= amount;
+ for ( i = 1, bankEntity = g_entities + i; i < level.num_entities; i++, bankEntity++ )
+ {
+ if( bankEntity->s.eType != ET_BUILDABLE )
+ continue;
+
+ if( bankEntity->s.modelindex == BA_A_OBANK )
+ {
+ VectorSubtract( ent->s.pos.trBase, bankEntity->s.origin, distance );
+ if( VectorLength( distance ) <= 100 )
+ nearBank = qtrue;
+ }
+ }
+
+ if( !Q_stricmp( s, "all" ) )
+ amount = level.bankCredits[ ent->client->ps.clientNum ];
+ else
+ amount = atoi( s );
+
+ //no Bank nearby
+ if( !nearBank )
+ {
+ trap_SendServerCommand( ent-g_entities, va("print \"You must be near an Bank\n\"" ) );
+ return;
+ }
+
+ if( amount <= level.bankCredits[ ent->client->ps.clientNum ] )
+ {
+ ent->client->ps.stats[ STAT_CREDIT ] += amount;
+ ent->client->ps.stats[ STAT_BANK ] -= amount;
+ level.bankCredits[ ent->client->ps.clientNum ] -= amount;
+ }
+ else
+ G_AddPredictableEvent( ent, EV_MENU, MN_H_NOFUNDS );
}
- else
- G_AddPredictableEvent( ent, EV_MENU, MN_H_NOFUNDS );
}
diff --git a/src/game/g_local.h b/src/game/g_local.h
index a643fefe..1628f5bd 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -480,6 +480,7 @@ typedef struct {
int humanBuildPointsPowered;
int bankCredits[ MAX_CLIENTS ]; //global credits storage
+ int oBankCredits[ MAX_CLIENTS ]; //global credits storage
int alienKills;
int humanKills;