void G_FireUpgrade( gentity_t *self, upgrade_t upgrade ) { if ( !self || !self->client ) { Com_Printf( S_WARNING "G_FireUpgrade: Called with non-player parameter.\n" ); return; } if ( upgrade <= UP_NONE || upgrade >= UP_NUM_UPGRADES ) { Com_Printf( S_WARNING "G_FireUpgrade: Called with unknown upgrade.\n" ); return; } AngleVectors( self->client->ps.viewangles, forward, right, up ); G_CalcMuzzlePoint( self, forward, right, up, muzzle ); switch ( upgrade ) { case UP_GRENADE: FireGrenade( self ); break; case UP_FIREBOMB: FireFirebomb( self ); break; default: break; } }
qboolean G_CheckPounceAttack( gentity_t *self ) { trace_t tr; gentity_t *traceEnt; int damage, timeMax, pounceRange, payload; if ( self->client->pmext.pouncePayload <= 0 ) { return qfalse; } // In case the goon lands on his target, he gets one shot after landing payload = self->client->pmext.pouncePayload; if ( !( self->client->ps.pm_flags & PMF_CHARGE ) ) { self->client->pmext.pouncePayload = 0; } // Calculate muzzle point AngleVectors( self->client->ps.viewangles, forward, right, up ); G_CalcMuzzlePoint( self, forward, right, up, muzzle ); // Trace from muzzle to see what we hit pounceRange = self->client->ps.weapon == WP_ALEVEL3 ? LEVEL3_POUNCE_RANGE : LEVEL3_POUNCE_UPG_RANGE; G_WideTrace( &tr, self, pounceRange, LEVEL3_POUNCE_WIDTH, LEVEL3_POUNCE_WIDTH, &traceEnt ); if ( traceEnt == NULL ) { return qfalse; } // Send blood impact if ( traceEnt->takedamage ) { SendMeleeHitEvent( self, traceEnt, &tr ); } if ( !traceEnt->takedamage ) { return qfalse; } // Deal damage timeMax = self->client->ps.weapon == WP_ALEVEL3 ? LEVEL3_POUNCE_TIME : LEVEL3_POUNCE_TIME_UPG; damage = payload * LEVEL3_POUNCE_DMG / timeMax; self->client->pmext.pouncePayload = 0; G_Damage( traceEnt, self, self, forward, tr.endpos, damage, DAMAGE_NO_LOCDAMAGE, MOD_LEVEL3_POUNCE ); return qtrue; }
qboolean G_CheckVenomAttack( gentity_t *self ) { trace_t tr; gentity_t *traceEnt; int damage = LEVEL0_BITE_DMG; if ( self->client->ps.weaponTime ) { return qfalse; } // Calculate muzzle point AngleVectors( self->client->ps.viewangles, forward, right, up ); G_CalcMuzzlePoint( self, forward, right, up, muzzle ); G_WideTrace( &tr, self, LEVEL0_BITE_RANGE, LEVEL0_BITE_WIDTH, LEVEL0_BITE_WIDTH, &traceEnt ); if ( !traceEnt || !traceEnt->takedamage || traceEnt->health <= 0 || G_OnSameTeam( self, traceEnt ) ) { return qfalse; } // only allow bites to work against turrets or buildables in construction if ( traceEnt->s.eType == ET_BUILDABLE && traceEnt->spawned ) { switch ( traceEnt->s.modelindex ) { case BA_H_MGTURRET: case BA_H_TESLAGEN: break; default: return qfalse; } } SendMeleeHitEvent( self, traceEnt, &tr ); G_Damage( traceEnt, self, self, forward, tr.endpos, damage, DAMAGE_NO_KNOCKBACK, MOD_LEVEL0_BITE ); self->client->ps.weaponTime += LEVEL0_BITE_REPEAT; return qtrue; }
bool G_CheckPounceAttack( gentity_t *self ) { trace_t tr; gentity_t *traceEnt; int damage, timeMax, pounceRange, payload; if ( self->client->pmext.pouncePayload <= 0 ) { return false; } // In case the goon lands on his target, he gets one shot after landing payload = self->client->pmext.pouncePayload; if ( !( self->client->ps.pm_flags & PMF_CHARGE ) ) { self->client->pmext.pouncePayload = 0; } // Calculate muzzle point AngleVectors( self->client->ps.viewangles, forward, right, up ); G_CalcMuzzlePoint( self, forward, right, up, muzzle ); // Trace from muzzle to see what we hit pounceRange = self->client->ps.weapon == WP_ALEVEL3 ? LEVEL3_POUNCE_RANGE : LEVEL3_POUNCE_UPG_RANGE; G_WideTrace( &tr, self, pounceRange, LEVEL3_POUNCE_WIDTH, LEVEL3_POUNCE_WIDTH, &traceEnt ); if ( !G_Alive( traceEnt ) ) { return false; } timeMax = self->client->ps.weapon == WP_ALEVEL3 ? LEVEL3_POUNCE_TIME : LEVEL3_POUNCE_TIME_UPG; damage = payload * LEVEL3_POUNCE_DMG / timeMax; self->client->pmext.pouncePayload = 0; traceEnt->entity->Damage((float)damage, self, Vec3::Load(tr.endpos), Vec3::Load(forward), DAMAGE_NO_LOCDAMAGE, MOD_LEVEL3_POUNCE); SendMeleeHitEvent( self, traceEnt, &tr ); return true; }
bool G_CheckVenomAttack( gentity_t *self ) { trace_t tr; gentity_t *traceEnt; int damage = LEVEL0_BITE_DMG; if ( self->client->ps.weaponTime ) { return false; } // Calculate muzzle point AngleVectors( self->client->ps.viewangles, forward, right, up ); G_CalcMuzzlePoint( self, forward, right, up, muzzle ); G_WideTrace( &tr, self, LEVEL0_BITE_RANGE, LEVEL0_BITE_WIDTH, LEVEL0_BITE_WIDTH, &traceEnt ); if ( !traceEnt || !traceEnt->takedamage || traceEnt->health <= 0 || G_OnSameTeam( self, traceEnt ) ) { return false; } // only allow bites to work against buildables in construction if ( traceEnt->s.eType == ET_BUILDABLE && traceEnt->spawned ) { return false; } SendMeleeHitEvent( self, traceEnt, &tr ); G_Damage( traceEnt, self, self, forward, tr.endpos, damage, 0, MOD_LEVEL0_BITE ); self->client->ps.weaponTime += LEVEL0_BITE_REPEAT; return true; }
bool G_CheckVenomAttack( gentity_t *self ) { trace_t tr; gentity_t *traceEnt; if ( self->client->ps.weaponTime ) { return false; } // Calculate muzzle point AngleVectors( self->client->ps.viewangles, forward, right, up ); G_CalcMuzzlePoint( self, forward, right, up, muzzle ); G_WideTrace( &tr, self, LEVEL0_BITE_RANGE, LEVEL0_BITE_WIDTH, LEVEL0_BITE_WIDTH, &traceEnt ); if ( !G_Alive( traceEnt ) || G_OnSameTeam( self, traceEnt ) ) { return false; } // only allow bites to work against buildables in construction if ( traceEnt->s.eType == ET_BUILDABLE && traceEnt->spawned ) { return false; } traceEnt->entity->Damage((float)LEVEL0_BITE_DMG, self, Vec3::Load(tr.endpos), Vec3::Load(forward), 0, (meansOfDeath_t)MOD_LEVEL0_BITE); SendMeleeHitEvent( self, traceEnt, &tr ); self->client->ps.weaponTime += LEVEL0_BITE_REPEAT; return true; }
void G_FireWeapon( gentity_t *self, weapon_t weapon, weaponMode_t weaponMode ) { // calculate muzzle if ( self->client ) { AngleVectors( self->client->ps.viewangles, forward, right, up ); G_CalcMuzzlePoint( self, forward, right, up, muzzle ); } else { AngleVectors( self->buildableAim, forward, right, up ); VectorCopy( self->s.pos.trBase, muzzle ); } switch ( weaponMode ) { case WPM_PRIMARY: { switch ( weapon ) { case WP_ALEVEL1: FireLevel1Melee( self ); break; case WP_ALEVEL3: FireMelee( self, LEVEL3_CLAW_RANGE, LEVEL3_CLAW_WIDTH, LEVEL3_CLAW_WIDTH, LEVEL3_CLAW_DMG, MOD_LEVEL3_CLAW ); break; case WP_ALEVEL3_UPG: FireMelee( self, LEVEL3_CLAW_UPG_RANGE, LEVEL3_CLAW_WIDTH, LEVEL3_CLAW_WIDTH, LEVEL3_CLAW_DMG, MOD_LEVEL3_CLAW ); break; case WP_ALEVEL2: FireMelee( self, LEVEL2_CLAW_RANGE, LEVEL2_CLAW_WIDTH, LEVEL2_CLAW_WIDTH, LEVEL2_CLAW_DMG, MOD_LEVEL2_CLAW ); break; case WP_ALEVEL2_UPG: FireMelee( self, LEVEL2_CLAW_U_RANGE, LEVEL2_CLAW_WIDTH, LEVEL2_CLAW_WIDTH, LEVEL2_CLAW_DMG, MOD_LEVEL2_CLAW ); break; case WP_ALEVEL4: FireMelee( self, LEVEL4_CLAW_RANGE, LEVEL4_CLAW_WIDTH, LEVEL4_CLAW_HEIGHT, LEVEL4_CLAW_DMG, MOD_LEVEL4_CLAW ); break; case WP_BLASTER: FireBlaster( self ); break; case WP_MACHINEGUN: FireBullet( self, RIFLE_SPREAD, RIFLE_DMG, MOD_MACHINEGUN ); break; case WP_SHOTGUN: FireShotgun( self ); break; case WP_CHAINGUN: FireBullet( self, CHAINGUN_SPREAD, CHAINGUN_DMG, MOD_CHAINGUN ); break; case WP_FLAMER: FireFlamer( self ); break; case WP_PULSE_RIFLE: FirePrifle( self ); break; case WP_MASS_DRIVER: FireMassdriver( self ); break; case WP_LUCIFER_CANNON: FireLcannon( self, qfalse ); break; case WP_LAS_GUN: FireLasgun( self ); break; case WP_PAIN_SAW: FirePainsaw( self ); break; case WP_LOCKBLOB_LAUNCHER: FireLockblob( self ); break; case WP_HIVE: FireHive( self ); break; case WP_TESLAGEN: FireTesla( self ); break; case WP_MGTURRET: FireBullet( self, TURRET_SPREAD, self->turretCurrentDamage, MOD_MGTURRET ); break; case WP_ABUILD: case WP_ABUILD2: FireBuild( self, MN_A_BUILD ); break; case WP_HBUILD: FireBuild( self, MN_H_BUILD ); break; default: break; } break; } case WPM_SECONDARY: { switch ( weapon ) { case WP_LUCIFER_CANNON: FireLcannon( self, qtrue ); break; case WP_ALEVEL2_UPG: FireAreaZap( self ); break; case WP_ABUILD: case WP_ABUILD2: case WP_HBUILD: CancelBuild( self ); break; default: break; } break; } case WPM_TERTIARY: { switch ( weapon ) { case WP_ALEVEL3_UPG: FireBounceball( self ); break; case WP_ABUILD2: FireSlowblob( self ); break; default: break; } break; } default: { break; } } }