diff options
Diffstat (limited to 'src/game/g_weapon.c')
-rw-r--r-- | src/game/g_weapon.c | 309 |
1 files changed, 178 insertions, 131 deletions
diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c index e0dec309..f08ae2fe 100644 --- a/src/game/g_weapon.c +++ b/src/game/g_weapon.c @@ -28,27 +28,20 @@ static vec3_t muzzle; G_BounceProjectile ================ */ -void G_BounceProjectile( vec3_t start, vec3_t impact, vec3_t dir, vec3_t endout ) { +void G_BounceProjectile( vec3_t start, vec3_t impact, vec3_t dir, vec3_t endout ) +{ vec3_t v, newv; float dot; VectorSubtract( impact, start, v ); dot = DotProduct( v, dir ); - VectorMA( v, -2*dot, dir, newv ); + VectorMA( v, -2 * dot, dir, newv ); VectorNormalize(newv); VectorMA(impact, 8192, newv, endout); } /* -====================================================================== - -MACHINEGUN - -====================================================================== -*/ - -/* ====================== SnapVectorTowards @@ -58,18 +51,27 @@ rather than blindly truncating. This prevents it from truncating into a wall. ====================== */ -void SnapVectorTowards( vec3_t v, vec3_t to ) { +void SnapVectorTowards( vec3_t v, vec3_t to ) +{ int i; - for ( i = 0 ; i < 3 ; i++ ) { - if ( to[i] <= v[i] ) { - v[i] = (int)v[i]; - } else { - v[i] = (int)v[i] + 1; - } + for( i = 0 ; i < 3 ; i++ ) + { + if( to[ i ] <= v[ i ] ) + v[ i ] = (int)v[ i ]; + else + v[ i ] = (int)v[ i ] + 1; } } +/* +====================================================================== + +MACHINEGUN + +====================================================================== +*/ + #define MACHINEGUN_SPREAD 200 #define MACHINEGUN_DAMAGE 7 #define MACHINEGUN_TEAM_DAMAGE 5 // wimpier MG in teamplay @@ -77,7 +79,7 @@ void SnapVectorTowards( vec3_t v, vec3_t to ) { #define CHAINGUN_SPREAD 1200 #define CHAINGUN_DAMAGE 14 -void Bullet_Fire( gentity_t *ent, float spread, int damage, int mod ) +void bulletFire( gentity_t *ent, float spread, int damage, int mod ) { trace_t tr; vec3_t end; @@ -107,8 +109,6 @@ void Bullet_Fire( gentity_t *ent, float spread, int damage, int mod ) { tent = G_TempEntity( tr.endpos, EV_BULLET_HIT_FLESH ); tent->s.eventParm = traceEnt->s.number; - if( LogAccuracyHit( traceEnt, ent ) ) - ent->client->accuracy_hits++; } else { @@ -139,7 +139,7 @@ void massDriverFire( gentity_t *ent ) gentity_t *tent; gentity_t *traceEnt; - VectorMA( muzzle, 8192*16, forward, end ); + VectorMA( muzzle, 8192 * 16, forward, end ); trap_Trace( &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT ); if( tr.surfaceFlags & SURF_NOIMPACT ) @@ -169,7 +169,7 @@ LOCKBLOB ====================================================================== */ -void Weapon_LockBlobLauncher_Fire( gentity_t *ent ) +void lockBlobLauncherFire( gentity_t *ent ) { gentity_t *m; @@ -186,7 +186,8 @@ PLASMAGUN ====================================================================== */ -void Weapon_Plasma_Fire (gentity_t *ent) { +void plasmaFire( gentity_t *ent ) +{ gentity_t *m; m = fire_plasma (ent, muzzle, forward); @@ -202,7 +203,7 @@ PULSE RIFLE ====================================================================== */ -void Weapon_PulseRifle_Fire (gentity_t *ent) +void pulseRifleFire( gentity_t *ent ) { gentity_t *m; @@ -219,10 +220,11 @@ FLAME THROWER ====================================================================== */ -void Weapon_Flamer_Fire (gentity_t *ent) { +void flamerFire( gentity_t *ent ) +{ gentity_t *m; - m = fire_flamer (ent, muzzle, forward); + m = fire_flamer( ent, muzzle, forward ); VectorAdd( m->s.pos.trDelta, ent->client->ps.velocity, m->s.pos.trDelta ); // "real" physics } @@ -236,7 +238,7 @@ TESLA GENERATOR */ -void Weapon_TeslaFire( gentity_t *ent ) +void teslaFire( gentity_t *ent ) { trace_t tr; vec3_t end; @@ -266,9 +268,6 @@ void Weapon_TeslaFire( gentity_t *ent ) // send railgun beam effect tent = G_TempEntity( tr.endpos, EV_TESLATRAIL ); - // set player number for custom colors on the railtrail - tent->s.clientNum = ent->s.clientNum; - VectorCopy( muzzle, tent->s.origin2 ); // move origin a bit to come closer to the drawn gun muzzle VectorMA( tent->s.origin2, 16, up, tent->s.origin2 ); @@ -291,23 +290,12 @@ BUILD GUN ====================================================================== */ - -/* -=============== -Weapon_Cancel_Build -=============== -*/ -void Weapon_Cancel_Build( gentity_t *ent ) +void cancelBuildFire( gentity_t *ent ) { ent->client->ps.stats[ STAT_BUILDABLE ] = BA_NONE; } -/* -=============== -Weapon_Build_Fire -=============== -*/ -void Weapon_Build_Fire( gentity_t *ent, dynMenu_t menu ) +void buildFire( gentity_t *ent, dynMenu_t menu ) { if( ( ent->client->ps.stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT ) > BA_NONE ) { @@ -384,15 +372,6 @@ qboolean CheckVenomAttack( gentity_t *ent ) } /* -=============== -Weapon_Venom_Fire -=============== -*/ -void Weapon_Venom_Fire( gentity_t *ent ) -{ -} - -/* ====================================================================== GRAB AND CLAW @@ -400,12 +379,7 @@ GRAB AND CLAW ====================================================================== */ -/* -=============== -Weapon_GClaw_Fire -=============== -*/ -void Weapon_GClaw_Fire( gentity_t *ent ) +void gClawFire( gentity_t *ent ) { trace_t tr; vec3_t end; @@ -413,7 +387,7 @@ void Weapon_GClaw_Fire( gentity_t *ent ) gentity_t *traceEnt; // set aiming directions - AngleVectors (ent->client->ps.viewangles, forward, right, up); + AngleVectors( ent->client->ps.viewangles, forward, right, up ); CalcMuzzlePoint( ent, forward, right, up, muzzle ); @@ -438,12 +412,7 @@ void Weapon_GClaw_Fire( gentity_t *ent ) G_Damage( traceEnt, ent, ent, forward, tr.endpos, 5, DAMAGE_NO_KNOCKBACK, MOD_VENOM ); } -/* -=============== -Weapon_Grab_Fire -=============== -*/ -void Weapon_Grab_Fire( gentity_t *ent ) +void grabFire( gentity_t *ent ) { trace_t tr; vec3_t end; @@ -476,7 +445,9 @@ 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 ); + + if( !( traceEnt->client->ps.stats[ STAT_STATE ] & SS_GRABBED ) ) + VectorCopy( traceEnt->client->ps.viewangles, traceEnt->client->ps.grapplePoint ); } } @@ -526,10 +497,10 @@ CLAW AND POUNCE /* =============== -Weapon_Claw_Fire +clawFire =============== */ -void Weapon_Claw_Fire( gentity_t *ent ) +void clawFire( gentity_t *ent ) { trace_t tr; vec3_t end; @@ -582,25 +553,25 @@ qboolean CheckPounceAttack( gentity_t *ent ) return qfalse; // set aiming directions - AngleVectors (ent->client->ps.viewangles, forward, right, up); + AngleVectors( ent->client->ps.viewangles, forward, right, up ); CalcMuzzlePoint( ent, forward, right, up, muzzle ); - VectorMA (muzzle, 48, forward, end); + VectorMA( muzzle, 48, forward, end ); - trap_Trace (&tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT); + trap_Trace( &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT ); //miss if( tr.fraction >= 1.0 ) return qfalse; - if ( tr.surfaceFlags & SURF_NOIMPACT ) + if( tr.surfaceFlags & SURF_NOIMPACT ) return qfalse; traceEnt = &g_entities[ tr.entityNum ]; // send blood impact - if ( traceEnt->takedamage && traceEnt->client ) + if( traceEnt->takedamage && traceEnt->client ) { tent = G_TempEntity( tr.endpos, EV_MISSILE_HIT ); tent->s.otherEntityNum = traceEnt->s.number; @@ -620,45 +591,119 @@ qboolean CheckPounceAttack( gentity_t *ent ) return qtrue; } -//====================================================================== +/* +====================================================================== + +ZAP + +====================================================================== +*/ + +#define AREAZAP_DAMAGE 500.0f /* =============== -LogAccuracyHit +areaZapFire =============== */ -qboolean LogAccuracyHit( gentity_t *target, gentity_t *attacker ) -{ - //TA: theres a crash bug in here somewhere, but i'm too lazy to find it hence, - return qfalse; +void areaZapFire( gentity_t *ent ) +{ + int entityList[ MAX_GENTITIES ]; + int targetList[ MAX_GENTITIES ]; + vec3_t range = { 200, 200, 200 }; + vec3_t mins, maxs, dir; + int i, num, numTargets = 0; + gentity_t *enemy; + gentity_t *tent; + trace_t tr; + int damage; + + VectorAdd( muzzle, range, maxs ); + VectorSubtract( muzzle, range, mins ); - /*if( !target->takedamage ) { - return qfalse; - } + //do some damage + num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); + for( i = 0; i < num; i++ ) + { + enemy = &g_entities[ entityList[ i ] ]; + + if( ( enemy->client && enemy->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) || + ( enemy->s.eType == ET_BUILDABLE && BG_FindTeamForBuildable( enemy->s.modelindex ) == BIT_HUMANS ) ) + { + trap_Trace( &tr, muzzle, NULL, NULL, enemy->s.origin, ent->s.number, MASK_SHOT ); + + //can't see target from here + if( tr.entityNum == ENTITYNUM_WORLD ) + continue; - if ( target == attacker ) { - return qfalse; + targetList[ numTargets++ ] = entityList[ i ]; + } } - if( !target->client ) { - return qfalse; - } + damage = (int)( AREAZAP_DAMAGE / (float)numTargets ); + for( i = 0; i < numTargets; i++ ) + { + enemy = &g_entities[ targetList[ i ] ]; - if( !attacker->client ) { - return qfalse; - } + VectorSubtract( enemy->s.origin, muzzle, dir ); + VectorNormalize( dir ); + + G_Damage( enemy, ent, ent, dir, tr.endpos, + damage, DAMAGE_NO_KNOCKBACK, MOD_LIGHTNING ); + + // snap the endpos to integers to save net bandwidth, but nudged towards the line + SnapVectorTowards( tr.endpos, muzzle ); - if( target->client->ps.stats[STAT_HEALTH] <= 0 ) { - return qfalse; + // send railgun beam effect + tent = G_TempEntity( enemy->s.pos.trBase, EV_TESLATRAIL ); + + VectorCopy( muzzle, tent->s.origin2 ); } +} - if ( OnSameTeam( target, attacker ) ) { - return qfalse; +/* +=============== +directZapFire +=============== +*/ +void directZapFire( gentity_t *ent ) +{ + trace_t tr; + vec3_t end; + gentity_t *traceEnt, *tent; + int damage, i, passent; + + damage = 100; + + VectorMA( muzzle, LIGHTNING_RANGE, forward, end ); + + trap_Trace( &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT ); + + if( tr.entityNum != ENTITYNUM_NONE ) + traceEnt = &g_entities[ tr.entityNum ]; + + if( traceEnt->takedamage ) + { + G_Damage( traceEnt, ent, ent, forward, tr.endpos, + damage, 0, MOD_LIGHTNING); } - return qtrue;*/ + // snap the endpos to integers to save net bandwidth, but nudged towards the line + SnapVectorTowards( tr.endpos, muzzle ); + + // send railgun beam effect + tent = G_TempEntity( tr.endpos, EV_TESLATRAIL ); + + VectorCopy( muzzle, tent->s.origin2 ); + + // no explosion at end if SURF_NOIMPACT, but still make the trail + if( tr.surfaceFlags & SURF_NOIMPACT ) + tent->s.eventParm = 255; // don't make the explosion at the end + else + tent->s.eventParm = DirToByte( tr.plane.normal ); } +//====================================================================== /* =============== @@ -667,10 +712,12 @@ CalcMuzzlePoint set muzzle location relative to pivoting eye =============== */ -void CalcMuzzlePoint( gentity_t *ent, vec3_t forward, vec3_t right, vec3_t up, vec3_t muzzlePoint ) { +void CalcMuzzlePoint( gentity_t *ent, vec3_t forward, vec3_t right, vec3_t up, vec3_t muzzlePoint ) +{ VectorCopy( ent->s.pos.trBase, muzzlePoint ); - muzzlePoint[2] += ent->client->ps.viewheight; + muzzlePoint[ 2 ] += ent->client->ps.viewheight; VectorMA( muzzlePoint, 1, forward, muzzlePoint ); + VectorMA( muzzlePoint, 1, right, muzzlePoint ); // snap to integer coordinates for more efficient network bandwidth usage SnapVector( muzzlePoint ); } @@ -685,7 +732,7 @@ void FireWeapon2( gentity_t *ent ) if( ent->client ) { // set aiming directions - AngleVectors (ent->client->ps.viewangles, forward, right, up); + AngleVectors( ent->client->ps.viewangles, forward, right, up ); CalcMuzzlePoint( ent, forward, right, up, muzzle ); } else @@ -698,47 +745,43 @@ void FireWeapon2( gentity_t *ent ) switch( ent->s.weapon ) { case WP_TESLAGEN: - Weapon_TeslaFire( ent ); + teslaFire( ent ); break; case WP_MACHINEGUN: - Bullet_Fire( ent, MACHINEGUN_SPREAD, MACHINEGUN_DAMAGE, MOD_MACHINEGUN ); + bulletFire( ent, MACHINEGUN_SPREAD, MACHINEGUN_DAMAGE, MOD_MACHINEGUN ); break; case WP_CHAINGUN: - Bullet_Fire( ent, CHAINGUN_SPREAD, CHAINGUN_DAMAGE, MOD_CHAINGUN ); + bulletFire( ent, CHAINGUN_SPREAD, CHAINGUN_DAMAGE, MOD_CHAINGUN ); break; case WP_FLAMER: - Weapon_Flamer_Fire( ent ); + flamerFire( ent ); break; case WP_PLASMAGUN: - Weapon_Plasma_Fire( ent ); + plasmaFire( ent ); break; case WP_PULSE_RIFLE: - Weapon_PulseRifle_Fire( ent ); + pulseRifleFire( ent ); break; case WP_MASS_DRIVER: massDriverFire( ent ); break; case WP_LOCKBLOB_LAUNCHER: break; - case WP_VENOM: - Weapon_Venom_Fire( ent ); - break; case WP_GRAB_CLAW: - Weapon_Grab_Fire( ent ); + grabFire( ent ); + break; + case WP_AREA_ZAP: + case WP_DIRECT_ZAP: + areaZapFire( ent ); break; + case WP_VENOM: case WP_POUNCE: break; case WP_ABUILD: - Weapon_Cancel_Build( ent ); - break; case WP_ABUILD2: - Weapon_Cancel_Build( ent ); - break; case WP_HBUILD: - Weapon_Cancel_Build( ent ); - break; case WP_HBUILD2: - Weapon_Cancel_Build( ent ); + cancelBuildFire( ent ); break; default: // FIXME G_Error( "Bad ent->s.weapon" ); @@ -756,13 +799,12 @@ void FireWeapon( gentity_t *ent ) if( ent->client ) { // set aiming directions - AngleVectors (ent->client->ps.viewangles, forward, right, up); + AngleVectors( ent->client->ps.viewangles, forward, right, up ); CalcMuzzlePoint( ent, forward, right, up, muzzle ); } else { AngleVectors( ent->turretAim, forward, right, up ); - /*AngleVectors( ent->s.angles2, forward, right, up );*/ VectorCopy( ent->s.pos.trBase, muzzle ); } @@ -770,49 +812,54 @@ void FireWeapon( gentity_t *ent ) switch( ent->s.weapon ) { case WP_TESLAGEN: - Weapon_TeslaFire( ent ); + teslaFire( ent ); break; case WP_MACHINEGUN: - Bullet_Fire( ent, MACHINEGUN_SPREAD, MACHINEGUN_DAMAGE, MOD_MACHINEGUN ); + bulletFire( ent, MACHINEGUN_SPREAD, MACHINEGUN_DAMAGE, MOD_MACHINEGUN ); break; case WP_CHAINGUN: - Bullet_Fire( ent, CHAINGUN_SPREAD, CHAINGUN_DAMAGE, MOD_CHAINGUN ); + bulletFire( ent, CHAINGUN_SPREAD, CHAINGUN_DAMAGE, MOD_CHAINGUN ); break; case WP_FLAMER: - Weapon_Flamer_Fire( ent ); + flamerFire( ent ); break; case WP_PLASMAGUN: - Weapon_Plasma_Fire( ent ); + plasmaFire( ent ); break; case WP_PULSE_RIFLE: - Weapon_PulseRifle_Fire( ent ); + pulseRifleFire( ent ); break; case WP_MASS_DRIVER: massDriverFire( ent ); break; case WP_LOCKBLOB_LAUNCHER: - Weapon_LockBlobLauncher_Fire( ent ); + lockBlobLauncherFire( ent ); break; case WP_VENOM: - Weapon_Venom_Fire( ent ); break; case WP_GRAB_CLAW: - Weapon_GClaw_Fire( ent ); + gClawFire( ent ); break; case WP_POUNCE: - Weapon_Claw_Fire( ent ); + clawFire( ent ); + break; + case WP_AREA_ZAP: + areaZapFire( ent ); + break; + case WP_DIRECT_ZAP: + directZapFire( ent ); break; case WP_ABUILD: - Weapon_Build_Fire( ent, MN_A_BUILD ); + buildFire( ent, MN_A_BUILD ); break; case WP_ABUILD2: - Weapon_Build_Fire( ent, MN_A_BUILD ); + buildFire( ent, MN_A_BUILD ); break; case WP_HBUILD: - Weapon_Build_Fire( ent, MN_H_BUILD ); + buildFire( ent, MN_H_BUILD ); break; case WP_HBUILD2: - Weapon_Build_Fire( ent, MN_H_BUILD ); + buildFire( ent, MN_H_BUILD ); break; default: // FIXME G_Error( "Bad ent->s.weapon" ); |