File: entity.h

package info (click to toggle)
openmohaa 0.82.1%2Bdfsg-1
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid
  • size: 34,192 kB
  • sloc: cpp: 315,720; ansic: 275,789; sh: 312; xml: 246; asm: 141; makefile: 7
file content (853 lines) | stat: -rw-r--r-- 23,242 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
/*
===========================================================================
Copyright (C) 2023 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
===========================================================================
*/

// entity.h: Base class for all enities that are controlled by Sin.  If you have any
// object that should be called on a periodic basis and it is not an entity,
// then you have to have an dummy entity that calls it.
//
// An entity in Sin is any object that is not part of the world->  Any non-world
// object that is visible in Sin is an entity, although it is not required that
// all entities be visible to the player.  Some objects are basically just virtual
// constructs that act as an instigator of certain actions, for example, some
// triggers are invisible and cannot be touched, but when activated by other
// objects can cause things to happen.
//
// All entities are capable of receiving messages from Sin or from other entities.
// Messages received by an entity may be ignored, passed on to their superclass,
// or acted upon by the entity itself.  The programmer must decide on the proper
// action for the entity to take to any message.  There will be many messages
// that are completely irrelevant to an entity and should be ignored.  Some messages
// may require certain states to exist and if they are received by an entity when
// it these states don't exist may indicate a logic error on the part of the
// programmer or map designer and should be reported as warnings (if the problem is
// not severe enough for the game to be halted) or as errors (if the problem should
// not be ignored at any cost).
//

#pragma once

#include "g_local.h"
#include "class.h"
#include "vector.h"
#include "script.h"
#include "listener.h"
#include "simpleentity.h"
#include "../qcommon/delegate.h"

// modification flags
#define FLAG_IGNORE 0
#define FLAG_CLEAR  1
#define FLAG_ADD    2

typedef enum {
    DAMAGE_NO,
    DAMAGE_YES, // will take damage if hit
    DAMAGE_AIM  // auto targeting recognizes this
} damage_t;

typedef enum {
    legs,
    torso,
} bodypart_t;

enum eAIEvent {
    AI_EVENT_NONE,
    AI_EVENT_WEAPON_FIRE,
    AI_EVENT_WEAPON_IMPACT,
    AI_EVENT_EXPLOSION,
    AI_EVENT_AMERICAN_VOICE,
    AI_EVENT_GERMAN_VOICE,
    AI_EVENT_AMERICAN_URGENT,
    AI_EVENT_GERMAN_URGENT,
    AI_EVENT_MISC,
    AI_EVENT_MISC_LOUD,
    AI_EVENT_FOOTSTEP,
    AI_EVENT_GRENADE,
    AI_EVENT_BADPLACE, // Added in 2.0
    AI_EVENT_MAX
};

//deadflag
#define DEAD_NO          0
#define DEAD_DYING       1
#define DEAD_DEAD        2
#define DEAD_RESPAWNABLE 3

// Generic entity events
extern Event EV_SoundDone;
extern Event EV_Classname;
extern Event EV_Activate;
extern Event EV_ForceActivate;
extern Event EV_Use;
extern Event EV_FadeNoRemove;
extern Event EV_FadeOut;
extern Event EV_FadeIn;
extern Event EV_Fade;
extern Event EV_Killed;
extern Event EV_GotKill;
extern Event EV_Pain;
extern Event EV_Damage;
extern Event EV_Stun;
extern Event EV_Gib;
extern Event EV_Kill;
extern Event EV_DeathSinkStart;
extern Event EV_Entity_AddImmunity;
extern Event EV_Entity_RemoveImmunity;

// Physics events
extern Event EV_MoveDone;
extern Event EV_Touch;
extern Event EV_Blocked;
extern Event EV_Attach;
extern Event EV_AttachModel;
extern Event EV_RemoveAttachedModel;
extern Event EV_Detach;
extern Event EV_DetachAllChildren;
extern Event EV_UseBoundingBox;
extern Event EV_IsTouching;

// Animation events
extern Event EV_NewAnim;
extern Event EV_LastFrame;
extern Event EV_TakeDamage;
extern Event EV_NoDamage;

// script stuff
extern Event EV_Model;
extern Event EV_GetModel;
extern Event EV_Hide;
extern Event EV_Show;
extern Event EV_BecomeSolid;
extern Event EV_BecomeNonSolid;
extern Event EV_Sound;
extern Event EV_StopSound;
extern Event EV_Bind;
extern Event EV_Unbind;
extern Event EV_Glue;
extern Event EV_Unglue;
extern Event EV_JoinTeam;
extern Event EV_QuitTeam;
extern Event EV_SetHealth;
extern Event EV_SetHealth2;
extern Event EV_Entity_GetHealth;
extern Event EV_SetSize;
extern Event EV_SetAlpha;
extern Event EV_SetTargetName;
extern Event EV_SetTarget;
extern Event EV_SetKillTarget;
extern Event EV_StartAnimating;
extern Event EV_SurfaceModelEvent;
extern Event EV_Stop;
extern Event EV_StopLoopSound;
extern Event EV_SetControllerAngles;
extern Event EV_CanSee;

// dir is 1
// power is 2
// minsize is 3
// maxsize is 4
// percentage is 5
// thickness 6
// entity is 7
// origin 8

// AI sound events
extern Event EV_BroadcastAIEvent;
extern Event EV_Hurt;
extern Event EV_Heal;

// Define ScriptMaster
class ScriptMaster;

//
// Spawn args
//
// "spawnflags"
// "alpha" default 1.0
// "model"
// "origin"
// "targetname"
// "target"
//

// was 8, increased to 16
#define MAX_MODEL_CHILDREN 16
#define MAX_GLUE_CHILDREN  8

#define GL_USEANGLES       1

class Entity;

typedef SafePtr<Entity> EntityPtr;

class Entity : public SimpleEntity
{
public:
    CLASS_PROTOTYPE(Entity);

    // spawning variables
    int        entnum;
    int        radnum;
    gentity_t *edict;
    gclient_t *client;
    int        spawnflags;

    // standard variables
    str model;

    // physics variables
    Vector     mins;
    Vector     maxs;
    Vector     absmin;
    Vector     absmax;
    Vector     velocity;
    Vector     accel;
    Vector     avelocity;
    Vector     aaccel;
    Vector     size;
    int        movetype;
    int        mass;
    float      gravity;
    float      orientation[3][3];
    gentity_t *groundentity;
    cplane_t   groundplane;
    int        groundcontents;

    // Model Binding variables
    int numchildren;
    int children[MAX_MODEL_CHILDREN];

    // Light variables
    float lightRadius;

    // Team variables
    str           moveteam;
    class Entity *teamchain;
    class Entity *teammaster;

    // Binding variables
    class Entity *bindmaster;
    qboolean      bind_use_my_angles;
    Vector        localorigin;
    Vector        localangles;

    // targeting variables
    str killtarget;

    // Character state
    float health;
    float max_health;
    int   deadflag;
    int   flags;

    // underwater variables
    int watertype;
    int waterlevel;

    // Pain and damage variables
    damage_t  takedamage;
    EntityPtr enemy;
    float     pain_finished;
    float     damage_debounce_time;
    int       damage_type;

    // Glue variables
    int           m_iNumGlues;
    EntityPtr     m_pGlues[MAX_GLUE_CHILDREN];
    int           m_pGluesFlags[MAX_GLUE_CHILDREN];
    class Entity *m_pGlueMaster;
    bool          m_bGlueAngles;
    bool          m_bGlueDuckable;
    qboolean      detach_at_death;

    // Path variables
    float              stealthMovementScale; // how much it will notify AIs
    class pathway_ref *m_BlockedPaths;
    int                m_iNumBlockedPaths;

    // immune list
    Container<int> immunities;

#ifdef OPM_FEATURES
    //
    // Added in OPM
    //====
    // miscellaneous
    bool m_bHintRequiresLookAt;
    str  m_HintString;
    //====
#endif

    MulticastDelegate<void(const Event& ev)> delegate_damage;
    MulticastDelegate<void(const Event& ev)> delegate_killed;
    MulticastDelegate<void(const Event& ev)> delegate_gotKill;

public:
    Entity();
    virtual ~Entity();

    void EventGetNormalHealth(Event *ev);
    void EventNormalDamage(Event *ev);
    void ClassnameEvent(Event *ev);
    void SpawnFlagsEvent(Event *ev);
    void EventRevive(Event *ev);

    virtual void ShowInfo(float fDot, float fDist);

    qboolean DistanceTo(Vector pos) const;
    qboolean DistanceTo(Entity *ent) const;
    qboolean WithinDistance(Vector pos, float dist) const;
    qboolean WithinDistance(Entity *ent, float dist) const;

    Vector   GetControllerAngles(int num);
    void     SetControllerAngles(int num, vec3_t angles);
    void     SetControllerAngles(Event *ev);
    void     GetControllerAngles(Event *ev);
    void     SetControllerTag(int num, int tag_num);
    int      GetControllerTag(int num) const;
    qboolean GetTagPositionAndOrientation(str tagname, orientation_t *new_or);
    void     GetTagPositionAndOrientation(int tagnum, orientation_t *new_or);
    void     GetTagPosition(Event *ev);
    void     GetTagAngles(Event *ev);

    void EventTrace(Event *ev);
    void EventSightTrace(Event *ev);
    void EventInPVS(Event *ev);
    void IsTouching(Event *ev);
    void IsInside(Event *ev);
    void CanSeeInternal(Event *ev, bool bNoEnts); // new in 2.0
    void CanSee(Event *ev);
    void CanSeeNoEnts(Event *ev);

    void        SetKillTarget(const char *killtarget);
    const char *KillTarget(void);

    void AlwaysDraw(Event *ev);
    void NormalDraw(Event *ev);
    void NeverDraw(Event *ev);

    const char      *getModel() const;
    void             GetModelEvent(Event *ev);
    void             GetBrushModelEvent(Event *ev);
    virtual qboolean setModel(void);
    void             SetSize(void);
    void             setModel(const str& mdl);
    void             SetModelEvent(Event *ev);

    void         SetTeamEvent(Event *ev);
    virtual void TriggerEvent(Event *ev);
    void         hideModel(void);
    void         EventHideModel(Event *ev);
    virtual void showModel(void);
    void         EventShowModel(Event *ev);
    qboolean     hidden(void);
    void         ProcessInitCommands(void);

    void  setAlpha(float alpha);
    float alpha(void);

    void setMoveType(int type);
    int  getMoveType(void);

    void setSolidType(solid_t type);
    int  getSolidType(void);

    virtual void setContentsSolid(void);

    virtual Vector getParentVector(Vector vec);
    Vector         getLocalVector(Vector vec);

    virtual void setSize(Vector min, Vector max);
    virtual void updateOrigin(void);
    virtual void setLocalOrigin(Vector org);
    void         setOrigin(Vector org) override;
    void         setOriginEvent(Vector org) override;
    virtual void setOrigin(void);
    virtual void addOrigin(Vector org);

    void     GetRawTag(int tagnum, orientation_t *orient);
    qboolean GetRawTag(const char *tagname, orientation_t *orient);

    void     GetTag(int tagnum, orientation_t *orient);
    qboolean GetTag(const char *name, orientation_t *orient);
    void     GetTag(int tagnum, Vector *pos, Vector *forward = NULL, Vector *left = NULL, Vector *up = NULL);
    qboolean GetTag(const char *name, Vector *pos, Vector *forward = NULL, Vector *left = NULL, Vector *up = NULL);

    virtual int   CurrentAnim(int slot = 0) const;
    virtual float CurrentTime(int slot = 0) const;
    void          ClearAnimSlot(int slot);
    void          StartAnimSlot(int slot, int index, float weight);
    void          RestartAnimSlot(int slot);

    void         setAngles(Vector ang) override;
    virtual void setAngles(void);

    void link(void);
    void unlink(void);

    void setContents(int type);
    int  getContents(void);
    void setScale(float scale);

    qboolean droptofloor(float maxfall);
    qboolean isClient(void);

    virtual void SetDeltaAngles(void);
    virtual void DamageEvent(Event *event);
    void         Damage(
                Entity *inflictor,
                Entity *attacker,
                float   damage,
                Vector  position,
                Vector  direction,
                Vector  normal,
                int     knockback,
                int     flags,
                int     meansofdeath,
                int     location = -1
            );

    void     DamageType(Event *ev);
    qboolean IsTouching(Entity *e1);
    qboolean IsInside(Entity *e1);
    qboolean FovCheck(float *delta, float fovdot);
    // bNoEnts since 2.0
    virtual bool CanSee(Entity *ent, float fov, float vision_distance, bool bNoEnts = false);
    virtual bool CanSee(const Vector& org, float fov, float vision_distance, bool bNoEnts = false); // added in 2.0
    bool         AreasConnected(const Entity *other);
    void         FadeNoRemove(Event *ev);
    void         FadeOut(Event *ev);
    void         FadeIn(Event *ev);
    void         Fade(Event *ev);
    void         Sink(Event *ev);

    virtual void     CheckGround(void);
    virtual qboolean HitSky(trace_t *trace);
    virtual qboolean HitSky(void);

    void SafeSolid(Event *ev); // new in 2.0
    void BecomeSolid(Event *ev);
    void BecomeNonSolid(Event *ev);
    void SetSize(Event *ev);
    void SetMins(Event *ev);
    void SetMaxs(Event *ev);
    //==
    // added in 2.0
    void GetMins(Event *ev);
    void GetMaxs(Event *ev);
    //==
    void SetScale(Event *ev);
    void GetScale(Event *ev);
    void SetAlpha(Event *ev);
    void SetKillTarget(Event *ev);
    void TouchTriggersEvent(Event *ev);

    str  GetRandomAlias(str name, AliasListNode_t **ret);
    void SetWaterType(void);

    // model binding functions
    qboolean
    attach(int parent_entity_num, int tag_num, qboolean use_angles = qtrue, Vector attach_offset = Vector("0 0 0"));
    void detach(void);

    //
    // Sound functions
    //
    void         ProcessSoundEvent(Event *ev, qboolean checkSubtitle);
    void         Sound(Event *ev);
    virtual void Sound(
        str     sound_name,
        int     channel       = CHAN_BODY,
        float   volume        = -1.0,
        float   min_dist      = -1.0,
        Vector *origin        = NULL,
        float   pitch         = -1.0f,
        int     argstype      = 0,
        int     doCallback    = 0,
        int     checkSubtitle = 1,
        float   max_dist      = -1.0f
    );
    void StopSound(int channel);
    void StopSound(Event *ev);
    void LoopSound(Event *ev);
    void
    LoopSound(str sound_name, float volume = -1.0, float min_dist = -1.0, float max_dist = -1.0, float pitch = -1.0);
    void StopLoopSound(Event *ev);
    void StopLoopSound(void);
    void StopAllSounds();

    void SetLight(Event *ev);
    void LightOn(Event *ev);
    void LightOff(Event *ev);
    void LightRed(Event *ev);
    void LightGreen(Event *ev);
    void LightBlue(Event *ev);
    void LightRadius(Event *ev);
    void LightStyle(Event *ev);
    void Flags(Event *ev);
    void Effects(Event *ev);
    void RenderEffects(Event *ev);
    void SVFlags(Event *ev);

    void         BroadcastAIEvent(int iType = AI_EVENT_MISC, float rad = SOUND_RADIUS);
    void         BroadcastAIEvent(Event *ev);
    void         Kill(Event *ev);
    virtual void Killed(Event *ev);
    void         SurfaceModelEvent(Event *ev);
    void         SurfaceCommand(const char *surf_name, const char *token);
    virtual void Postthink(void);
    virtual void Think(void);

    void DamageSkin(trace_t *trace, float damage);

    void AttachEvent(Event *ev);
    void AttachModelEvent(Event *ev);
    void RemoveAttachedModelEvent(Event *ev);
    void AttachedModelAnimEvent(Event *ev);
    void DetachEvent(Event *ev);
    void TakeDamageEvent(Event *ev);
    void NoDamageEvent(Event *ev);
    void Gravity(Event *ev);
    void GiveOxygen(float time);
    void UseBoundingBoxEvent(Event *ev);
    void HurtEvent(Event *ev);
    void HealEvent(Event *ev);
    void SetMassEvent(Event *ev);
    void Censor(Event *ev);
    void Ghost(Event *ev);

    void StationaryEvent(Event *ev);
    void TossEvent(Event *ev);
    void Explosion(Event *ev);

    void Shader(Event *ev);

    void KillAttach(Event *ev);
    void SetBloodModel(Event *ev);

    void DropToFloorEvent(Event *ev);

    // Binding methods
    void         joinTeam(Entity *teammember);
    void         quitTeam(void);
    qboolean     isBoundTo(Entity *master);
    virtual void bind(Entity *master, qboolean use_my_angles = qfalse);
    virtual void unbind(void);
    virtual void glue(Entity *master, qboolean use_my_angles = qtrue, qboolean can_duck = qfalse);
    virtual void unglue(void);
    void         GlueEvent(Event *ev);
    void         DuckableGlueEvent(Event *ev);
    void         MakeClayPidgeon(Event *ev);
    void         EventUnglue(Event *ev);

    void JoinTeam(Event *ev);
    void EventQuitTeam(Event *ev);
    void BindEvent(Event *ev);
    void EventUnbind(Event *ev);
    void AddToSoundManager(Event *ev);
    void NoLerpThisFrame(void);

    virtual void addAngles(Vector add);

    void DeathSinkStart(Event *ev);
    void DeathSink(Event *ev);

    void DetachAllChildren(Event *ev);
    void SetMovementStealth(float fStealthScale);
    void EventMovementStealth(Event *ev);

    virtual void VelocityModified(void);

    qboolean CheckEventFlags(Event *event);
    void     PusherEvent(Event *ev);
    void     SetShaderData(Event *ev);

    void GetVelocity(Event *ev);
    void SetVelocity(Event *ev);
    void GetAVelocity(Event *ev);
    void DoForceActivate(void);
    void ForceActivate(Event *ev);

    void ConnectPaths(void);
    void DisconnectPaths(void);

    void         EventConnectPaths(Event *ev);
    void         EventDisconnectPaths(Event *ev);
    virtual void Delete(void);
    void         Remove(Event *ev);
    void         EventSoundDone(Event *ev);

    void VolumeDamage(float damage);
    void EventVolumeDamage(Event *ev);

    virtual qboolean IsDead() const;
    virtual void     AddImmunity(Event *ev);
    virtual void     RemoveImmunity(Event *ev);
    qboolean         Immune(int meansofdeath);

    virtual void ClientThink(void);

    virtual void     EndFrame(void);
    virtual void     CalcBlend(void);
    void             Archive(Archiver& arc) override;
    virtual bool     AutoArchiveModel(void);
    virtual void     PathnodeClaimRevoked(class PathNode *node);
    virtual qboolean BlocksAIMovement() const;
    virtual qboolean AIDontFace(void) const;
    void             SetHealth(Event *ev);
    void             GetHealth(Event *ev);
    void             EventSetMaxHealth(Event *ev);
    void             EventGetMaxHealth(Event *ev);
    void             EventSetHealthOnly(Event *ev);
    void             GetYaw(Event *ev);

    virtual void PreAnimate(void);
    virtual void PostAnimate(void);
    virtual bool HasVehicle(void) const;
    void         EventGetEntnum(Event *ev);
    void         EventGetClassname(Event *ev);
    void         EventSetRadnum(Event *ev);
    void         EventGetRadnum(Event *ev);
    void         EventSetRotatedBbox(Event *ev);
    void         EventGetRotatedBbox(Event *ev);
    void         MPrintf(const char *msg, ...);
    void         DrawBoundingBox(int showbboxes);

    void EventSinglePlayerCommand(Event *ev);
    void EventMultiPlayerCommand(Event *ev);
    void EventRealismModeCommand(Event *ev);
    void EventSPRealismModeCommand(Event *ev);
    void EventDMRealismModeCommand(Event *ev);
    void GetLocalYawFromVector(Event *ev);
    void EventShootableOnly(Event *ev);
    void SetShaderTime(Event *ev);
    void NoTarget(Event *ev);

    //
    // Custom openmohaa features
    //
    void ProcessHint(gentity_t *client, bool bShow);
    void GetZone(Event *ev);
    void IsInZone(Event *ev);
    void SetDepthHack(Event *ev);
#ifdef OPM_FEATURES
    void SetHintRequireLookAt(Event *ev);
    void SetHintString(Event *ev);
    void SetShader(Event *ev);
#endif
    void PlayNonPvsSound(const str& soundName, float volume = 1);
};

inline void Entity::PreAnimate(void) {}

inline void Entity::PostAnimate(void) {}

inline bool Entity::HasVehicle(void) const
{
    return false;
}

inline int Entity::getSolidType(void)
{
    return edict->solid;
}

inline qboolean Entity::DistanceTo(Vector pos) const
{
    Vector delta;

    delta = origin - pos;
    return delta.length() != 0 ? qtrue : qfalse;
}

inline qboolean Entity::DistanceTo(Entity *ent) const
{
    Vector delta;

    assert(ent);

    if (!ent) {
        // "Infinite" distance
        return 999999;
    }

    delta = origin - ent->origin;
    return delta.length() != 0 ? qtrue : qfalse;
}

inline qboolean Entity::WithinDistance(Vector pos, float dist) const
{
    Vector delta;

    delta = origin - pos;

    // check squared distance
    return ((delta * delta) < (dist * dist)) ? qtrue : qfalse;
}

inline qboolean Entity::WithinDistance(Entity *ent, float dist) const
{
    Vector delta;

    assert(ent);

    if (!ent) {
        return false;
    }

    delta = origin - ent->origin;

    // check squared distance
    return ((delta * delta) < (dist * dist));
}

inline const char *Entity::KillTarget(void)
{
    return killtarget.c_str();
}

inline qboolean Entity::hidden(void)
{
    if (edict->s.renderfx & RF_DONTDRAW) {
        return true;
    }
    return false;
}

inline void Entity::GetBrushModelEvent(Event *ev)
{
    ev->AddString(model);
}

inline void Entity::GetModelEvent(Event *ev)
{
    if (!edict->tiki) {
        ev->AddNil();
        return;
    }

    const char *name = gi.TIKI_NameForNum(edict->tiki);

    if (!name) {
        if (model != "") {
            ev->AddString(model);
        } else {
            ev->AddNil();
            return;
        }
    } else {
        ev->AddString(name);
    }
}

inline void Entity::hideModel(void)
{
    edict->s.renderfx |= RF_DONTDRAW;
    if (getSolidType() <= SOLID_TRIGGER) {
        edict->r.svFlags |= SVF_NOCLIENT;
    }
}

inline void Entity::showModel(void)
{
    edict->s.renderfx &= ~RF_DONTDRAW;
    edict->r.svFlags &= ~SVF_NOCLIENT;
}

inline float Entity::alpha(void)
{
    return edict->s.alpha;
}

inline void Entity::setMoveType(int type)
{
    movetype = type;
}

inline int Entity::getMoveType(void)
{
    return movetype;
}

inline void Entity::unlink(void)
{
    gi.unlinkentity(edict);
}

inline void Entity::setContents(int type)
{
    edict->r.contents = type;
}

inline int Entity::getContents(void)
{
    return edict->r.contents;
}

inline qboolean Entity::isClient(void)
{
    if (client) {
        return true;
    }
    return false;
}

inline void Entity::SetDeltaAngles(void)
{
    int i;

    if (client) {
        for (i = 0; i < 3; i++) {
            client->ps.delta_angles[i] = ANGLE2SHORT(client->ps.viewangles[i]);
        }
    }
}

inline str Entity::GetRandomAlias(str name, AliasListNode_t **ret)
{
    str         realname;
    const char *s;

    if (edict->tiki) {
        s = gi.Alias_FindRandom(edict->tiki, name.c_str(), ret);
    } else {
        s = NULL;
    }

    if (s) {
        realname = s;
    } else {
        s = gi.GlobalAlias_FindRandom(name.c_str(), ret);
        if (s) {
            realname = s;
        }
    }

    return realname;
}

inline bool Entity::AreasConnected(const Entity *other)
{
    return gi.AreasConnected(edict->r.areanum, other->edict->r.areanum) != 0;
}

#include "worldspawn.h"