diff options
author | Mikko Tiusanen <ams@daug.net> | 2014-07-22 00:21:00 +0300 |
---|---|---|
committer | Mikko Tiusanen <ams@daug.net> | 2014-07-22 00:21:00 +0300 |
commit | 4c26da913161e0bc3d5a912c6b154e33c38d9546 (patch) | |
tree | 2ec1adbca3e49c502d006f62ace7ade643ecced5 | |
parent | 8ec700b583a9f061072270d1c18964942f4e17fc (diff) |
Added basic portable force field implementation as lasgun secondary fire.
-rw-r--r-- | assets/models/weapons/lgun/weapon.cfg | 8 | ||||
-rw-r--r-- | src/game/bg_misc.c | 6 | ||||
-rw-r--r-- | src/game/bg_pmove.c | 54 | ||||
-rw-r--r-- | src/game/g_combat.c | 6 | ||||
-rw-r--r-- | src/game/g_missile.c | 150 | ||||
-rw-r--r-- | src/game/g_weapon.c | 13 | ||||
-rw-r--r-- | src/game/tremulous.h | 7 |
7 files changed, 221 insertions, 23 deletions
diff --git a/assets/models/weapons/lgun/weapon.cfg b/assets/models/weapons/lgun/weapon.cfg index 1cbb7f2..9612f9d 100644 --- a/assets/models/weapons/lgun/weapon.cfg +++ b/assets/models/weapons/lgun/weapon.cfg @@ -11,3 +11,11 @@ primary impactParticleSystem models/weapons/lasgun/impactPS } + +secondary +{ + flashDlightColor 0.5 0.5 1.0 + flashSound 0 models/weapons/lgun/flash0.wav + + missileModel models/buildables/light/light.md3 +} 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 |