/* =========================================================================== Copyright (C) 2015 the OpenMoHAA team This file is part of OpenMoHAA source code. OpenMoHAA source code is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. OpenMoHAA source code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenMoHAA source code; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ // trigger.h: Environment based triggers. // #ifndef __TRIGGER_H__ #define __TRIGGER_H__ #include "glb_local.h" #include "animate.h" #include "gamescript.h" class ScriptMaster; extern Event EV_Trigger_ActivateTargets; extern Event EV_Trigger_SetWait; extern Event EV_Trigger_SetDelay; extern Event EV_Trigger_SetCount; extern Event EV_Trigger_SetMessage; extern Event EV_Trigger_SetNoise; extern Event EV_Trigger_SetKey; extern Event EV_Trigger_SetThread; extern Event EV_Trigger_Effect; extern Event EV_Trigger_StartThread; extern Event EV_Trigger_SetKey; extern Event EV_Trigger_SetTriggerable; extern Event EV_Trigger_SetNotTriggerable; #define TRIGGER_PLAYERS 4 #define TRIGGER_MONSTERS 8 #define TRIGGER_PROJECTILES 16 class Trigger : public Animate { protected: float wait; float delay; float trigger_time; qboolean triggerActivated; int count; str noise; str message; str key; ScriptThreadLabel label; EntityPtr activator; int respondto; qboolean useTriggerDir; float triggerCone; Vector triggerDir; float triggerDirYaw; qboolean triggerable; qboolean removable; // if count is 0, should this be removed? qboolean edgeTriggered; // if true, trigger only triggers when entering trigger, not when standing in it int multiFaceted; // if 0, it isn't. if 1 it is N/S oriented, if 2 it is E/W oriented public: CLASS_PROTOTYPE( Trigger ); Trigger(); virtual ~Trigger(); // override this to allow objects other than players, projectiles, and monsters to activate the trigger virtual qboolean respondTo( Entity *other ); // override this to redirect messages to an entity other than the one who triggered it virtual Entity *getActivator( Entity *other ); void SetModelEvent( Event *ev ); void Touch( Event *ev ); void EventSetWait( Event *ev ); void EventSetDelay( Event *ev ); void EventSetCount( Event *ev ); void EventSetKey( Event *ev ); void EventSetHealth( Event *ev ); void EventSetThread( Event *ev ); void SetTriggerDir( Event *ev ); void SetTriggerable( Event *ev ); void SetNotTriggerable( Event *ev ); void SetMultiFaceted( Event *ev ); void SetEdgeTriggered( Event *ev ); void SetTriggerCone( Event *ev ); void EventSetMessage( Event *ev ); void SetMessage( const char *message ); str &Message( void ); void EventSetNoise( Event *ev ); void SetNoise( const char *text ); str &Noise( void ); void SetTriggerDir( float angle ); Vector GetTriggerDir( void ); qboolean UsingTriggerDir( void ); void SetMultiFaceted( int newFacet ); void SetEdgeTriggered( qboolean newEdge ); int GetMultiFaceted( void ); qboolean GetEdgeTriggered( void ); void StartThread( Event *ev ); void TriggerStuff( Event *ev ); void ActivateTargets( Event *ev ); void Archive( Archiver &arc ) override; }; inline void Trigger::Archive ( Archiver &arc ) { Animate::Archive( arc ); arc.ArchiveFloat( &wait ); arc.ArchiveFloat( &delay ); arc.ArchiveFloat( &trigger_time ); arc.ArchiveBoolean( &triggerActivated ); arc.ArchiveInteger( &count ); arc.ArchiveString( &noise ); if ( arc.Loading() ) { SetNoise( noise.c_str() ); } arc.ArchiveString( &message ); arc.ArchiveString( &key ); arc.ArchiveSafePointer( &activator ); arc.ArchiveInteger( &respondto ); arc.ArchiveBoolean( &useTriggerDir ); arc.ArchiveFloat( &triggerCone ); arc.ArchiveVector( &triggerDir ); arc.ArchiveFloat( &triggerDirYaw ); arc.ArchiveBoolean( &triggerable ); arc.ArchiveBoolean( &removable ); arc.ArchiveBoolean( &edgeTriggered ); arc.ArchiveInteger( &multiFaceted ); } class TriggerVehicle : public Trigger { public: CLASS_PROTOTYPE( TriggerVehicle ); qboolean respondTo( Entity *other ) override; }; class TriggerAllEntry { public: EntityPtr ent; float time; public: static void Archive( Archiver& arc, TriggerAllEntry *obj ); }; class TriggerAll : public Trigger { private: Container< TriggerAllEntry > entries; public: CLASS_PROTOTYPE( TriggerAll ); void Archive( Archiver& arc ) override; void TriggerStuff( Event *ev ); bool IsTriggerable( Entity *other ); void SetTriggerTime( Entity *other, float time ); }; inline void TriggerAll::Archive ( Archiver& arc ) { Trigger::Archive( arc ); entries.Archive( arc, &TriggerAllEntry::Archive ); } class TouchField : public Trigger { private: Event *ontouch; EntityPtr owner; public: CLASS_PROTOTYPE( TouchField ); TouchField(); virtual void Setup( Entity *ownerentity, Event &ontouch, Vector min, Vector max, int respondto ); void SendEvent( Event *ev ); void Archive( Archiver &arc ) override; }; inline void TouchField::Archive ( Archiver &arc ) { Trigger::Archive( arc ); arc.ArchiveEventPointer( &ontouch ); arc.ArchiveSafePointer( &owner ); } typedef SafePtr TouchFieldPtr; class TriggerOnce : public Trigger { public: CLASS_PROTOTYPE( TriggerOnce ); TriggerOnce(); }; class TriggerSave : public Trigger { private: str m_sSaveName; public: CLASS_PROTOTYPE( TriggerSave ); void SaveGame( Event *ev ); void EventSaveName( Event *ev ); void Archive( Archiver& arc ) override; }; inline void TriggerSave::Archive ( Archiver &arc ) { Trigger::Archive( arc ); arc.ArchiveString( &m_sSaveName ); } class TriggerRelay : public Trigger { public: CLASS_PROTOTYPE( TriggerRelay ); TriggerRelay(); }; class TriggerSecret : public TriggerOnce { public: CLASS_PROTOTYPE( TriggerSecret ); TriggerSecret(); void FoundSecret( Event *ev ); void Activate( Event *ev ); }; class TriggerPush : public Trigger { protected: float speed; public: CLASS_PROTOTYPE( TriggerPush ); TriggerPush(); void Push( Event *ev ); void SetPushDir( Event *ev ); void SetPushSpeed( Event *ev ); void Archive( Archiver &arc ) override; }; inline void TriggerPush::Archive ( Archiver &arc ) { Trigger::Archive( arc ); arc.ArchiveFloat( &speed ); } class TriggerPushAny : public Trigger { protected: float speed; public: CLASS_PROTOTYPE( TriggerPushAny ); TriggerPushAny(); void Push( Event *ev ); void SetSpeed( Event *ev ); void Archive( Archiver &arc ) override; }; inline void TriggerPushAny::Archive ( Archiver &arc ) { Trigger::Archive( arc ); arc.ArchiveFloat( &speed ); } #define AMBIENT_ON ( 1 << 0 ) #define AMBIENT_OFF ( 1 << 1 ) #define TOGGLESOUND ( 1 << 5 ) class TriggerPlaySound : public Trigger { protected: friend class SoundManager; int state; float min_dist; float volume; int channel; qboolean ambient; public: CLASS_PROTOTYPE( TriggerPlaySound ); TriggerPlaySound(); void ToggleSound( Event *ev ); void SetVolume( Event *ev ); void SetMinDist( Event *ev ); void SetChannel( Event *ev ); void StartSound( void ); void SetVolume( float vol ); void SetMinDist( float dist ); void Archive( Archiver &arc ) override; }; inline void TriggerPlaySound::Archive ( Archiver &arc ) { Trigger::Archive( arc ); arc.ArchiveInteger( &state ); arc.ArchiveFloat( &min_dist ); arc.ArchiveFloat( &volume ); arc.ArchiveInteger( &channel ); arc.ArchiveBoolean( &ambient ); if ( arc.Loading() ) { // // see if its a toggle sound, if it is, lets start its sound again // if ( spawnflags & TOGGLESOUND ) { // // invert state so that final state will be right // state = !state; PostEvent( EV_Trigger_Effect, EV_POSTSPAWN ); } } } class TriggerSpeaker : public TriggerPlaySound { public: CLASS_PROTOTYPE( TriggerSpeaker ); TriggerSpeaker(); }; class RandomSpeaker : public TriggerSpeaker { protected: friend class SoundManager; float chance; float mindelay; float maxdelay; public: CLASS_PROTOTYPE( RandomSpeaker ); RandomSpeaker(); void TriggerSound( Event *ev ); void SetMinDelay( Event *ev ); void SetMaxDelay( Event *ev ); void SetChance( Event *ev ); void SetMinDelay( float value ); void SetMaxDelay( float value ); void SetChance( float value ); void ScheduleSound( void ); void Archive( Archiver &arc ) override; }; inline void RandomSpeaker::Archive ( Archiver &arc ) { TriggerSpeaker::Archive( arc ); arc.ArchiveFloat( &chance ); arc.ArchiveFloat( &mindelay ); arc.ArchiveFloat( &maxdelay ); } class TriggerChangeLevel : public Trigger { protected: const_str map; const_str spawnspot; public: CLASS_PROTOTYPE(TriggerChangeLevel); TriggerChangeLevel(); void SetMap(Event* ev); void SetSpawnSpot(Event* ev); void ChangeLevel(Event* ev); const char* Map(void); const char* SpawnSpot(void); void Archive(Archiver& arc) override; }; class TriggerExit : public Trigger { public: CLASS_PROTOTYPE( TriggerExit ); TriggerExit(); void DisplayExitSign( Event *ev ); void TurnExitSignOff( Event *ev ); }; class TriggerUse : public Trigger { public: CLASS_PROTOTYPE( TriggerUse ); TriggerUse(); }; class TriggerUseOnce : public TriggerUse { public: CLASS_PROTOTYPE( TriggerUseOnce ); TriggerUseOnce(); }; class TriggerHurt : public TriggerUse { protected: float damage; void Hurt( Event *ev ); void SetDamage( Event *ev ); public: CLASS_PROTOTYPE( TriggerHurt ); TriggerHurt(); void Archive( Archiver &arc ) override; }; inline void TriggerHurt::Archive ( Archiver &arc ) { TriggerUse::Archive( arc ); arc.ArchiveFloat( &damage ); } class TriggerDamageTargets : public Trigger { protected: float damage; void DamageTargets( Event *ev ); void SetDamage( Event *ev ); public: CLASS_PROTOTYPE( TriggerDamageTargets ); TriggerDamageTargets(); void PassDamage( Event *ev ); void Archive( Archiver &arc ) override; }; inline void TriggerDamageTargets::Archive ( Archiver &arc ) { Trigger::Archive( arc ); arc.ArchiveFloat( &damage ); } class TriggerCameraUse : public TriggerUse { public: CLASS_PROTOTYPE( TriggerCameraUse ); void TriggerCamera( Event * ev ); }; class TriggerBox : public Trigger { public: CLASS_PROTOTYPE( TriggerBox ); void SetMins( Event *ev ); void SetMaxs( Event *ev ); }; class TriggerMusic : public Trigger { private: friend class SoundManager; qboolean oneshot; str current; str fallback; str altcurrent; str altfallback; public: CLASS_PROTOTYPE( TriggerMusic ); TriggerMusic(); void SetCurrentMood( Event *ev ); void SetFallbackMood( Event *ev ); void SetAltCurrentMood( Event *ev ); void SetAltFallbackMood( Event *ev ); void ChangeMood( Event *ev ); void AltChangeMood( Event *ev ); void SetOneShot( Event *ev ); void SetMood( str crnt, str fback ); void SetAltMood( str crnt, str fback ); void SetOneShot( qboolean once ); void Archive( Archiver &arc ) override; }; inline void TriggerMusic::Archive ( Archiver &arc ) { Trigger::Archive( arc ); arc.ArchiveBoolean( &oneshot ); arc.ArchiveString( ¤t ); arc.ArchiveString( &fallback ); arc.ArchiveString( &altcurrent ); arc.ArchiveString( &altfallback ); } class TriggerReverb : public Trigger { private: friend class SoundManager; qboolean oneshot; int reverbtype; int altreverbtype; float reverblevel; float altreverblevel; public: CLASS_PROTOTYPE( TriggerReverb ); TriggerReverb(); void SetReverbLevel( Event *ev ); void SetReverbType( Event *ev ); void SetAltReverbType( Event *ev ); void SetAltReverbLevel( Event *ev ); void ChangeReverb( Event *ev ); void AltChangeReverb( Event *ev ); void SetOneShot( Event *ev ); void SetReverb( int type, float level ); void SetAltReverb( int type, float level ); void SetOneShot( qboolean once ); void Archive( Archiver &arc ) override; }; inline void TriggerReverb::Archive ( Archiver &arc ) { Trigger::Archive( arc ); arc.ArchiveBoolean( &oneshot ); arc.ArchiveInteger( &reverbtype ); arc.ArchiveInteger( &altreverbtype ); arc.ArchiveFloat( &reverblevel ); arc.ArchiveFloat( &altreverblevel ); } class TriggerByPushObject : public TriggerOnce { private: str triggername; void setTriggerName( Event *event ); public: CLASS_PROTOTYPE( TriggerByPushObject ); qboolean respondTo( Entity *other ) override; Entity *getActivator( Entity *other ) override; void Archive( Archiver &arc ) override; }; inline void TriggerByPushObject::Archive ( Archiver &arc ) { TriggerOnce::Archive( arc ); arc.ArchiveString( &triggername ); } class TriggerGivePowerup : public Trigger { private: qboolean oneshot; str powerup_name; public: CLASS_PROTOTYPE( TriggerGivePowerup ); TriggerGivePowerup(); void SetOneShot( Event *ev ); void SetPowerupName( Event *ev ); void GivePowerup( Event *ev ); void Archive( Archiver &arc ) override; }; inline void TriggerGivePowerup::Archive ( Archiver &arc ) { Trigger::Archive( arc ); arc.ArchiveBoolean( &oneshot ); arc.ArchiveString( &powerup_name ); } class TriggerClickItem : public Trigger { public: CLASS_PROTOTYPE( TriggerClickItem ); TriggerClickItem(); void SetClickItemModelEvent( Event *ev ); void Archive( Archiver& arc ) override; }; inline void TriggerClickItem::Archive ( Archiver &arc ) { Trigger::Archive( arc ); } #endif /* trigger.h */