/*** * * Copyright (c) 1996-2001, Valve LLC. All rights reserved. * * This product contains software technology licensed from Id * Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * All Rights Reserved. * * Use, distribution, and modification of this source code and/or resulting * object code is restricted to non-commercial enhancements to products from * Valve LLC. All other use, distribution, or modification is prohibited * without written permission from Valve LLC. * ****/ #include "extdll.h" #include "util.h" #include "cbase.h" #include "weapons.h" #include "player.h" #include "skill.h" #include "items.h" #include "gamerules.h" //========================================================= // Nuclear bomb //========================================================= class CNuclearBombTimer : public CBaseEntity { public: void Precache(); void Spawn(); void EXPORT NuclearBombTimerThink(); void SetNuclearBombTimer(bool on); int ObjectCaps() {return FCAP_DONT_SAVE;} BOOL bPlayBombSound; BOOL bBombSoundPlaying; }; LINK_ENTITY_TO_CLASS(item_nuclearbombtimer, CNuclearBombTimer) void CNuclearBombTimer::Precache() { PRECACHE_MODEL("models/nuke_timer.mdl"); PRECACHE_SOUND("common/nuke_ticking.wav"); } void CNuclearBombTimer::Spawn() { Precache(); SET_MODEL(ENT(pev), "models/nuke_timer.mdl"); pev->solid = SOLID_NOT; UTIL_SetSize(pev, Vector(-16,-16,0), Vector(16,16,32)); pev->movetype = MOVETYPE_NONE; UTIL_SetOrigin(pev, pev->origin); if( DROP_TO_FLOOR(ENT( pev ) ) == 0 ) { ALERT(at_error, "Nuclear Bomb timer fell out of level at %f,%f,%f\n", pev->origin.x, pev->origin.y, pev->origin.z); UTIL_Remove( this ); return; } pev->skin = 0; bPlayBombSound = FALSE; bBombSoundPlaying = FALSE; } void CNuclearBombTimer::NuclearBombTimerThink() { if (pev->skin <= 1) pev->skin++; else pev->skin = 0; if (bPlayBombSound) { EMIT_SOUND(ENT(pev), CHAN_BODY, "common/nuke_ticking.wav", 0.75, ATTN_IDLE); bBombSoundPlaying = TRUE; } pev->nextthink = gpGlobals->time + 0.1; } void CNuclearBombTimer::SetNuclearBombTimer(bool on) { if (on) { SetThink(&CNuclearBombTimer::NuclearBombTimerThink); pev->nextthink = gpGlobals->time; bPlayBombSound = TRUE; } else { SetThink(NULL); pev->nextthink = gpGlobals->time; pev->skin = 3; if (bBombSoundPlaying) { EMIT_SOUND_DYN(ENT(pev), CHAN_BODY, "common/nuke_ticking.wav", 0.0, 0.0, SND_STOP, PITCH_NORM); bBombSoundPlaying = FALSE; } } } class CNuclearBombButton : public CBaseEntity { public: void Precache(); void Spawn(); void SetNuclearBombButton(bool on); int ObjectCaps() {return FCAP_DONT_SAVE;} }; LINK_ENTITY_TO_CLASS(item_nuclearbombbutton, CNuclearBombButton) void CNuclearBombButton::Precache() { PRECACHE_MODEL("models/nuke_button.mdl"); } void CNuclearBombButton::Spawn() { Precache(); SET_MODEL(ENT(pev), "models/nuke_button.mdl"); pev->solid = SOLID_NOT; UTIL_SetSize(pev, Vector(-16,-16,0), Vector(16,16,32)); pev->movetype = MOVETYPE_NONE; UTIL_SetOrigin(pev, pev->origin); if( DROP_TO_FLOOR(ENT( pev ) ) == 0 ) { ALERT(at_error, "Nuclear Bomb button fell out of level at %f,%f,%f\n", pev->origin.x, pev->origin.y, pev->origin.z); UTIL_Remove( this ); return; } pev->skin = 0; } void CNuclearBombButton::SetNuclearBombButton(bool on) { pev->skin = 1; } class CNuclearBomb : public CBaseToggle { public: void Precache(); void Spawn(); void KeyValue(KeyValueData* pkvd); void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value); int ObjectCaps() {return FCAP_ACROSS_TRANSITION | FCAP_IMPULSE_USE;} void UpdateOnRemove(); virtual int Save( CSave &save ); virtual int Restore( CRestore &restore ); static TYPEDESCRIPTION m_SaveData[]; BOOL m_fOn; float m_flLastPush; int m_iPushCount; CNuclearBombTimer* m_pTimer; CNuclearBombButton* m_pButton; }; LINK_ENTITY_TO_CLASS(item_nuclearbomb, CNuclearBomb) TYPEDESCRIPTION CNuclearBomb::m_SaveData[] = { DEFINE_FIELD(CNuclearBomb, m_fOn, FIELD_BOOLEAN), DEFINE_FIELD(CNuclearBomb, m_flLastPush, FIELD_TIME), DEFINE_FIELD(CNuclearBomb, m_iPushCount, FIELD_INTEGER), }; IMPLEMENT_SAVERESTORE(CNuclearBomb, CBaseToggle) void CNuclearBomb::Precache() { PRECACHE_MODEL("models/nuke_case.mdl"); UTIL_PrecacheOther("item_nuclearbombtimer"); UTIL_PrecacheOther("item_nuclearbombbutton"); PRECACHE_SOUND("buttons/button4.wav"); PRECACHE_SOUND("buttons/button6.wav"); m_pTimer = (CNuclearBombTimer*)Create("item_nuclearbombtimer", pev->origin, pev->angles); if (m_pTimer) m_pTimer->SetNuclearBombTimer(m_fOn); m_pButton = (CNuclearBombButton*)Create("item_nuclearbombbutton", pev->origin, pev->angles); if (m_pButton) m_pButton->SetNuclearBombButton(m_fOn); } void CNuclearBomb::Spawn() { Precache(); SET_MODEL(ENT(pev), "models/nuke_case.mdl"); pev->solid = SOLID_BBOX; UTIL_SetOrigin(pev, pev->origin); UTIL_SetSize(pev, Vector(-16,-16,0), Vector(16,16,32)); pev->movetype = MOVETYPE_NONE; if( DROP_TO_FLOOR(ENT( pev ) ) == 0 ) { ALERT(at_error, "Nuclear Bomb fell out of level at %f,%f,%f\n", pev->origin.x, pev->origin.y, pev->origin.z); UTIL_Remove( this ); return; } m_iPushCount = 0; m_flLastPush = gpGlobals->time; } void CNuclearBomb::KeyValue(KeyValueData *pkvd) { if( FStrEq( pkvd->szKeyName, "initialstate" ) ) { m_fOn = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } else if( FStrEq( pkvd->szKeyName, "wait" ) ) { m_flWait = atof( pkvd->szValue ); pkvd->fHandled = TRUE; } else CBaseToggle::KeyValue(pkvd); } void CNuclearBomb::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value) { if ((m_flWait >= 0 || m_iPushCount <= 0) && m_flWait <= gpGlobals->time - m_flLastPush && ShouldToggle(useType, m_fOn)) { const char* sound = NULL; if (m_fOn) { m_fOn = FALSE; sound = "buttons/button4.wav"; } else { m_fOn = TRUE; sound = "buttons/button6.wav"; } EMIT_SOUND(ENT(pev), CHAN_VOICE, sound, VOL_NORM, ATTN_NORM); SUB_UseTargets(pActivator, USE_TOGGLE, 0); if (m_pButton) { m_pButton->SetNuclearBombButton(m_fOn); } if (m_pTimer) { m_pTimer->SetNuclearBombTimer(m_fOn); } m_iPushCount++; m_flLastPush = gpGlobals->time; } } void CNuclearBomb::UpdateOnRemove() { CBaseToggle::UpdateOnRemove(); if (m_pTimer) { UTIL_Remove(m_pTimer); m_pTimer = NULL; } if (m_pButton) { UTIL_Remove(m_pButton); m_pButton = NULL; } }