openmohaa/code/fgame/trigger.h

636 lines
14 KiB
C
Raw Normal View History

2016-03-27 11:49:47 +02:00
/*
===========================================================================
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.
2023-08-08 23:46:45 +02:00
//
2016-03-27 11:49:47 +02:00
#ifndef __TRIGGER_H__
#define __TRIGGER_H__
#include "glb_local.h"
#include "animate.h"
2023-01-30 17:43:50 +01:00
#include "gamescript.h"
2016-03-27 11:49:47 +02:00
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_SetThread;
extern Event EV_Trigger_Effect;
extern Event EV_Trigger_StartThread;
extern Event EV_Trigger_SetTriggerable;
extern Event EV_Trigger_SetNotTriggerable;
2023-08-08 23:46:45 +02:00
#define TRIGGER_PLAYERS 4
#define TRIGGER_MONSTERS 8
#define TRIGGER_PROJECTILES 16
2016-03-27 11:49:47 +02:00
class Trigger : public Animate
2023-08-08 23:46:45 +02:00
{
protected:
float wait;
float delay;
float trigger_time;
qboolean triggerActivated;
int count;
2023-08-09 00:54:06 +02:00
const_str noise;
const_str message;
2023-08-08 23:46:45 +02:00
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 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;
};
2016-03-27 11:49:47 +02:00
class TriggerVehicle : public Trigger
{
public:
2023-08-08 23:46:45 +02:00
CLASS_PROTOTYPE(TriggerVehicle);
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
qboolean respondTo(Entity *other) override;
2016-03-27 11:49:47 +02:00
};
class TriggerAllEntry
{
public:
2023-08-08 23:46:45 +02:00
EntityPtr ent;
float time;
2016-03-27 11:49:47 +02:00
public:
2023-08-08 23:46:45 +02:00
static void Archive(Archiver& arc, TriggerAllEntry *obj);
2016-03-27 11:49:47 +02:00
};
class TriggerAll : public Trigger
{
private:
2023-08-08 23:46:45 +02:00
Container<TriggerAllEntry> entries;
2016-03-27 11:49:47 +02:00
public:
2023-08-08 23:46:45 +02:00
CLASS_PROTOTYPE(TriggerAll);
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
void Archive(Archiver& arc) override;
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
void TriggerStuff(Event *ev);
bool IsTriggerable(Entity *other);
void SetTriggerTime(Entity *other, float time);
2016-03-27 11:49:47 +02:00
};
2023-08-08 23:46:45 +02:00
inline void TriggerAll::Archive(Archiver& arc)
2016-03-27 11:49:47 +02:00
{
2023-08-08 23:46:45 +02:00
Trigger::Archive(arc);
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
entries.Archive(arc, &TriggerAllEntry::Archive);
2016-03-27 11:49:47 +02:00
}
class TouchField : public Trigger
2023-08-08 23:46:45 +02:00
{
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);
}
2016-03-27 11:49:47 +02:00
typedef SafePtr<TouchField> TouchFieldPtr;
class TriggerOnce : public Trigger
2023-08-08 23:46:45 +02:00
{
public:
CLASS_PROTOTYPE(TriggerOnce);
TriggerOnce();
};
2016-03-27 11:49:47 +02:00
class TriggerSave : public Trigger
{
private:
2023-08-08 23:46:45 +02:00
str m_sSaveName;
2016-03-27 11:49:47 +02:00
public:
2023-08-08 23:46:45 +02:00
CLASS_PROTOTYPE(TriggerSave);
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
void SaveGame(Event *ev);
void EventSaveName(Event *ev);
void Archive(Archiver& arc) override;
2016-03-27 11:49:47 +02:00
};
class TriggerRelay : public Trigger
2023-08-08 23:46:45 +02:00
{
public:
CLASS_PROTOTYPE(TriggerRelay);
TriggerRelay();
};
2016-03-27 11:49:47 +02:00
class TriggerSecret : public TriggerOnce
2023-08-08 23:46:45 +02:00
{
public:
CLASS_PROTOTYPE(TriggerSecret);
TriggerSecret();
void FoundSecret(Event *ev);
void Activate(Event *ev);
};
2016-03-27 11:49:47 +02:00
class TriggerPush : public Trigger
2023-08-08 23:46:45 +02:00
{
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);
}
2016-03-27 11:49:47 +02:00
class TriggerPushAny : public Trigger
2023-08-08 23:46:45 +02:00
{
protected:
float speed;
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
public:
CLASS_PROTOTYPE(TriggerPushAny);
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
TriggerPushAny();
void Push(Event *ev);
void SetSpeed(Event *ev);
void Archive(Archiver& arc) override;
};
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
inline void TriggerPushAny::Archive(Archiver& arc)
{
Trigger::Archive(arc);
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
arc.ArchiveFloat(&speed);
}
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
#define AMBIENT_ON (1 << 0)
#define AMBIENT_OFF (1 << 1)
#define TOGGLESOUND (1 << 5)
2016-03-27 11:49:47 +02:00
class TriggerPlaySound : public Trigger
2023-08-08 23:46:45 +02:00
{
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);
}
}
}
2016-03-27 11:49:47 +02:00
class TriggerSpeaker : public TriggerPlaySound
2023-08-08 23:46:45 +02:00
{
public:
CLASS_PROTOTYPE(TriggerSpeaker);
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
TriggerSpeaker();
};
2016-03-27 11:49:47 +02:00
class RandomSpeaker : public TriggerSpeaker
2023-08-08 23:46:45 +02:00
{
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);
}
2016-03-27 11:49:47 +02:00
class TriggerChangeLevel : public Trigger
2023-01-30 17:43:50 +01:00
{
protected:
2023-08-08 23:46:45 +02:00
const_str map;
const_str spawnspot;
2016-03-27 11:49:47 +02:00
2023-01-30 17:43:50 +01:00
public:
2023-08-08 23:46:45 +02:00
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;
2023-01-30 17:43:50 +01:00
};
2016-03-27 11:49:47 +02:00
class TriggerExit : public Trigger
2023-08-08 23:46:45 +02:00
{
public:
CLASS_PROTOTYPE(TriggerExit);
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
TriggerExit();
void DisplayExitSign(Event *ev);
void TurnExitSignOff(Event *ev);
};
2016-03-27 11:49:47 +02:00
class TriggerUse : public Trigger
2023-08-08 23:46:45 +02:00
{
public:
CLASS_PROTOTYPE(TriggerUse);
TriggerUse();
};
2016-03-27 11:49:47 +02:00
class TriggerUseOnce : public TriggerUse
2023-08-08 23:46:45 +02:00
{
public:
CLASS_PROTOTYPE(TriggerUseOnce);
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
TriggerUseOnce();
};
2016-03-27 11:49:47 +02:00
class TriggerHurt : public TriggerUse
2023-08-08 23:46:45 +02:00
{
protected:
float damage;
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
void Hurt(Event *ev);
void SetDamage(Event *ev);
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
public:
CLASS_PROTOTYPE(TriggerHurt);
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
TriggerHurt();
void Archive(Archiver& arc) override;
};
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
inline void TriggerHurt::Archive(Archiver& arc)
{
TriggerUse::Archive(arc);
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
arc.ArchiveFloat(&damage);
}
2016-03-27 11:49:47 +02:00
class TriggerDamageTargets : public Trigger
2023-08-08 23:46:45 +02:00
{
protected:
float damage;
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
void DamageTargets(Event *ev);
void SetDamage(Event *ev);
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
public:
CLASS_PROTOTYPE(TriggerDamageTargets);
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
TriggerDamageTargets();
void PassDamage(Event *ev);
void Archive(Archiver& arc) override;
};
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
inline void TriggerDamageTargets::Archive(Archiver& arc)
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
{
Trigger::Archive(arc);
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
arc.ArchiveFloat(&damage);
}
2016-03-27 11:49:47 +02:00
class TriggerCameraUse : public TriggerUse
2023-08-08 23:46:45 +02:00
{
public:
CLASS_PROTOTYPE(TriggerCameraUse);
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
void TriggerCamera(Event *ev);
};
2016-03-27 11:49:47 +02:00
class TriggerBox : public Trigger
2023-08-08 23:46:45 +02:00
{
public:
CLASS_PROTOTYPE(TriggerBox);
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
void SetMins(Event *ev);
void SetMaxs(Event *ev);
};
2016-03-27 11:49:47 +02:00
class TriggerMusic : public Trigger
2023-08-08 23:46:45 +02:00
{
private:
friend class SoundManager;
2023-08-09 00:54:06 +02:00
qboolean oneshot;
const_str current;
const_str fallback;
const_str altcurrent;
const_str altfallback;
2023-08-08 23:46:45 +02:00
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;
};
2016-03-27 11:49:47 +02:00
class TriggerReverb : public Trigger
2023-08-08 23:46:45 +02:00
{
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);
}
2016-03-27 11:49:47 +02:00
class TriggerByPushObject : public TriggerOnce
2023-08-08 23:46:45 +02:00
{
private:
2023-08-09 00:54:06 +02:00
const_str triggername;
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
void setTriggerName(Event *event);
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
public:
CLASS_PROTOTYPE(TriggerByPushObject);
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
qboolean respondTo(Entity *other) override;
Entity *getActivator(Entity *other) override;
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
void Archive(Archiver& arc) override;
};
2016-03-27 11:49:47 +02:00
class TriggerGivePowerup : public Trigger
2023-08-08 23:46:45 +02:00
{
private:
2023-08-09 00:42:09 +02:00
qboolean oneshot;
const_str powerup_name;
2023-08-08 23:46:45 +02:00
public:
CLASS_PROTOTYPE(TriggerGivePowerup);
TriggerGivePowerup();
2023-08-09 00:42:09 +02:00
2023-08-08 23:46:45 +02:00
void SetOneShot(Event *ev);
void SetPowerupName(Event *ev);
void GivePowerup(Event *ev);
void Archive(Archiver& arc) override;
};
2016-03-27 11:49:47 +02:00
class TriggerClickItem : public Trigger
{
public:
2023-08-08 23:46:45 +02:00
CLASS_PROTOTYPE(TriggerClickItem);
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
TriggerClickItem();
2016-03-27 11:49:47 +02:00
2023-08-08 23:46:45 +02:00
void SetClickItemModelEvent(Event *ev);
void Archive(Archiver& arc) override;
2016-03-27 11:49:47 +02:00
};
2023-08-08 23:46:45 +02:00
inline void TriggerClickItem::Archive(Archiver& arc)
2016-03-27 11:49:47 +02:00
{
2023-08-08 23:46:45 +02:00
Trigger::Archive(arc);
2016-03-27 11:49:47 +02:00
}
2023-08-08 23:46:45 +02:00
class TriggerNoDamage : public TriggerUse
{
public:
CLASS_PROTOTYPE(TriggerNoDamage);
public:
2023-08-08 23:46:45 +02:00
void TakeNoDamage(Event *ev);
};
2023-08-08 23:46:45 +02:00
class TriggerEntity : public Trigger
{
public:
CLASS_PROTOTYPE(TriggerEntity);
};
2023-08-08 23:46:45 +02:00
class TriggerLandmine : public TriggerEntity
{
public:
CLASS_PROTOTYPE(TriggerLandmine);
2023-08-08 23:46:45 +02:00
TriggerLandmine();
void Archive(Archiver& arc) override;
2023-08-08 23:46:45 +02:00
void EventIsAbandoned(Event *ev);
void EventIsImmune(Event *ev);
void EventSetDamageable(Event *ev);
2023-08-08 23:46:45 +02:00
void SetDamageable(qboolean damageable);
qboolean IsImmune(Entity *other) const;
void SetTeam(int team);
private:
2023-08-08 23:46:45 +02:00
int team;
};
inline void TriggerLandmine::Archive(Archiver& arc)
{
2023-08-08 23:46:45 +02:00
Trigger::Archive(arc);
arc.ArchiveInteger(&team);
}
2016-03-27 11:49:47 +02:00
#endif /* trigger.h */