summaryrefslogtreecommitdiff
path: root/src/game
diff options
context:
space:
mode:
Diffstat (limited to 'src/game')
-rw-r--r--src/game/bg_misc.c13
-rw-r--r--src/game/bg_pmove.c42
-rw-r--r--src/game/bg_public.h8
-rw-r--r--src/game/g_active.c32
-rw-r--r--src/game/g_admin.c6
-rw-r--r--src/game/g_buildable.c78
-rw-r--r--src/game/g_client.c9
-rw-r--r--src/game/g_cmds.c138
-rw-r--r--src/game/g_combat.c27
-rw-r--r--src/game/g_local.h2
-rw-r--r--src/game/g_main.c8
-rw-r--r--src/game/g_weapon.c58
-rw-r--r--src/game/tremulous.h10
13 files changed, 272 insertions, 159 deletions
diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c
index b96c8a9..a416ecb 100644
--- a/src/game/bg_misc.c
+++ b/src/game/bg_misc.c
@@ -2804,6 +2804,19 @@ static const upgradeAttributes_t bg_upgrades[ ] =
qtrue, //qboolean purchasable
qfalse, //qboolean usable
TEAM_HUMANS //team_t team;
+ },
+ {
+ UP_NIGHTVISION, //int upgradeNum;
+ 0, //int price;
+ 0, //int stages
+ SLOT_NONE, //int slots;
+ "nightvision", //char *upgradeName;
+ "", //char *humanName;
+ "",
+ 0,
+ qfalse, //qboolean purchasable
+ qtrue, //qboolean usable
+ TEAM_ALIENS //team_t team;
}
};
diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c
index 3b53dc9..d5719a5 100644
--- a/src/game/bg_pmove.c
+++ b/src/game/bg_pmove.c
@@ -672,6 +672,9 @@ static qboolean PM_CheckWallJump( void )
float upFraction = 1.5f;
trace_t trace;
+ if( pm->waterlevel )
+ return qfalse;
+
if( !( BG_Class( pm->ps->stats[ STAT_CLASS ] )->abilities & SCA_WALLJUMPER ) )
return qfalse;
@@ -935,27 +938,45 @@ static qboolean PM_CheckWaterJump( void )
vec3_t spot;
int cont;
vec3_t flatforward;
+ vec3_t mins, maxs;
+ float a, r;
if( pm->ps->pm_time )
return qfalse;
- // check for water jump
- if( pm->waterlevel != 2 )
+ if( pm->cmd.upmove < 10 )
+ // not holding jump
return qfalse;
+ // check for water jump
+ //if( pm->waterlevel != 2 )
+ // return qfalse;
+
flatforward[ 0 ] = pml.forward[ 0 ];
flatforward[ 1 ] = pml.forward[ 1 ];
flatforward[ 2 ] = 0;
VectorNormalize( flatforward );
- VectorMA( pm->ps->origin, 30, flatforward, spot );
- spot[ 2 ] += 4;
+ BG_ClassBoundingBox( pm->ps->stats[ STAT_CLASS ], mins, maxs, NULL, NULL, NULL );
+
+ // bbox bottom
+ spot[ 0 ] = pm->ps->origin[ 0 ];
+ spot[ 1 ] = pm->ps->origin[ 1 ];
+ spot[ 2 ] = pm->ps->origin[ 2 ] + mins[ 2 ];
+
+ // project the flatforward vector onto the bbox (just a bit longer, so we'll actually hit a wall)
+ // then add it to spot
+ #define fmod(a,n) ((a)-(n)*floor((a)/(n)))
+ a = pm->ps->viewangles[ YAW ] / ( 180.0f / M_PI );
+ r = ( maxs[ 0 ] + 1 ) * 1.0f / cos( fmod( a+0.25f*M_PI, 0.5f*M_PI ) - 0.25f*M_PI );
+ VectorMA( spot, r, flatforward, spot );
+
cont = pm->pointcontents( spot, pm->ps->clientNum );
if( !( cont & CONTENTS_SOLID ) )
return qfalse;
- spot[ 2 ] += 16;
+ spot[ 2 ] = pm->ps->origin[ 2 ] + maxs[ 2 ];
cont = pm->pointcontents( spot, pm->ps->clientNum );
if( cont )
@@ -2409,32 +2430,35 @@ static void PM_SetWaterLevel( void )
int cont;
int sample1;
int sample2;
+ vec3_t mins;
//
// get waterlevel, accounting for ducking
//
pm->waterlevel = 0;
pm->watertype = 0;
+
+ BG_ClassBoundingBox( pm->ps->stats[ STAT_CLASS ], mins, NULL, NULL, NULL, NULL );
point[ 0 ] = pm->ps->origin[ 0 ];
point[ 1 ] = pm->ps->origin[ 1 ];
- point[ 2 ] = pm->ps->origin[ 2 ] + MINS_Z + 1;
+ point[ 2 ] = pm->ps->origin[ 2 ] + mins[2] + 1;
cont = pm->pointcontents( point, pm->ps->clientNum );
if( cont & MASK_WATER )
{
- sample2 = pm->ps->viewheight - MINS_Z;
+ sample2 = pm->ps->viewheight - mins[2];
sample1 = sample2 / 2;
pm->watertype = cont;
pm->waterlevel = 1;
- point[ 2 ] = pm->ps->origin[ 2 ] + MINS_Z + sample1;
+ point[ 2 ] = pm->ps->origin[ 2 ] + mins[2] + sample1;
cont = pm->pointcontents( point, pm->ps->clientNum );
if( cont & MASK_WATER )
{
pm->waterlevel = 2;
- point[ 2 ] = pm->ps->origin[ 2 ] + MINS_Z + sample2;
+ point[ 2 ] = pm->ps->origin[ 2 ] + mins[2] + sample2;
cont = pm->pointcontents( point, pm->ps->clientNum );
if( cont & MASK_WATER )
diff --git a/src/game/bg_public.h b/src/game/bg_public.h
index 64ce615..e06015d 100644
--- a/src/game/bg_public.h
+++ b/src/game/bg_public.h
@@ -233,8 +233,9 @@ typedef enum
STAT_BUILDABLE, // which ghost model to display for building
STAT_FALLDIST, // the distance the player fell
STAT_VIEWLOCK, // direction to lock the view in
- STAT_FUEL // jetpacks
- // netcode has space for 2 more
+ STAT_FUEL, // jetpacks
+ STAT_SHAKE // camera shake
+ // netcode has space for 1 more
} statIndex_t;
#define SCA_WALLCLIMBER 0x00000001
@@ -397,6 +398,8 @@ typedef enum
UP_BIORES,
UP_AMMO,
+
+ UP_NIGHTVISION, // aliens
UP_NUM_UPGRADES
} upgrade_t;
@@ -630,6 +633,7 @@ typedef enum
MN_B_CUBOID_MODE1,
MN_B_CUBOID_MODE2,
MN_B_TOODENSE,
+ MN_B_INVALIDSIZE,
//alien build
MN_A_ONEOVERMIND,
diff --git a/src/game/g_active.c b/src/game/g_active.c
index 05bda16..1fa0caa 100644
--- a/src/game/g_active.c
+++ b/src/game/g_active.c
@@ -168,6 +168,19 @@ void P_WorldEffects( gentity_t *ent )
ent->client->airOutTime = level.time + 12000;
ent->damage = 2;
}
+}
+
+void P_WorldEffects_Fast( gentity_t *ent )
+{
+ int waterlevel;
+
+ if( ent->client->noclip )
+ {
+ ent->client->airOutTime = level.time + 12000; // don't need air
+ return;
+ }
+
+ waterlevel = ent->waterlevel;
//
// check for sizzle damage (move to pmove?)
@@ -175,26 +188,24 @@ void P_WorldEffects( gentity_t *ent )
if( waterlevel &&
( ent->watertype & ( CONTENTS_LAVA | CONTENTS_SLIME ) ) )
{
- if( ent->health > 0 &&
- ent->pain_debounce_time <= level.time )
+ if( ent->health > 0 )
{
if( ent->watertype & CONTENTS_LAVA )
{
G_Damage( ent, NULL, NULL, NULL, NULL,
- 30 * waterlevel, 0, MOD_LAVA );
+ 3 * waterlevel, 0, MOD_LAVA );
}
if( ent->watertype & CONTENTS_SLIME )
{
G_Damage( ent, NULL, NULL, NULL, NULL,
- 10 * waterlevel, 0, MOD_SLIME );
+ 1 * waterlevel, 0, MOD_SLIME );
}
}
}
}
-
/*
===============
G_SetClientSound
@@ -629,6 +640,8 @@ void ClientTimerActions( gentity_t *ent, int msec )
weapon_t weapon = BG_GetPlayerWeapon( &client->ps );
client->time100 -= 100;
+
+ P_WorldEffects_Fast( ent );
// Restore or subtract stamina
if( stopped || client->ps.pm_type == PM_JETPACK )
@@ -757,13 +770,16 @@ void ClientTimerActions( gentity_t *ent, int msec )
if( ent->client->bioresHealTimer >= 100 )
{
int delta;
-
+
delta = ent->client->bioresHealTimer / 100;
ent->health = MAX( MIN( ent->health+delta, ent->client->ps.stats[ STAT_MAX_HEALTH ] ), 1 );
-
+
ent->client->bioresHealTimer %= 100;
}
-
+
+ ent->client->ps.stats[ STAT_SHAKE ] *= 0.77f;
+ if( ent->client->ps.stats[ STAT_SHAKE ] < 0 )
+ ent->client->ps.stats[ STAT_SHAKE ] = 0;
}
while( client->time1000 >= 1000 )
diff --git a/src/game/g_admin.c b/src/game/g_admin.c
index 25e3e9b..90f42c8 100644
--- a/src/game/g_admin.c
+++ b/src/game/g_admin.c
@@ -641,7 +641,7 @@ static void admin_default_levels( void )
l->level = level++;
Q_strncpyz( l->name, "^4Unknown Player", sizeof( l->name ) );
Q_strncpyz( l->flags,
- "listplayers admintest adminhelp time",
+ "listplayers admintest adminhelp time register",
sizeof( l->flags ) );
l = l->next = BG_Alloc( sizeof( g_admin_level_t ) );
@@ -3498,6 +3498,8 @@ qboolean G_admin_register( gentity_t *ent )
Q_strncpyz( ent->client->pers.admin->name,
ent->client->pers.netname,
sizeof( ent->client->pers.admin->name ) );
-
+
+ admin_writeconfig( );
+
return qtrue;
}
diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c
index b13c54a..0039ccd 100644
--- a/src/game/g_buildable.c
+++ b/src/game/g_buildable.c
@@ -2524,39 +2524,46 @@ void Cuboid_Think(gentity_t *self)
}
//Cuboids need a new die function because of the cuboid explosion effects.
-void Cuboid_Die(gentity_t *self,gentity_t *inflictor,gentity_t *attacker,int damage,int mod)
+void Cuboid_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod )
{
vec3_t dir;
- qboolean event=qfalse;
+ qboolean event = qfalse;
const cuboidAttributes_t *cuboid;
- cuboid=BG_CuboidAttributes(self->s.modelindex);
- G_SetBuildableAnim(self,BANIM_DESTROY1,qtrue); // just for sound
- self->die=nullDieFunction;
- self->killedBy=attacker-g_entities;
- self->powered=qfalse;
- self->s.eFlags&=~EF_FIRING;
- G_LogDestruction(self,attacker,mod);
- dir[0]=dir[1]=0;
- dir[2]=1;
+ cuboid = BG_CuboidAttributes( self->s.modelindex );
+ G_SetBuildableAnim( self, BANIM_DESTROY1, qtrue ); // just for sound
+ self->die = nullDieFunction;
+ self->killedBy = attacker - g_entities;
+ self->powered = qfalse;
+ self->s.eFlags &= ~EF_FIRING;
+ G_LogDestruction( self, attacker, mod );
+ dir[ 0 ] =
+ dir[ 1 ] = 0;
+ dir[ 2 ] = 1;
self->timestamp = level.time;
- G_QueueBuildPoints(self);
- if(mod!=MOD_DECONSTRUCT&&self->spawned)
+ G_QueueBuildPoints( self );
+
+ if( mod != MOD_DECONSTRUCT && self->spawned )
{
- G_RewardAttackers(self);
- G_RadiusDamage(self->s.pos.trBase,g_entities+self->killedBy,self->splashDamage,self->splashRadius,self,self->splashMethodOfDeath);
+ G_RewardAttackers( self );
+ G_RadiusDamage( self->s.pos.trBase,
+ g_entities + self->killedBy,
+ self->splashDamage,
+ self->splashRadius,
+ self,
+ self->splashMethodOfDeath );
//NOTE: all cuboid info is already packed
- self->s.eType=ET_EVENTS+EV_CUBOID_EXPLOSION;
+ self->s.eType = ET_EVENTS + EV_CUBOID_EXPLOSION;
self->freeAfterEvent = qtrue;
- G_AddEvent(self,EV_HUMAN_BUILDABLE_EXPLOSION,DirToByte(dir));
- event=qtrue;
- self->r.contents=0;
- trap_LinkEntity(self);
+ G_AddEvent( self, EV_HUMAN_BUILDABLE_EXPLOSION, DirToByte( dir ) );
+ event = qtrue;
+ self->r.contents = 0;
+ trap_LinkEntity( self );
}
else
{
- self->s.eType=0;
- G_FreeEntity(self);
+ self->s.eType = 0;
+ G_FreeEntity( self );
}
}
@@ -3440,12 +3447,18 @@ itemBuildError_t G_CanBuild( gentity_t *ent, buildable_t buildable, int distance
int contents;
playerState_t *ps = &ent->client->ps;
- if( BG_Buildable(buildable,NULL)->cuboid )
- BG_CuboidBBox(cuboidSize,mins,maxs);
+ if( BG_Buildable( buildable, NULL )->cuboid )
+ {
+ if( !G_CheckCuboidSize( cuboidSize, buildable ) )
+ return IBE_INVALIDSIZE;
+ BG_CuboidBBox( cuboidSize, mins, maxs );
+ }
else
BG_BuildableBoundingBox( buildable, mins, maxs );
-
- if(!BG_PositionBuildableRelativeToPlayer( ps, BG_Buildable(buildable,NULL)->cuboid, mins, maxs, trap_Trace, entity_origin, angles, &tr1 ))
+
+ if( !BG_PositionBuildableRelativeToPlayer(
+ ps, BG_Buildable( buildable, NULL )->cuboid,
+ mins, maxs, trap_Trace, entity_origin, angles, &tr1 ) )
return IBE_NOSURF;
trap_Trace( &tr2, entity_origin, mins, maxs, entity_origin, -1, MASK_PLAYERSOLID );
trap_Trace( &tr3, ps->origin, NULL, NULL, entity_origin, ent->s.number, MASK_PLAYERSOLID );
@@ -3964,15 +3977,19 @@ qboolean G_BuildIfValid( gentity_t *ent, buildable_t buildable, vec3_t cuboidSiz
case IBE_LASTSPAWN:
G_TriggerMenu( ent->client->ps.clientNum, MN_B_LASTSPAWN );
return qfalse;
-
+
case IBE_NOSURF:
G_TriggerMenu( ent->client->ps.clientNum, MN_B_NOSURF );
return qfalse;
-
+
case IBE_TOODENSE:
G_TriggerMenu( ent->client->ps.clientNum, MN_B_TOODENSE );
return qfalse;
+ case IBE_INVALIDSIZE:
+ G_TriggerMenu( ent->client->ps.clientNum, MN_B_INVALIDSIZE );
+ return qfalse;
+
default:
break;
}
@@ -4577,7 +4594,10 @@ void G_RemoveUnbuiltBuildables( gentity_t *self )
if( ent->builtBy != self->client->ps.clientNum )
continue;
-
+
+ if( ent->s.modelindex < CUBOID_FIRST )
+ continue;
+
G_Damage( ent, self, NULL, dir, dir, ent->health, 0, MOD_DECONSTRUCT );
}
}
diff --git a/src/game/g_client.c b/src/game/g_client.c
index c8421f0..7596ea1 100644
--- a/src/game/g_client.c
+++ b/src/game/g_client.c
@@ -1397,7 +1397,7 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles
// try to unblock the player
if( tr.startsolid )
{
- Com_Printf("DEBUG: player is stuck!\n");
+ //Com_Printf("DEBUG: player is stuck!\n");
for( i = 0; i < 16*2; i++ )
{
float a, r;
@@ -1414,7 +1414,7 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles
if( !tr.startsolid )
{
- Com_Printf("DEBUG: player position fixed at iteration %i\n",i);
+ //Com_Printf("DEBUG: player position fixed at iteration %i\n",i);
VectorCopy( neworigin, spawn_origin );
break;
}
@@ -1547,6 +1547,11 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles
else
weapon = WP_NONE;
+ // give nightvision to basilisks
+ if( ent->client->pers.classSelection == PCL_ALIEN_LEVEL1 ||
+ ent->client->pers.classSelection == PCL_ALIEN_LEVEL1_UPG )
+ BG_AddUpgradeToInventory( UP_NIGHTVISION, client->ps.stats );
+
maxAmmo = BG_Weapon( weapon )->maxAmmo;
maxClips = BG_Weapon( weapon )->maxClips;
client->ps.stats[ STAT_WEAPON ] = weapon;
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index 468dde0..2c15638 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -2527,21 +2527,30 @@ void Cmd_Sell_f( gentity_t *ent )
/*
=================
-Cmd_CheckCuboidSize
+G_CheckCuboidSize
Check if the specified dimensions are valid.
=================
*/
-qboolean Cmd_CheckCuboidSize(vec3_t dims)
+qboolean G_CheckCuboidSize( vec3_t dims, buildable_t type )
{
- if(g_cuboidSizeLimit.integer)
- if(dims[0]>g_cuboidSizeLimit.integer||dims[1]>g_cuboidSizeLimit.integer||dims[2]>g_cuboidSizeLimit.integer)
- return qfalse;
- if(dims[0]*dims[1]*dims[2]<CUBOID_MINVOLUME)
- return qfalse;
- if(dims[0]<1||dims[1]<1||dims[2]<1)
- return qfalse;
- return qtrue;
+ if( g_cuboidSizeLimit.integer )
+ if( dims[ 0 ] > g_cuboidSizeLimit.integer ||
+ dims[ 1 ] > g_cuboidSizeLimit.integer ||
+ dims[ 2 ] > g_cuboidSizeLimit.integer )
+ return qfalse;
+
+ if( dims[ 0 ] * dims[ 1 ] * dims[ 2 ] < CUBOID_MINVOLUME)
+ return qfalse;
+
+ if( dims[ 0 ] < 1 || dims[ 1 ] < 1 || dims[ 2 ] < 1 )
+ return qfalse;
+
+ if( g_cuboidHealthLimit.integer )
+ if( BG_Buildable( type, dims )->health > g_cuboidHealthLimit.integer )
+ return qfalse;
+
+ return qtrue;
}
/*
@@ -2554,33 +2563,32 @@ Update player's cuboid selection (after validation) with data sent over network.
*/
void Cmd_Cb_f(gentity_t *ent)
{
- char s[MAX_TOKEN_CHARS];
- int echo;
- vec3_t dims;
+ char s[MAX_TOKEN_CHARS];
+ int echo;
+ vec3_t dims;
- if(trap_Argc()!=5)
- return;
- trap_Argv(1,s,sizeof(s));
- echo=atoi(s);
- trap_Argv(2,s,sizeof(s));
- dims[0]=atof(s);
- trap_Argv(3,s,sizeof(s));
- dims[1]=atof(s);
- trap_Argv(4,s,sizeof(s));
- dims[2]=atof(s);
- if(Cmd_CheckCuboidSize(dims))
- {
- VectorCopy(dims,ent->client->cuboidSelection);
- trap_SendServerCommand(ent->client-level.clients,va("cb3 %i\n",echo));
- G_RelayCuboidToSpectators(ent->client);
- }
- else
- {
- if(Cmd_CheckCuboidSize(ent->client->cuboidSelection))
- trap_SendServerCommand(ent->client-level.clients,va("cb3 %i %f %f %f\n",echo,ent->client->cuboidSelection[0],ent->client->cuboidSelection[1],ent->client->cuboidSelection[2]));
+ if( trap_Argc( ) != 5 )
+ return;
+
+ trap_Argv( 1, s, sizeof( s ) );
+ echo = atoi( s );
+ trap_Argv( 2, s, sizeof( s ) );
+ dims[ 0 ] = atof( s );
+ trap_Argv( 3, s, sizeof( s ) );
+ dims[ 1 ] = atof( s );
+ trap_Argv( 4, s, sizeof( s ) );
+ dims[ 2 ] = atof( s );
+
+ VectorCopy( dims, ent->client->cuboidSelection );
+ G_RelayCuboidToSpectators( ent->client );
+
+ if( G_CheckCuboidSize( dims, ent->client->ps.stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT ) )
+ trap_SendServerCommand( ent->client - level.clients, va( "cb3 %i\n", echo ) );
else
- trap_SendServerCommand(ent->client-level.clients,va("cb3 %i %f %f %f\n",echo,g_cuboidSizeLimit.integer,g_cuboidSizeLimit.integer,g_cuboidSizeLimit.integer));
- }
+ {
+ trap_SendServerCommand( ent->client - level.clients, va( "cb4 %i\n", echo ) );
+ ent->client->ps.stats[ STAT_BUILDABLE ] &= ~SB_VALID_TOGGLEBIT;
+ }
}
@@ -2627,37 +2635,35 @@ void Cmd_Build_f( gentity_t *ent )
{
if( trap_Argc() >= 5 )
{
- trap_Argv(2,s,sizeof(s));
- dims[0]=MAX(1,atof(s));
- trap_Argv(3,s,sizeof(s));
- dims[1]=MAX(1,atof(s));
- trap_Argv(4,s,sizeof(s));
- dims[2]=MAX(1,atof(s));
- if(!Cmd_CheckCuboidSize(dims))
+ trap_Argv( 2, s, sizeof( s ) );
+ dims[ 0 ] = MAX( 1, atof( s ) );
+ trap_Argv( 3, s, sizeof( s ) );
+ dims[ 1 ] = MAX( 1, atof( s ) );
+ trap_Argv( 4, s, sizeof( s ) );
+ dims[ 2 ] = MAX( 1, atof( s ) );
+ if( !G_CheckCuboidSize( dims, buildable ) )
{
- Com_sprintf(buf,sizeof(buf),"print \"^1error: invalid cuboid size (min volume: %i, max size: %s)\n\"",
- CUBOID_MINVOLUME,(g_cuboidSizeLimit.integer?va("%ix%ix%i",g_cuboidSizeLimit.integer,g_cuboidSizeLimit.integer, g_cuboidSizeLimit.integer):"no limit"));
- trap_SendServerCommand(ent->client-level.clients,buf);
+ G_TriggerMenu( ent->client->ps.clientNum, MN_B_INVALIDSIZE );
return;
}
- VectorCopy(dims,ent->client->cuboidSelection);
+ VectorCopy( dims, ent->client->cuboidSelection );
}
// client is building a cuboid for the first time so reset the selection to default
- if(!Cmd_CheckCuboidSize(ent->client->cuboidSelection))
+ if( !G_CheckCuboidSize(ent->client->cuboidSelection, buildable) )
{
- ent->client->cuboidSelection[0]=32;
- ent->client->cuboidSelection[1]=32;
- ent->client->cuboidSelection[2]=32;
- trap_SendServerCommand(ent->client-level.clients,"cb2 32 32 32");
- G_RelayCuboidToSpectators(ent->client);
+ ent->client->cuboidSelection[ 0 ] = 30;
+ ent->client->cuboidSelection[ 1 ] = 30;
+ ent->client->cuboidSelection[ 2 ] = 30;
+ trap_SendServerCommand( ent->client-level.clients, "cb2 30 30 30" );
+ G_RelayCuboidToSpectators( ent->client );
}
- if(!BG_CuboidAllowed((team==TEAM_ALIENS?g_alienStage.integer:g_humanStage.integer)))
+ if( !BG_CuboidAllowed( ( team == TEAM_ALIENS ? g_alienStage.integer : g_humanStage.integer ) ) )
{
- if(BG_CuboidMode()==1)
- G_TriggerMenu(ent->client->ps.clientNum,MN_B_CUBOID_MODE1);
+ if( BG_CuboidMode() == 1 )
+ G_TriggerMenu(ent->client->ps.clientNum, MN_B_CUBOID_MODE1 );
else
- G_TriggerMenu(ent->client->ps.clientNum,MN_B_CUBOID_MODE2);
+ G_TriggerMenu(ent->client->ps.clientNum, MN_B_CUBOID_MODE2 );
return;
}
}
@@ -2751,12 +2757,13 @@ void Cmd_Build_f( gentity_t *ent )
if( err == MN_NONE || ent->client->pers.disableBlueprintErrors )
{
- trap_SendServerCommand(ent->client-level.clients,va("cb2 %f %f %f\n",
- ent->client->cuboidSelection[0],
- ent->client->cuboidSelection[1],
- ent->client->cuboidSelection[2]));
- G_RelayCuboidToSpectators(ent->client);
- ent->client->ps.stats[ STAT_BUILDABLE ] |= buildable;
+ trap_SendServerCommand( ent->client - level.clients,
+ va( "cb2 %f %f %f\n",
+ ent->client->cuboidSelection[ 0 ],
+ ent->client->cuboidSelection[ 1 ],
+ ent->client->cuboidSelection[ 2 ] ) );
+ G_RelayCuboidToSpectators( ent->client );
+ ent->client->ps.stats[ STAT_BUILDABLE ] |= buildable;
}
else
G_TriggerMenu( ent->client->ps.clientNum, err );
@@ -3298,12 +3305,7 @@ Cmd_Debug1_f
*/
void Cmd_Debug1_f( gentity_t *other )
{
- other->client->isImpregnated = qtrue;
- other->client->isImplantMature = qfalse;
- other->client->impregnationTime = level.time;
- other->client->impregnatedBy = -1;
- other->client->isImplantMature = qtrue;
- other->client->ps.stats[ STAT_STATE ] |= SS_IMPLANTED;
+ other->client->ps.stats[ STAT_SHAKE ] += 70;
}
/*
diff --git a/src/game/g_combat.c b/src/game/g_combat.c
index 1b6708f..fe5d607 100644
--- a/src/game/g_combat.c
+++ b/src/game/g_combat.c
@@ -1329,7 +1329,7 @@ G_RadiusDamage
qboolean G_RadiusDamage( vec3_t origin, gentity_t *attacker, float damage,
float radius, gentity_t *ignore, int mod )
{
- float points, dist;
+ float points, dist, shake;
gentity_t *ent;
int entityList[ MAX_GENTITIES ];
int numListedEntities;
@@ -1389,6 +1389,31 @@ qboolean G_RadiusDamage( vec3_t origin, gentity_t *attacker, float damage,
}
}
+ for( i = 0; i < 3; i++ )
+ {
+ mins[ i ] = origin[ i ] - radius * 2;
+ maxs[ i ] = origin[ i ] + radius * 2;
+ }
+
+ numListedEntities = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES );
+
+ for( e = 0; e < numListedEntities; e++ )
+ {
+ ent = g_entities + entityList[ e ];
+
+ if( ent == ignore )
+ continue;
+
+ if( !ent->client )
+ continue;
+
+ if( !ent->takedamage )
+ continue;
+
+ shake = damage * 10 / Distance( origin, ent->r.currentOrigin );
+ ent->client->ps.stats[ STAT_SHAKE ] += (int) shake;
+ }
+
return hitClient;
}
diff --git a/src/game/g_local.h b/src/game/g_local.h
index 3bd8642..001c7d9 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -790,6 +790,7 @@ typedef enum
IBE_LASTSPAWN,
IBE_NOSURF,
IBE_TOODENSE,
+ IBE_INVALIDSIZE,
IBE_MAXERRORS
} itemBuildError_t;
@@ -1221,6 +1222,7 @@ extern vmCvar_t g_censorship;
extern vmCvar_t g_unlimited;
extern vmCvar_t g_instantBuild;
extern vmCvar_t g_cuboidSizeLimit;
+extern vmCvar_t g_cuboidHealthLimit;
extern vmCvar_t g_buildableDensityLimit;
extern vmCvar_t g_buildableDensityLimitRange;
diff --git a/src/game/g_main.c b/src/game/g_main.c
index 8f43d81..0f9c31c 100644
--- a/src/game/g_main.c
+++ b/src/game/g_main.c
@@ -152,6 +152,7 @@ vmCvar_t g_tag;
vmCvar_t g_unlimited;
vmCvar_t g_instantBuild;
vmCvar_t g_cuboidSizeLimit;
+vmCvar_t g_cuboidHealthLimit;
vmCvar_t g_cuboidMode;
vmCvar_t g_buildableDensityLimit;
@@ -295,11 +296,12 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_unlimited, "g_unlimited", "0", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qfalse },
{ &g_instantBuild, "g_instantBuild", "0", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qfalse },
- { &g_cuboidSizeLimit, "g_cuboidSizeLimit", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_cuboidSizeLimit, "g_cuboidSizeLimit", "0", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qfalse },
+ { &g_cuboidHealthLimit, "g_cuboidHealthLimit", "0", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qfalse },
{ &g_cuboidMode, "g_cuboidMode", "0", CVAR_ARCHIVE, 0, qfalse },
- { &g_buildableDensityLimit, "g_buildableDensityLimit", "0", CVAR_ARCHIVE, 0, qfalse },
- { &g_buildableDensityLimitRange, "g_buildableDensityLimitRange", "0", CVAR_ARCHIVE, 0, qfalse }
+ { &g_buildableDensityLimit, "g_buildableDensityLimit", "0", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qfalse },
+ { &g_buildableDensityLimitRange, "g_buildableDensityLimitRange", "0", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qfalse }
};
static int gameCvarTableSize = sizeof( gameCvarTable ) / sizeof( gameCvarTable[ 0 ] );
diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c
index 42c85b5..4a28083 100644
--- a/src/game/g_weapon.c
+++ b/src/game/g_weapon.c
@@ -45,7 +45,7 @@ void G_ForceWeaponChange( gentity_t *ent, weapon_t weapon )
ps->weaponTime = 250;
ps->weaponstate = WEAPON_READY;
}
-
+
if( weapon == WP_NONE ||
!BG_InventoryContainsWeapon( weapon, ps->stats ) )
{
@@ -76,7 +76,7 @@ void G_GiveClientMaxAmmo( gentity_t *ent, qboolean buyingEnergyAmmo )
for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ )
{
qboolean energyWeapon;
-
+
energyWeapon = BG_Weapon( i )->usesEnergy;
if( !BG_InventoryContainsWeapon( i, ent->client->ps.stats ) ||
BG_Weapon( i )->infiniteAmmo ||
@@ -84,10 +84,10 @@ void G_GiveClientMaxAmmo( gentity_t *ent, qboolean buyingEnergyAmmo )
ent->client->ps.ammo, ent->client->ps.clips ) ||
( buyingEnergyAmmo && !energyWeapon ) )
continue;
-
+
maxAmmo = BG_Weapon( i )->maxAmmo;
maxClips = BG_Weapon( i )->maxClips;
-
+
// Apply battery pack modifier
if( energyWeapon &&
BG_InventoryContainsUpgrade( UP_BATTPACK, ent->client->ps.stats ) )
@@ -142,7 +142,7 @@ static void G_WideTrace( trace_t *tr, gentity_t *ent, float range,
vec3_t end;
VectorSet( mins, -width, -width, -height );
- VectorSet( maxs, width, width, height );
+ VectorSet( maxs, width, width, width );
*target = NULL;
@@ -459,8 +459,8 @@ void massDriverFire( gentity_t *ent )
SnapVectorTowards( tr.endpos, muzzle );
// send impact
- if( traceEnt->takedamage &&
- (traceEnt->s.eType == ET_BUILDABLE ||
+ if( traceEnt->takedamage &&
+ (traceEnt->s.eType == ET_BUILDABLE ||
traceEnt->s.eType == ET_PLAYER ) )
{
BloodSpurt( ent, traceEnt, &tr );
@@ -507,7 +507,7 @@ void hiveFire( gentity_t *ent )
// Fire from the hive tip, not the center
VectorMA( muzzle, ent->r.maxs[ 2 ], ent->s.origin2, origin );
-
+
fire_hive( ent, origin, forward );
}
@@ -549,7 +549,7 @@ void flamerFire( gentity_t *ent )
{
vec3_t origin;
- // Correct muzzle so that the missile does not start in the ceiling
+ // Correct muzzle so that the missile does not start in the ceiling
VectorMA( muzzle, -7.0f, up, origin );
// Correct muzzle so that the missile fires from the player's hand
@@ -606,8 +606,8 @@ void lasGunFire( gentity_t *ent )
SnapVectorTowards( tr.endpos, muzzle );
// send impact
- if( traceEnt->takedamage &&
- (traceEnt->s.eType == ET_BUILDABLE ||
+ if( traceEnt->takedamage &&
+ (traceEnt->s.eType == ET_BUILDABLE ||
traceEnt->s.eType == ET_PLAYER ) )
{
BloodSpurt( ent, traceEnt, &tr );
@@ -771,9 +771,9 @@ void CheckCkitRepair( gentity_t *ent )
if(BG_Buildable(traceEnt->s.modelindex,NULL)->cuboid)
if(!BG_CuboidAttributes(traceEnt->s.modelindex)->repairable)
return;
-
+
bHealth = BG_Buildable( traceEnt->s.modelindex, traceEnt->cuboidSize )->health;
-
+
if( traceEnt->health < bHealth )
{
traceEnt->health += HBUILD_HEALRATE;
@@ -960,7 +960,7 @@ void CheckGrabAttack( gentity_t *ent )
if( traceEnt->client->ps.stats[ STAT_HEALTH ] <= 0 )
return;
-
+
if( !( traceEnt->client->ps.stats[ STAT_STATE ] & SS_GRABBED ) )
{
AngleVectors( traceEnt->client->ps.viewangles, dir, NULL, NULL );
@@ -1001,7 +1001,7 @@ void poisonCloud( gentity_t *ent )
for( i = 0; i < num; i++ )
{
humanPlayer = &g_entities[ entityList[ i ] ];
-
+
if( humanPlayer->client &&
humanPlayer->client->pers.teamSelection == TEAM_HUMANS )
{
@@ -1066,13 +1066,12 @@ static void G_FindZapChainTargets( zap_t *zap )
distance = Distance( ent->s.origin, enemy->s.origin );
- if ( ( enemy->client
- &&
- enemy->client->ps.stats[ STAT_TEAM ] == TEAM_HUMANS) ||
- ( enemy->s.eType == ET_BUILDABLE && BG_Buildable( enemy->s.modelindex, NULL )->team == TEAM_HUMANS &&
- ( !BG_Buildable(enemy->s.modelindex,NULL)->cuboid||BG_CuboidAttributes( enemy->s.modelindex )->zappable ) ) &&
- enemy->health > 0 && distance <= LEVEL2_AREAZAP_CHAIN_RANGE )
+ if((enemy->client&&enemy->client->ps.stats[STAT_TEAM]==TEAM_HUMANS) ||
+ (enemy->s.eType==ET_BUILDABLE&&BG_Buildable(enemy->s.modelindex,NULL)->team==TEAM_HUMANS &&
+ (!BG_Buildable(enemy->s.modelindex,NULL)->cuboid||BG_CuboidAttributes(enemy->s.modelindex)->zappable)) &&
+ enemy->health>0 && distance <= LEVEL2_AREAZAP_CHAIN_RANGE)
{
+
// world-LOS check: trace against the world, ignoring other BODY entities
trap_Trace( &tr, ent->s.origin, NULL, NULL,
enemy->s.origin, ent->s.number, CONTENTS_SOLID );
@@ -1147,7 +1146,7 @@ static void G_CreateNewZap( gentity_t *creator, gentity_t *target )
{
G_Damage( zap->targets[ i ], target, zap->creator, forward, target->s.origin,
LEVEL2_AREAZAP_DMG * ( 1 - pow( (zap->distances[ i ] /
- LEVEL2_AREAZAP_CHAIN_RANGE ), LEVEL2_AREAZAP_CHAIN_FALLOFF ) ) + 1,
+ LEVEL2_AREAZAP_CHAIN_RANGE ) , LEVEL2_AREAZAP_CHAIN_FALLOFF ) ) + 1,
DAMAGE_NO_KNOCKBACK | DAMAGE_NO_LOCDAMAGE,
MOD_LEVEL2_ZAP );
}
@@ -1163,7 +1162,6 @@ static void G_CreateNewZap( gentity_t *creator, gentity_t *target )
}
-
/*
===============
G_UpdateZaps
@@ -1253,9 +1251,9 @@ void areaZapFire( gentity_t *ent )
if( traceEnt == NULL )
return;
- if( ( ( traceEnt->client && traceEnt->client->ps.stats[ STAT_TEAM ] == TEAM_HUMANS ) ||
+ if( ( traceEnt->client && traceEnt->client->ps.stats[ STAT_TEAM ] == TEAM_HUMANS ) ||
( traceEnt->s.eType == ET_BUILDABLE &&
- BG_Buildable( traceEnt->s.modelindex, NULL )->team == TEAM_HUMANS ) ) &&
+ BG_Buildable( traceEnt->s.modelindex, NULL )->team == TEAM_HUMANS ) &&
( !BG_Buildable( traceEnt->s.modelindex, NULL )->cuboid ||
BG_CuboidAttributes( traceEnt->s.modelindex )->zappable ) )
{
@@ -1309,7 +1307,7 @@ qboolean CheckPounceAttack( gentity_t *ent )
if( !traceEnt->takedamage )
return qfalse;
-
+
// Deal damage
timeMax = ent->client->ps.weapon == WP_ALEVEL3 ? LEVEL3_POUNCE_TIME :
LEVEL3_POUNCE_TIME_UPG;
@@ -1411,7 +1409,7 @@ void G_CrushAttack( gentity_t *ent, gentity_t *victim )
if( damage < 0 )
damage = 0;
-
+
// Players also get damaged periodically
if( victim->client &&
ent->client->lastCrushTime + LEVEL4_CRUSH_REPEAT < level.time )
@@ -1419,7 +1417,7 @@ void G_CrushAttack( gentity_t *ent, gentity_t *victim )
ent->client->lastCrushTime = level.time;
damage += LEVEL4_CRUSH_DAMAGE;
}
-
+
if( damage < 1 )
return;
@@ -1527,7 +1525,7 @@ void FireWeapon2( gentity_t *ent )
case WP_ALEVEL2_UPG:
areaZapFire( ent );
break;
-
+
case WP_ABUILD:
case WP_ABUILD2:
case WP_HBUILD:
@@ -1549,7 +1547,7 @@ void FireWeapon( gentity_t *ent )
{
// set aiming directions
AngleVectors( ent->client->ps.viewangles, forward, right, up );
- CalcMuzzlePoint( ent, forward, right, up, muzzle );
+ CalcMuzzlePoint( ent, forward, right, up, muzzle );
}
else
{
diff --git a/src/game/tremulous.h b/src/game/tremulous.h
index 7f8836f..bf60cd0 100644
--- a/src/game/tremulous.h
+++ b/src/game/tremulous.h
@@ -95,7 +95,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define LEVEL3_CLAW_DMG ADM(80)
#define LEVEL3_CLAW_RANGE 80.0f
-#define LEVEL3_CLAW_UPG_RANGE LEVEL3_CLAW_RANGE + 3.0f
+#define LEVEL3_CLAW_UPG_RANGE LEVEL3_CLAW_RANGE + 3.0f
#define LEVEL3_CLAW_WIDTH 12.0f
#define LEVEL3_CLAW_REPEAT 900
#define LEVEL3_CLAW_K_SCALE 1.0f
@@ -107,7 +107,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define LEVEL3_POUNCE_WIDTH 14.0f
#define LEVEL3_POUNCE_TIME 800 // msec for full Dragoon pounce
#define LEVEL3_POUNCE_TIME_UPG 800 // msec for full Adv. Dragoon pounce
-#define LEVEL3_POUNCE_TIME_MIN 200 // msec before which pounce cancels
+#define LEVEL3_POUNCE_TIME_MIN 200 // msec before which pounce cancels
#define LEVEL3_POUNCE_REPEAT 400 // msec before a new pounce starts
#define LEVEL3_POUNCE_SPEED_MOD 0.75f // walking speed modifier for pounce charging
#define LEVEL3_POUNCE_JUMP_MAG 700 // Dragoon pounce jump power
@@ -139,7 +139,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define LEVEL4_CRUSH_REPEAT 500 // player damage repeat
#define LEVEL4_BOMB_DMG 150
-#define LEVEL4_BOMB_RADIUS 400
+#define LEVEL4_BOMB_RADIUS 400
#define LEVEL4_BOMB_SPEED 500.0f
#define LEVEL4_BOMB_REGEN 120000 // minimum time between getting a bomb
@@ -692,7 +692,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define DAMAGE_FRACTION_FOR_KILL 0.5f //how much damage players (versus structures) need to
//do to increment the stage kill counters
-
+
#define MAXIMUM_BUILD_TIME 20000 // used for pie timer
/*
@@ -715,5 +715,5 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define ALIEN_IMPLANT_MATURING_CHANCE 0.05f //chance of maturing (every second)
#define ALIEN_HATCHING_VELOCITY 250.0f
-#define ALIEN_HATCHING_MAX_BATTLESUIT_HEALTH 80 // alien dies if tried to spawn from a battlesuit at least this healthy
+#define ALIEN_HATCHING_MAX_BATTLESUIT_HEALTH 80 // alien dies if tried to spawn from a battlesuit at least this healthy
#define ALIEN_FAILED_HATCH_DAMAGE 65 // shouldn't be higher than the value above