summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cgame/cg_event.c4
-rw-r--r--src/cgame/cg_view.c3
-rw-r--r--src/cgame/cg_weapons.c5
-rw-r--r--src/game/bg_misc.c23
-rw-r--r--src/game/bg_pmove.c14
-rw-r--r--src/game/bg_public.h3
-rw-r--r--src/game/g_active.c18
-rw-r--r--src/game/g_client.c4
-rw-r--r--src/game/g_local.h3
-rw-r--r--src/game/g_missile.c47
-rw-r--r--src/game/g_weapon.c42
11 files changed, 155 insertions, 11 deletions
diff --git a/src/cgame/cg_event.c b/src/cgame/cg_event.c
index 4ae78987..6dc12f29 100644
--- a/src/cgame/cg_event.c
+++ b/src/cgame/cg_event.c
@@ -818,6 +818,10 @@ void CG_EntityEvent( centity_t *cent, vec3_t position )
DEBUGNAME("EV_FIRE_WEAPON2");
CG_FireWeapon( cent ); //FIXME:??
break;
+ case EV_FIRE_WEAPON3:
+ DEBUGNAME("EV_FIRE_WEAPON3");
+ CG_FireWeapon( cent ); //FIXME:??
+ break;
case EV_FIRE_WEAPONBOTH:
DEBUGNAME("EV_FIRE_WEAPONBOTH");
CG_FireWeapon( cent ); //FIXME:??
diff --git a/src/cgame/cg_view.c b/src/cgame/cg_view.c
index 6d434eab..2d56f353 100644
--- a/src/cgame/cg_view.c
+++ b/src/cgame/cg_view.c
@@ -428,7 +428,8 @@ static void CG_OffsetFirstPersonView( void ) {
}
//provide some feedback for pouncing
- if( cg.predictedPlayerState.weapon == WP_POUNCE )
+ if( cg.predictedPlayerState.weapon == WP_POUNCE ||
+ cg.predictedPlayerState.weapon == WP_POUNCE_UPG )
{
if( cg.predictedPlayerState.stats[ STAT_MISC ] > 0 )
{
diff --git a/src/cgame/cg_weapons.c b/src/cgame/cg_weapons.c
index d8441016..91dc841e 100644
--- a/src/cgame/cg_weapons.c
+++ b/src/cgame/cg_weapons.c
@@ -708,7 +708,6 @@ void CG_RegisterWeapon( int weaponNum )
break;
case WP_LOCKBLOB_LAUNCHER:
- weaponInfo->missileModel = trap_R_RegisterModel( "models/ammo/trapper/trapper.md3" );
/* weaponInfo->missileSound = trap_S_RegisterSound( "sound/weapons/rocket/rockfly.wav", qfalse );
weaponInfo->missileTrailFunc = CG_RocketTrail;
weaponInfo->missileDlight = 200;
@@ -716,6 +715,7 @@ void CG_RegisterWeapon( int weaponNum )
weaponInfo->trailRadius = 64;
MAKERGB( weaponInfo->missileDlightColor, 1, 0.75f, 0 );
MAKERGB( weaponInfo->flashDlightColor, 1, 0.75f, 0 );*/
+ weaponInfo->missileModel = trap_R_RegisterModel( "models/ammo/grenade1.md3" );
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/rocket/rocklf1a.wav", qfalse );
/*cgs.media.rocketExplosionShader = trap_R_RegisterShader( "rocketExplosion" );*/
break;
@@ -775,8 +775,10 @@ void CG_RegisterWeapon( int weaponNum )
break;
case WP_POUNCE:
+ case WP_POUNCE_UPG:
MAKERGB( weaponInfo->flashDlightColor, 0, 0, 0 );
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/melee/fstatck.wav", qfalse );
+ weaponInfo->missileModel = trap_R_RegisterModel( "models/ammo/grenade1.md3" );
break;
case WP_ABUILD:
@@ -1902,6 +1904,7 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, vec3_t dir, im
radius = 24;
break;
case WP_LOCKBLOB_LAUNCHER:
+ case WP_POUNCE_UPG:
sfx = cgs.media.gibBounce1Sound;
mark = cgs.media.greenBloodMarkShader;
radius = 64;
diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c
index 3f60271b..3ff59a77 100644
--- a/src/game/bg_misc.c
+++ b/src/game/bg_misc.c
@@ -2435,6 +2435,28 @@ weaponAttributes_t bg_weapons[ ] =
WUT_ALIENS //WUTeam_t team;
},
{
+ WP_POUNCE_UPG, //int weaponNum;
+ 100, //int price;
+ ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
+ SLOT_WEAPON, //int slots;
+ "pounce_upgrade", //char *weaponName;
+ "Claw and pounce (upgrade)", //char *weaponHumanName;
+ { "models/weapons2/gauntlet/gauntlet.md3", 0, 0, 0 },
+ "icons/iconw_gauntlet",
+ 0, //int quan;
+ 0, //int clips;
+ 0, //int maxClips;
+ qtrue, //int infiniteAmmo;
+ qfalse, //int usesEnergy;
+ 750, //int repeatRate;
+ 0, //int reloadTime;
+ qfalse, //qboolean hasAltMode;
+ qfalse, //qboolean synced;
+ qfalse, //qboolean purchasable;
+ 0, //int buildDelay;
+ WUT_ALIENS //WUTeam_t team;
+ },
+ {
WP_LOCKBLOB_LAUNCHER, //int weaponNum;
100, //int price;
( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages
@@ -3371,6 +3393,7 @@ char *eventnames[] = {
"EV_NEXT_WEAPON",
"EV_FIRE_WEAPON",
"EV_FIRE_WEAPON2",
+ "EV_FIRE_WEAPON3",
"EV_FIRE_WEAPONBOTH",
"EV_USE_ITEM0",
diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c
index 40399dd7..642f2129 100644
--- a/src/game/bg_pmove.c
+++ b/src/game/bg_pmove.c
@@ -404,7 +404,7 @@ static qboolean PM_CheckPounce( void )
{
vec3_t forward;
- if( pm->ps->weapon != WP_POUNCE )
+ if( pm->ps->weapon != WP_POUNCE && pm->ps->weapon != WP_POUNCE_UPG )
return qfalse;
if( pm->cmd.buttons & BUTTON_ATTACK2 )
@@ -446,7 +446,7 @@ static qboolean PM_CheckJump( void )
return qfalse;
//can't jump and pounce charge at the same time
- if( pm->ps->weapon == WP_POUNCE && pm->ps->stats[ STAT_MISC ] > 0 )
+ if( ( pm->ps->weapon == WP_POUNCE || pm->ps->weapon == WP_POUNCE_UPG ) && pm->ps->stats[ STAT_MISC ] > 0 )
return qfalse;
if( ( pm->ps->stats[ STAT_PTEAM ] == PTE_HUMANS ) &&
@@ -2137,6 +2137,7 @@ static void PM_Weapon( void )
int ammo, clips, maxclips;
qboolean attack1 = qfalse;
qboolean attack2 = qfalse;
+ qboolean attack3 = qfalse;
// don't allow attack until all buttons are up
if ( pm->ps->pm_flags & PMF_RESPAWNED )
@@ -2274,11 +2275,15 @@ static void PM_Weapon( void )
break;
case WP_POUNCE:
+ case WP_POUNCE_UPG:
//pouncing has primary secondary AND autohit procedures
attack1 = pm->cmd.buttons & BUTTON_ATTACK;
attack2 = pm->cmd.buttons & BUTTON_ATTACK2;
+
+ if( pm->ps->weapon == WP_POUNCE_UPG )
+ attack3 = pm->cmd.buttons & BUTTON_USE_HOLDABLE;
- if( !pm->autoWeaponHit[ pm->ps->weapon ] && !attack1 && !attack2 )
+ if( !pm->autoWeaponHit[ pm->ps->weapon ] && !attack1 && !attack2 && !attack3 )
{
pm->ps->weaponTime = 0;
pm->ps->weaponstate = WEAPON_READY;
@@ -2317,6 +2322,8 @@ static void PM_Weapon( void )
}
//TA: fire events for non auto weapons
+ if( attack3 )
+ PM_AddEvent( EV_FIRE_WEAPON3 );
if( attack2 )
{
if( BG_WeaponHasAltMode( pm->ps->weapon ) )
@@ -2346,6 +2353,7 @@ static void PM_Weapon( void )
break;
case WP_POUNCE:
+ case WP_POUNCE_UPG:
PM_AddEvent( EV_FIRE_WEAPON2 );
break;
diff --git a/src/game/bg_public.h b/src/game/bg_public.h
index 2d59fe82..bd1953ff 100644
--- a/src/game/bg_public.h
+++ b/src/game/bg_public.h
@@ -247,6 +247,7 @@ typedef enum {
#define SS_POISONED 0x00000080
#define SS_HOVELING 0x00000100
#define SS_BOOSTED 0x00000200
+#define SS_SLOWLOCKED 0x00000400
#define SB_VALID_TOGGLEBIT 0x00004000
@@ -339,6 +340,7 @@ typedef enum
WP_VENOM,
WP_GRAB_CLAW,
WP_POUNCE,
+ WP_POUNCE_UPG,
WP_AREA_ZAP,
WP_DIRECT_ZAP,
WP_MASS_DRIVER,
@@ -507,6 +509,7 @@ typedef enum {
EV_NEXT_WEAPON,
EV_FIRE_WEAPON,
EV_FIRE_WEAPON2,
+ EV_FIRE_WEAPON3,
EV_FIRE_WEAPONBOTH,
EV_USE_ITEM0,
diff --git a/src/game/g_active.c b/src/game/g_active.c
index f1d77c97..2276962a 100644
--- a/src/game/g_active.c
+++ b/src/game/g_active.c
@@ -472,7 +472,7 @@ void ClientTimerActions( gentity_t *ent, int msec )
}
//client is charging up for a pounce
- if( client->ps.weapon == WP_POUNCE )
+ if( client->ps.weapon == WP_POUNCE || client->ps.weapon == WP_POUNCE_UPG )
{
if( client->ps.stats[ STAT_MISC ] < MAX_POUNCE_SPEED && ucmd->buttons & BUTTON_ATTACK2 )
{
@@ -632,6 +632,10 @@ void ClientEvents( gentity_t *ent, int oldEventSequence ) {
FireWeapon2( ent );
break;
+ case EV_FIRE_WEAPON3:
+ FireWeapon3( ent );
+ break;
+
case EV_FIRE_WEAPONBOTH:
FireWeapon( ent );
FireWeapon2( ent );
@@ -896,9 +900,14 @@ void ClientThink_real( gentity_t *ent ) {
client->ps.speed = g_speed.value * BG_FindSpeedForClass( client->ps.stats[ STAT_PCLASS ] );
//TA: slow player if charging up for a pounce
- if( client->ps.weapon == WP_POUNCE && ucmd->buttons & BUTTON_ATTACK2 )
+ if( ( client->ps.weapon == WP_POUNCE || client->ps.weapon == WP_POUNCE_UPG ) &&
+ ucmd->buttons & BUTTON_ATTACK2 )
client->ps.speed *= 0.75;
+ //TA: slow the player if slow locked
+ if( client->ps.stats[ STAT_STATE ] & SS_SLOWLOCKED )
+ client->ps.speed *= 0.5;
+
//TA: slow player if standing in creep
for ( i = 1, creepNode = g_entities + i; i < level.num_entities; i++, creepNode++ )
{
@@ -976,12 +985,13 @@ void ClientThink_real( gentity_t *ent ) {
{
case WP_VENOM:
if( client->ps.weaponTime <= 0 )
- pm.autoWeaponHit[ WP_VENOM ] = CheckVenomAttack( ent );
+ pm.autoWeaponHit[ client->ps.weapon ] = CheckVenomAttack( ent );
break;
case WP_POUNCE:
+ case WP_POUNCE_UPG:
if( client->ps.weaponTime <= 0 )
- pm.autoWeaponHit[ WP_POUNCE ] = CheckPounceAttack( ent );
+ pm.autoWeaponHit[ client->ps.weapon ] = CheckPounceAttack( ent );
break;
default:
diff --git a/src/game/g_client.c b/src/game/g_client.c
index 8642a06c..7e28ca62 100644
--- a/src/game/g_client.c
+++ b/src/game/g_client.c
@@ -1469,8 +1469,8 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn )
break;
case PCL_A_O_LEV2_UPG:
- BG_packWeapon( WP_POUNCE, client->ps.stats );
- BG_packAmmoArray( WP_POUNCE, client->ps.ammo, client->ps.powerups, 0, 0, 0 );
+ BG_packWeapon( WP_POUNCE_UPG, client->ps.stats );
+ BG_packAmmoArray( WP_POUNCE_UPG, client->ps.ammo, client->ps.powerups, 0, 0, 0 );
break;
case PCL_A_O_LEV3:
diff --git a/src/game/g_local.h b/src/game/g_local.h
index 4967751a..7f52515a 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -343,6 +343,7 @@ struct gclient_s {
int lastPoisonTime;
int lastGrabTime; //TA: yuck yuck hack urgh
int lastLockTime; //TA: " "
+ int lastSlowTime; //TA: " "
int lastBoostedTime;
int pouncePayload; //TA: amount of damage pounce attack will do
@@ -631,6 +632,7 @@ 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_lockblob( gentity_t *self, vec3_t start, vec3_t dir );
gentity_t *fire_paraLockBlob( gentity_t *self, vec3_t start, vec3_t dir );
+gentity_t *fire_slowBlob( 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 );
@@ -703,6 +705,7 @@ qboolean G_FilterPacket (char *from);
//
void FireWeapon( gentity_t *ent );
void FireWeapon2( gentity_t *ent );
+void FireWeapon3( gentity_t *ent );
//
// p_hud.c
diff --git a/src/game/g_missile.c b/src/game/g_missile.c
index b885a628..94381fdc 100644
--- a/src/game/g_missile.c
+++ b/src/game/g_missile.c
@@ -134,6 +134,15 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
VectorCopy( other->client->ps.viewangles, other->client->ps.grapplePoint );
}
}
+ else if( !strcmp( ent->classname, "slowblob" ) )
+ {
+ if( other->client && other->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
+ {
+ other->client->ps.stats[ STAT_STATE ] |= SS_SLOWLOCKED;
+ other->client->lastSlowTime = 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?
@@ -445,6 +454,44 @@ gentity_t *fire_lockblob( gentity_t *self, vec3_t start, vec3_t dir )
/*
=================
+fire_SlowBlob
+=================
+*/
+gentity_t *fire_slowBlob( gentity_t *self, vec3_t start, vec3_t dir )
+{
+ gentity_t *bolt;
+
+ VectorNormalize ( dir );
+
+ bolt = G_Spawn( );
+ bolt->classname = "slowblob";
+ bolt->nextthink = level.time + 15000;
+ bolt->think = G_ExplodeMissile;
+ bolt->s.eType = ET_MISSILE;
+ bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
+ bolt->s.weapon = WP_POUNCE_UPG;
+ bolt->r.ownerNum = self->s.number;
+ bolt->parent = self;
+ bolt->damage = 20;
+ bolt->splashDamage = 0;
+ bolt->splashRadius = 0;
+ bolt->methodOfDeath = MOD_ROCKET;
+ bolt->splashMethodOfDeath = MOD_ROCKET_SPLASH;
+ bolt->clipmask = MASK_SHOT;
+ bolt->target_ent = NULL;
+
+ bolt->s.pos.trType = TR_GRAVITY;
+ 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, 800, bolt->s.pos.trDelta );
+ SnapVector( bolt->s.pos.trDelta ); // save net bandwidth
+ VectorCopy (start, bolt->r.currentOrigin);
+
+ return bolt;
+}
+
+/*
+=================
fire_paraLockBlob
=================
*/
diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c
index 29800953..12509b90 100644
--- a/src/game/g_weapon.c
+++ b/src/game/g_weapon.c
@@ -723,6 +723,15 @@ qboolean CheckPounceAttack( gentity_t *ent )
return qtrue;
}
+void slowBlobFire( gentity_t *ent )
+{
+ gentity_t *m;
+
+ m = fire_slowBlob( ent, muzzle, forward );
+
+// VectorAdd( m->s.pos.trDelta, ent->client->ps.velocity, m->s.pos.trDelta ); // "real" physics
+}
+
/*
======================================================================
@@ -890,6 +899,37 @@ void CalcMuzzlePoint( gentity_t *ent, vec3_t forward, vec3_t right, vec3_t up, v
/*
===============
+FireWeapon3
+===============
+*/
+void FireWeapon3( gentity_t *ent )
+{
+ if( ent->client )
+ {
+ // set aiming directions
+ AngleVectors( ent->client->ps.viewangles, forward, right, up );
+ CalcMuzzlePoint( ent, forward, right, up, muzzle );
+ }
+ else
+ {
+ AngleVectors( ent->s.angles2, forward, right, up );
+ VectorCopy( ent->s.pos.trBase, muzzle );
+ }
+
+ // fire the specific weapon
+ switch( ent->s.weapon )
+ {
+ case WP_POUNCE_UPG:
+ slowBlobFire( ent );
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*
+===============
FireWeapon2
===============
*/
@@ -942,6 +982,7 @@ void FireWeapon2( gentity_t *ent )
break;
case WP_VENOM:
case WP_POUNCE:
+ case WP_POUNCE_UPG:
break;
case WP_LUCIFER_CANON:
LCChargeFire( ent, qtrue );
@@ -1014,6 +1055,7 @@ void FireWeapon( gentity_t *ent )
gClawFire( ent );
break;
case WP_POUNCE:
+ case WP_POUNCE_UPG:
clawFire( ent );
break;
case WP_AREA_ZAP: