void W_FireSpikes( float ox ) { vec3_t dir, tmp; // gedict_t* old; makevectors( self->s.v.v_angle ); if ( self->s.v.ammo_nails >= 2 && self->s.v.weapon == IT_SUPER_NAILGUN ) { W_FireSuperSpikes(); return; } if ( self->s.v.ammo_nails < 1 ) { self->s.v.weapon = W_BestWeapon(); W_SetCurrentAmmo(); return; } sound( self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM ); self->attack_finished = g_globalvars.time + 0.2; if ( deathmatch != 4 ) self->s.v.currentammo = self->s.v.ammo_nails = self->s.v.ammo_nails - 1; aim( dir ); // dir = aim (self, 1000); VectorScale( g_globalvars.v_right, ox, tmp ); VectorAdd( tmp, self->s.v.origin, tmp ); tmp[2] += 16; launch_spike( tmp, dir ); g_globalvars.msg_entity = EDICT_TO_PROG( self ); trap_WriteByte( MSG_ONE, SVC_SMALLKICK ); }
// Nailgun void CBasePlayer::W_FireSpikes(int iQuadSound) { // If we're wielding the Super nailgun and we've got ammo for it, fire Super nails if(*m_pCurrentAmmo >= 2 && m_iQuakeWeapon == IT_SUPER_NAILGUN) { W_FireSuperSpikes(iQuadSound); return; } // Swap to next best weapon if this one just ran out if(*m_pCurrentAmmo < 1) { m_iQuakeWeapon = W_BestWeapon(); W_SetCurrentAmmo(); return; } PLAYBACK_EVENT_FULL(FEV_NOTHOST, edict(), m_usSpike, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, iQuadSound, 0, m_iNailOffset > 0.0 ? 1 : 0, 0); // Fire left then right if(m_iNailOffset == 2) m_iNailOffset = -2; else m_iNailOffset = 2; if(gpGlobals->deathmatch != 4) *m_pCurrentAmmo -= 1; m_flNextAttack = UTIL_WeaponTimeBase() + 0.1; // Fire the nail UTIL_MakeVectors(pev->v_angle); Vector vecDir = GetAutoaimVector(AUTOAIM_5DEGREES); CQuakeNail *pNail = CQuakeNail::CreateNail(pev->origin + Vector(0, 0, 10) + (gpGlobals->v_right * m_iNailOffset), vecDir, this); }
// Return TRUE if the weapon still has ammo BOOL CBasePlayer::W_CheckNoAmmo() { if(m_pCurrentAmmo && *m_pCurrentAmmo > 0) return TRUE; if(m_iQuakeWeapon == IT_AXE) return TRUE; #ifdef THREEWAVE if(m_iQuakeWeapon == IT_EXTRA_WEAPON) return TRUE; #endif if(m_iQuakeWeapon == IT_LIGHTNING) { PLAYBACK_EVENT_FULL(FEV_NOTHOST, edict(), m_usLightning, 0, (float *)&pev->origin, (float *)&pev->angles, 0.0, 0.0, 0, 1, 0, 0); if(m_pActiveItem) ((CQuakeGun *)m_pActiveItem)->DestroyEffect(); } m_iQuakeWeapon = W_BestWeapon(); W_SetCurrentAmmo(); return FALSE; }
int W_CheckNoAmmo() { if ( self->s.v.currentammo > 0 ) return true; if ( self->s.v.weapon == IT_AXE ) return true; self->s.v.weapon = W_BestWeapon(); W_SetCurrentAmmo(); // drop the weapon down return false; }
void W_FireLightning() { vec3_t org; float cells; vec3_t tmp; if ( self->s.v.ammo_cells < 1 ) { self->s.v.weapon = W_BestWeapon(); W_SetCurrentAmmo(); return; } // explode if under water if ( self->s.v.waterlevel > 1 ) { if ( deathmatch > 3 ) { if ( g_random() <= 0.5 ) { self->deathtype = "selfwater"; T_Damage( self, self, PROG_TO_EDICT( self->s.v.owner ), 4000 ); } else { cells = self->s.v.ammo_cells; self->s.v.ammo_cells = 0; W_SetCurrentAmmo(); T_RadiusDamage( self, self, 35 * cells, world, "" ); return; } } else { cells = self->s.v.ammo_cells; self->s.v.ammo_cells = 0; W_SetCurrentAmmo(); T_RadiusDamage( self, self, 35 * cells, world, "" ); return; } } if ( self->t_width < g_globalvars.time ) { sound( self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM ); self->t_width = g_globalvars.time + 0.6; } g_globalvars.msg_entity = EDICT_TO_PROG( self ); trap_WriteByte( MSG_ONE, SVC_SMALLKICK ); if ( deathmatch != 4 ) self->s.v.currentammo = self->s.v.ammo_cells = self->s.v.ammo_cells - 1; VectorCopy( self->s.v.origin, org ); //org = self->s.v.origin + '0 0 16'; org[2] += 16; traceline( PASSVEC3( org ), org[0] + g_globalvars.v_forward[0] * 600, org[1] + g_globalvars.v_forward[1] * 600, org[2] + g_globalvars.v_forward[2] * 600, true, self ); trap_WriteByte( MSG_MULTICAST, SVC_TEMPENTITY ); trap_WriteByte( MSG_MULTICAST, TE_LIGHTNING2 ); WriteEntity( MSG_MULTICAST, self ); trap_WriteCoord( MSG_MULTICAST, org[0] ); trap_WriteCoord( MSG_MULTICAST, org[1] ); trap_WriteCoord( MSG_MULTICAST, org[2] ); trap_WriteCoord( MSG_MULTICAST, g_globalvars.trace_endpos[0] ); trap_WriteCoord( MSG_MULTICAST, g_globalvars.trace_endpos[1] ); trap_WriteCoord( MSG_MULTICAST, g_globalvars.trace_endpos[2] ); trap_multicast( PASSVEC3( org ), MULTICAST_PHS ); VectorScale( g_globalvars.v_forward, 4, tmp ); VectorAdd( g_globalvars.trace_endpos, tmp, tmp ); LightningDamage( self->s.v.origin, tmp, self, 30 ); }
// Lightning Gun void CBasePlayer::W_FireLightning(int iQuadSound) { if(*m_pCurrentAmmo < 1) { //This should already be IT_LIGHTNING but what the heck. if(m_iQuakeWeapon == IT_LIGHTNING) { PLAYBACK_EVENT_FULL(FEV_NOTHOST, edict(), m_usLightning, 0, (float *)&pev->origin, (float *)&pev->angles, 0.0, 0.0, 0, 1, 0, 0); if(m_pActiveItem) ((CQuakeGun *)m_pActiveItem)->DestroyEffect(); } m_iQuakeWeapon = W_BestWeapon(); W_SetCurrentAmmo(); return; } bool playsound = false; // Make lightning sound every 0.6 seconds if(m_flLightningTime <= gpGlobals->time) { playsound = true; m_flLightningTime = gpGlobals->time + 0.6; } // explode if under water if(pev->waterlevel > 1) { if((gpGlobals->deathmatch > 3) && (RANDOM_FLOAT(0, 1) <= 0.5)) { strcpy(gszQ_DeathType, "selfwater"); TakeDamage(pev, pev, 4000, DMG_GENERIC); } else { float flCellsBurnt = *m_pCurrentAmmo; *m_pCurrentAmmo = 0; W_SetCurrentAmmo(); #if !defined(CLIENT_DLL) Q_RadiusDamage(this, this, 35 * flCellsBurnt, NULL); #endif return; } } PLAYBACK_EVENT_FULL(FEV_NOTHOST, edict(), m_usLightning, 0, (float *)&pev->origin, (float *)&pev->angles, 0.0, 0.0, iQuadSound, 0, playsound, 0); #if !defined(CLIENT_DLL) if(gpGlobals->deathmatch != 4) *m_pCurrentAmmo -= 1; // Lightning bolt effect TraceResult trace; Vector vecOrg = pev->origin + Vector(0, 0, 16); UTIL_MakeVectors(pev->v_angle); UTIL_TraceLine(vecOrg, vecOrg + (gpGlobals->v_forward * 600), ignore_monsters, ENT(pev), &trace); Vector vecDir = gpGlobals->v_forward + (0.001 * gpGlobals->v_right) + (0.001 * gpGlobals->v_up); // Do damage LightningDamage(pev->origin, trace.vecEndPos + (gpGlobals->v_forward * 4), this, 30, vecDir); #endif }