summaryrefslogtreecommitdiff
path: root/src/game
diff options
context:
space:
mode:
authorMikko Tiusanen <ams@daug.net>2014-07-22 00:21:00 +0300
committerMikko Tiusanen <ams@daug.net>2014-07-22 00:21:00 +0300
commit4c26da913161e0bc3d5a912c6b154e33c38d9546 (patch)
tree2ec1adbca3e49c502d006f62ace7ade643ecced5 /src/game
parent8ec700b583a9f061072270d1c18964942f4e17fc (diff)
Added basic portable force field implementation as lasgun secondary fire.
Diffstat (limited to 'src/game')
-rw-r--r--src/game/bg_misc.c6
-rw-r--r--src/game/bg_pmove.c54
-rw-r--r--src/game/g_combat.c6
-rw-r--r--src/game/g_missile.c150
-rw-r--r--src/game/g_weapon.c13
-rw-r--r--src/game/tremulous.h7
6 files changed, 213 insertions, 23 deletions
diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c
index 5bdd5cd..9daed0b 100644
--- a/src/game/bg_misc.c
+++ b/src/game/bg_misc.c
@@ -3450,11 +3450,11 @@ static const weaponAttributes_t bg_weapons[ ] =
qfalse, //int infiniteAmmo;
qtrue, //int usesEnergy;
LASGUN_REPEAT, //int repeatRate1;
- 0, //int repeatRate2;
+ LASGUN_REPEAT2, //int repeatRate2;
0, //int repeatRate3;
LASGUN_RELOAD, //int reloadTime;
LASGUN_K_SCALE, //float knockbackScale;
- qfalse, //qboolean hasAltMode;
+ qtrue, //qboolean hasAltMode;
qfalse, //qboolean hasThirdMode;
qfalse, //qboolean canZoom;
90.0f, //float zoomFov;
@@ -3478,7 +3478,7 @@ static const weaponAttributes_t bg_weapons[ ] =
qtrue, //int usesEnergy;
MDRIVER_REPEAT, //int repeatRate1;
0, //int repeatRate2;
- MDRIVER_REPEAT2, //int repeatRate3;
+ MDRIVER_REPEAT2, //int repeatRate3;
MDRIVER_RELOAD, //int reloadTime;
MDRIVER_K_SCALE, //float knockbackScale;
qfalse, //qboolean hasAltMode;
diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c
index a50d781..62151f4 100644
--- a/src/game/bg_pmove.c
+++ b/src/game/bg_pmove.c
@@ -1206,7 +1206,6 @@ static void PM_WaterMove( void )
return;
}
-#if 0
// jump = head for surface
if ( pm->cmd.upmove >= 10 ) {
if (pm->ps->velocity[2] > -300) {
@@ -1219,7 +1218,6 @@ static void PM_WaterMove( void )
}
}
}
-#endif
PM_Friction( );
@@ -3066,6 +3064,7 @@ static void PM_Weapon( void )
qboolean attack1 = pm->cmd.buttons & BUTTON_ATTACK;
qboolean attack2 = pm->cmd.buttons & BUTTON_ATTACK2;
qboolean attack3 = pm->cmd.buttons & BUTTON_USE_HOLDABLE;
+ int minAmmo;
// Ignore weapons in some cases
if( pm->ps->persistant[ PERS_SPECSTATE ] != SPECTATOR_NOT )
@@ -3325,8 +3324,12 @@ static void PM_Weapon( void )
return;
}
+ if ( pm->ps->weapon == WP_LAS_GUN && attack2 )
+ minAmmo = 20;
+ else minAmmo = 1;
+
// check for out of ammo
- if( !pm->ps->ammo && !pm->ps->clips && !BG_Weapon( pm->ps->weapon )->infiniteAmmo )
+ if( pm->ps->ammo < minAmmo && !pm->ps->clips && !BG_Weapon( pm->ps->weapon )->infiniteAmmo )
{
if( attack1 || ( BG_Weapon( pm->ps->weapon )->hasAltMode && attack2 ) || ( BG_Weapon( pm->ps->weapon )->hasThirdMode && attack3 ) )
{
@@ -3725,22 +3728,35 @@ static void PM_Weapon( void )
( pm->ps->weapon == WP_ALEVEL4 && attack3 )||
( pm->ps->weapon == WP_ALEVEL5 && attack3 ))
{
- // Special case for md third mode, need a bat for function (6+1)
- if( (pm->ps->weapon == WP_MASS_DRIVER) && attack3 )
- pm->ps->ammo -= 7;
- //prevent removing ammo from player if plasma isnt working yet but still eats all ammo if player has ammo >6 and no s3
- if( (pm->ps->weapon == WP_MASS_DRIVER) && attack3 && pm->ps->ammo < 7 )
- pm->ps->ammo += 1;
- // Special case for lcannon
- if( (pm->ps->weapon == WP_LUCIFER_CANNON) && attack1 && !attack2 )
- pm->ps->ammo -= ( pm->ps->stats[ STAT_MISC ] * LCANNON_CHARGE_AMMO +
- LCANNON_CHARGE_TIME_MAX - 1 ) / LCANNON_CHARGE_TIME_MAX;
-
- if( (pm->ps->weapon == WP_FLAMER) && attack1 && !attack2 )
- pm->ps->ammo -= ( pm->ps->stats[ STAT_MISC ] * FLAMER_CHARGE_AMMO +
- FLAMER_CHARGE_TIME_MAX - 1 ) / FLAMER_CHARGE_TIME_MAX;
- else
- pm->ps->ammo--;
+ switch( pm->ps->weapon ) {
+ case WP_MASS_DRIVER:
+ if( attack3 ) {
+ pm->ps->ammo -= 7;
+ if( pm->ps->ammo < 7 ) pm->ps->ammo += 1;
+ } else pm->ps->ammo--;
+ break;
+ case WP_LUCIFER_CANNON:
+ if( attack1 && !attack2 ) {
+ pm->ps->ammo -= ( pm->ps->stats[ STAT_MISC ] * LCANNON_CHARGE_AMMO +
+ LCANNON_CHARGE_TIME_MAX - 1 ) / LCANNON_CHARGE_TIME_MAX;
+ } else pm->ps->ammo--;
+ break;
+ case WP_FLAMER:
+ if( attack1 && !attack2 ) {
+ pm->ps->ammo -= ( pm->ps->stats[ STAT_MISC ] * FLAMER_CHARGE_AMMO +
+ FLAMER_CHARGE_TIME_MAX - 1 ) / FLAMER_CHARGE_TIME_MAX;
+ } else pm->ps->ammo--;
+ break;
+ case WP_LAS_GUN:
+ if( attack2 ) {
+ pm->ps->ammo -= 25;
+ } else pm->ps->ammo--;
+ break;
+ default:
+ pm->ps->ammo--;
+ break;
+ }
+
// Stay on the safe side
if( pm->ps->ammo < 0 )
pm->ps->ammo = 0;
diff --git a/src/game/g_combat.c b/src/game/g_combat.c
index 5a522a5..c10c8da 100644
--- a/src/game/g_combat.c
+++ b/src/game/g_combat.c
@@ -525,6 +525,12 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
self->client->pers.netname, killerName ) );
goto finish_dying;
}
+
+ // Parent node on player used for tracking the shield projectile
+ if( self->parentNode )
+ {
+ G_FreeEntity(self->parentNode);
+ }
// broadcast the death event to everyone
ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY );
diff --git a/src/game/g_missile.c b/src/game/g_missile.c
index aaa1f2b..3fea37b 100644
--- a/src/game/g_missile.c
+++ b/src/game/g_missile.c
@@ -1007,6 +1007,156 @@ gentity_t *launch_grenade( gentity_t *self, vec3_t start, vec3_t dir )
}
/*
+=============
+Lasgun shield
+=============
+*/
+
+void G_LasgunPush( gentity_t *self )
+{
+ int entityList[ MAX_GENTITIES ];
+ vec3_t range = { LASGUN_PUSH_RANGE, LASGUN_PUSH_RANGE, LASGUN_PUSH_RANGE };
+ vec3_t mins, maxs;
+ int i, num;
+ gentity_t *enemy;
+ vec3_t start,dir,end;
+ float force;
+ qboolean active = qfalse;
+
+ self->nextthink = level.time + LASGUN_PUSH_REPEAT;
+
+ VectorCopy( self->parent->s.origin, self->s.pos.trBase );
+ AngleVectors( self->parent->s.angles, self->s.pos.trDelta, NULL, NULL );
+ VectorCopy( self->parent->s.origin, self->r.currentOrigin );
+
+ VectorAdd( self->r.currentOrigin, range, maxs );
+ VectorSubtract( self->r.currentOrigin, range, mins );
+
+ num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES );
+
+ for( i = 0; i < num; i++ )
+ {
+ enemy = &g_entities[ entityList[ i ] ];
+
+ if( enemy->flags & FL_NOTARGET )
+ continue;
+
+ if( !G_Visible( self, enemy, CONTENTS_SOLID ) )
+ continue;
+
+ if( enemy->client && enemy->client->ps.stats[ STAT_TEAM ] != TEAM_HUMANS )
+ {
+ if (!enemy->client)
+ continue;
+
+ if (enemy == self->parent)
+ continue;
+
+ if (!enemy->takedamage)
+ continue;
+
+ active = qtrue;
+ break;
+ }
+ }
+
+ if (active)
+ {
+ for( i = 0; i < num; i++ )
+ {
+ enemy = &g_entities[ entityList[ i ] ];
+
+ if( enemy->flags & FL_NOTARGET )
+ continue;
+
+ if( !G_Visible( self, enemy, CONTENTS_SOLID ) )
+ continue;
+
+ if( enemy->client && enemy->client->ps.stats[ STAT_TEAM ] != TEAM_NONE )
+ {
+ if (!enemy->client)
+ continue;
+
+ if (enemy == self->parent)
+ continue;
+
+ if (!enemy->takedamage)
+ continue;
+
+ if ( enemy->client->ps.stats[ STAT_CLASS ] == PCL_ALIEN_LEVEL5 )
+ force = LASGUN_PUSH_FORCE;
+ else
+ force = LASGUN_WEAK_FORCE;
+
+ VectorSubtract( enemy->r.currentOrigin, self->r.currentOrigin, dir);
+ VectorNormalize( dir );
+ VectorScale( dir, force, enemy->client->ps.velocity );
+ }
+ }
+ }
+ /*
+ if( enemy->client && enemy->client->ps.stats[ STAT_TEAM ] == TEAM_ALIENS )
+ {
+ // start the attack animation
+ G_AddEvent( self, EV_FORCE_FIELD, DirToByte( self->s.origin2 ) );
+
+ if( level.time >= self->timestamp + 500 )
+ {
+ self->timestamp = level.time;
+ G_SetBuildableAnim( self, BANIM_ATTACK1, qfalse );
+ }
+ return;
+ }
+ }
+ */
+ if( level.time >= self->timestamp ) {
+ self->freeAfterEvent = qtrue;
+ self->parent->parentNode = NULL;
+ }
+ trap_LinkEntity( self );
+}
+
+gentity_t *launch_shield( gentity_t *self, vec3_t start, vec3_t dir )
+{
+ vec3_t range = { LASGUN_PUSH_RANGE, LASGUN_PUSH_RANGE, LASGUN_PUSH_RANGE };
+ gentity_t *bolt;
+ VectorNormalize( dir );
+ bolt = G_Spawn( );
+ bolt->classname = "light";
+ bolt->pointAgainstWorld = qfalse;
+ bolt->nextthink = level.time + LASGUN_PUSH_REPEAT;
+ bolt->timestamp = level.time + LASGUN_PUSH_DURATION;
+ bolt->think = G_LasgunPush;
+ bolt->s.eType = ET_MISSILE;
+ bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
+ bolt->s.weapon = WP_LAS_GUN;
+ // bolt->s.eFlags |= EF_BOUNCE_HALF | EF_NO_BOUNCE_SOUND;
+ bolt->s.generic1 = WPM_SECONDARY; //weaponMode
+ bolt->r.ownerNum = self->s.number;
+ bolt->parent = self;
+ bolt->damage = bolt->splashDamage = 0;
+ bolt->splashRadius = 0;
+ bolt->methodOfDeath = MOD_UNKNOWN;
+ bolt->splashMethodOfDeath = MOD_UNKNOWN;
+ // bolt->clipmask = MASK_SHOT;
+ bolt->target_ent = NULL;
+ bolt->r.mins[ 0 ] = bolt->r.mins[ 1 ] = bolt->r.mins[ 2 ] = -4.0f;
+ bolt->r.maxs[ 0 ] = bolt->r.maxs[ 1 ] = bolt->r.maxs[ 2 ] = 4.0f;
+ bolt->r.ownerNum = self->s.number; // *
+ bolt->s.time = level.time;
+ bolt->s.pos.trType = TR_STATIONARY;
+ bolt->s.pos.trTime = level.time;
+ // 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, 1, bolt->s.pos.trDelta );
+ SnapVector( bolt->s.pos.trDelta ); // save net bandwidth
+ VectorCopy( start, bolt->r.currentOrigin );
+ self->parentNode = bolt;
+ return bolt;
+}
+
+/*
=================
launch_saw
=================
diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c
index aae97f9..184949f 100644
--- a/src/game/g_weapon.c
+++ b/src/game/g_weapon.c
@@ -754,6 +754,13 @@ void lasGunFire( gentity_t *ent )
G_Damage( traceEnt, ent, ent, forward, tr.endpos, LASGUN_DAMAGE, 0, MOD_LASGUN );
}
+// Lasgun 2ndary (shield)
+
+void lasGunFire2( gentity_t *ent )
+{
+ launch_shield( ent, muzzle, forward );
+}
+
/*
======================================================================
PAIN SAW
@@ -1802,7 +1809,7 @@ void FireWeapon2( gentity_t *ent )
switch( ent->s.weapon )
{
- case WP_MACHINEGUN:
+ case WP_MACHINEGUN:
bulletFire( ent, RIFLE_SPREAD2, RIFLE_DMG2, MOD_MACHINEGUN );
break;
@@ -1829,6 +1836,10 @@ void FireWeapon2( gentity_t *ent )
case WP_FLAMER:
FlamerNormal( ent );
break;
+
+ case WP_LAS_GUN:
+ lasGunFire2( ent );
+ break;
case WP_PULSE_RIFLE:
prifleStasisFire( ent );
diff --git a/src/game/tremulous.h b/src/game/tremulous.h
index 879b290..ca59a92 100644
--- a/src/game/tremulous.h
+++ b/src/game/tremulous.h
@@ -451,6 +451,13 @@ TREMULOUS EDGE MOD SRC FILE
#define LASGUN_RELOAD 2000
#define LASGUN_DAMAGE HDM(9)
+#define LASGUN_REPEAT2 5000
+#define LASGUN_PUSH_DURATION 4000
+#define LASGUN_PUSH_REPEAT 400
+#define LASGUN_PUSH_RANGE 140
+#define LASGUN_PUSH_FORCE 900
+#define LASGUN_WEAK_FORCE 675
+
#define MDRIVER_PRICE 350
#define MDRIVER_CLIPSIZE 5
#define MDRIVER_MAXCLIPS 3