void CEgon::Fire( const Vector &vecOrigSrc, const Vector &vecDir ) { Vector vecDest = vecOrigSrc + vecDir * 2048; edict_t *pentIgnore; TraceResult tr; pentIgnore = m_pPlayer->edict(); Vector tmpSrc = vecOrigSrc + gpGlobals->v_up * -8 + gpGlobals->v_right * 3; // ALERT( at_console, "." ); UTIL_TraceLine( vecOrigSrc, vecDest, dont_ignore_monsters, pentIgnore, &tr ); if (tr.fAllSolid) return; #ifndef CLIENT_DLL CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit); if (pEntity == NULL) return; if ( g_pGameRules->IsMultiplayer() ) { if ( m_pSprite && pEntity->pev->takedamage ) { m_pSprite->pev->effects &= ~EF_NODRAW; } else if ( m_pSprite ) { m_pSprite->pev->effects |= EF_NODRAW; } } #endif float timedist; switch ( m_fireMode ) { case FIRE_NARROW: #ifndef CLIENT_DLL if ( pev->dmgtime < gpGlobals->time ) { // Narrow mode only does damage to the entity it hits ClearMultiDamage(); if (pEntity->pev->takedamage) { pEntity->TraceAttack( m_pPlayer->pev, gSkillData.plrDmgEgonNarrow, vecDir, &tr, DMG_ENERGYBEAM ); } ApplyMultiDamage(m_pPlayer->pev, m_pPlayer->pev); if ( g_pGameRules->IsMultiplayer() ) { // multiplayer uses 1 ammo every 1/10th second if ( gpGlobals->time >= m_flAmmoUseTime ) { UseAmmo( 1 ); m_flAmmoUseTime = gpGlobals->time + 0.1; } } else { // single player, use 3 ammo/second if ( gpGlobals->time >= m_flAmmoUseTime ) { UseAmmo( 1 ); m_flAmmoUseTime = gpGlobals->time + 0.166; } } pev->dmgtime = gpGlobals->time + GetPulseInterval(); } #endif timedist = ( pev->dmgtime - gpGlobals->time ) / GetPulseInterval(); break; case FIRE_WIDE: #ifndef CLIENT_DLL if ( pev->dmgtime < gpGlobals->time ) { // wide mode does damage to the ent, and radius damage ClearMultiDamage(); if (pEntity->pev->takedamage) { pEntity->TraceAttack( m_pPlayer->pev, gSkillData.plrDmgEgonWide, vecDir, &tr, DMG_ENERGYBEAM | DMG_ALWAYSGIB); } ApplyMultiDamage(m_pPlayer->pev, m_pPlayer->pev); if ( g_pGameRules->IsMultiplayer() ) { // radius damage a little more potent in multiplayer. ::RadiusDamage( tr.vecEndPos, pev, m_pPlayer->pev, gSkillData.plrDmgEgonWide/4, 128, CLASS_NONE, DMG_ENERGYBEAM | DMG_BLAST | DMG_ALWAYSGIB ); } if ( !m_pPlayer->IsAlive() ) return; if ( g_pGameRules->IsMultiplayer() ) { //multiplayer uses 5 ammo/second if ( gpGlobals->time >= m_flAmmoUseTime ) { UseAmmo( 1 ); m_flAmmoUseTime = gpGlobals->time + 0.2; } } else { // Wide mode uses 10 charges per second in single player if ( gpGlobals->time >= m_flAmmoUseTime ) { UseAmmo( 1 ); m_flAmmoUseTime = gpGlobals->time + 0.1; } } pev->dmgtime = gpGlobals->time + GetDischargeInterval(); if ( m_shakeTime < gpGlobals->time ) { UTIL_ScreenShake( tr.vecEndPos, 5.0, 150.0, 0.75, 250.0 ); m_shakeTime = gpGlobals->time + 1.5; } } #endif timedist = ( pev->dmgtime - gpGlobals->time ) / GetDischargeInterval(); break; } if ( timedist < 0 ) timedist = 0; else if ( timedist > 1 ) timedist = 1; timedist = 1-timedist; UpdateEffect( tmpSrc, tr.vecEndPos, timedist ); }
void CEgon::Attack( void ) { // don't fire underwater /**if ( m_pPlayer->pev->waterlevel == 3 ) { if ( m_fireState != FIRE_OFF || m_pBeam ) { EndAttack(); } else { PlayEmptySound( ); } return; }*/ // rather than not working, we're gonna explode in water. makes sense for a prototype supergun. if ( m_pPlayer->pev->waterlevel > 1 ) { // get the remaining ammo to calculate how much damage the explosion will do, and then "use up" the ammo. int remainingAmmo = m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]; m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] = 0; // do damage! #ifndef CLIENT_DLL ::RadiusDamage( m_pPlayer->pev->origin, m_pPlayer->pev, m_pPlayer->pev, 35 * remainingAmmo, ( 35 * remainingAmmo ) + 40, CLASS_NONE, DMG_ENERGYBEAM | DMG_BLAST | DMG_ALWAYSGIB ); #endif } UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle ); Vector vecAiming = gpGlobals->v_forward; Vector vecSrc = m_pPlayer->GetGunPosition( ); int flags; #if defined( CLIENT_WEAPONS ) flags = FEV_NOTHOST; #else flags = 0; #endif switch( m_fireState ) { case FIRE_OFF: { if ( !HasAmmo() ) { m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.25; PlayEmptySound( ); return; } m_flAmmoUseTime = gpGlobals->time;// start using ammo ASAP. PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usEgonFire, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, m_fireState, m_fireMode, 1, 0 ); m_shakeTime = 0; m_pPlayer->m_iWeaponVolume = EGON_PRIMARY_VOLUME; m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.1; pev->fuser1 = UTIL_WeaponTimeBase() + 2; pev->dmgtime = gpGlobals->time + GetPulseInterval(); m_fireState = FIRE_CHARGE; } break; case FIRE_CHARGE: { Fire( vecSrc, vecAiming ); m_pPlayer->m_iWeaponVolume = EGON_PRIMARY_VOLUME; if ( pev->fuser1 <= UTIL_WeaponTimeBase() ) { PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usEgonFire, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, m_fireState, m_fireMode, 0, 0 ); pev->fuser1 = 1000; } if ( !HasAmmo() ) { EndAttack(); m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1.0; } } break; } }
void CEgon::Attack( void ) { // don't fire underwater if ( m_pPlayer->pev->waterlevel == 3 ) { if ( m_fireState != FIRE_OFF || m_pBeam ) { EndAttack(); } else { PlayEmptySound( ); } return; } UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle ); Vector vecAiming = gpGlobals->v_forward; Vector vecSrc = m_pPlayer->GetGunPosition( ); int flags; #if defined( CLIENT_WEAPONS ) flags = FEV_NOTHOST; #else flags = 0; #endif switch( m_fireState ) { case FIRE_OFF: { if ( !HasAmmo() ) { m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.25; PlayEmptySound( ); return; } m_flAmmoUseTime = gpGlobals->time;// start using ammo ASAP. PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usEgonFire, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, m_fireState, m_fireMode, 1, 0 ); m_shakeTime = 0; m_pPlayer->m_iWeaponVolume = EGON_PRIMARY_VOLUME; m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.1; pev->fuser1 = UTIL_WeaponTimeBase() + 2; pev->dmgtime = gpGlobals->time + GetPulseInterval(); m_fireState = FIRE_CHARGE; } break; case FIRE_CHARGE: { Fire( vecSrc, vecAiming ); m_pPlayer->m_iWeaponVolume = EGON_PRIMARY_VOLUME; if ( pev->fuser1 <= UTIL_WeaponTimeBase() ) { PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usEgonFire, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, m_fireState, m_fireMode, 0, 0 ); pev->fuser1 = 1000; } if ( !HasAmmo() ) { EndAttack(); m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1.0; } } break; } }
void CEgon::Attack( void ) { // don't fire underwater if (m_pPlayer->pev->waterlevel == 3) { if ( m_pBeam ) { EndAttack(); } else { PlayEmptySound( ); } return; } UTIL_MakeVectors( m_pPlayer->pev->viewangles + m_pPlayer->pev->punchangle ); Vector vecAiming = gpGlobals->v_forward; Vector vecSrc = m_pPlayer->GetGunPosition( ); switch( m_fireState ) { case FIRE_OFF: { if ( !HasAmmo() ) { m_flNextPrimaryAttack = m_flNextSecondaryAttack = gpGlobals->time + 0.25; PlayEmptySound( ); return; } m_flAmmoUseTime = gpGlobals->time;// start using ammo ASAP. SendWeaponAnim( g_fireAnims1[ RANDOM_LONG(0,ARRAYSIZE(g_fireAnims1)-1) ] ); m_shakeTime = 0; m_pPlayer->m_iWeaponVolume = EGON_PRIMARY_VOLUME; m_flTimeWeaponIdle = gpGlobals->time + 0.1; m_shootTime = gpGlobals->time + 2; if ( m_fireMode == FIRE_WIDE ) { EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_WEAPON, EGON_SOUND_STARTUP, 0.98, ATTN_NORM, 0, 125 ); } else { EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_WEAPON, EGON_SOUND_STARTUP, 0.9, ATTN_NORM, 0, 100 ); } pev->dmgtime = gpGlobals->time + GetPulseInterval(); m_fireState = FIRE_CHARGE; } break; case FIRE_CHARGE: { Fire( vecSrc, vecAiming ); m_pPlayer->m_iWeaponVolume = EGON_PRIMARY_VOLUME; if ( m_shootTime != 0 && gpGlobals->time > m_shootTime ) { if ( m_fireMode == FIRE_WIDE ) { EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_STATIC, EGON_SOUND_RUN, 0.98, ATTN_NORM, 0, 125 ); } else { EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_STATIC, EGON_SOUND_RUN, 0.9, ATTN_NORM, 0, 100 ); } m_shootTime = 0; } if ( !HasAmmo() ) { EndAttack(); m_fireState = FIRE_OFF; m_flNextPrimaryAttack = m_flNextSecondaryAttack = gpGlobals->time + 1.0; } } break; } }