summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTim Angus <tim@ngus.net>2001-09-15 03:42:41 +0000
committerTim Angus <tim@ngus.net>2001-09-15 03:42:41 +0000
commitcab6cb5c4a989b11e6f45b74f87d84a961235984 (patch)
treefa10bd39de3cfbad896ad63a260b3d07c164bdb3 /src
parent5e95698bb34a46c68bae1f5f1c089bf794e5a43d (diff)
Trapper buildable. Other fixes/tweaks
Diffstat (limited to 'src')
-rw-r--r--src/cgame/cg_ents.c12
-rw-r--r--src/cgame/cg_playerstate.c2
-rw-r--r--src/cgame/cg_weapons.c28
-rw-r--r--src/game/bg_misc.c51
-rw-r--r--src/game/bg_pmove.c73
-rw-r--r--src/game/bg_public.h18
-rw-r--r--src/game/g_active.c10
-rw-r--r--src/game/g_buildable.c89
-rw-r--r--src/game/g_combat.c4
-rw-r--r--src/game/g_local.h3
-rw-r--r--src/game/g_missile.c30
-rw-r--r--src/game/g_weapon.c11
12 files changed, 218 insertions, 113 deletions
diff --git a/src/cgame/cg_ents.c b/src/cgame/cg_ents.c
index ddac7a13..df34af3c 100644
--- a/src/cgame/cg_ents.c
+++ b/src/cgame/cg_ents.c
@@ -443,18 +443,6 @@ static void CG_Missile( centity_t *cent )
return;
break;
- case WP_SAWBLADE_LAUNCHER:
- ent.hModel = weapon->missileModel;
-
- // convert direction of travel into axis
- AngleVectors( s1->angles, NULL, NULL, up );
- if( VectorNormalize2( up, ent.axis[ 0 ] ) == 0 )
- ent.axis[ 0 ][ 2 ] = 1;
-
- // spin as it moves
- RotateAroundDirection( ent.axis, cg.time );
- break;
-
default:
// flicker between two skins
ent.skinNum = cg.clientFrame & 1;
diff --git a/src/cgame/cg_playerstate.c b/src/cgame/cg_playerstate.c
index c31216b2..ec4df684 100644
--- a/src/cgame/cg_playerstate.c
+++ b/src/cgame/cg_playerstate.c
@@ -55,7 +55,7 @@ void CG_CheckAmmo( void ) {
switch ( i ) {
case WP_ROCKET_LAUNCHER:
- case WP_SAWBLADE_LAUNCHER:
+ case WP_LOCKBLOB_LAUNCHER:
case WP_GRENADE_LAUNCHER:
case WP_RAILGUN:
case WP_SHOTGUN:
diff --git a/src/cgame/cg_weapons.c b/src/cgame/cg_weapons.c
index 3d665e07..fbf44067 100644
--- a/src/cgame/cg_weapons.c
+++ b/src/cgame/cg_weapons.c
@@ -691,10 +691,10 @@ void CG_RegisterWeapon( int weaponNum ) {
cgs.media.rocketExplosionShader = trap_R_RegisterShader( "rocketExplosion" );
break;
- case WP_SAWBLADE_LAUNCHER:
+ case WP_LOCKBLOB_LAUNCHER:
weaponInfo->missileModel = trap_R_RegisterModel( "models/ammo/sawblade/sawblade.md3" );
- weaponInfo->missileSound = trap_S_RegisterSound( "sound/weapons/rocket/rockfly.wav", qfalse );
-/* weaponInfo->missileTrailFunc = CG_RocketTrail;
+/* weaponInfo->missileSound = trap_S_RegisterSound( "sound/weapons/rocket/rockfly.wav", qfalse );
+ weaponInfo->missileTrailFunc = CG_RocketTrail;
weaponInfo->missileDlight = 200;
weaponInfo->wiTrailTime = 2000;
weaponInfo->trailRadius = 64;
@@ -1825,13 +1825,11 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, vec3_t dir, im
CG_ParticleExplosion( "explode1", sprOrg, sprVel, 1400, 20, 30 );
}
break;
- case WP_SAWBLADE_LAUNCHER:
- mod = cgs.media.dishFlashModel;
-/* shader = cgs.media.rocketExplosionShader;
- sfx = cgs.media.sfx_rockexp;
- mark = cgs.media.burnMarkShader;
+ case WP_LOCKBLOB_LAUNCHER:
+ sfx = cgs.media.gibBounce1Sound;
+ mark = cgs.media.greenBloodMarkShader;
radius = 64;
- isSprite = qtrue;*/
+ isSprite = qtrue;
break;
case WP_RAILGUN:
mod = cgs.media.ringFlashModel;
@@ -1914,14 +1912,20 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, vec3_t dir, im
//
// impact mark
//
- alphaFade = (mark == cgs.media.energyMarkShader); // plasma fades alpha, all others fade color
- if ( weapon == WP_RAILGUN ) {
+ // plasma fades alpha, all others fade color
+ alphaFade = ( mark == cgs.media.energyMarkShader ||
+ mark == cgs.media.greenBloodMarkShader );
+
+ if( weapon == WP_RAILGUN )
+ {
float *color;
// colorize with client color
color = cgs.clientinfo[clientNum].color2;
CG_ImpactMark( mark, origin, dir, random()*360, color[0],color[1], color[2],1, alphaFade, radius, qfalse );
- } else {
+ }
+ else
+ {
CG_ImpactMark( mark, origin, dir, random()*360, 1,1,1,1, alphaFade, radius, qfalse );
}
}
diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c
index 0d5c5c7e..431f433f 100644
--- a/src/game/bg_misc.c
+++ b/src/game/bg_misc.c
@@ -469,15 +469,14 @@ gitem_t bg_itemlist[] =
/*QUAKED weapon_sawbladelauncher (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
*/
{
- "weapon_sawbladelauncher",
+ "weapon_lockbloblauncher",
"sound/misc/w_pkup.wav",
- { "models/weapons2/rocketl/rocketl.md3",
- 0, 0, 0},
+ { 0, 0, 0, 0},
"icons/iconw_rocket",
- "Sawblade Launcher",
+ "Lockblob Launcher",
10,
IT_WEAPON,
- WP_SAWBLADE_LAUNCHER,
+ WP_LOCKBLOB_LAUNCHER,
"",
""
},
@@ -866,6 +865,22 @@ TA: droid defense item
"" //sounds
},
+/*QUAKED team_droid_trapper (0 0 1) (-16 -16 -16) (16 16 16)
+TA: droid defense item
+*/
+ {
+ "team_droid_trapper",
+ "sound/items/holdable.wav",
+ { "models/buildables/trapper/trapper.md3", 0, 0, 0 },
+ "icons/teleporter", //icon
+ "Trapper", //pickup
+ 0,
+ IT_BUILDABLE,
+ BA_D_TRAPPER,
+ "", //precache
+ "" //sounds
+ },
+
/*QUAKED team_droid_hivemind (0 0 1) (-16 -16 -16) (16 16 16)
TA: droid build limitation item
*/
@@ -1271,6 +1286,32 @@ buildableAttributes_t bg_buildableList[ ] =
qfalse //qboolean reactorTest;
},
{
+ BA_D_TRAPPER, //int buildNum;
+ "trapper", //char *buildName;
+ "team_droid_trapper", //char *entityName;
+ { -15, -15, -15 }, //vec3_t mins;
+ { 15, 15, 15 }, //vec3_t maxs;
+ TR_GRAVITY, //trType_t traj;
+ 0.0, //float bounce;
+ 80, //int buildPoints;
+ 1000, //int health;
+ 50, //int damage;
+ 20, //int splashDamage;
+ 50, //int splashRadius;
+ MOD_DSPAWN, //int meansOfDeath;
+ BIT_DROIDS, //int team;
+ ( 1 << WP_DBUILD )|( 1 << WP_DBUILD2 ), //weapon_t buildWeapon;
+ BANIM_IDLE1, //int idleAnim;
+ 1000, //int nextthink;
+ 0, //int turretFireSpeed;
+ 400, //int turretRange;
+ WP_LOCKBLOB_LAUNCHER, //weapon_t turretProjType;
+ 0.707f, //float minNormal;
+ qfalse, //qboolean invertNormal;
+ qtrue, //qboolean creepTest;
+ qfalse //qboolean reactorTest;
+ },
+ {
BA_D_HIVEMIND, //int buildNum;
"hivemind", //char *buildName;
"team_droid_hivemind", //char *entityName;
diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c
index 1e722df4..d9d66ceb 100644
--- a/src/game/bg_pmove.c
+++ b/src/game/bg_pmove.c
@@ -1612,7 +1612,8 @@ static void PM_GroundTrace( void ) {
pm->ps->legsAnim &= ~ANIM_WALLCLIMBING;
//make sure that the surfNormal is reset to the ground
- VectorCopy( refNormal, pm->ps->grapplePoint );
+ if( BG_ClassHasAbility( pm->ps->stats[ STAT_PCLASS ], SCA_WALLCLIMBER ) )
+ VectorCopy( refNormal, pm->ps->grapplePoint );
point[0] = pm->ps->origin[0];
point[1] = pm->ps->origin[1];
@@ -1626,22 +1627,17 @@ static void PM_GroundTrace( void ) {
pml.groundTrace = trace;
// do something corrective if the trace starts in a solid...
- if ( trace.allsolid ) {
- if ( !PM_CorrectAllSolid(&trace) )
+ if( trace.allsolid )
+ if( !PM_CorrectAllSolid(&trace) )
return;
- }
// if the trace didn't hit anything, we are in free fall
- if ( trace.fraction == 1.0 ) {
+ if( trace.fraction == 1.0 )
+ {
PM_GroundTraceMissed();
pml.groundPlane = qfalse;
pml.walking = qfalse;
- pm->ps->stats[ STAT_STATE ] &= ~SS_WALLCLIMBINGCEILING;
-
- //we get very bizarre effects if we don't do this :0
- VectorCopy( refNormal, pm->ps->grapplePoint );
-
return;
}
@@ -2342,7 +2338,7 @@ static void PM_Weapon( void )
case WP_RAILGUN:
addTime = 1500;
break;
- case WP_SAWBLADE_LAUNCHER:
+ case WP_LOCKBLOB_LAUNCHER:
addTime = 1000;
break;
case WP_BFG:
@@ -2443,7 +2439,8 @@ This can be used as another entry point when only the viewangles
are being updated instead of a full move
================
*/
-void PM_UpdateViewAngles( playerState_t *ps, const usercmd_t *cmd ) {
+void PM_UpdateViewAngles( playerState_t *ps, const usercmd_t *cmd )
+{
short temp[3];
int i;
vec3_t surfNormal, xNormal;
@@ -2456,29 +2453,29 @@ void PM_UpdateViewAngles( playerState_t *ps, const usercmd_t *cmd ) {
if( ps->pm_type == PM_INTERMISSION || ps->pm_type == PM_SPINTERMISSION )
return; // no view changes at all
- //TA: FIXME: perhaps do something a little more interesting here later
- //i.e. allow a little view angle change to reflect struggling/stretching ...?
- if( ps->pm_type == PM_GRABBED )
- return;
-
if( ps->pm_type != PM_SPECTATOR && ps->stats[STAT_HEALTH] <= 0 )
return; // no view changes at all
// circularly clamp the angles with deltas
- for (i=0 ; i<3 ; i++) {
- temp[i] = cmd->angles[i] + ps->delta_angles[i];
+ for( i = 0; i < 3; i++ )
+ {
+ temp[ i ] = cmd->angles[ i ] + ps->delta_angles[ i ];
- if ( i == PITCH ) {
+ if( i == PITCH )
+ {
// don't let the player look up or down more than 90 degrees
- if ( temp[i] > 16000 ) {
- ps->delta_angles[i] = 16000 - cmd->angles[i];
- temp[i] = 16000;
- } else if ( temp[i] < -16000 ) {
- ps->delta_angles[i] = -16000 - cmd->angles[i];
- temp[i] = -16000;
+ if( temp[ i ] > 16000 )
+ {
+ ps->delta_angles[ i ] = 16000 - cmd->angles[ i ];
+ temp[ i ] = 16000;
+ }
+ else if( temp[ i ] < -16000 )
+ {
+ ps->delta_angles[ i ] = -16000 - cmd->angles[ i ];
+ temp[ i ] = -16000;
}
}
- tempang[i] = SHORT2ANGLE( temp[i] );
+ tempang[ i ] = SHORT2ANGLE( temp[ i ] );
}
//convert viewangles -> axis
@@ -2536,8 +2533,28 @@ void PM_UpdateViewAngles( playerState_t *ps, const usercmd_t *cmd ) {
}
//actually set the viewangles
- for ( i = 0; i < 3; i++ )
+ for( i = 0; i < 3; i++ )
ps->viewangles[ i ] = tempang[ i ];
+
+ //pull the view into the lock point
+ if( ps->pm_type == PM_GRABBED )
+ {
+ for( i = 0; i < 3; i++ )
+ {
+ float diff = AngleSubtract( ps->viewangles[ i ], ps->grapplePoint[ i ] );
+
+ while( diff > 180.0f )
+ diff -= 360.0f;
+ while( diff < -180.0f )
+ diff += 360.0f;
+
+ if( diff < 0 )
+ ps->delta_angles[ i ] += ANGLE2SHORT( fabs( diff ) * 0.05f );
+ else if( diff > 0 )
+ ps->delta_angles[ i ] -= ANGLE2SHORT( fabs( diff ) * 0.05f );
+ }
+ }
+
}
diff --git a/src/game/bg_public.h b/src/game/bg_public.h
index 7af74969..6f8454c2 100644
--- a/src/game/bg_public.h
+++ b/src/game/bg_public.h
@@ -250,7 +250,8 @@ typedef enum {
#define SS_SPEEDBOOST 16
#define SS_INFESTING 32
#define SS_GRABBED 64
-#define SS_POISONED 128
+#define SS_BLOBLOCKED 128
+#define SS_POISONED 256
// player_state->persistant[] indexes
@@ -326,7 +327,8 @@ typedef enum {
HI_NUM_HOLDABLE
} holdable_t;
-typedef enum {
+typedef enum
+{
WP_NONE,
WP_GAUNTLET,
@@ -335,7 +337,7 @@ typedef enum {
WP_SHOTGUN,
WP_GRENADE_LAUNCHER,
WP_ROCKET_LAUNCHER,
- WP_SAWBLADE_LAUNCHER,
+ WP_LOCKBLOB_LAUNCHER,
WP_LIGHTNING,
WP_RAILGUN,
WP_FLAMER,
@@ -359,7 +361,8 @@ typedef enum {
WP_NUM_WEAPONS
} weapon_t;
-typedef enum {
+typedef enum
+{
UP_NONE,
UP_TORCH,
@@ -387,13 +390,16 @@ typedef enum {
#define SLOT_WEAPON 32
#define SLOT_SIDEARM 64
-typedef enum {
+typedef enum
+{
BA_NONE,
BA_D_SPAWN,
+ BA_D_HIVEMIND,
+
BA_D_BARRICADE,
BA_D_ACIDTUBE,
- BA_D_HIVEMIND,
+ BA_D_TRAPPER,
BA_H_SPAWN,
diff --git a/src/game/g_active.c b/src/game/g_active.c
index 2a9e27fb..95b638b3 100644
--- a/src/game/g_active.c
+++ b/src/game/g_active.c
@@ -814,14 +814,20 @@ void ClientThink_real( gentity_t *ent ) {
client->ps.pm_type = PM_DEAD;
else if( client->ps.stats[ STAT_STATE ] & SS_INFESTING )
client->ps.pm_type = PM_FREEZE;
- else if( client->ps.stats[ STAT_STATE ] & SS_GRABBED )
+ else if( client->ps.stats[ STAT_STATE ] & SS_BLOBLOCKED ||
+ client->ps.stats[ STAT_STATE ] & SS_GRABBED )
client->ps.pm_type = PM_GRABBED;
else
client->ps.pm_type = PM_NORMAL;
- if( client->ps.stats[ STAT_STATE ] & SS_GRABBED && client->lastGrabTime + 500 < level.time )
+ if( client->ps.stats[ STAT_STATE ] & SS_GRABBED &&
+ client->lastGrabTime + 500 < level.time )
client->ps.stats[ STAT_STATE ] &= ~SS_GRABBED;
+ if( client->ps.stats[ STAT_STATE ] & SS_BLOBLOCKED &&
+ client->lastLockTime + 5000 < level.time )
+ client->ps.stats[ STAT_STATE ] &= ~SS_BLOBLOCKED;
+
client->ps.gravity = g_gravity.value;
// set speed
diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c
index bb578210..09630f5b 100644
--- a/src/game/g_buildable.c
+++ b/src/game/g_buildable.c
@@ -381,13 +381,20 @@ void DSpawn_Think( gentity_t *self )
displacement = ( self->r.maxs[ 2 ] + MAX_ALIEN_BBOX ) * M_ROOT3 + 1.0f;
VectorMA( origin, displacement, self->s.origin2, origin );
- trap_Trace( &tr, origin, mins, maxs, origin, self->s.number, MASK_SHOT );
- ent = &g_entities[ tr.entityNum ];
-
- if( ent->s.eType == ET_BUILDABLE || ent->s.number == ENTITYNUM_WORLD )
+ //only suicide if at rest
+ if( self->s.groundEntityNum )
{
- G_Damage( self, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE );
- return;
+ trap_Trace( &tr, origin, mins, maxs, origin, self->s.number, MASK_SHOT );
+ ent = &g_entities[ tr.entityNum ];
+
+ if( ent->s.eType == ET_BUILDABLE || ent->s.number == ENTITYNUM_WORLD )
+ {
+ G_Damage( self, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE );
+ return;
+ }
+
+ if( ent->s.eType == ET_CORPSE )
+ G_FreeEntity( ent ); //quietly remove
}
self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.clientNum );
@@ -583,6 +590,7 @@ void DAcidTube_Think( gentity_t *self )
//==================================================================================
+#define BLOB_PROJSPEED 500
/*
================
@@ -594,8 +602,29 @@ Used by DDef2_Think to fire at enemy
void ddef_fireonenemy( gentity_t *self, int firespeed )
{
vec3_t dirToTarget;
+ vec3_t target;
+ vec3_t halfAcceleration, thirdJerk;
+ float distanceToTarget = BG_FindRangeForBuildable( self->s.clientNum );
+ int i;
- VectorSubtract( self->enemy->s.pos.trBase, self->s.pos.trBase, dirToTarget );
+ VectorScale( self->enemy->acceleration, 1.0f / 2.0f, halfAcceleration );
+ VectorScale( self->enemy->jerk, 1.0f / 3.0f, thirdJerk );
+
+ //O( time ) - worst case O( time ) = 250 iterations
+ for( i = 0; ( i * BLOB_PROJSPEED ) / 1000.0f < distanceToTarget; i++ )
+ {
+ float time = (float)i / 1000.0f;
+
+ VectorMA( self->enemy->s.pos.trBase, time, self->enemy->s.pos.trDelta,
+ dirToTarget );
+ VectorMA( dirToTarget, time * time, halfAcceleration, dirToTarget );
+ VectorMA( dirToTarget, time * time * time, thirdJerk, dirToTarget );
+ VectorSubtract( dirToTarget, self->s.pos.trBase, dirToTarget );
+ distanceToTarget = VectorLength( dirToTarget );
+
+ distanceToTarget -= self->enemy->r.maxs[ 0 ];
+ }
+
VectorNormalize( dirToTarget );
vectoangles( dirToTarget, self->s.angles2 );
@@ -625,12 +654,14 @@ qboolean ddef_checktarget( gentity_t *self, gentity_t *target, int range )
return qfalse;
if( !target->client ) // is the target a bot or player?
return qfalse;
- if( target->client->ps.stats[ STAT_PTEAM ] == PTE_DROIDS ) // is the target one of us?
+ if( target->client->ps.stats[ STAT_PTEAM ] == PTE_DROIDS ) // one of us?
return qfalse;
if( target->client->sess.sessionTeam == TEAM_SPECTATOR ) // is the target alive?
return qfalse;
if( target->health <= 0 ) // is the target still alive?
return qfalse;
+ if( target->client->ps.stats[ STAT_STATE ] & SS_BLOBLOCKED ) // locked?
+ return qfalse;
VectorSubtract( target->r.currentOrigin, self->r.currentOrigin, distance );
if( VectorLength( distance ) > range ) // is the target within range?
@@ -654,10 +685,8 @@ void ddef_findenemy( gentity_t *ent, int range )
{
gentity_t *target;
- target = g_entities;
-
//iterate through entities
- for (; target < &g_entities[ level.num_entities ]; target++)
+ for( target = g_entities; target < &g_entities[ level.num_entities ]; target++ )
{
//if target is not valid keep searching
if( !ddef_checktarget( ent, target, range ) )
@@ -674,12 +703,12 @@ void ddef_findenemy( gentity_t *ent, int range )
/*
================
-DDef2_Think
+DTrapper_Think
think function for Droid Defense
================
*/
-void DDef2_Think( gentity_t *self )
+void DTrapper_Think( gentity_t *self )
{
int range = BG_FindRangeForBuildable( self->s.clientNum );
int firespeed = BG_FindFireSpeedForBuildable( self->s.clientNum );
@@ -1426,6 +1455,7 @@ void HSpawn_Think( gentity_t *self )
vec3_t mins, maxs, origin;
gentity_t *ent;
trace_t tr;
+ vec3_t up = { 0, 0, 1 };
BG_FindBBoxForClass( PCL_H_BASE, mins, maxs, NULL, NULL, NULL );
@@ -1435,13 +1465,20 @@ void HSpawn_Think( gentity_t *self )
//make sure we have power
self->powered = findPower( self );
- trap_Trace( &tr, origin, mins, maxs, origin, self->s.number, MASK_SHOT );
- ent = &g_entities[ tr.entityNum ];
-
- if( ent->s.eType == ET_BUILDABLE || ent->s.number == ENTITYNUM_WORLD )
+ //only suicide if at rest
+ if( self->s.groundEntityNum )
{
- G_Damage( self, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE );
- return;
+ trap_Trace( &tr, origin, mins, maxs, origin, self->s.number, MASK_SHOT );
+ ent = &g_entities[ tr.entityNum ];
+
+ if( ent->s.eType == ET_BUILDABLE || ent->s.number == ENTITYNUM_WORLD )
+ {
+ G_Damage( self, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE );
+ return;
+ }
+
+ if( ent->s.eType == ET_CORPSE )
+ G_FreeEntity( ent ); //quietly remove
}
self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.clientNum );
@@ -1705,13 +1742,11 @@ gentity_t *G_buildItem( gentity_t *ent, buildable_t buildable, int distance, flo
built->pain = DSpawn_Pain;
break;
-/* case BA_D_DEF2:
- built->die = DDef1_Die;
- built->think = DDef2_Think;
+ case BA_D_TRAPPER:
+ built->die = DBarricade_Die;
+ built->think = DTrapper_Think;
built->pain = DSpawn_Pain;
- built->enemy = NULL;
- built->s.weapon = BG_FindProjTypeForBuildable( buildable );
- break;*/
+ break;
case BA_D_HIVEMIND:
built->die = DSpawn_Die;
@@ -1728,8 +1763,6 @@ gentity_t *G_buildItem( gentity_t *ent, buildable_t buildable, int distance, flo
case BA_H_DEF3:
built->die = HSpawn_Die;
built->think = HDef_Think;
- built->enemy = NULL;
- built->s.weapon = BG_FindProjTypeForBuildable( buildable );
break;
case BA_H_MCU:
@@ -1779,6 +1812,8 @@ gentity_t *G_buildItem( gentity_t *ent, buildable_t buildable, int distance, flo
built->s.number = built - g_entities;
built->r.contents = CONTENTS_BODY;
built->clipmask = MASK_PLAYERSOLID;
+ built->enemy = NULL;
+ built->s.weapon = BG_FindProjTypeForBuildable( buildable );
if( ent->client )
built->builtBy = ent->client->ps.clientNum;
diff --git a/src/game/g_combat.c b/src/game/g_combat.c
index bf36808a..fb4e073e 100644
--- a/src/game/g_combat.c
+++ b/src/game/g_combat.c
@@ -873,13 +873,9 @@ float G_CalcDamageModifier( vec3_t point, gentity_t *targ, gentity_t *attacker,
clientHeight = targ->r.maxs[ 2 ] - targ->r.mins[ 2 ];
if( targ->client->ps.stats[ STAT_STATE ] & SS_WALLCLIMBING )
- {
VectorCopy( targ->client->ps.grapplePoint, normal );
- }
else
- {
VectorSet( normal, 0, 0, 1 );
- }
VectorMA( targ->r.currentOrigin, targ->r.mins[ 2 ], normal, floor );
VectorSubtract( point, floor, pMINUSfloor );
diff --git a/src/game/g_local.h b/src/game/g_local.h
index 74653277..f70ade0b 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -348,6 +348,7 @@ struct gclient_s {
int lastPoisonTime;
int lastGrabTime; //TA: yuck yuck hack urgh
+ int lastLockTime; //TA: " "
int pouncePayload; //TA: amount of damage pounce attack will do
qboolean allowedToPounce;
@@ -616,7 +617,7 @@ gentity_t *fire_flamer( gentity_t *self, vec3_t start, vec3_t aimdir );
gentity_t *fire_plasma( gentity_t *self, vec3_t start, vec3_t aimdir );
gentity_t *fire_grenade( gentity_t *self, vec3_t start, vec3_t aimdir );
gentity_t *fire_rocket( gentity_t *self, vec3_t start, vec3_t dir );
-gentity_t *fire_sawblade( gentity_t *self, vec3_t start, vec3_t dir );
+gentity_t *fire_lockblob( gentity_t *self, vec3_t start, vec3_t dir );
gentity_t *fire_bfg( gentity_t *self, vec3_t start, vec3_t dir );
gentity_t *fire_grapple( gentity_t *self, vec3_t start, vec3_t dir );
diff --git a/src/game/g_missile.c b/src/game/g_missile.c
index 819f19e6..46fe9239 100644
--- a/src/game/g_missile.c
+++ b/src/game/g_missile.c
@@ -83,7 +83,7 @@ void G_ExplodeMissile( gentity_t *ent ) {
ent->s.eType = ET_GENERAL;
//TA: tired... can't be fucked... hack
- if( ent->s.weapon != WP_SAWBLADE_LAUNCHER )
+ if( ent->s.weapon != WP_LOCKBLOB_LAUNCHER )
G_AddEvent( ent, EV_MISSILE_MISS, DirToByte( dir ) );
ent->freeAfterEvent = qtrue;
@@ -140,7 +140,8 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
}
}
- if (!strcmp(ent->classname, "hook")) {
+ if( !strcmp( ent->classname, "hook" ) )
+ {
gentity_t *nent;
vec3_t v;
@@ -185,6 +186,16 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
return;
}
+ if( !strcmp( ent->classname, "lockblob" ) )
+ {
+ if( other->client && other->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
+ {
+ other->client->ps.stats[ STAT_STATE ] |= SS_BLOBLOCKED;
+ other->client->lastLockTime = level.time;
+ VectorCopy( other->client->ps.viewangles, other->client->ps.grapplePoint );
+ }
+ }
+
// is it cheaper in bandwidth to just remove this ent and create a new
// one, rather than changing the missile into the explosion?
@@ -490,26 +501,25 @@ gentity_t *fire_rocket (gentity_t *self, vec3_t start, vec3_t dir) {
/*
=================
-fire_sawblade
+fire_lockblob
=================
*/
-gentity_t *fire_sawblade( gentity_t *self, vec3_t start, vec3_t dir )
+gentity_t *fire_lockblob( gentity_t *self, vec3_t start, vec3_t dir )
{
gentity_t *bolt;
VectorNormalize ( dir );
bolt = G_Spawn( );
- bolt->classname = "sawblade";
- bolt->nextthink = level.time + 5000;
+ bolt->classname = "lockblob";
+ bolt->nextthink = level.time + 15000;
bolt->think = G_ExplodeMissile;
bolt->s.eType = ET_MISSILE;
bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
- bolt->s.eFlags = EF_BOUNCE;
- bolt->s.weapon = WP_SAWBLADE_LAUNCHER;
+ bolt->s.weapon = WP_LOCKBLOB_LAUNCHER;
bolt->r.ownerNum = self->s.number;
bolt->parent = self;
- bolt->damage = 100;
+ bolt->damage = 0;
bolt->splashDamage = 0;
bolt->splashRadius = 0;
bolt->methodOfDeath = MOD_ROCKET;
@@ -520,7 +530,7 @@ gentity_t *fire_sawblade( gentity_t *self, vec3_t start, vec3_t dir )
bolt->s.pos.trType = TR_LINEAR;
bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit on the very first frame
VectorCopy( start, bolt->s.pos.trBase );
- VectorScale( dir, 1000, bolt->s.pos.trDelta );
+ VectorScale( dir, 500, bolt->s.pos.trDelta );
SnapVector( bolt->s.pos.trDelta ); // save net bandwidth
VectorCopy (start, bolt->r.currentOrigin);
diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c
index 3e2e2caa..85a9b59d 100644
--- a/src/game/g_weapon.c
+++ b/src/game/g_weapon.c
@@ -346,11 +346,11 @@ SAWBLADE
======================================================================
*/
-void Weapon_SawbladeLauncher_Fire( gentity_t *ent )
+void Weapon_LockBlobLauncher_Fire( gentity_t *ent )
{
gentity_t *m;
- m = fire_sawblade( ent, muzzle, forward );
+ m = fire_lockblob( ent, muzzle, forward );
// VectorAdd( m->s.pos.trDelta, ent->client->ps.velocity, m->s.pos.trDelta ); // "real" physics
}
@@ -774,6 +774,7 @@ void Weapon_Grab_Fire( gentity_t *ent )
//lock client
traceEnt->client->ps.stats[ STAT_STATE ] |= SS_GRABBED;
traceEnt->client->lastGrabTime = level.time;
+ VectorCopy( traceEnt->client->ps.viewangles, traceEnt->client->ps.grapplePoint );
}
}
@@ -1024,7 +1025,7 @@ void FireWeapon2( gentity_t *ent )
case WP_RAILGUN:
weapon_railgun_fire( ent );
break;
- case WP_SAWBLADE_LAUNCHER:
+ case WP_LOCKBLOB_LAUNCHER:
break;
case WP_BFG:
BFG_Fire( ent );
@@ -1111,8 +1112,8 @@ void FireWeapon( gentity_t *ent )
case WP_RAILGUN:
weapon_railgun_fire( ent );
break;
- case WP_SAWBLADE_LAUNCHER:
- Weapon_SawbladeLauncher_Fire( ent );
+ case WP_LOCKBLOB_LAUNCHER:
+ Weapon_LockBlobLauncher_Fire( ent );
break;
case WP_BFG:
BFG_Fire( ent );