summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Angus <tim@ngus.net>2003-08-31 01:18:40 +0000
committerTim Angus <tim@ngus.net>2003-08-31 01:18:40 +0000
commitc7d3bd75523726fc4f5230a9c23b5f31537fc5a8 (patch)
tree5fcec7f1c10997cf640393271ae18c5522ed3c82
parent703dcc641a188c128dc5acb7bfc6d7b8333bdd35 (diff)
* Fixed hovel problems
-rw-r--r--src/cgame/cg_players.c4
-rw-r--r--src/cgame/cg_servercmds.c6
-rw-r--r--src/game/bg_misc.c8
-rw-r--r--src/game/bg_public.h5
-rw-r--r--src/game/g_active.c26
-rw-r--r--src/game/g_buildable.c76
-rw-r--r--src/game/g_cmds.c4
-rw-r--r--src/game/g_local.h16
-rw-r--r--src/game/q_math.c44
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;
+}