/
actor.h
1556 lines (1337 loc) · 60.8 KB
/
actor.h
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
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//-----------------------------------------------------------------------------
//
// Copyright 1993-1996 id Software
// Copyright 1994-1996 Raven Software
// Copyright 1999-2016 Randy Heit
// Copyright 2002-2016 Christoph Oelckers
//
// This program 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 3 of the License, or
// (at your option) any later version.
//
// This program 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 this program. If not, see http://www.gnu.org/licenses/
//
//-----------------------------------------------------------------------------
//
// DESCRIPTION:
// Map Objects, MObj, definition and handling.
//
//-----------------------------------------------------------------------------
#ifndef __P_MOBJ_H__
#define __P_MOBJ_H__
// Basics.
#include "templates.h"
// We need the thinker_t stuff.
#include "dthinker.h"
// States are tied to finite states are tied to animation frames.
#include "info.h"
#include "doomdef.h"
#include "textures/textures.h"
#include "r_data/renderstyle.h"
#include "s_sound.h"
#include "memarena.h"
#include "g_level.h"
#include "tflags.h"
#include "portal.h"
struct subsector_t;
struct FBlockNode;
struct FPortalGroupArray;
struct visstyle_t;
class FLightDefaults;
struct FSection;
struct FLevelLocals;
struct FDynamicLight;
//
// NOTES: AActor
//
// Actors are used to tell the refresh where to draw an image,
// tell the world simulation when objects are contacted,
// and tell the sound driver how to position a sound.
//
// The refresh uses the next and prev links to follow
// lists of things in sectors as they are being drawn.
// The sprite, frame, and angle elements determine which patch_t
// is used to draw the sprite if it is visible.
// The sprite and frame values are almost always set
// from state_t structures.
// The statescr.exe utility generates the states.h and states.c
// files that contain the sprite/frame numbers from the
// statescr.txt source file.
// The xyz origin point represents a point at the bottom middle
// of the sprite (between the feet of a biped).
// This is the default origin position for patch_ts grabbed
// with lumpy.exe.
// A walking creature will have its z equal to the floor
// it is standing on.
//
// The sound code uses the x,y, and sometimes z fields
// to do stereo positioning of any sound emitted by the actor.
//
// The play simulation uses the blocklinks, x,y,z, radius, height
// to determine when AActors are touching each other,
// touching lines in the map, or hit by trace lines (gunshots,
// lines of sight, etc).
// The AActor->flags element has various bit flags
// used by the simulation.
//
// Every actor is linked into a single sector
// based on its origin coordinates.
// The subsector_t is found with PointInSector(x,y).
// The sector links are only used by the rendering code,
// the play simulation does not care about them at all.
//
// Any actor that needs to be acted upon by something else
// in the play world (block movement, be shot, etc) will also
// need to be linked into the blockmap.
// If the thing has the MF_NOBLOCK flag set, it will not use
// the block links. It can still interact with other things,
// but only as the instigator (missiles will run into other
// things, but nothing can run into a missile).
// Each block in the grid is 128*128 units, and knows about
// every line_t that it contains a piece of, and every
// interactable actor that has its origin contained.
//
// A valid actor is an actor that has the proper subsector_t
// filled in for its xy coordinates and is linked into the
// sector from which the subsector was made, or has the
// MF_NOSECTOR flag set (the subsector_t needs to be valid
// even if MF_NOSECTOR is set), and is linked into a blockmap
// block or has the MF_NOBLOCKMAP flag set.
// Links should only be modified by the P_[Un]SetThingPosition()
// functions.
// Do not change the MF_NO* flags while a thing is valid.
//
// Any questions?
//
// --- mobj.flags ---
enum ActorFlag
{
MF_SPECIAL = 0x00000001, // call P_SpecialThing when touched
MF_SOLID = 0x00000002,
MF_SHOOTABLE = 0x00000004,
MF_NOSECTOR = 0x00000008, // don't use the sector links
// (invisible but touchable)
MF_NOBLOCKMAP = 0x00000010, // don't use the blocklinks
// (inert but displayable)
MF_AMBUSH = 0x00000020, // not activated by sound; deaf monster
MF_JUSTHIT = 0x00000040, // try to attack right back
MF_JUSTATTACKED = 0x00000080, // take at least one step before attacking
MF_SPAWNCEILING = 0x00000100, // hang from ceiling instead of floor
MF_NOGRAVITY = 0x00000200, // don't apply gravity every tic
// movement flags
MF_DROPOFF = 0x00000400, // allow jumps from high places
MF_PICKUP = 0x00000800, // for players to pick up items
MF_NOCLIP = 0x00001000, // player cheat
MF_INCHASE = 0x00002000, // [RH] used by A_Chase and A_Look to avoid recursion
MF_FLOAT = 0x00004000, // allow moves to any height, no gravity
MF_TELEPORT = 0x00008000, // don't cross lines or look at heights
MF_MISSILE = 0x00010000, // don't hit same species, explode on block
MF_DROPPED = 0x00020000, // dropped by a demon, not level spawned
MF_SHADOW = 0x00040000, // actor is hard for monsters to see
MF_NOBLOOD = 0x00080000, // don't bleed when shot (use puff)
MF_CORPSE = 0x00100000, // don't stop moving halfway off a step
MF_INFLOAT = 0x00200000, // floating to a height for a move, don't
// auto float to target's height
MF_INBOUNCE = 0x00200000, // used by Heretic bouncing missiles
MF_COUNTKILL = 0x00400000, // count towards intermission kill total
MF_COUNTITEM = 0x00800000, // count towards intermission item total
MF_SKULLFLY = 0x01000000, // skull in flight
MF_NOTDMATCH = 0x02000000, // don't spawn in death match (key cards)
MF_SPAWNSOUNDSOURCE = 0x04000000, // Plays missile's see sound at spawning object.
MF_FRIENDLY = 0x08000000, // [RH] Friendly monsters for Strife (and MBF)
MF_UNMORPHED = 0x10000000, // [RH] Actor is the unmorphed version of something else
MF_NOLIFTDROP = 0x20000000, // [RH] Used with MF_NOGRAVITY to avoid dropping with lifts
MF_STEALTH = 0x40000000, // [RH] Andy Baker's stealth monsters
MF_ICECORPSE = 0x80000000, // a frozen corpse (for blasting) [RH] was 0x800000
// --- dummies for unknown/unimplemented Strife flags ---
MF_STRIFEx8000000 = 0, // seems related to MF_SHADOW
};
// --- mobj.flags2 ---
enum ActorFlag2
{
MF2_DONTREFLECT = 0x00000001, // this projectile cannot be reflected
MF2_WINDTHRUST = 0x00000002, // gets pushed around by the wind specials
MF2_DONTSEEKINVISIBLE=0x00000004, // For seeker missiles: Don't home in on invisible/shadow targets
MF2_BLASTED = 0x00000008, // actor will temporarily take damage from impact
MF2_FLY = 0x00000010, // fly mode is active
MF2_FLOORCLIP = 0x00000020, // if feet are allowed to be clipped
MF2_SPAWNFLOAT = 0x00000040, // spawn random float z
MF2_NOTELEPORT = 0x00000080, // does not teleport
MF2_RIP = 0x00000100, // missile rips through solid targets
MF2_PUSHABLE = 0x00000200, // can be pushed by other moving actors
MF2_SLIDE = 0x00000400, // slides against walls
MF2_ONMOBJ = 0x00000800, // actor is resting on top of another actor
MF2_PASSMOBJ = 0x00001000, // Enable z block checking. If on,
// this flag will allow the actor to
// pass over/under other actors.
MF2_CANNOTPUSH = 0x00002000, // cannot push other pushable mobjs
MF2_THRUGHOST = 0x00004000, // missile will pass through ghosts [RH] was 8
MF2_BOSS = 0x00008000, // mobj is a major boss
MF2_DONTTRANSLATE = 0x00010000, // Don't apply palette translations
MF2_NODMGTHRUST = 0x00020000, // does not thrust target when damaging
MF2_TELESTOMP = 0x00040000, // mobj can stomp another
MF2_FLOATBOB = 0x00080000, // use float bobbing z movement
MF2_THRUACTORS = 0x00100000, // performs no actor<->actor collision checks
MF2_IMPACT = 0x00200000, // an MF_MISSILE mobj can activate SPAC_IMPACT
MF2_PUSHWALL = 0x00400000, // mobj can push walls
MF2_MCROSS = 0x00800000, // can activate monster cross lines
MF2_PCROSS = 0x01000000, // can activate projectile cross lines
MF2_CANTLEAVEFLOORPIC=0x02000000, // stay within a certain floor type
MF2_NONSHOOTABLE = 0x04000000, // mobj is totally non-shootable,
// but still considered solid
MF2_INVULNERABLE = 0x08000000, // mobj is invulnerable
MF2_DORMANT = 0x10000000, // thing is dormant
MF2_ARGSDEFINED = 0x20000000, // Internal flag used by DECORATE to signal that the
// args should not be taken from the mapthing definition
MF2_SEEKERMISSILE = 0x40000000, // is a seeker (for reflection)
MF2_REFLECTIVE = 0x80000000, // reflects missiles
};
// --- mobj.flags3 ---
enum ActorFlag3
{
MF3_FLOORHUGGER = 0x00000001, // Missile stays on floor
MF3_CEILINGHUGGER = 0x00000002, // Missile stays on ceiling
MF3_NORADIUSDMG = 0x00000004, // Actor does not take radius damage
MF3_GHOST = 0x00000008, // Actor is a ghost
MF3_ALWAYSPUFF = 0x00000010, // Puff always appears, even when hit nothing
MF3_SPECIALFLOORCLIP= 0x00000020, // Actor uses floorclip for special effect (e.g. Wraith)
MF3_DONTSPLASH = 0x00000040, // Thing doesn't make a splash
MF3_NOSIGHTCHECK = 0x00000080, // Go after first acceptable target without checking sight
MF3_DONTOVERLAP = 0x00000100, // Don't pass over/under other things with this bit set
MF3_DONTMORPH = 0x00000200, // Immune to arti_egg
MF3_DONTSQUASH = 0x00000400, // Death ball can't squash this actor
MF3_EXPLOCOUNT = 0x00000800, // Don't explode until special2 counts to special1
MF3_FULLVOLACTIVE = 0x00001000, // Active sound is played at full volume
MF3_ISMONSTER = 0x00002000, // Actor is a monster
MF3_SKYEXPLODE = 0x00004000, // Explode missile when hitting sky
MF3_STAYMORPHED = 0x00008000, // Monster cannot unmorph
MF3_DONTBLAST = 0x00010000, // Actor cannot be pushed by blasting
MF3_CANBLAST = 0x00020000, // Actor is not a monster but can be blasted
MF3_NOTARGET = 0x00040000, // This actor not targetted when it hurts something else
MF3_DONTGIB = 0x00080000, // Don't gib this corpse
MF3_NOBLOCKMONST = 0x00100000, // Can cross ML_BLOCKMONSTERS lines
MF3_CRASHED = 0x00200000, // Actor entered its crash state
MF3_FULLVOLDEATH = 0x00400000, // DeathSound is played full volume (for missiles)
MF3_AVOIDMELEE = 0x00800000, // Avoids melee attacks (same as MBF's monster_backing but must be explicitly set)
MF3_SCREENSEEKER = 0x01000000, // Fails the IsOkayToAttack test if potential target is outside player FOV
MF3_FOILINVUL = 0x02000000, // Actor can hurt MF2_INVULNERABLE things
MF3_NOTELEOTHER = 0x04000000, // Monster is unaffected by teleport other artifact
MF3_BLOODLESSIMPACT = 0x08000000, // Projectile does not leave blood
MF3_NOEXPLODEFLOOR = 0x10000000, // Missile stops at floor instead of exploding
MF3_WARNBOT = 0x20000000, // Missile warns bot
MF3_PUFFONACTORS = 0x40000000, // Puff appears even when hit bleeding actors
MF3_HUNTPLAYERS = 0x80000000, // Used with TIDtoHate, means to hate players too
};
// --- mobj.flags4 ---
enum ActorFlag4
{
MF4_NOHATEPLAYERS = 0x00000001, // Ignore player attacks
MF4_QUICKTORETALIATE= 0x00000002, // Always switch targets when hurt
MF4_NOICEDEATH = 0x00000004, // Actor never enters an ice death, not even the generic one
MF4_BOSSDEATH = 0x00000008, // A_FreezeDeathChunks calls A_BossDeath
MF4_RANDOMIZE = 0x00000010, // Missile has random initial tic count
MF4_NOSKIN = 0x00000020, // Player cannot use skins
MF4_FIXMAPTHINGPOS = 0x00000040, // Fix this actor's position when spawned as a map thing
MF4_ACTLIKEBRIDGE = 0x00000080, // Pickups can "stand" on this actor / cannot be moved by any sector action.
MF4_STRIFEDAMAGE = 0x00000100, // Strife projectiles only do up to 4x damage, not 8x
MF4_CANUSEWALLS = 0x00000200, // Can activate 'use' specials
MF4_MISSILEMORE = 0x00000400, // increases the chance of a missile attack
MF4_MISSILEEVENMORE = 0x00000800, // significantly increases the chance of a missile attack
MF4_FORCERADIUSDMG = 0x00001000, // if put on an object it will override MF3_NORADIUSDMG
MF4_DONTFALL = 0x00002000, // Doesn't have NOGRAVITY disabled when dying.
MF4_SEESDAGGERS = 0x00004000, // This actor can see you striking with a dagger
MF4_INCOMBAT = 0x00008000, // Don't alert others when attacked by a dagger
MF4_LOOKALLAROUND = 0x00010000, // Monster has eyes in the back of its head
MF4_STANDSTILL = 0x00020000, // Monster should not chase targets unless attacked?
MF4_SPECTRAL = 0x00040000,
MF4_SCROLLMOVE = 0x00080000, // velocity has been applied by a scroller
MF4_NOSPLASHALERT = 0x00100000, // Splashes don't alert this monster
MF4_SYNCHRONIZED = 0x00200000, // For actors spawned at load-time only: Do not randomize tics
MF4_NOTARGETSWITCH = 0x00400000, // monster never switches target until current one is dead
MF4_VFRICTION = 0x00800000, // Internal flag used by A_PainAttack to push a monster down
MF4_DONTHARMCLASS = 0x01000000, // Don't hurt one's own kind with explosions (hitscans, too?)
MF4_SHIELDREFLECT = 0x02000000,
MF4_DEFLECT = 0x04000000, // different projectile reflection styles
MF4_ALLOWPARTICLES = 0x08000000, // this puff type can be replaced by particles
MF4_NOEXTREMEDEATH = 0x10000000, // this projectile or weapon never gibs its victim
MF4_EXTREMEDEATH = 0x20000000, // this projectile or weapon always gibs its victim
MF4_FRIGHTENED = 0x40000000, // Monster runs away from player
MF4_BOSSSPAWNED = 0x80000000, // Spawned by a boss spawn cube
};
// --- mobj.flags5 ---
enum ActorFlag5
{
MF5_DONTDRAIN = 0x00000001, // cannot be drained health from.
MF5_GETOWNER = 0x00000002,
MF5_NODROPOFF = 0x00000004, // cannot drop off under any circumstances.
MF5_NOFORWARDFALL = 0x00000008, // Does not make any actor fall forward by being damaged by this
MF5_COUNTSECRET = 0x00000010, // From Doom 64: actor acts like a secret
MF5_AVOIDINGDROPOFF = 0x00000020, // Used to move monsters away from dropoffs
MF5_NODAMAGE = 0x00000040, // Actor can be shot and reacts to being shot but takes no damage
MF5_CHASEGOAL = 0x00000080, // Walks to goal instead of target if a valid goal is set.
MF5_BLOODSPLATTER = 0x00000100, // Blood splatter like in Raven's games.
MF5_OLDRADIUSDMG = 0x00000200, // Use old radius damage code (for barrels and boss brain)
MF5_DEHEXPLOSION = 0x00000400, // Use the DEHACKED explosion options when this projectile explodes
MF5_PIERCEARMOR = 0x00000800, // Armor doesn't protect against damage from this actor
MF5_NOBLOODDECALS = 0x00001000, // Actor bleeds but doesn't spawn blood decals
MF5_USESPECIAL = 0x00002000, // Actor executes its special when being 'used'.
MF5_NOPAIN = 0x00004000, // If set the pain state won't be entered
MF5_ALWAYSFAST = 0x00008000, // always uses 'fast' attacking logic
MF5_NEVERFAST = 0x00010000, // never uses 'fast' attacking logic
MF5_ALWAYSRESPAWN = 0x00020000, // always respawns, regardless of skill setting
MF5_NEVERRESPAWN = 0x00040000, // never respawns, regardless of skill setting
MF5_DONTRIP = 0x00080000, // Ripping projectiles explode when hitting this actor
MF5_NOINFIGHTING = 0x00100000, // This actor doesn't switch target when it's hurt
MF5_NOINTERACTION = 0x00200000, // Thing is completely excluded from any gameplay related checks
MF5_NOTIMEFREEZE = 0x00400000, // Actor is not affected by time freezer
MF5_PUFFGETSOWNER = 0x00800000, // [BB] Sets the owner of the puff to the player who fired it
MF5_SPECIALFIREDAMAGE=0x01000000, // Special treatment of PhoenixFX1 turned into a flag to remove
// dependence of main engine code of specific actor types.
MF5_SUMMONEDMONSTER = 0x02000000, // To mark the friendly Minotaur. Hopefully to be generalized later.
MF5_NOVERTICALMELEERANGE=0x04000000,// Does not check vertical distance for melee range
MF5_BRIGHT = 0x08000000, // Actor is always rendered fullbright
MF5_CANTSEEK = 0x10000000, // seeker missiles cannot home in on this actor
MF5_INCONVERSATION = 0x20000000, // Actor is having a conversation
MF5_PAINLESS = 0x40000000, // Actor always inflicts painless damage.
MF5_MOVEWITHSECTOR = 0x80000000, // P_ChangeSector() will still process this actor if it has MF_NOBLOCKMAP
};
// --- mobj.flags6 ---
enum ActorFlag6
{
MF6_NOBOSSRIP = 0x00000001, // For rippermissiles: Don't rip through bosses.
MF6_THRUSPECIES = 0x00000002, // Actors passes through other of the same species.
MF6_MTHRUSPECIES = 0x00000004, // Missile passes through actors of its shooter's species.
MF6_FORCEPAIN = 0x00000008, // forces target into painstate (unless it has the NOPAIN flag)
MF6_NOFEAR = 0x00000010, // Not scared of frightening players
MF6_BUMPSPECIAL = 0x00000020, // Actor executes its special when being collided (as the ST flag)
MF6_DONTHARMSPECIES = 0x00000040, // Don't hurt one's own species with explosions (hitscans, too?)
MF6_STEPMISSILE = 0x00000080, // Missile can "walk" up steps
MF6_NOTELEFRAG = 0x00000100, // [HW] Actor can't be telefragged
MF6_TOUCHY = 0x00000200, // From MBF: killough 11/98: dies when solids touch it
MF6_CANJUMP = 0x00000400, // From MBF: a dedicated flag instead of the BOUNCES+FLOAT+sentient combo
MF6_JUMPDOWN = 0x00000800, // From MBF: generalization of dog behavior wrt. dropoffs.
MF6_VULNERABLE = 0x00001000, // Actor can be damaged (even if not shootable).
MF6_ARMED = 0x00002000, // From MBF: Object is armed (for MF6_TOUCHY objects)
MF6_FALLING = 0x00004000, // From MBF: Object is falling (for pseudotorque simulation)
MF6_LINEDONE = 0x00008000, // From MBF: Object has already run a line effect
MF6_NOTRIGGER = 0x00010000, // actor cannot trigger any line actions
MF6_SHATTERING = 0x00020000, // marks an ice corpse for forced shattering
MF6_KILLED = 0x00040000, // Something that was killed (but not necessarily a corpse)
MF6_BLOCKEDBYSOLIDACTORS = 0x00080000, // Blocked by solid actors, even if not solid itself
MF6_ADDITIVEPOISONDAMAGE = 0x00100000,
MF6_ADDITIVEPOISONDURATION = 0x00200000,
MF6_NOMENU = 0x00400000, // Player class should not appear in the class selection menu.
MF6_BOSSCUBE = 0x00800000, // Actor spawned by A_BrainSpit, flagged for timefreeze reasons.
MF6_SEEINVISIBLE = 0x01000000, // Monsters can see invisible player.
MF6_DONTCORPSE = 0x02000000, // [RC] Don't autoset MF_CORPSE upon death and don't force Crash state change.
MF6_POISONALWAYS = 0x04000000, // Always apply poison, even when target can't take the damage.
MF6_DOHARMSPECIES = 0x08000000, // Do hurt one's own species with projectiles.
MF6_INTRYMOVE = 0x10000000, // Executing P_TryMove
MF6_NOTAUTOAIMED = 0x20000000, // Do not subject actor to player autoaim.
MF6_NOTONAUTOMAP = 0x40000000, // will not be shown on automap with the 'scanner' powerup.
MF6_RELATIVETOFLOOR = 0x80000000, // [RC] Make flying actors be affected by lifts.
};
// --- mobj.flags7 ---
enum ActorFlag7
{
MF7_NEVERTARGET = 0x00000001, // can not be targetted at all, even if monster friendliness is considered.
MF7_NOTELESTOMP = 0x00000002, // cannot telefrag under any circumstances (even when set by MAPINFO)
MF7_ALWAYSTELEFRAG = 0x00000004, // will unconditionally be telefragged when in the way. Overrides all other settings.
MF7_HANDLENODELAY = 0x00000008, // respect NoDelay state flag
MF7_WEAPONSPAWN = 0x00000010, // subject to DF_NO_COOP_WEAPON_SPAWN dmflag
MF7_HARMFRIENDS = 0x00000020, // is allowed to harm friendly monsters.
MF7_BUDDHA = 0x00000040, // Behaves just like the buddha cheat.
MF7_FOILBUDDHA = 0x00000080, // Similar to FOILINVUL, foils buddha mode.
MF7_DONTTHRUST = 0x00000100, // Thrusting functions do not take, and do not give thrust (damage) to actors with this flag.
MF7_ALLOWPAIN = 0x00000200, // Invulnerable or immune (via damagefactors) actors can still react to taking damage even if they don't.
MF7_CAUSEPAIN = 0x00000400, // Damage sources with this flag can cause similar effects like ALLOWPAIN.
MF7_THRUREFLECT = 0x00000800, // Actors who are reflective cause the missiles to not slow down or change angles.
MF7_MIRRORREFLECT = 0x00001000, // Actor is turned directly 180 degrees around when reflected.
MF7_AIMREFLECT = 0x00002000, // Actor is directly reflected straight back at the one who fired the projectile.
MF7_HITTARGET = 0x00004000, // The actor the projectile dies on is set to target, provided it's targetable anyway.
MF7_HITMASTER = 0x00008000, // Same as HITTARGET, except it's master instead of target.
MF7_HITTRACER = 0x00010000, // Same as HITTARGET, but for tracer.
MF7_FLYCHEAT = 0x00020000, // must be part of the actor so that it can be tracked properly
MF7_NODECAL = 0x00040000, // [ZK] Forces puff to have no impact decal
MF7_FORCEDECAL = 0x00080000, // [ZK] Forces puff's decal to override the weapon's.
MF7_LAXTELEFRAGDMG = 0x00100000, // [MC] Telefrag damage can be reduced.
MF7_ICESHATTER = 0x00200000, // [MC] Shatters ice corpses regardless of damagetype.
MF7_ALLOWTHRUFLAGS = 0x00400000, // [MC] Allow THRUACTORS and the likes on puffs to prevent mod breakage.
MF7_USEKILLSCRIPTS = 0x00800000, // [JM] Use "KILL" Script on death if not forced by GameInfo.
MF7_NOKILLSCRIPTS = 0x01000000, // [JM] No "KILL" Script on death whatsoever, even if forced by GameInfo.
MF7_SPRITEANGLE = 0x02000000, // [MC] Utilize the SpriteAngle property and lock the rotation to the degrees specified.
MF7_SMASHABLE = 0x04000000, // dies if hitting the floor.
MF7_NOSHIELDREFLECT = 0x08000000, // will not be reflected by shields.
MF7_FORCEZERORADIUSDMG = 0x10000000, // passes zero radius damage on to P_DamageMobj, this is necessary in some cases where DoSpecialDamage gets overrideen.
MF7_NOINFIGHTSPECIES = 0x20000000, // don't start infights with one's own species.
MF7_FORCEINFIGHTING = 0x40000000, // overrides a map setting of 'no infighting'.
};
enum ActorFlag8
{
MF8_FRIGHTENING = 0x00000001, // for those moments when halloween just won't do
MF8_INSCROLLSEC = 0x00000002, // actor is partially inside a scrolling sector
MF8_BLOCKASPLAYER = 0x00000004, // actor is blocked by player-blocking lines even if not a player
MF8_DONTFACETALKER = 0x00000008, // don't alter the angle to face the player in conversations
MF8_HITOWNER = 0x00000010, // projectile can hit the actor that fired it
MF8_NOFRICTION = 0x00000020, // friction doesn't apply to the actor at all
MF8_NOFRICTIONBOUNCE = 0x00000040, // don't bounce off walls when on icy floors
MF8_RETARGETAFTERSLAM = 0x00000080 // Forces jumping to the idle state after slamming into something
};
// --- mobj.renderflags ---
enum ActorRenderFlag
{
RF_XFLIP = 0x0001, // Flip sprite horizontally
RF_YFLIP = 0x0002, // Flip sprite vertically
RF_ONESIDED = 0x0004, // Wall/floor sprite is visible from front only
RF_FULLBRIGHT = 0x0010, // Sprite is drawn at full brightness
RF_RELMASK = 0x0300, // ---Relative z-coord for bound actors (these obey texture pegging)
RF_RELABSOLUTE = 0x0000, // Actor z is absolute
RF_RELUPPER = 0x0100, // Actor z is relative to upper part of wall
RF_RELLOWER = 0x0200, // Actor z is relative to lower part of wall
RF_RELMID = 0x0300, // Actor z is relative to middle part of wall
RF_CLIPMASK = 0x0c00, // ---Clipping for bound actors
RF_CLIPFULL = 0x0000, // Clip sprite to full height of wall
RF_CLIPUPPER = 0x0400, // Clip sprite to upper part of wall
RF_CLIPMID = 0x0800, // Clip sprite to mid part of wall
RF_CLIPLOWER = 0x0c00, // Clip sprite to lower part of wall
RF_DECALMASK = RF_RELMASK|RF_CLIPMASK,
RF_SPRITETYPEMASK = 0x7000, // ---Different sprite types, not all implemented
RF_FACESPRITE = 0x0000, // Face sprite
RF_WALLSPRITE = 0x1000, // Wall sprite
RF_FLATSPRITE = 0x2000, // Flat sprite
RF_VOXELSPRITE = 0x3000, // Voxel object
RF_INVISIBLE = 0x8000, // Don't bother drawing this actor
RF_FORCEYBILLBOARD = 0x10000, // [BB] OpenGL only: draw with y axis billboard, i.e. anchored to the floor (overrides gl_billboard_mode setting)
RF_FORCEXYBILLBOARD = 0x20000, // [BB] OpenGL only: draw with xy axis billboard, i.e. unanchored (overrides gl_billboard_mode setting)
RF_ROLLSPRITE = 0x40000, //[marrub]roll the sprite billboard
RF_DONTFLIP = 0x80000, // Don't flip it when viewed from behind.
RF_ROLLCENTER = 0x00100000, // Rotate from the center of sprite instead of offsets
RF_MASKROTATION = 0x00200000, // [MC] Only draw the actor when viewed from a certain angle range.
RF_ABSMASKANGLE = 0x00400000, // [MC] The mask rotation does not offset by the actor's angle.
RF_ABSMASKPITCH = 0x00800000, // [MC] The mask rotation does not offset by the actor's pitch.
RF_INTERPOLATEANGLES = 0x01000000, // [MC] Allow interpolation of the actor's angle, pitch and roll.
RF_MAYBEINVISIBLE = 0x02000000,
RF_DONTINTERPOLATE = 0x04000000, // no render interpolation ever!
RF_SPRITEFLIP = 0x08000000, // sprite flipped on x-axis
RF_ZDOOMTRANS = 0x10000000, // is not normally transparent in Vanilla Doom
RF_NOINTERPOLATEVIEW = 0x40000000, // don't interpolate the view next frame if this actor is a camera.
};
// This translucency value produces the closest match to Heretic's TINTTAB.
// ~40% of the value of the overlaid image shows through.
const double HR_SHADOW = (0x6800 / 65536.);
// Hexen's TINTTAB is the same as Heretic's, just reversed.
const double HX_SHADOW = (0x9800 / 65536.);
const double HX_ALTSHADOW = (0x6800 / 65536.);
// This could easily be a bool but then it'd be much harder to find later. ;)
enum replace_t
{
NO_REPLACE = 0,
ALLOW_REPLACE = 1
};
enum ActorBounceFlag
{
BOUNCE_Walls = 1<<0, // bounces off of walls
BOUNCE_Floors = 1<<1, // bounces off of floors
BOUNCE_Ceilings = 1<<2, // bounces off of ceilings
BOUNCE_Actors = 1<<3, // bounces off of some actors
BOUNCE_AllActors = 1<<4, // bounces off of all actors (requires BOUNCE_Actors to be set, too)
BOUNCE_AutoOff = 1<<5, // when bouncing off a sector plane, if the new Z velocity is below 3.0, disable further bouncing
BOUNCE_HereticType = 1<<6, // goes into Death state when bouncing on floors or ceilings
BOUNCE_UseSeeSound = 1<<7, // compatibility fallback. This will only be set by
// the compatibility handlers for the old bounce flags.
BOUNCE_NoWallSound = 1<<8, // don't make noise when bouncing off a wall
BOUNCE_Quiet = 1<<9, // Strife's grenades don't make a bouncing sound
BOUNCE_ExplodeOnWater = 1<<10, // explodes when hitting a water surface
BOUNCE_CanBounceWater = 1<<11, // can bounce on water
// MBF bouncing is a bit different from other modes as Killough coded many special behavioral cases
// for them that are not present in ZDoom, so it is necessary to identify it properly.
BOUNCE_MBF = 1<<12, // This in itself is not a valid mode, but replaces MBF's MF_BOUNCE flag.
BOUNCE_AutoOffFloorOnly = 1<<13, // like BOUNCE_AutoOff, but only on floors
BOUNCE_UseBounceState = 1<<14, // Use Bounce[.*] states
BOUNCE_NotOnShootables = 1<<15, // do not bounce off shootable actors if we are a projectile. Explode instead.
BOUNCE_BounceOnUnrips = 1<<16, // projectile bounces on actors with DONTRIP
BOUNCE_NotOnSky = 1<<17, // Don't bounce on sky floors / ceilings / walls
BOUNCE_TypeMask = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors | BOUNCE_AutoOff | BOUNCE_HereticType | BOUNCE_MBF,
// The three "standard" types of bounciness are:
// HERETIC - Missile will only bounce off the floor once and then enter
// its death state. It does not bounce off walls at all.
// HEXEN - Missile bounces off of walls and floors indefinitely.
// DOOM - Like Hexen, but the bounce turns off if its vertical velocity
// is too low.
BOUNCE_None = 0,
BOUNCE_Heretic = BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_HereticType,
BOUNCE_Doom = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors | BOUNCE_AutoOff,
BOUNCE_Hexen = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors,
BOUNCE_Grenade = BOUNCE_MBF | BOUNCE_Doom, // Bounces on walls and flats like ZDoom bounce.
BOUNCE_Classic = BOUNCE_MBF | BOUNCE_Floors | BOUNCE_Ceilings, // Bounces on flats only, but
// does not die when bouncing.
// combined types
BOUNCE_DoomCompat = BOUNCE_Doom | BOUNCE_UseSeeSound,
BOUNCE_HereticCompat = BOUNCE_Heretic | BOUNCE_UseSeeSound,
BOUNCE_HexenCompat = BOUNCE_Hexen | BOUNCE_UseSeeSound
// The distinction between BOUNCE_Actors and BOUNCE_AllActors: A missile with
// BOUNCE_Actors set will bounce off of reflective and "non-sentient" actors.
// A missile that also has BOUNCE_AllActors set will bounce off of any actor.
// For compatibility reasons when BOUNCE_Actors was implied by the bounce type
// being "Doom" or "Hexen" and BOUNCE_AllActors was the separate
// MF5_BOUNCEONACTORS, you must set BOUNCE_Actors for BOUNCE_AllActors to have
// an effect.
};
// this is a special flag set that is exposed directly to DECORATE/ZScript
// these flags are for filtering actor visibility based on certain conditions of the renderer's feature support.
// currently, no renderer supports every single one of these features.
enum ActorRenderFeatureFlag
{
RFF_FLATSPRITES = 1<<0, // flat sprites
RFF_MODELS = 1<<1, // 3d models
RFF_SLOPE3DFLOORS = 1<<2, // sloped 3d floor support
RFF_TILTPITCH = 1<<3, // full free-look
RFF_ROLLSPRITES = 1<<4, // roll sprites
RFF_UNCLIPPEDTEX = 1<<5, // midtex and sprite can render "into" flats and walls
RFF_MATSHADER = 1<<6, // material shaders
RFF_POSTSHADER = 1<<7, // post-process shaders (renderbuffers)
RFF_BRIGHTMAP = 1<<8, // brightmaps
RFF_COLORMAP = 1<<9, // custom colormaps (incl. ability to fullbright certain ranges, ala Strife)
RFF_POLYGONAL = 1<<10, // uses polygons instead of wallscans/visplanes (i.e. softpoly and hardware opengl)
RFF_TRUECOLOR = 1<<11, // renderer is currently truecolor
RFF_VOXELS = 1<<12, // renderer is capable of voxels
};
// [TP] Flagset definitions
typedef TFlags<ActorFlag> ActorFlags;
typedef TFlags<ActorFlag2> ActorFlags2;
typedef TFlags<ActorFlag3> ActorFlags3;
typedef TFlags<ActorFlag4> ActorFlags4;
typedef TFlags<ActorFlag5> ActorFlags5;
typedef TFlags<ActorFlag6> ActorFlags6;
typedef TFlags<ActorFlag7> ActorFlags7;
typedef TFlags<ActorFlag8> ActorFlags8;
typedef TFlags<ActorRenderFlag> ActorRenderFlags;
typedef TFlags<ActorBounceFlag> ActorBounceFlags;
typedef TFlags<ActorRenderFeatureFlag> ActorRenderFeatureFlags;
DEFINE_TFLAGS_OPERATORS (ActorFlags)
DEFINE_TFLAGS_OPERATORS (ActorFlags2)
DEFINE_TFLAGS_OPERATORS (ActorFlags3)
DEFINE_TFLAGS_OPERATORS (ActorFlags4)
DEFINE_TFLAGS_OPERATORS (ActorFlags5)
DEFINE_TFLAGS_OPERATORS (ActorFlags6)
DEFINE_TFLAGS_OPERATORS (ActorFlags7)
DEFINE_TFLAGS_OPERATORS (ActorFlags8)
DEFINE_TFLAGS_OPERATORS (ActorRenderFlags)
DEFINE_TFLAGS_OPERATORS (ActorBounceFlags)
DEFINE_TFLAGS_OPERATORS (ActorRenderFeatureFlags)
// Used to affect the logic for thing activation through death, USESPECIAL and BUMPSPECIAL
// "thing" refers to what has the flag and the special, "trigger" refers to what used or bumped it
enum EThingSpecialActivationType
{
THINGSPEC_Default = 0, // Normal behavior: a player must be the trigger, and is the activator
THINGSPEC_ThingActs = 1, // The thing itself is the activator of the special
THINGSPEC_ThingTargets = 1<<1, // The thing changes its target to the trigger
THINGSPEC_TriggerTargets = 1<<2, // The trigger changes its target to the thing
THINGSPEC_MonsterTrigger = 1<<3, // The thing can be triggered by a monster
THINGSPEC_MissileTrigger = 1<<4, // The thing can be triggered by a projectile
THINGSPEC_ClearSpecial = 1<<5, // Clears special after successful activation
THINGSPEC_NoDeathSpecial = 1<<6, // Don't activate special on death
THINGSPEC_TriggerActs = 1<<7, // The trigger is the activator of the special
// (overrides LEVEL_ACTOWNSPECIAL Hexen hack)
THINGSPEC_Activate = 1<<8, // The thing is activated when triggered
THINGSPEC_Deactivate = 1<<9, // The thing is deactivated when triggered
THINGSPEC_Switch = 1<<10, // The thing is alternatively activated and deactivated when triggered
};
#define ONFLOORZ FIXED_MIN
#define ONCEILINGZ FIXED_MAX
#define FLOATRANDZ (FIXED_MAX-1)
class FDecalBase;
inline AActor *GetDefaultByName (const char *name)
{
return (AActor *)(PClass::FindClass(name)->Defaults);
}
inline AActor *GetDefaultByType (const PClass *type)
{
return (AActor *)(type->Defaults);
}
template<class T>
inline T *GetDefault ()
{
return (T *)(RUNTIME_CLASS_CASTLESS(T)->Defaults);
}
struct line_t;
struct secplane_t;
struct msecnode_t;
struct FStrifeDialogueNode;
struct FLinkContext
{
msecnode_t *sector_list = nullptr;
msecnode_t *render_list = nullptr;
};
struct FDropItem
{
FDropItem *Next;
FName Name;
int Probability;
int Amount;
};
const double MinVel = EQUAL_EPSILON;
// Map Object definition.
class AActor : public DThinker
{
DECLARE_CLASS_WITH_META (AActor, DThinker, PClassActor)
HAS_OBJECT_POINTERS
public:
AActor() = default;
AActor(const AActor &other) = delete; // Calling this would be disastrous.
AActor &operator= (const AActor &other);
~AActor ();
virtual void OnDestroy() override;
virtual void Serialize(FSerializer &arc) override;
virtual void PostSerialize() override;
virtual void PostBeginPlay() override; // Called immediately before the actor's first tick
virtual void Tick() override;
static AActor *StaticSpawn (FLevelLocals *Level, PClassActor *type, const DVector3 &pos, replace_t allowreplacement, bool SpawningMapThing = false);
inline AActor *GetDefault () const
{
return (AActor *)(this->GetClass()->Defaults);
}
FActorInfo *GetInfo() const
{
return static_cast<PClassActor*>(GetClass())->ActorInfo();
}
FDropItem *GetDropItems() const;
// Return true if the monster should use a missile attack, false for melee
bool SuggestMissileAttack (double dist);
// Adjusts the angle for deflection/reflection of incoming missiles
// Returns true if the missile should be allowed to explode anyway
bool AdjustReflectionAngle (AActor *thing, DAngle &angle);
int AbsorbDamage(int damage, FName dmgtype);
void AlterWeaponSprite(visstyle_t *vis);
// Returns true if this actor is within melee range of its target
bool CheckMeleeRange();
bool CheckNoDelay();
virtual void BeginPlay(); // Called immediately after the actor is created
void CallBeginPlay();
// [ZZ] custom postbeginplay (calls E_WorldThingSpawned)
void CallPostBeginPlay() override;
void LevelSpawned(); // Called after BeginPlay if this actor was spawned by the world
void HandleSpawnFlags(); // Translates SpawnFlags into in-game flags.
virtual void Activate (AActor *activator);
void CallActivate(AActor *activator);
virtual void Deactivate(AActor *activator);
void CallDeactivate(AActor *activator);
// Called when actor dies
virtual void Die (AActor *source, AActor *inflictor, int dmgflags = 0, FName MeansOfDeath = NAME_None);
void CallDie(AActor *source, AActor *inflictor, int dmgflags = 0, FName MeansOfDeath = NAME_None);
// Perform some special damage action. Returns the amount of damage to do.
// Returning -1 signals the damage routine to exit immediately
virtual int DoSpecialDamage (AActor *target, int damage, FName damagetype);
int CallDoSpecialDamage(AActor *target, int damage, FName damagetype);
// Like DoSpecialDamage, but called on the actor receiving the damage.
virtual int TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FName damagetype);
int CallTakeSpecialDamage(AActor *inflictor, AActor *source, int damage, FName damagetype);
// Actor had MF_SKULLFLY set and rammed into something
// Returns false to stop moving and true to keep moving
virtual bool Slam(AActor *victim);
bool CallSlam(AActor *victim);
// Something just touched this actor.
virtual void Touch(AActor *toucher);
void CallTouch(AActor *toucher);
// Centaurs and ettins squeal when electrocuted, poisoned, or "holy"-ed
// Made a metadata property so no longer virtual
void Howl ();
// plays bouncing sound
void PlayBounceSound(bool onfloor);
// Called when an actor with MF_MISSILE and MF2_FLOORBOUNCE hits the floor
bool FloorBounceMissile (secplane_t &plane);
// Called by RoughBlockCheck
bool IsOkayToAttack (AActor *target);
// Plays the actor's ActiveSound if its voice isn't already making noise.
void PlayActiveSound ();
void RestoreSpecialPosition();
// Called by PIT_CheckThing() and needed for some Hexen things.
// Returns -1 for normal behavior, 0 to return false, and 1 to return true.
// I'm not sure I like it this way, but it will do for now.
// (virtual on the script side only)
int SpecialMissileHit (AActor *victim);
// Returns true if it's okay to switch target to "other" after being attacked by it.
bool CallOkayToSwitchTarget(AActor *other);
bool OkayToSwitchTarget (AActor *other);
// Uses an item and removes it from the inventory.
bool UseInventory (AActor *item);
// Tosses an item out of the inventory.
AActor *DropInventory (AActor *item, int amt = -1);
// Removes all items from the inventory.
void ClearInventory();
// Returns true if this view is considered "local" for the player.
bool CheckLocalView() const;
// Finds the first item of a particular type.
AActor *FindInventory (PClassActor *type, bool subclass=false);
AActor *FindInventory (FName type, bool subclass = false);
template<class T> T *FindInventory ()
{
return static_cast<T *> (FindInventory (RUNTIME_CLASS(T)));
}
// Adds one item of a particular type. Returns NULL if it could not be added.
AActor *GiveInventoryType (PClassActor *type);
// Destroys all the inventory the actor is holding.
void DestroyAllInventory ();
// Set the alphacolor field properly
void SetShade (uint32_t rgb);
void SetShade (int r, int g, int b);
// Plays a conversation animation
void ConversationAnimation (int animnum);
// Make this actor hate the same things as another actor
void CopyFriendliness (AActor *other, bool changeTarget, bool resetHealth=true);
// Moves the other actor's inventory to this one
void ObtainInventory (AActor *other);
// Die. Now.
bool Massacre ();
// Transforms the actor into a finely-ground paste
bool Grind(bool items);
bool CallGrind(bool items);
// Get this actor's team
int GetTeam();
// Is the other actor on my team?
bool IsTeammate (AActor *other);
// Is the other actor my friend?
bool IsFriend (AActor *other);
// Do I hate the other actor?
bool IsHostile (AActor *other);
inline bool IsNoClip2() const;
void CheckPortalTransition(bool islinked);
DVector3 GetPortalTransition(double byoffset, sector_t **pSec = NULL);
// What species am I?
FName GetSpecies();
// set translation
void SetTranslation(FName trname);
double GetBobOffset(double ticfrac = 0) const;
// Enter the crash state
void Crash();
// Return starting health adjusted by skill level
double AttackOffset(double offset = 0);
int SpawnHealth() const;
virtual int GetMaxHealth(bool withupgrades = false) const;
int GetGibHealth() const;
double GetCameraHeight() const;
inline bool isMissile(bool precise=true)
{
return (flags&MF_MISSILE) || (precise && GetDefault()->flags&MF_MISSILE);
}
// Check for monsters that count as kill but excludes all friendlies.
bool CountsAsKill() const
{
return (flags & MF_COUNTKILL) && !(flags & MF_FRIENDLY);
}
// These also set CF_INTERPVIEW for players.
void SetPitch(DAngle p, bool interpolate, bool forceclamp = false);
void SetAngle(DAngle ang, bool interpolate);
void SetRoll(DAngle roll, bool interpolate);
PClassActor *GetBloodType(int type = 0) const;
double Distance2DSquared(AActor *other, bool absolute = false)
{
DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this);
return (Pos().XY() - otherpos).LengthSquared();
}
double Distance2D(AActor *other, bool absolute = false)
{
DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this);
return (Pos().XY() - otherpos).Length();
}
double Distance2D(double x, double y) const
{
return DVector2(X() - x, Y() - y).Length();
}
double Distance2D(AActor *other, double xadd, double yadd, bool absolute = false)
{
DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this);
return DVector2(X() - otherpos.X + xadd, Y() - otherpos.Y + yadd).Length();
}
// a full 3D version of the above
double Distance3DSquared(AActor *other, bool absolute = false)
{
DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this);
return (Pos() - otherpos).LengthSquared();
}
double Distance3D(AActor *other, bool absolute = false)
{
DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this);
return (Pos() - otherpos).Length();
}
DAngle AngleTo(AActor *other, bool absolute = false)
{
DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this);
return VecToAngle(otherpos - Pos().XY());
}
DAngle AngleTo(AActor *other, double oxofs, double oyofs, bool absolute = false) const
{
DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this);
return VecToAngle(otherpos - Pos() + DVector2(oxofs, oyofs));
}
DVector2 Vec2To(AActor *other) const
{
return other->PosRelative(this) - Pos();
}
DVector3 Vec3To(AActor *other) const
{
return other->PosRelative(this) - Pos();
}
DVector2 Vec2Offset(double dx, double dy, bool absolute = false);
DVector3 Vec2OffsetZ(double dx, double dy, double atz, bool absolute = false);
DVector2 Vec2Angle(double length, DAngle angle, bool absolute = false);
DVector3 Vec3Offset(double dx, double dy, double dz, bool absolute = false);
DVector3 Vec3Offset(const DVector3 &ofs, bool absolute = false);
DVector3 Vec3Angle(double length, DAngle angle, double dz, bool absolute = false);
void ClearInterpolation();
void Move(const DVector3 &vel)
{
SetOrigin(Pos() + vel, true);
}
virtual void SetOrigin(double x, double y, double z, bool moving);
void SetOrigin(const DVector3 & npos, bool moving)
{
SetOrigin(npos.X, npos.Y, npos.Z, moving);
}
inline void SetFriendPlayer(player_t *player);
bool IsVisibleToPlayer() const;
bool IsInsideVisibleAngles() const;
// Calculate amount of missile damage
int GetMissileDamage(int mask, int add);
bool CanSeek(AActor *target) const;
double GetGravity() const;
bool IsSentient() const;
const char *GetTag(const char *def = NULL) const;
void SetTag(const char *def);
// Triggers SECSPAC_Exit/SECSPAC_Enter and related events if oldsec != current sector
void CheckSectorTransition(sector_t *oldsec);
void UpdateRenderSectorList();
void ClearRenderSectorList();
void ClearRenderLineList();
void AttachLight(unsigned int count, const FLightDefaults *lightdef);
void SetDynamicLights();
// info for drawing
// NOTE: The first member variable *must* be snext.
AActor *snext, **sprev; // links in sector (if needed)
DVector3 __Pos; // double underscores so that it won't get used by accident. Access to this should be exclusively through the designated access functions.
DAngle SpriteAngle;
DAngle SpriteRotation;
DRotator Angles;
DVector2 Scale; // Scaling values; 1 is normal size
double Alpha; // Since P_CheckSight makes an alpha check this can't be a float. It has to be a double.
int sprite; // used to find patch_t and flip value
uint8_t frame; // sprite frame to draw
uint8_t effects; // [RH] see p_effect.h
uint8_t fountaincolor; // Split out of 'effect' to have easier access.
FRenderStyle RenderStyle; // Style to draw this actor with
FTextureID picnum; // Draw this instead of sprite if valid
uint32_t fillcolor; // Color to draw when STYLE_Shaded
uint32_t Translation;
uint32_t RenderRequired; // current renderer must have this feature set
uint32_t RenderHidden; // current renderer must *not* have any of these features
ActorRenderFlags renderflags; // Different rendering flags
ActorFlags flags;
ActorFlags2 flags2; // Heretic flags
ActorFlags3 flags3; // [RH] Hexen/Heretic actor-dependant behavior made flaggable
ActorFlags4 flags4; // [RH] Even more flags!
ActorFlags5 flags5; // OMG! We need another one.
ActorFlags6 flags6; // Shit! Where did all the flags go?
ActorFlags7 flags7; // WHO WANTS TO BET ON 8!?
ActorFlags8 flags8; // I see your 8, and raise you a bet for 9.
double Floorclip; // value to use for floor clipping
double radius, Height; // for movement checking
DAngle VisibleStartAngle;
DAngle VisibleStartPitch;
DAngle VisibleEndAngle;
DAngle VisibleEndPitch;
DVector3 OldRenderPos;
DVector3 Vel;
double Speed;
double FloatSpeed;
// interaction info
FBlockNode *BlockNode; // links in blocks (if needed)
struct sector_t *Sector;
subsector_t * subsector;
FSection * section;
double floorz, ceilingz; // closest together of contacted secs
double dropoffz; // killough 11/98: the lowest floor over all contacted Sectors.