diff options
-rw-r--r-- | src/cgame/cg_players.c | 4 | ||||
-rw-r--r-- | src/cgame/cg_servercmds.c | 6 | ||||
-rw-r--r-- | src/game/bg_misc.c | 8 | ||||
-rw-r--r-- | src/game/bg_public.h | 5 | ||||
-rw-r--r-- | src/game/g_active.c | 26 | ||||
-rw-r--r-- | src/game/g_buildable.c | 76 | ||||
-rw-r--r-- | src/game/g_cmds.c | 4 | ||||
-rw-r--r-- | src/game/g_local.h | 16 | ||||
-rw-r--r-- | src/game/q_math.c | 44 |
9 files changed, 157 insertions, 32 deletions
diff --git a/src/cgame/cg_players.c b/src/cgame/cg_players.c index f7042456..1cce4788 100644 --- a/src/cgame/cg_players.c +++ b/src/cgame/cg_players.c @@ -1972,6 +1972,10 @@ void CG_Player( centity_t *cent ) if( !ci->infoValid ) return; + //don't draw + if( es->eFlags & EF_NODRAW ) + return; + // get the player model information renderfx = 0; if( es->number == cg.snap->ps.clientNum ) diff --git a/src/cgame/cg_servercmds.c b/src/cgame/cg_servercmds.c index 31685518..98af076a 100644 --- a/src/cgame/cg_servercmds.c +++ b/src/cgame/cg_servercmds.c @@ -678,6 +678,12 @@ void CG_Menu( int menu ) trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" ); break; + case MN_A_HOVEL_EXIT: + trap_Cvar_Set( "ui_dialog", "The exit to this Hovel will always be blocked. Please choose " + "a more suitable location." ); + trap_SendConsoleCommand( "menu tremulous_alien_dialog\n" ); + break; + case MN_A_INFEST: trap_Cvar_Set( "ui_currentClass", va( "%d %d", cg.snap->ps.stats[ STAT_PCLASS ], cg.snap->ps.persistant[ PERS_CREDIT ] ) ); diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c index 0a9e2928..de2d74d6 100644 --- a/src/game/bg_misc.c +++ b/src/game/bg_misc.c @@ -244,8 +244,8 @@ buildableAttributes_t bg_buildableList[ ] = 0, //int turretRange; 0, //int turretFireSpeed; WP_NONE, //weapon_t turretProjType; - 0.707f, //float minNormal; - qtrue, //qboolean invertNormal; + 0.95f, //float minNormal; + qfalse, //qboolean invertNormal; qtrue, //qboolean creepTest; HOVEL_CREEPSIZE, //int creepSize; qfalse, //qboolean dccTest; @@ -1233,7 +1233,7 @@ classAttributes_t bg_classList[ ] = { 15, 15, 20 }, //vec3_t crouchmaxs; { -15, -15, -4 }, //vec3_t deadmins; { 15, 15, 4 }, //vec3_t deadmaxs; - 20, 20, //int viewheight, crouchviewheight; + 0, 0, //int viewheight, crouchviewheight; ABUILDER_HEALTH, //int health; ABUILDER_REGEN, //int regenRate; SCA_TAKESFALLDAMAGE|SCA_FOVWARPS| @@ -1264,7 +1264,7 @@ classAttributes_t bg_classList[ ] = { 20, 20, 20 }, //vec3_t crouchmaxs; { -20, -20, -4 }, //vec3_t deadmins; { 20, 20, 4 }, //vec3_t deadmaxs; - 20, 20, //int viewheight, crouchviewheight; + 0, 0, //int viewheight, crouchviewheight; ABUILDER_UPG_HEALTH, //int health; ABUILDER_UPG_REGEN, //int regenRate; SCA_CANJUMP|SCA_FOVWARPS|SCA_WALLCLIMBER| diff --git a/src/game/bg_public.h b/src/game/bg_public.h index ff96700d..690ac0e4 100644 --- a/src/game/bg_public.h +++ b/src/game/bg_public.h @@ -559,6 +559,7 @@ typedef enum MN_A_NORMAL, MN_A_HOVEL_OCCUPIED, MN_A_HOVEL_BLOCKED, + MN_A_HOVEL_EXIT, MN_A_OBANK, MN_A_NOFUNDS, MN_A_NOEROOM, @@ -1201,6 +1202,8 @@ qboolean BG_PlayerTouchesItem( playerState_t *ps, entityState_t *item, int atTi void AxisToAngles( vec3_t axis[3], vec3_t angles ); #define Vector2Set(v, x, y) ((v)[0]=(x), (v)[1]=(y)) float pointToLineDistance( const vec3_t point, const vec3_t p1, const vec3_t p2 ); +#define MAX(x,y) (x)>(y)?(x):(y) +#define MIN(x,y) (x)<(y)?(x):(y) // Ridah @@ -1211,3 +1214,5 @@ void ProjectPointOntoVector( vec3_t point, vec3_t vStart, float VectorDistance( vec3_t v1, vec3_t v2 ); // done. +float VectorMinComponent( vec3_t v ); +float VectorMaxComponent( vec3_t v ); diff --git a/src/game/g_active.c b/src/game/g_active.c index fc4b4ea3..df67d1a3 100644 --- a/src/game/g_active.c +++ b/src/game/g_active.c @@ -1056,31 +1056,23 @@ void ClientThink_real( gentity_t *ent ) if( client->ps.stats[ STAT_STATE ] & SS_HOVELING ) { - gentity_t *hovel = client->infestBody; - vec3_t forward, newOrigin, newAngles; - trace_t tr; + gentity_t *hovel = client->hovel; + vec3_t newOrigin, newAngles; vec3_t mins, maxs; BG_FindBBoxForClass( client->ps.stats[ STAT_PCLASS ], mins, maxs, NULL, NULL, NULL ); - AngleVectors( hovel->s.angles, forward, NULL, NULL ); - VectorInverse( forward ); - - VectorMA( hovel->s.origin, 95.0f, forward, newOrigin ); - vectoangles( forward, newAngles ); - - VectorMA( newOrigin, 1.0f, hovel->s.origin2, newOrigin ); - - trap_Trace( &tr, newOrigin, mins, maxs, newOrigin, 0, MASK_PLAYERSOLID ); - //only let the player out if there is room - if( tr.fraction == 1.0 ) + if( !AHovel_Blocked( hovel->s.angles, hovel->s.origin, hovel->s.origin2, + mins, maxs, 0, newOrigin, newAngles ) ) { //prevent lerping - ent->client->ps.eFlags ^= EF_TELEPORT_BIT; - + client->ps.eFlags ^= EF_TELEPORT_BIT; + client->ps.eFlags &= ~EF_NODRAW; + G_SetOrigin( ent, newOrigin ); - VectorCopy( newOrigin, ent->client->ps.origin ); + VectorCopy( newOrigin, client->ps.origin ); + VectorCopy( vec3_origin, client->ps.velocity ); SetClientViewAngle( ent, newAngles ); //client leaves hovel diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c index 50c45950..b1152e3e 100644 --- a/src/game/g_buildable.c +++ b/src/game/g_buildable.c @@ -792,6 +792,59 @@ void AAcidTube_Think( gentity_t *self ) + +#define HOVEL_TRACE_DEPTH 16.0f + +/* +================ +AHovel_Blocked + +Is this hovel entrace blocked? +================ +*/ +qboolean AHovel_Blocked( vec3_t srcAngles, vec3_t srcOrigin, vec3_t normal, + vec3_t mins, vec3_t maxs, int entityNum, + vec3_t newOrigin, vec3_t newAngles ) +{ + vec3_t forward, origin, start, end, angles, hovelMaxs; + float displacement; + trace_t tr; + + BG_FindBBoxForBuildable( BA_A_HOVEL, NULL, hovelMaxs ); + + AngleVectors( srcAngles, forward, NULL, NULL ); + VectorInverse( forward ); + + displacement = VectorMaxComponent( maxs ) + VectorMaxComponent( hovelMaxs ) + 1.0f; + + VectorMA( srcOrigin, displacement, forward, origin ); + vectoangles( forward, angles ); + + VectorMA( origin, HOVEL_TRACE_DEPTH, normal, start ); + VectorMA( origin, -HOVEL_TRACE_DEPTH, normal, end ); + + trap_Trace( &tr, start, mins, maxs, end, entityNum, MASK_PLAYERSOLID ); + + if( tr.startsolid ) + return qfalse; + + VectorCopy( tr.endpos, origin ); + + trap_Trace( &tr, origin, mins, maxs, origin, entityNum, MASK_PLAYERSOLID ); + + if( newOrigin != NULL ) + VectorCopy( origin, newOrigin ); + + if( newAngles != NULL ) + VectorCopy( angles, newAngles ); + + if( tr.fraction < 1.0 ) + return qtrue; + else + return qfalse; +} + + /* ================ AHovel_Use @@ -818,10 +871,10 @@ void AHovel_Use( gentity_t *self, gentity_t *other, gentity_t *activator ) //prevent lerping activator->client->ps.eFlags ^= EF_TELEPORT_BIT; - - activator->client->sess.sessionTeam = TEAM_FREE; + activator->client->ps.eFlags |= EF_NODRAW; + activator->client->ps.stats[ STAT_STATE ] |= SS_HOVELING; - activator->client->infestBody = self; + activator->client->hovel = self; self->builder = activator; VectorCopy( self->s.pos.trBase, hovelOrigin ); @@ -1962,6 +2015,7 @@ itemBuildError_t G_itemFits( gentity_t *ent, buildable_t buildable, int distance trap_Trace( &tr3, player_origin, NULL, NULL, entity_origin, ent->s.number, MASK_PLAYERSOLID ); VectorCopy( entity_origin, origin ); + vectoangles( forward, angles ); //this item does not fit here if( tr2.fraction < 1.0 || tr3.fraction < 1.0 ) @@ -1987,6 +2041,18 @@ itemBuildError_t G_itemFits( gentity_t *ent, buildable_t buildable, int distance reason = IBE_NOCREEP; } + if( buildable == BA_A_HOVEL ) + { + vec3_t builderMins, builderMaxs; + + //this assumes the adv builder is the biggest thing that'll use the hovel + BG_FindBBoxForClass( PCL_A_B_LEV1, builderMins, builderMaxs, NULL, NULL, NULL ); + + if( AHovel_Blocked( angles, origin, normal, builderMins, builderMaxs, + ent->client->ps.clientNum, NULL, NULL ) ) + reason = IBE_HOVELEXIT; + } + //look for a hivemind for ( i = 1, tempent = g_entities + i; i < level.num_entities; i++, tempent++ ) { @@ -2316,6 +2382,10 @@ qboolean G_ValidateBuild( gentity_t *ent, buildable_t buildable ) G_TriggerMenu( ent->client->ps.clientNum, MN_A_OVERMIND ); return qfalse; + case IBE_HOVELEXIT: + G_TriggerMenu( ent->client->ps.clientNum, MN_A_HOVEL_EXIT ); + return qfalse; + case IBE_NORMAL: G_TriggerMenu( ent->client->ps.clientNum, MN_A_NORMAL ); return qfalse; diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index 0f31c7e7..d1dc7eca 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -1144,7 +1144,7 @@ void Cmd_Destroy_f( gentity_t *ent, qboolean deconstruct ) gentity_t *traceEnt; if( ent->client->ps.stats[ STAT_STATE ] & SS_HOVELING ) - G_Damage( ent->client->infestBody, ent, ent, forward, ent->s.origin, 10000, 0, MOD_SUICIDE ); + G_Damage( ent->client->hovel, ent, ent, forward, ent->s.origin, 10000, 0, MOD_SUICIDE ); if( !( ent->client->ps.stats[ STAT_STATE ] & SS_INFESTING ) ) { @@ -1725,6 +1725,7 @@ void Cmd_Build_f( gentity_t *ent ) { dist = BG_FindBuildDistForClass( ent->client->ps.stats[ STAT_PCLASS ] ); + //these are the errors displayed when the builder first selects something to use switch( G_itemFits( ent, buildable, dist, origin ) ) { case IBE_NONE: @@ -1733,6 +1734,7 @@ void Cmd_Build_f( gentity_t *ent ) case IBE_SPWNWARN: case IBE_NOROOM: case IBE_NORMAL: + case IBE_HOVELEXIT: ent->client->ps.stats[ STAT_BUILDABLE ] = ( buildable | SB_VALID_TOGGLEBIT ); break; diff --git a/src/game/g_local.h b/src/game/g_local.h index 52ccc09f..e156d0f0 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -349,8 +349,7 @@ struct gclient_s char *areabits; - int lastInfestTime; //TA: to keep track of how long infests take - gentity_t *infestBody; //TA: body that is being infested. must be persistant + gentity_t *hovel; //TA: body that is being infested. must be persistant int lastPoisonTime; gentity_t *lastPoisonClient; @@ -542,23 +541,30 @@ typedef enum { IBE_NONE, - IBE_NOROOM, IBE_NOOVERMIND, IBE_OVERMIND, IBE_NOASSERT, IBE_SPWNWARN, + IBE_NOCREEP, + IBE_HOVELEXIT, + IBE_REACTOR, IBE_REPEATER, IBE_RPLWARN, IBE_RPTWARN, IBE_NOPOWER, - IBE_NORMAL, - IBE_NOCREEP, IBE_NODCC, + + IBE_NORMAL, + IBE_NOROOM, IBE_MAXERRORS } itemBuildError_t; +qboolean AHovel_Blocked( vec3_t srcAngles, vec3_t srcOrigin, vec3_t normal, + vec3_t mins, vec3_t maxs, int entityNum, + vec3_t newOrigin, vec3_t newAngles ); + itemBuildError_t G_itemFits( gentity_t *ent, buildable_t buildable, int distance, vec3_t origin ); gentity_t *G_buildItem( gentity_t *builder, buildable_t buildable, vec3_t origin, vec3_t angles ); qboolean G_ValidateBuild( gentity_t *ent, buildable_t buildable ); diff --git a/src/game/q_math.c b/src/game/q_math.c index f4b737ec..1cfe25cc 100644 --- a/src/game/q_math.c +++ b/src/game/q_math.c @@ -333,7 +333,7 @@ qboolean PlaneFromPoints( vec4_t plane, const vec3_t a, const vec3_t b, const ve /// These optimised and much cleaner implementations of the Vector Rotation -/// functions were provided by Riv of planetquake (riviera@planetquake.com) +/// functions were provided by Riv (riviera@planetquake.com) /// ...Cheers Riv... /* =============== @@ -1384,7 +1384,7 @@ float pointToLineDistance( const vec3_t p0, const vec3_t p1, const vec3_t p2 ) ================= GetPerpendicularViewVector - Used to find an "up" vector for drawing a sprite so that it always faces the view as best as possible +Used to find an "up" vector for drawing a sprite so that it always faces the view as best as possible ================= */ void GetPerpendicularViewVector( const vec3_t point, const vec3_t p1, const vec3_t p2, vec3_t up ) @@ -1425,3 +1425,43 @@ float VectorDistance(vec3_t v1, vec3_t v2) return VectorLength(dir); } // done. + +/* +================ +VectorMaxComponent + +Return the biggest component of some vector +================ +*/ +float VectorMaxComponent( vec3_t v ) +{ + float biggest = v[ 0 ]; + + if( v[ 1 ] > biggest ) + biggest = v[ 1 ]; + + if( v[ 2 ] > biggest ) + biggest = v[ 2 ]; + + return biggest; +} + +/* +================ +VectorMinComponent + +Return the smallest component of some vector +================ +*/ +float VectorMinComponent( vec3_t v ) +{ + float smallest = v[ 0 ]; + + if( v[ 1 ] < smallest ) + smallest = v[ 1 ]; + + if( v[ 2 ] < smallest ) + smallest = v[ 2 ]; + + return smallest; +} |