mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-29 06:07:57 +03:00

This makes TriggerEntity respond to any object that is a subclass of Entity. This is useful for scripts wanting script_model to touch triggers for cinematic purposes (for example, the bike crash gag at the end of e2l2)
658 lines
14 KiB
C++
658 lines
14 KiB
C++
/*
|
|
===========================================================================
|
|
Copyright (C) 2024 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.
|
|
//
|
|
|
|
#pragma once
|
|
|
|
#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_SetThread;
|
|
extern Event EV_Trigger_Effect;
|
|
extern Event EV_Trigger_StartThread;
|
|
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;
|
|
const_str noise;
|
|
const_str message;
|
|
ScriptThreadLabel m_Thread;
|
|
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 DamageEvent(Event *ev) override;
|
|
void EventGetActivator(Event *ev); // Added in 2.30
|
|
void Archive(Archiver& arc) override;
|
|
};
|
|
|
|
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<TouchField> TouchFieldPtr;
|
|
|
|
class TriggerOnce : public Trigger
|
|
{
|
|
public:
|
|
CLASS_PROTOTYPE(TriggerOnce);
|
|
TriggerOnce();
|
|
};
|
|
|
|
class TriggerSave : public TriggerOnce
|
|
{
|
|
private:
|
|
str m_sSaveName;
|
|
|
|
public:
|
|
CLASS_PROTOTYPE(TriggerSave);
|
|
|
|
TriggerSave();
|
|
|
|
void SaveGame(Event *ev);
|
|
void EventSaveName(Event *ev);
|
|
void Archive(Archiver& arc) override;
|
|
};
|
|
|
|
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();
|
|
};
|
|
|
|
//
|
|
// Added in 2.30
|
|
// Can only be triggered if within specific degrees
|
|
class TriggerSidedUse : public TriggerUse
|
|
{
|
|
public:
|
|
CLASS_PROTOTYPE(TriggerSidedUse);
|
|
|
|
TriggerSidedUse();
|
|
};
|
|
|
|
class TriggerUseOnce : public TriggerUse
|
|
{
|
|
public:
|
|
CLASS_PROTOTYPE(TriggerUseOnce);
|
|
|
|
TriggerUseOnce();
|
|
};
|
|
|
|
class TriggerHurt : public Trigger
|
|
{
|
|
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)
|
|
{
|
|
Trigger::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;
|
|
const_str current;
|
|
const_str fallback;
|
|
const_str altcurrent;
|
|
const_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;
|
|
};
|
|
|
|
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:
|
|
const_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;
|
|
};
|
|
|
|
class TriggerGivePowerup : public Trigger
|
|
{
|
|
private:
|
|
qboolean oneshot;
|
|
const_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;
|
|
};
|
|
|
|
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);
|
|
}
|
|
|
|
//
|
|
// Added in 2.0
|
|
//
|
|
|
|
class TriggerNoDamage : public TriggerUse
|
|
{
|
|
public:
|
|
CLASS_PROTOTYPE(TriggerNoDamage);
|
|
|
|
public:
|
|
void TakeNoDamage(Event *ev);
|
|
};
|
|
|
|
//
|
|
// Added in 2.30
|
|
//
|
|
|
|
class TriggerEntity : public Trigger
|
|
{
|
|
public:
|
|
CLASS_PROTOTYPE(TriggerEntity);
|
|
|
|
public:
|
|
qboolean respondTo(Entity *other) override;
|
|
};
|
|
|
|
class TriggerLandmine : public TriggerEntity
|
|
{
|
|
public:
|
|
CLASS_PROTOTYPE(TriggerLandmine);
|
|
|
|
TriggerLandmine();
|
|
void Archive(Archiver& arc) override;
|
|
|
|
void EventIsAbandoned(Event *ev);
|
|
void EventIsImmune(Event *ev);
|
|
void EventSetDamageable(Event *ev);
|
|
|
|
void SetDamageable(qboolean damageable);
|
|
qboolean IsImmune(Entity *other) const;
|
|
void SetTeam(int team);
|
|
|
|
private:
|
|
int team;
|
|
};
|
|
|
|
inline void TriggerLandmine::Archive(Archiver& arc)
|
|
{
|
|
Trigger::Archive(arc);
|
|
|
|
arc.ArchiveInteger(&team);
|
|
}
|