From f9a8b76c0f912cea66eacf71162a3090fda698d8 Mon Sep 17 00:00:00 2001 From: Paweł Redman Date: Sun, 19 Jan 2014 11:44:43 +0100 Subject: 0.1.6 --- src/game/bg_misc.c | 13 +++++ src/game/bg_pmove.c | 42 +++++++++++---- src/game/bg_public.h | 8 ++- src/game/g_active.c | 32 +++++++++--- src/game/g_admin.c | 6 ++- src/game/g_buildable.c | 78 +++++++++++++++++----------- src/game/g_client.c | 9 +++- src/game/g_cmds.c | 138 +++++++++++++++++++++++++------------------------ src/game/g_combat.c | 27 +++++++++- src/game/g_local.h | 2 + src/game/g_main.c | 8 +-- src/game/g_weapon.c | 9 ++-- src/game/tremulous.h | 2 +- 13 files changed, 243 insertions(+), 131 deletions(-) (limited to 'src/game') 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] 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 11d4892..4a28083 100644 --- a/src/game/g_weapon.c +++ b/src/game/g_weapon.c @@ -1136,9 +1136,7 @@ static void G_CreateNewZap( gentity_t *creator, gentity_t *target ) if( target->health > 0 ) { G_Damage( target, creator, creator, forward, - target->s.origin, LEVEL2_AREAZAP_DMG * - ( ( target->s.eType == ET_BUILDABLE ) - ? LEVEL2_AREAZAP_DMG_MOD : 1.0f ), + target->s.origin, LEVEL2_AREAZAP_DMG, DAMAGE_NO_KNOCKBACK | DAMAGE_NO_LOCDAMAGE, MOD_LEVEL2_ZAP ); @@ -1147,9 +1145,8 @@ static void G_CreateNewZap( gentity_t *creator, gentity_t *target ) for( i = 1; i < zap->numTargets; i++ ) { 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 ) - * ( ( zap->targets[ i ]->s.eType == ET_BUILDABLE ) ? LEVEL2_AREAZAP_DMG_MOD : 1.0f ), + LEVEL2_AREAZAP_DMG * ( 1 - pow( (zap->distances[ i ] / + LEVEL2_AREAZAP_CHAIN_RANGE ) , LEVEL2_AREAZAP_CHAIN_FALLOFF ) ) + 1, DAMAGE_NO_KNOCKBACK | DAMAGE_NO_LOCDAMAGE, MOD_LEVEL2_ZAP ); } diff --git a/src/game/tremulous.h b/src/game/tremulous.h index a44a306..bf60cd0 100644 --- a/src/game/tremulous.h +++ b/src/game/tremulous.h @@ -82,7 +82,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define LEVEL2_CLAW_K_SCALE 1.0f #define LEVEL2_CLAW_U_REPEAT 400 #define LEVEL2_CLAW_U_K_SCALE 1.0f -#define LEVEL2_AREAZAP_DMG 6 //ADM(60) +#define LEVEL2_AREAZAP_DMG ADM(60) #define LEVEL2_AREAZAP_RANGE 200.0f #define LEVEL2_AREAZAP_CHAIN_RANGE 150.0f #define LEVEL2_AREAZAP_CHAIN_FALLOFF 8.0f -- cgit