1 // Emacs style mode select	 -*- C++ -*-
2 //-----------------------------------------------------------------------------
3 //
4 // $Id:$
5 //
6 // Copyright (C) 1993-1996 by id Software, Inc.
7 //
8 // This source is available for distribution and/or modification
9 // only under the terms of the DOOM Source Code License as
10 // published by id Software. All rights reserved.
11 //
12 // The source is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
15 // for more details.
16 //
17 // DESCRIPTION:
18 //		Map Objects, MObj, definition and handling.
19 //
20 //-----------------------------------------------------------------------------
21 
22 
23 #ifndef __P_MOBJ_H__
24 #define __P_MOBJ_H__
25 
26 // Basics.
27 #include "tables.h"
28 
29 // We need the thinker_t stuff.
30 #include "dthinker.h"
31 
32 
33 // States are tied to finite states are tied to animation frames.
34 #include "info.h"
35 
36 #include "doomdef.h"
37 #include "textures/textures.h"
38 #include "r_data/renderstyle.h"
39 #include "s_sound.h"
40 #include "memarena.h"
41 #include "g_level.h"
42 #include "tflags.h"
43 
44 struct subsector_t;
45 //
46 // NOTES: AActor
47 //
48 // Actors are used to tell the refresh where to draw an image,
49 // tell the world simulation when objects are contacted,
50 // and tell the sound driver how to position a sound.
51 //
52 // The refresh uses the next and prev links to follow
53 // lists of things in sectors as they are being drawn.
54 // The sprite, frame, and angle elements determine which patch_t
55 // is used to draw the sprite if it is visible.
56 // The sprite and frame values are almost always set
57 // from state_t structures.
58 // The statescr.exe utility generates the states.h and states.c
59 // files that contain the sprite/frame numbers from the
60 // statescr.txt source file.
61 // The xyz origin point represents a point at the bottom middle
62 // of the sprite (between the feet of a biped).
63 // This is the default origin position for patch_ts grabbed
64 // with lumpy.exe.
65 // A walking creature will have its z equal to the floor
66 // it is standing on.
67 //
68 // The sound code uses the x,y, and sometimes z fields
69 // to do stereo positioning of any sound emitted by the actor.
70 //
71 // The play simulation uses the blocklinks, x,y,z, radius, height
72 // to determine when AActors are touching each other,
73 // touching lines in the map, or hit by trace lines (gunshots,
74 // lines of sight, etc).
75 // The AActor->flags element has various bit flags
76 // used by the simulation.
77 //
78 // Every actor is linked into a single sector
79 // based on its origin coordinates.
80 // The subsector_t is found with R_PointInSubsector(x,y),
81 // and the sector_t can be found with subsector->sector.
82 // The sector links are only used by the rendering code,
83 // the play simulation does not care about them at all.
84 //
85 // Any actor that needs to be acted upon by something else
86 // in the play world (block movement, be shot, etc) will also
87 // need to be linked into the blockmap.
88 // If the thing has the MF_NOBLOCK flag set, it will not use
89 // the block links. It can still interact with other things,
90 // but only as the instigator (missiles will run into other
91 // things, but nothing can run into a missile).
92 // Each block in the grid is 128*128 units, and knows about
93 // every line_t that it contains a piece of, and every
94 // interactable actor that has its origin contained.
95 //
96 // A valid actor is an actor that has the proper subsector_t
97 // filled in for its xy coordinates and is linked into the
98 // sector from which the subsector was made, or has the
99 // MF_NOSECTOR flag set (the subsector_t needs to be valid
100 // even if MF_NOSECTOR is set), and is linked into a blockmap
101 // block or has the MF_NOBLOCKMAP flag set.
102 // Links should only be modified by the P_[Un]SetThingPosition()
103 // functions.
104 // Do not change the MF_NO* flags while a thing is valid.
105 //
106 // Any questions?
107 //
108 
109 // --- mobj.flags ---
110 enum ActorFlag
111 {
112 	MF_SPECIAL			= 0x00000001,	// call P_SpecialThing when touched
113 	MF_SOLID			= 0x00000002,
114 	MF_SHOOTABLE		= 0x00000004,
115 	MF_NOSECTOR			= 0x00000008,	// don't use the sector links
116 										// (invisible but touchable)
117 	MF_NOBLOCKMAP		= 0x00000010,	// don't use the blocklinks
118 										// (inert but displayable)
119 	MF_AMBUSH			= 0x00000020,	// not activated by sound; deaf monster
120 	MF_JUSTHIT			= 0x00000040,	// try to attack right back
121 	MF_JUSTATTACKED		= 0x00000080,	// take at least one step before attacking
122 	MF_SPAWNCEILING		= 0x00000100,	// hang from ceiling instead of floor
123 	MF_NOGRAVITY		= 0x00000200,	// don't apply gravity every tic
124 
125 // movement flags
126 	MF_DROPOFF			= 0x00000400,	// allow jumps from high places
127 	MF_PICKUP			= 0x00000800,	// for players to pick up items
128 	MF_NOCLIP			= 0x00001000,	// player cheat
129 	MF_INCHASE			= 0x00002000,	// [RH] used by A_Chase and A_Look to avoid recursion
130 	MF_FLOAT			= 0x00004000,	// allow moves to any height, no gravity
131 	MF_TELEPORT			= 0x00008000,	// don't cross lines or look at heights
132 	MF_MISSILE			= 0x00010000,	// don't hit same species, explode on block
133 
134 	MF_DROPPED			= 0x00020000,	// dropped by a demon, not level spawned
135 	MF_SHADOW			= 0x00040000,	// actor is hard for monsters to see
136 	MF_NOBLOOD			= 0x00080000,	// don't bleed when shot (use puff)
137 	MF_CORPSE			= 0x00100000,	// don't stop moving halfway off a step
138 	MF_INFLOAT			= 0x00200000,	// floating to a height for a move, don't
139 										// auto float to target's height
140 	MF_INBOUNCE			= 0x00200000,	// used by Heretic bouncing missiles
141 
142 	MF_COUNTKILL		= 0x00400000,	// count towards intermission kill total
143 	MF_COUNTITEM		= 0x00800000,	// count towards intermission item total
144 
145 	MF_SKULLFLY			= 0x01000000,	// skull in flight
146 	MF_NOTDMATCH		= 0x02000000,	// don't spawn in death match (key cards)
147 
148 	MF_SPAWNSOUNDSOURCE	= 0x04000000,	// Plays missile's see sound at spawning object.
149 	MF_FRIENDLY			= 0x08000000,	// [RH] Friendly monsters for Strife (and MBF)
150 	MF_UNMORPHED		= 0x10000000,	// [RH] Actor is the unmorphed version of something else
151 	MF_NOLIFTDROP		= 0x20000000,	// [RH] Used with MF_NOGRAVITY to avoid dropping with lifts
152 	MF_STEALTH			= 0x40000000,	// [RH] Andy Baker's stealth monsters
153 	MF_ICECORPSE		= 0x80000000,	// a frozen corpse (for blasting) [RH] was 0x800000
154 
155 	// --- dummies for unknown/unimplemented Strife flags ---
156 	MF_STRIFEx8000000 = 0,		// seems related to MF_SHADOW
157 };
158 
159 // --- mobj.flags2 ---
160 enum ActorFlag2
161 {
162 	MF2_DONTREFLECT		= 0x00000001,	// this projectile cannot be reflected
163 	MF2_WINDTHRUST		= 0x00000002,	// gets pushed around by the wind specials
164 	MF2_DONTSEEKINVISIBLE=0x00000004,	// For seeker missiles: Don't home in on invisible/shadow targets
165 	MF2_BLASTED			= 0x00000008,	// actor will temporarily take damage from impact
166 	MF2_FLY				= 0x00000010,	// fly mode is active
167 	MF2_FLOORCLIP		= 0x00000020,	// if feet are allowed to be clipped
168 	MF2_SPAWNFLOAT		= 0x00000040,	// spawn random float z
169 	MF2_NOTELEPORT		= 0x00000080,	// does not teleport
170 	MF2_RIP				= 0x00000100,	// missile rips through solid targets
171 	MF2_PUSHABLE		= 0x00000200,	// can be pushed by other moving actors
172 	MF2_SLIDE			= 0x00000400,	// slides against walls
173 	MF2_ONMOBJ			= 0x00000800,	// actor is resting on top of another actor
174 	MF2_PASSMOBJ		= 0x00001000,	// Enable z block checking. If on,
175 										// this flag will allow the actor to
176 										// pass over/under other actors.
177 	MF2_CANNOTPUSH		= 0x00002000,	// cannot push other pushable mobjs
178 	MF2_THRUGHOST		= 0x00004000,	// missile will pass through ghosts [RH] was 8
179 	MF2_BOSS			= 0x00008000,	// mobj is a major boss
180 
181 	MF2_DONTTRANSLATE	= 0x00010000,	// Don't apply palette translations
182 	MF2_NODMGTHRUST		= 0x00020000,	// does not thrust target when damaging
183 	MF2_TELESTOMP		= 0x00040000,	// mobj can stomp another
184 	MF2_FLOATBOB		= 0x00080000,	// use float bobbing z movement
185 	MF2_THRUACTORS		= 0x00100000,	// performs no actor<->actor collision checks
186 	MF2_IMPACT			= 0x00200000, 	// an MF_MISSILE mobj can activate SPAC_IMPACT
187 	MF2_PUSHWALL		= 0x00400000, 	// mobj can push walls
188 	MF2_MCROSS			= 0x00800000,	// can activate monster cross lines
189 	MF2_PCROSS			= 0x01000000,	// can activate projectile cross lines
190 	MF2_CANTLEAVEFLOORPIC=0x02000000,	// stay within a certain floor type
191 	MF2_NONSHOOTABLE	= 0x04000000,	// mobj is totally non-shootable,
192 										// but still considered solid
193 	MF2_INVULNERABLE	= 0x08000000,	// mobj is invulnerable
194 	MF2_DORMANT			= 0x10000000,	// thing is dormant
195 	MF2_ARGSDEFINED		= 0x20000000,	// Internal flag used by DECORATE to signal that the
196 										// args should not be taken from the mapthing definition
197 	MF2_SEEKERMISSILE	= 0x40000000,	// is a seeker (for reflection)
198 	MF2_REFLECTIVE		= 0x80000000,	// reflects missiles
199 };
200 
201 // --- mobj.flags3 ---
202 enum ActorFlag3
203 {
204 	MF3_FLOORHUGGER		= 0x00000001,	// Missile stays on floor
205 	MF3_CEILINGHUGGER	= 0x00000002,	// Missile stays on ceiling
206 	MF3_NORADIUSDMG		= 0x00000004,	// Actor does not take radius damage
207 	MF3_GHOST			= 0x00000008,	// Actor is a ghost
208 	MF3_ALWAYSPUFF		= 0x00000010,	// Puff always appears, even when hit nothing
209 	MF3_SPECIALFLOORCLIP= 0x00000020,	// Actor uses floorclip for special effect (e.g. Wraith)
210 	MF3_DONTSPLASH		= 0x00000040,	// Thing doesn't make a splash
211 	MF3_NOSIGHTCHECK	= 0x00000080,	// Go after first acceptable target without checking sight
212 	MF3_DONTOVERLAP		= 0x00000100,	// Don't pass over/under other things with this bit set
213 	MF3_DONTMORPH		= 0x00000200,	// Immune to arti_egg
214 	MF3_DONTSQUASH		= 0x00000400,	// Death ball can't squash this actor
215 	MF3_EXPLOCOUNT		= 0x00000800,	// Don't explode until special2 counts to special1
216 	MF3_FULLVOLACTIVE	= 0x00001000,	// Active sound is played at full volume
217 	MF3_ISMONSTER		= 0x00002000,	// Actor is a monster
218 	MF3_SKYEXPLODE		= 0x00004000,	// Explode missile when hitting sky
219 	MF3_STAYMORPHED		= 0x00008000,	// Monster cannot unmorph
220 	MF3_DONTBLAST		= 0x00010000,	// Actor cannot be pushed by blasting
221 	MF3_CANBLAST		= 0x00020000,	// Actor is not a monster but can be blasted
222 	MF3_NOTARGET		= 0x00040000,	// This actor not targetted when it hurts something else
223 	MF3_DONTGIB			= 0x00080000,	// Don't gib this corpse
224 	MF3_NOBLOCKMONST	= 0x00100000,	// Can cross ML_BLOCKMONSTERS lines
225 	MF3_CRASHED			= 0x00200000,	// Actor entered its crash state
226 	MF3_FULLVOLDEATH	= 0x00400000,	// DeathSound is played full volume (for missiles)
227 	MF3_AVOIDMELEE		= 0x00800000,	// Avoids melee attacks (same as MBF's monster_backing but must be explicitly set)
228 	MF3_SCREENSEEKER    = 0x01000000,	// Fails the IsOkayToAttack test if potential target is outside player FOV
229 	MF3_FOILINVUL		= 0x02000000,	// Actor can hurt MF2_INVULNERABLE things
230 	MF3_NOTELEOTHER		= 0x04000000,	// Monster is unaffected by teleport other artifact
231 	MF3_BLOODLESSIMPACT	= 0x08000000,	// Projectile does not leave blood
232 	MF3_NOEXPLODEFLOOR	= 0x10000000,	// Missile stops at floor instead of exploding
233 	MF3_WARNBOT			= 0x20000000,	// Missile warns bot
234 	MF3_PUFFONACTORS	= 0x40000000,	// Puff appears even when hit bleeding actors
235 	MF3_HUNTPLAYERS		= 0x80000000,	// Used with TIDtoHate, means to hate players too
236 };
237 
238 // --- mobj.flags4 ---
239 enum ActorFlag4
240 {
241 	MF4_NOHATEPLAYERS	= 0x00000001,	// Ignore player attacks
242 	MF4_QUICKTORETALIATE= 0x00000002,	// Always switch targets when hurt
243 	MF4_NOICEDEATH		= 0x00000004,	// Actor never enters an ice death, not even the generic one
244 	MF4_BOSSDEATH		= 0x00000008,	// A_FreezeDeathChunks calls A_BossDeath
245 	MF4_RANDOMIZE		= 0x00000010,	// Missile has random initial tic count
246 	MF4_NOSKIN			= 0x00000020,	// Player cannot use skins
247 	MF4_FIXMAPTHINGPOS	= 0x00000040,	// Fix this actor's position when spawned as a map thing
248 	MF4_ACTLIKEBRIDGE	= 0x00000080,	// Pickups can "stand" on this actor / cannot be moved by any sector action.
249 	MF4_STRIFEDAMAGE	= 0x00000100,	// Strife projectiles only do up to 4x damage, not 8x
250 
251 	MF4_CANUSEWALLS		= 0x00000200,	// Can activate 'use' specials
252 	MF4_MISSILEMORE		= 0x00000400,	// increases the chance of a missile attack
253 	MF4_MISSILEEVENMORE	= 0x00000800,	// significantly increases the chance of a missile attack
254 	MF4_FORCERADIUSDMG	= 0x00001000,	// if put on an object it will override MF3_NORADIUSDMG
255 	MF4_DONTFALL		= 0x00002000,	// Doesn't have NOGRAVITY disabled when dying.
256 	MF4_SEESDAGGERS		= 0x00004000,	// This actor can see you striking with a dagger
257 	MF4_INCOMBAT		= 0x00008000,	// Don't alert others when attacked by a dagger
258 	MF4_LOOKALLAROUND	= 0x00010000,	// Monster has eyes in the back of its head
259 	MF4_STANDSTILL		= 0x00020000,	// Monster should not chase targets unless attacked?
260 	MF4_SPECTRAL		= 0x00040000,
261 	MF4_SCROLLMOVE		= 0x00080000,	// velocity has been applied by a scroller
262 	MF4_NOSPLASHALERT	= 0x00100000,	// Splashes don't alert this monster
263 	MF4_SYNCHRONIZED	= 0x00200000,	// For actors spawned at load-time only: Do not randomize tics
264 	MF4_NOTARGETSWITCH	= 0x00400000,	// monster never switches target until current one is dead
265 	MF4_VFRICTION		= 0x00800000,	// Internal flag used by A_PainAttack to push a monster down
266 	MF4_DONTHARMCLASS	= 0x01000000,	// Don't hurt one's own kind with explosions (hitscans, too?)
267 	MF4_SHIELDREFLECT	= 0x02000000,
268 	MF4_DEFLECT			= 0x04000000,	// different projectile reflection styles
269 	MF4_ALLOWPARTICLES	= 0x08000000,	// this puff type can be replaced by particles
270 	MF4_NOEXTREMEDEATH	= 0x10000000,	// this projectile or weapon never gibs its victim
271 	MF4_EXTREMEDEATH	= 0x20000000,	// this projectile or weapon always gibs its victim
272 	MF4_FRIGHTENED		= 0x40000000,	// Monster runs away from player
273 	MF4_BOSSSPAWNED		= 0x80000000,	// Spawned by a boss spawn cube
274 };
275 
276 // --- mobj.flags5 ---
277 
278 enum ActorFlag5
279 {
280 	MF5_DONTDRAIN		= 0x00000001,	// cannot be drained health from.
281 	/*					= 0x00000002,	   reserved for use by scripting branch */
282 	MF5_NODROPOFF		= 0x00000004,	// cannot drop off under any circumstances.
283 	MF5_NOFORWARDFALL	= 0x00000008,	// Does not make any actor fall forward by being damaged by this
284 	MF5_COUNTSECRET		= 0x00000010,	// From Doom 64: actor acts like a secret
285 	MF5_AVOIDINGDROPOFF = 0x00000020,	// Used to move monsters away from dropoffs
286 	MF5_NODAMAGE		= 0x00000040,	// Actor can be shot and reacts to being shot but takes no damage
287 	MF5_CHASEGOAL		= 0x00000080,	// Walks to goal instead of target if a valid goal is set.
288 	MF5_BLOODSPLATTER	= 0x00000100,	// Blood splatter like in Raven's games.
289 	MF5_OLDRADIUSDMG	= 0x00000200,	// Use old radius damage code (for barrels and boss brain)
290 	MF5_DEHEXPLOSION	= 0x00000400,	// Use the DEHACKED explosion options when this projectile explodes
291 	MF5_PIERCEARMOR		= 0x00000800,	// Armor doesn't protect against damage from this actor
292 	MF5_NOBLOODDECALS	= 0x00001000,	// Actor bleeds but doesn't spawn blood decals
293 	MF5_USESPECIAL		= 0x00002000,	// Actor executes its special when being 'used'.
294 	MF5_NOPAIN			= 0x00004000,	// If set the pain state won't be entered
295 	MF5_ALWAYSFAST		= 0x00008000,	// always uses 'fast' attacking logic
296 	MF5_NEVERFAST		= 0x00010000,	// never uses 'fast' attacking logic
297 	MF5_ALWAYSRESPAWN	= 0x00020000,	// always respawns, regardless of skill setting
298 	MF5_NEVERRESPAWN	= 0x00040000,	// never respawns, regardless of skill setting
299 	MF5_DONTRIP			= 0x00080000,	// Ripping projectiles explode when hitting this actor
300 	MF5_NOINFIGHTING	= 0x00100000,	// This actor doesn't switch target when it's hurt
301 	MF5_NOINTERACTION	= 0x00200000,	// Thing is completely excluded from any gameplay related checks
302 	MF5_NOTIMEFREEZE	= 0x00400000,	// Actor is not affected by time freezer
303 	MF5_PUFFGETSOWNER	= 0x00800000,	// [BB] Sets the owner of the puff to the player who fired it
304 	MF5_SPECIALFIREDAMAGE=0x01000000,	// Special treatment of PhoenixFX1 turned into a flag to remove
305 										// dependence of main engine code of specific actor types.
306 	MF5_SUMMONEDMONSTER	= 0x02000000,	// To mark the friendly Minotaur. Hopefully to be generalized later.
307 	MF5_NOVERTICALMELEERANGE=0x04000000,// Does not check vertical distance for melee range
308 	MF5_BRIGHT			= 0x08000000,	// Actor is always rendered fullbright
309 	MF5_CANTSEEK		= 0x10000000,	// seeker missiles cannot home in on this actor
310 	MF5_INCONVERSATION	= 0x20000000,	// Actor is having a conversation
311 	MF5_PAINLESS		= 0x40000000,	// Actor always inflicts painless damage.
312 	MF5_MOVEWITHSECTOR	= 0x80000000,	// P_ChangeSector() will still process this actor if it has MF_NOBLOCKMAP
313 };
314 
315 // --- mobj.flags6 ---
316 enum ActorFlag6
317 {
318 	MF6_NOBOSSRIP		= 0x00000001,	// For rippermissiles: Don't rip through bosses.
319 	MF6_THRUSPECIES		= 0x00000002,	// Actors passes through other of the same species.
320 	MF6_MTHRUSPECIES	= 0x00000004,	// Missile passes through actors of its shooter's species.
321 	MF6_FORCEPAIN		= 0x00000008,	// forces target into painstate (unless it has the NOPAIN flag)
322 	MF6_NOFEAR			= 0x00000010,	// Not scared of frightening players
323 	MF6_BUMPSPECIAL		= 0x00000020,	// Actor executes its special when being collided (as the ST flag)
324 	MF6_DONTHARMSPECIES = 0x00000040,	// Don't hurt one's own species with explosions (hitscans, too?)
325 	MF6_STEPMISSILE		= 0x00000080,	// Missile can "walk" up steps
326 	MF6_NOTELEFRAG		= 0x00000100,	// [HW] Actor can't be telefragged
327 	MF6_TOUCHY			= 0x00000200,	// From MBF: killough 11/98: dies when solids touch it
328 	MF6_CANJUMP			= 0x00000400,	// From MBF: a dedicated flag instead of the BOUNCES+FLOAT+sentient combo
329 	MF6_JUMPDOWN		= 0x00000800,	// From MBF: generalization of dog behavior wrt. dropoffs.
330 	MF6_VULNERABLE		= 0x00001000,	// Actor can be damaged (even if not shootable).
331 	MF6_ARMED			= 0x00002000,	// From MBF: Object is armed (for MF6_TOUCHY objects)
332 	MF6_FALLING			= 0x00004000,	// From MBF: Object is falling (for pseudotorque simulation)
333 	MF6_LINEDONE		= 0x00008000,	// From MBF: Object has already run a line effect
334 	MF6_NOTRIGGER		= 0x00010000,	// actor cannot trigger any line actions
335 	MF6_SHATTERING		= 0x00020000,	// marks an ice corpse for forced shattering
336 	MF6_KILLED			= 0x00040000,	// Something that was killed (but not necessarily a corpse)
337 	MF6_BLOCKEDBYSOLIDACTORS = 0x00080000, // Blocked by solid actors, even if not solid itself
338 	MF6_ADDITIVEPOISONDAMAGE	= 0x00100000,
339 	MF6_ADDITIVEPOISONDURATION	= 0x00200000,
340 	MF6_NOMENU			= 0x00400000,	// Player class should not appear in the class selection menu.
341 	MF6_BOSSCUBE		= 0x00800000,	// Actor spawned by A_BrainSpit, flagged for timefreeze reasons.
342 	MF6_SEEINVISIBLE	= 0x01000000,	// Monsters can see invisible player.
343 	MF6_DONTCORPSE		= 0x02000000,	// [RC] Don't autoset MF_CORPSE upon death and don't force Crash state change.
344 	MF6_POISONALWAYS	= 0x04000000,	// Always apply poison, even when target can't take the damage.
345 	MF6_DOHARMSPECIES	= 0x08000000,	// Do hurt one's own species with projectiles.
346 	MF6_INTRYMOVE		= 0x10000000,	// Executing P_TryMove
347 	MF6_NOTAUTOAIMED	= 0x20000000,	// Do not subject actor to player autoaim.
348 	MF6_NOTONAUTOMAP	= 0x40000000,	// will not be shown on automap with the 'scanner' powerup.
349 	MF6_RELATIVETOFLOOR	= 0x80000000,	// [RC] Make flying actors be affected by lifts.
350 };
351 
352 // --- mobj.flags7 ---
353 enum ActorFlag7
354 {
355 	MF7_NEVERTARGET		= 0x00000001,	// can not be targetted at all, even if monster friendliness is considered.
356 	MF7_NOTELESTOMP		= 0x00000002,	// cannot telefrag under any circumstances (even when set by MAPINFO)
357 	MF7_ALWAYSTELEFRAG	= 0x00000004,	// will unconditionally be telefragged when in the way. Overrides all other settings.
358 	MF7_HANDLENODELAY	= 0x00000008,	// respect NoDelay state flag
359 	MF7_WEAPONSPAWN		= 0x00000010,	// subject to DF_NO_COOP_WEAPON_SPAWN dmflag
360 	MF7_HARMFRIENDS		= 0x00000020,	// is allowed to harm friendly monsters.
361 	MF7_BUDDHA			= 0x00000040,	// Behaves just like the buddha cheat.
362 	MF7_FOILBUDDHA		= 0x00000080,	// Similar to FOILINVUL, foils buddha mode.
363 	MF7_DONTTHRUST		= 0x00000100,	// Thrusting functions do not take, and do not give thrust (damage) to actors with this flag.
364 	MF7_ALLOWPAIN		= 0x00000200,	// Invulnerable or immune (via damagefactors) actors can still react to taking damage even if they don't.
365 	MF7_CAUSEPAIN		= 0x00000400,	// Damage sources with this flag can cause similar effects like ALLOWPAIN.
366 	MF7_THRUREFLECT		= 0x00000800,	// Actors who are reflective cause the missiles to not slow down or change angles.
367 	MF7_MIRRORREFLECT	= 0x00001000,	// Actor is turned directly 180 degrees around when reflected.
368 	MF7_AIMREFLECT		= 0x00002000,	// Actor is directly reflected straight back at the one who fired the projectile.
369 	MF7_HITTARGET		= 0x00004000,	// The actor the projectile dies on is set to target, provided it's targetable anyway.
370 	MF7_HITMASTER		= 0x00008000,	// Same as HITTARGET, except it's master instead of target.
371 	MF7_HITTRACER		= 0x00010000,	// Same as HITTARGET, but for tracer.
372 	MF7_FLYCHEAT		= 0x00020000,	// must be part of the actor so that it can be tracked properly
373 	MF7_NODECAL			= 0x00040000,	// [ZK] Forces puff to have no impact decal
374 	MF7_FORCEDECAL		= 0x00080000,	// [ZK] Forces puff's decal to override the weapon's.
375 	MF7_LAXTELEFRAGDMG	= 0x00100000,	// [MC] Telefrag damage can be reduced.
376 	MF7_ICESHATTER		= 0x00200000,	// [MC] Shatters ice corpses regardless of damagetype.
377 };
378 
379 // --- mobj.renderflags ---
380 enum ActorRenderFlag
381 {
382 	RF_XFLIP			= 0x0001,	// Flip sprite horizontally
383 	RF_YFLIP			= 0x0002,	// Flip sprite vertically
384 	RF_ONESIDED			= 0x0004,	// Wall/floor sprite is visible from front only
385 	RF_FULLBRIGHT		= 0x0010,	// Sprite is drawn at full brightness
386 
387 	RF_RELMASK			= 0x0300,	// ---Relative z-coord for bound actors (these obey texture pegging)
388 	RF_RELABSOLUTE		= 0x0000,	// Actor z is absolute
389 	RF_RELUPPER			= 0x0100,	// Actor z is relative to upper part of wall
390 	RF_RELLOWER			= 0x0200,	// Actor z is relative to lower part of wall
391 	RF_RELMID			= 0x0300,	// Actor z is relative to middle part of wall
392 
393 	RF_CLIPMASK			= 0x0c00,	// ---Clipping for bound actors
394 	RF_CLIPFULL			= 0x0000,	// Clip sprite to full height of wall
395 	RF_CLIPUPPER		= 0x0400,	// Clip sprite to upper part of wall
396 	RF_CLIPMID			= 0x0800,	// Clip sprite to mid part of wall
397 	RF_CLIPLOWER		= 0x0c00,	// Clip sprite to lower part of wall
398 
399 	RF_DECALMASK		= RF_RELMASK|RF_CLIPMASK,
400 
401 	RF_SPRITETYPEMASK	= 0x7000,	// ---Different sprite types, not all implemented
402 	RF_FACESPRITE		= 0x0000,	// Face sprite
403 	RF_WALLSPRITE		= 0x1000,	// Wall sprite
404 	RF_FLOORSPRITE		= 0x2000,	// Floor sprite
405 	RF_VOXELSPRITE		= 0x3000,	// Voxel object
406 	RF_INVISIBLE		= 0x8000,	// Don't bother drawing this actor
407 
408 	RF_FORCEYBILLBOARD		= 0x10000,	// [BB] OpenGL only: draw with y axis billboard, i.e. anchored to the floor (overrides gl_billboard_mode setting)
409 	RF_FORCEXYBILLBOARD		= 0x20000,	// [BB] OpenGL only: draw with xy axis billboard, i.e. unanchored (overrides gl_billboard_mode setting)
410 };
411 
412 #define TRANSLUC25			(FRACUNIT/4)
413 #define TRANSLUC33			(FRACUNIT/3)
414 #define TRANSLUC50			(FRACUNIT/2)
415 #define TRANSLUC66			((FRACUNIT*2)/3)
416 #define TRANSLUC75			((FRACUNIT*3)/4)
417 
418 // <wingdi.h> also #defines OPAQUE
419 #ifndef OPAQUE
420 #define OPAQUE				(FRACUNIT)
421 #endif
422 
423 // This translucency value produces the closest match to Heretic's TINTTAB.
424 // ~40% of the value of the overlaid image shows through.
425 #define HR_SHADOW			(0x6800)
426 
427 // Hexen's TINTTAB is the same as Heretic's, just reversed.
428 #define HX_SHADOW			(0x9800)
429 #define HX_ALTSHADOW		(0x6800)
430 
431 // This could easily be a bool but then it'd be much harder to find later. ;)
432 enum replace_t
433 {
434 	NO_REPLACE = 0,
435 	ALLOW_REPLACE = 1
436 };
437 
438 enum ActorBounceFlag
439 {
440 	BOUNCE_Walls = 1<<0,		// bounces off of walls
441 	BOUNCE_Floors = 1<<1,		// bounces off of floors
442 	BOUNCE_Ceilings = 1<<2,		// bounces off of ceilings
443 	BOUNCE_Actors = 1<<3,		// bounces off of some actors
444 	BOUNCE_AllActors = 1<<4,	// bounces off of all actors (requires BOUNCE_Actors to be set, too)
445 	BOUNCE_AutoOff = 1<<5,		// when bouncing off a sector plane, if the new Z velocity is below 3.0, disable further bouncing
446 	BOUNCE_HereticType = 1<<6,	// goes into Death state when bouncing on floors or ceilings
447 
448 	BOUNCE_UseSeeSound = 1<<7,	// compatibility fallback. This will only be set by
449 								// the compatibility handlers for the old bounce flags.
450 	BOUNCE_NoWallSound = 1<<8,	// don't make noise when bouncing off a wall
451 	BOUNCE_Quiet = 1<<9,		// Strife's grenades don't make a bouncing sound
452 	BOUNCE_ExplodeOnWater = 1<<10,	// explodes when hitting a water surface
453 	BOUNCE_CanBounceWater = 1<<11,	// can bounce on water
454 	// MBF bouncing is a bit different from other modes as Killough coded many special behavioral cases
455 	// for them that are not present in ZDoom, so it is necessary to identify it properly.
456 	BOUNCE_MBF = 1<<12,			// This in itself is not a valid mode, but replaces MBF's MF_BOUNCE flag.
457 	BOUNCE_AutoOffFloorOnly = 1<<13,		// like BOUNCE_AutoOff, but only on floors
458 	BOUNCE_UseBounceState = 1<<14,	// Use Bounce[.*] states
459 
460 	BOUNCE_TypeMask = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors | BOUNCE_AutoOff | BOUNCE_HereticType | BOUNCE_MBF,
461 
462 	// The three "standard" types of bounciness are:
463 	// HERETIC - Missile will only bounce off the floor once and then enter
464 	//			 its death state. It does not bounce off walls at all.
465 	// HEXEN -	 Missile bounces off of walls and floors indefinitely.
466 	// DOOM -	 Like Hexen, but the bounce turns off if its vertical velocity
467 	//			 is too low.
468 	BOUNCE_None = 0,
469 	BOUNCE_Heretic = BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_HereticType,
470 	BOUNCE_Doom = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors | BOUNCE_AutoOff,
471 	BOUNCE_Hexen = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors,
472 	BOUNCE_Grenade = BOUNCE_MBF | BOUNCE_Doom,		// Bounces on walls and flats like ZDoom bounce.
473 	BOUNCE_Classic = BOUNCE_MBF | BOUNCE_Floors | BOUNCE_Ceilings,	// Bounces on flats only, but
474 																	// does not die when bouncing.
475 
476 	// combined types
477 	BOUNCE_DoomCompat = BOUNCE_Doom | BOUNCE_UseSeeSound,
478 	BOUNCE_HereticCompat = BOUNCE_Heretic | BOUNCE_UseSeeSound,
479 	BOUNCE_HexenCompat = BOUNCE_Hexen | BOUNCE_UseSeeSound
480 
481 	// The distinction between BOUNCE_Actors and BOUNCE_AllActors: A missile with
482 	// BOUNCE_Actors set will bounce off of reflective and "non-sentient" actors.
483 	// A missile that also has BOUNCE_AllActors set will bounce off of any actor.
484 	// For compatibility reasons when BOUNCE_Actors was implied by the bounce type
485 	// being "Doom" or "Hexen" and BOUNCE_AllActors was the separate
486 	// MF5_BOUNCEONACTORS, you must set BOUNCE_Actors for BOUNCE_AllActors to have
487 	// an effect.
488 
489 
490 };
491 
492 // [TP] Flagset definitions
493 typedef TFlags<ActorFlag> ActorFlags;
494 typedef TFlags<ActorFlag2> ActorFlags2;
495 typedef TFlags<ActorFlag3> ActorFlags3;
496 typedef TFlags<ActorFlag4> ActorFlags4;
497 typedef TFlags<ActorFlag5> ActorFlags5;
498 typedef TFlags<ActorFlag6> ActorFlags6;
499 typedef TFlags<ActorFlag7> ActorFlags7;
500 typedef TFlags<ActorRenderFlag> ActorRenderFlags;
501 typedef TFlags<ActorBounceFlag, WORD> ActorBounceFlags;
502 DEFINE_TFLAGS_OPERATORS (ActorFlags)
503 DEFINE_TFLAGS_OPERATORS (ActorFlags2)
504 DEFINE_TFLAGS_OPERATORS (ActorFlags3)
505 DEFINE_TFLAGS_OPERATORS (ActorFlags4)
506 DEFINE_TFLAGS_OPERATORS (ActorFlags5)
507 DEFINE_TFLAGS_OPERATORS (ActorFlags6)
508 DEFINE_TFLAGS_OPERATORS (ActorFlags7)
509 DEFINE_TFLAGS_OPERATORS (ActorRenderFlags)
510 DEFINE_TFLAGS_OPERATORS (ActorBounceFlags)
511 
512 // Used to affect the logic for thing activation through death, USESPECIAL and BUMPSPECIAL
513 // "thing" refers to what has the flag and the special, "trigger" refers to what used or bumped it
514 enum EThingSpecialActivationType
515 {
516 	THINGSPEC_Default			= 0,		// Normal behavior: a player must be the trigger, and is the activator
517 	THINGSPEC_ThingActs			= 1,		// The thing itself is the activator of the special
518 	THINGSPEC_ThingTargets		= 1<<1,		// The thing changes its target to the trigger
519 	THINGSPEC_TriggerTargets	= 1<<2,		// The trigger changes its target to the thing
520 	THINGSPEC_MonsterTrigger	= 1<<3,		// The thing can be triggered by a monster
521 	THINGSPEC_MissileTrigger	= 1<<4,		// The thing can be triggered by a projectile
522 	THINGSPEC_ClearSpecial		= 1<<5,		// Clears special after successful activation
523 	THINGSPEC_NoDeathSpecial	= 1<<6,		// Don't activate special on death
524 	THINGSPEC_TriggerActs		= 1<<7,		// The trigger is the activator of the special
525 											// (overrides LEVEL_ACTOWNSPECIAL Hexen hack)
526 	THINGSPEC_Activate			= 1<<8,		// The thing is activated when triggered
527 	THINGSPEC_Deactivate		= 1<<9,		// The thing is deactivated when triggered
528 	THINGSPEC_Switch			= 1<<10,	// The thing is alternatively activated and deactivated when triggered
529 };
530 
531 // [RH] Like msecnode_t, but for the blockmap
532 struct FBlockNode
533 {
534 	AActor *Me;						// actor this node references
535 	int BlockIndex;					// index into blocklinks for the block this node is in
536 	FBlockNode **PrevActor;			// previous actor in this block
537 	FBlockNode *NextActor;			// next actor in this block
538 	FBlockNode **PrevBlock;			// previous block this actor is in
539 	FBlockNode *NextBlock;			// next block this actor is in
540 
541 	static FBlockNode *Create (AActor *who, int x, int y);
542 	void Release ();
543 
544 	static FBlockNode *FreeBlocks;
545 };
546 
547 class FDecalBase;
548 class AInventory;
549 
GetDefaultByName(const char * name)550 inline AActor *GetDefaultByName (const char *name)
551 {
552 	return (AActor *)(PClass::FindClass(name)->Defaults);
553 }
554 
GetDefaultByType(const PClass * type)555 inline AActor *GetDefaultByType (const PClass *type)
556 {
557 	return (AActor *)(type->Defaults);
558 }
559 
560 template<class T>
GetDefault()561 inline T *GetDefault ()
562 {
563 	return (T *)(RUNTIME_CLASS(T)->Defaults);
564 }
565 
566 struct line_t;
567 struct secplane_t;
568 struct FStrifeDialogueNode;
569 
570 enum
571 {
572 	AMETA_BASE = 0x12000,
573 
574 	AMETA_Obituary,			// string (player was killed by this actor)
575 	AMETA_HitObituary,		// string (player was killed by this actor in melee)
576 	AMETA_DeathHeight,		// fixed (height on normal death)
577 	AMETA_BurnHeight,		// fixed (height on burning death)
578 	AMETA_StrifeName,		// string (for named Strife objects)
579 	AMETA_BloodColor,		// colorized blood
580 	AMETA_GibHealth,		// negative health below which this monster dies an extreme death
581 	AMETA_WoundHealth,		// health needed to enter wound state
582 	AMETA_FastSpeed,		// Speed in fast mode
583 	AMETA_RDFactor,			// Radius damage factor
584 	AMETA_CameraHeight,		// Height of camera when used as such
585 	AMETA_HowlSound,		// Sound being played when electrocuted or poisoned
586 	AMETA_BloodType,		// Blood replacement type
587 	AMETA_BloodType2,		// Bloodsplatter replacement type
588 	AMETA_BloodType3,		// AxeBlood replacement type
589 };
590 
591 struct fixedvec3
592 {
593 	fixed_t x, y, z;
594 };
595 
596 struct fixedvec2
597 {
598 	fixed_t x, y;
599 };
600 
601 struct FDropItem
602 {
603 	FName Name;
604 	int probability;
605 	int amount;
606 	FDropItem * Next;
607 };
608 
609 class FDropItemPtrArray : public TArray<FDropItem *>
610 {
611 public:
~FDropItemPtrArray()612 	~FDropItemPtrArray()
613 	{
614 		Clear();
615 	}
616 
617 	void Clear();
618 };
619 
620 extern FDropItemPtrArray DropItemList;
621 
622 void FreeDropItemChain(FDropItem *chain);
623 int StoreDropItemChain(FDropItem *chain);
624 fixed_t P_AproxDistance (fixed_t dx, fixed_t dy);	// since we cannot include p_local here...
625 angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2); // same reason here with r_defs.h
626 
627 
628 // Map Object definition.
629 class AActor : public DThinker
630 {
631 	DECLARE_CLASS (AActor, DThinker)
632 	HAS_OBJECT_POINTERS
633 public:
634 	AActor () throw();
635 	AActor (const AActor &other) throw();
636 	AActor &operator= (const AActor &other);
637 	void Destroy ();
638 	~AActor ();
639 
640 	void Serialize (FArchive &arc);
641 
642 	static AActor *StaticSpawn (const PClass *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement, bool SpawningMapThing = false);
643 
GetDefault()644 	inline AActor *GetDefault () const
645 	{
646 		return (AActor *)(RUNTIME_TYPE(this)->Defaults);
647 	}
648 
649 	FDropItem *GetDropItems();
650 
651 	// Return true if the monster should use a missile attack, false for melee
652 	bool SuggestMissileAttack (fixed_t dist);
653 
654 	// Adjusts the angle for deflection/reflection of incoming missiles
655 	// Returns true if the missile should be allowed to explode anyway
656 	bool AdjustReflectionAngle (AActor *thing, angle_t &angle);
657 
658 	// Returns true if this actor is within melee range of its target
659 	bool CheckMeleeRange();
660 
661 	virtual void BeginPlay();			// Called immediately after the actor is created
662 	virtual void PostBeginPlay();		// Called immediately before the actor's first tick
663 	virtual void LevelSpawned();		// Called after BeginPlay if this actor was spawned by the world
664 	virtual void HandleSpawnFlags();	// Translates SpawnFlags into in-game flags.
665 
666 	virtual void MarkPrecacheSounds() const;	// Marks sounds used by this actor for precaching.
667 
668 	virtual void Activate (AActor *activator);
669 	virtual void Deactivate (AActor *activator);
670 
671 	virtual void Tick ();
672 
673 	// Called when actor dies
674 	virtual void Die (AActor *source, AActor *inflictor, int dmgflags = 0);
675 
676 	// Perform some special damage action. Returns the amount of damage to do.
677 	// Returning -1 signals the damage routine to exit immediately
678 	virtual int DoSpecialDamage (AActor *target, int damage, FName damagetype);
679 
680 	// Like DoSpecialDamage, but called on the actor receiving the damage.
681 	virtual int TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FName damagetype);
682 
683 	// Centaurs and ettins squeal when electrocuted, poisoned, or "holy"-ed
684 	// Made a metadata property so no longer virtual
685 	void Howl ();
686 
687 	// Actor just hit the floor
688 	virtual void HitFloor ();
689 
690 	// plays bouncing sound
691 	void PlayBounceSound(bool onfloor);
692 
693 	// Called when an actor with MF_MISSILE and MF2_FLOORBOUNCE hits the floor
694 	virtual bool FloorBounceMissile (secplane_t &plane);
695 
696 	// Called when an actor is to be reflected by a disc of repulsion.
697 	// Returns true to continue normal blast processing.
698 	virtual bool SpecialBlastHandling (AActor *source, fixed_t strength);
699 
700 	// Called by RoughBlockCheck
701 	bool IsOkayToAttack (AActor *target);
702 
703 	// Plays the actor's ActiveSound if its voice isn't already making noise.
704 	void PlayActiveSound ();
705 
706 	// Actor had MF_SKULLFLY set and rammed into something
707 	// Returns false to stop moving and true to keep moving
708 	virtual bool Slam (AActor *victim);
709 
710 	// Called by PIT_CheckThing() and needed for some Hexen things.
711 	// Returns -1 for normal behavior, 0 to return false, and 1 to return true.
712 	// I'm not sure I like it this way, but it will do for now.
713 	virtual int SpecialMissileHit (AActor *victim);
714 
715 	// Returns true if it's okay to switch target to "other" after being attacked by it.
716 	virtual bool OkayToSwitchTarget (AActor *other);
717 
718 	// Something just touched this actor.
719 	virtual void Touch (AActor *toucher);
720 
721 	// Adds the item to this actor's inventory and sets its Owner.
722 	virtual void AddInventory (AInventory *item);
723 
724 	// Removes the item from the inventory list.
725 	virtual void RemoveInventory (AInventory *item);
726 
727 	// Take the amount value of an item from the inventory list.
728 	// If nothing is left, the item may be destroyed.
729 	// Returns true if the initial item count is positive.
730 	virtual bool TakeInventory (const PClass *itemclass, int amount, bool fromdecorate = false, bool notakeinfinite = false);
731 
732 	// Uses an item and removes it from the inventory.
733 	virtual bool UseInventory (AInventory *item);
734 
735 	// Tosses an item out of the inventory.
736 	virtual AInventory *DropInventory (AInventory *item);
737 
738 	// Removes all items from the inventory.
739 	void ClearInventory();
740 
741 	// Returns true if this view is considered "local" for the player.
742 	bool CheckLocalView (int playernum) const;
743 
744 	// Finds the first item of a particular type.
745 	AInventory *FindInventory (const PClass *type, bool subclass = false);
746 	AInventory *FindInventory (FName type);
FindInventory()747 	template<class T> T *FindInventory ()
748 	{
749 		return static_cast<T *> (FindInventory (RUNTIME_CLASS(T)));
750 	}
751 
752 	// Adds one item of a particular type. Returns NULL if it could not be added.
753 	AInventory *GiveInventoryType (const PClass *type);
754 
755 	// Returns the first item held with IF_INVBAR set.
756 	AInventory *FirstInv ();
757 
758 	// Tries to give the actor some ammo.
759 	bool GiveAmmo (const PClass *type, int amount);
760 
761 	// Destroys all the inventory the actor is holding.
762 	void DestroyAllInventory ();
763 
764 	// Set the alphacolor field properly
765 	void SetShade (DWORD rgb);
766 	void SetShade (int r, int g, int b);
767 
768 	// Plays a conversation animation
769 	void ConversationAnimation (int animnum);
770 
771 	// Make this actor hate the same things as another actor
772 	void CopyFriendliness (AActor *other, bool changeTarget, bool resetHealth=true);
773 
774 	// Moves the other actor's inventory to this one
775 	void ObtainInventory (AActor *other);
776 
777 	// Die. Now.
778 	virtual bool Massacre ();
779 
780 	// Transforms the actor into a finely-ground paste
781 	virtual bool Grind(bool items);
782 
783 	// Get this actor's team
784 	int GetTeam();
785 
786 	// Is the other actor on my team?
787 	bool IsTeammate (AActor *other);
788 
789 	// Is the other actor my friend?
790 	bool IsFriend (AActor *other);
791 
792 	// Do I hate the other actor?
793 	bool IsHostile (AActor *other);
794 
795 	inline bool IsNoClip2() const;
796 
797 	// What species am I?
798 	virtual FName GetSpecies();
799 
800 	fixed_t GetBobOffset(fixed_t ticfrac=0) const
801 	{
802 		 if (!(flags2 & MF2_FLOATBOB))
803 		 {
804 			 return 0;
805 		 }
806 		 return finesine[MulScale22(((FloatBobPhase + level.maptime) << FRACBITS) + ticfrac, FINEANGLES) & FINEMASK] * 8;
807 	}
808 
809 	// Enter the crash state
810 	void Crash();
811 
812 	// Return starting health adjusted by skill level
813 	int SpawnHealth();
814 	int GibHealth();
815 
816 	inline bool isMissile(bool precise=true)
817 	{
818 		return (flags&MF_MISSILE) || (precise && GetDefault()->flags&MF_MISSILE);
819 	}
820 
821 	// Check for monsters that count as kill but excludes all friendlies.
CountsAsKill()822 	bool CountsAsKill() const
823 	{
824 		return (flags & MF_COUNTKILL) && !(flags & MF_FRIENDLY);
825 	}
826 
GetBloodColor()827 	PalEntry GetBloodColor() const
828 	{
829 		return (PalEntry)GetClass()->Meta.GetMetaInt(AMETA_BloodColor);
830 	}
831 
832 	// These also set CF_INTERPVIEW for players.
833 	void SetPitch(int p, bool interpolate, bool forceclamp = false);
834 	void SetAngle(angle_t ang, bool interpolate);
835 	void SetRoll(angle_t roll, bool interpolate);
836 
837 	const PClass *GetBloodType(int type = 0) const
838 	{
839 		const PClass *bloodcls;
840 		if (type == 0)
841 		{
842 			bloodcls = PClass::FindClass((ENamedName)GetClass()->Meta.GetMetaInt(AMETA_BloodType, NAME_Blood));
843 		}
844 		else if (type == 1)
845 		{
846 			bloodcls = PClass::FindClass((ENamedName)GetClass()->Meta.GetMetaInt(AMETA_BloodType2, NAME_BloodSplatter));
847 		}
848 		else if (type == 2)
849 		{
850 			bloodcls = PClass::FindClass((ENamedName)GetClass()->Meta.GetMetaInt(AMETA_BloodType3, NAME_AxeBlood));
851 		}
852 		else return NULL;
853 
854 		if (bloodcls != NULL)
855 		{
856 			bloodcls = bloodcls->GetReplacement();
857 		}
858 		return bloodcls;
859 	}
860 
intersects(AActor * other)861 	bool intersects(AActor *other) const
862 	{
863 		fixed_t blockdist = radius + other->radius;
864 		return ( abs(X() - other->X()) < blockdist && abs(Y() - other->Y()) < blockdist);
865 	}
866 
867 	// 'absolute' is reserved for a linked portal implementation which needs
868 	// to distinguish between portal-aware and portal-unaware distance calculation.
869 	fixed_t AproxDistance(AActor *other, bool absolute = false)
870 	{
871 		return P_AproxDistance(X() - other->X(), Y() - other->Y());
872 	}
873 
874 	// same with 'ref' here.
875 	fixed_t AproxDistance(fixed_t otherx, fixed_t othery, AActor *ref = NULL)
876 	{
877 		return P_AproxDistance(X() - otherx, Y() - othery);
878 	}
879 
880 	fixed_t AproxDistance(AActor *other, fixed_t xadd, fixed_t yadd, bool absolute = false)
881 	{
882 		return P_AproxDistance(X() - other->X() + xadd, Y() - other->Y() + yadd);
883 	}
884 
885 	fixed_t AproxDistance3D(AActor *other, bool absolute = false)
886 	{
887 		return P_AproxDistance(AproxDistance(other), Z() - other->Z());
888 	}
889 
890 	// more precise, but slower version, being used in a few places
891 	fixed_t Distance2D(AActor *other, bool absolute = false)
892 	{
893 		return xs_RoundToInt(FVector2(X() - other->X(), Y() - other->Y()).Length());
894 	}
895 
896 	// a full 3D version of the above
897 	fixed_t Distance3D(AActor *other, bool absolute = false)
898 	{
899 		return xs_RoundToInt(FVector3(X() - other->X(), Y() - other->Y(), Z() - other->Z()).Length());
900 	}
901 
902 	angle_t AngleTo(AActor *other, bool absolute = false) const
903 	{
904 		return R_PointToAngle2(X(), Y(), other->X(), other->Y());
905 	}
906 
907 	angle_t AngleTo(AActor *other, fixed_t oxofs, fixed_t oyofs, bool absolute = false) const
908 	{
909 		return R_PointToAngle2(X(), Y(), other->X() + oxofs, other->Y() + oyofs);
910 	}
911 
912 	fixed_t AngleTo(fixed_t otherx, fixed_t othery, AActor *ref = NULL)
913 	{
914 		return R_PointToAngle2(X(), Y(), otherx, othery);
915 	}
916 
917 	fixed_t AngleXYTo(fixed_t myx, fixed_t myy, AActor *other, bool absolute = false)
918 	{
919 		return R_PointToAngle2(myx, myy, other->X(), other->Y());
920 	}
921 
Vec2To(AActor * other)922 	fixedvec2 Vec2To(AActor *other) const
923 	{
924 		fixedvec2 ret = { other->X() - X(), other->Y() - Y() };
925 		return ret;
926 	}
927 
Vec3To(AActor * other)928 	fixedvec3 Vec3To(AActor *other) const
929 	{
930 		fixedvec3 ret = { other->X() - X(), other->Y() - Y(), other->Z() - Z() };
931 		return ret;
932 	}
933 
934 	fixedvec2 Vec2Offset(fixed_t dx, fixed_t dy, bool absolute = false) const
935 	{
936 		fixedvec2 ret = { X() + dx, Y() + dy };
937 		return ret;
938 	}
939 
940 
941 	fixedvec2 Vec2Angle(fixed_t length, angle_t angle, bool absolute = false) const
942 	{
943 		fixedvec2 ret = { X() + FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]),
944 						  Y() + FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]) };
945 		return ret;
946 	}
947 
948 	fixedvec3 Vec3Offset(fixed_t dx, fixed_t dy, fixed_t dz, bool absolute = false) const
949 	{
950 		fixedvec3 ret = { X() + dx, Y() + dy, Z() + dz };
951 		return ret;
952 	}
953 
954 	fixedvec3 Vec3Angle(fixed_t length, angle_t angle, fixed_t dz, bool absolute = false) const
955 	{
956 		fixedvec3 ret = { X() + FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]),
957 						  Y() + FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]), Z() + dz };
958 		return ret;
959 	}
960 
Move(fixed_t dx,fixed_t dy,fixed_t dz)961 	void Move(fixed_t dx, fixed_t dy, fixed_t dz)
962 	{
963 		SetOrigin(X() + dx, Y() + dy, Z() + dz, true);
964 	}
965 
SetOrigin(const fixedvec3 & npos,bool moving)966 	void SetOrigin(const fixedvec3 & npos, bool moving)
967 	{
968 		SetOrigin(npos.x, npos.y, npos.z, moving);
969 	}
970 
971 	inline void SetFriendPlayer(player_t *player);
972 
973 	bool IsVisibleToPlayer() const;
974 
975 	// Calculate amount of missile damage
976 	virtual int GetMissileDamage(int mask, int add);
977 
978 	bool CanSeek(AActor *target) const;
979 
980 	fixed_t GetGravity() const;
981 	bool IsSentient() const;
982 	const char *GetTag(const char *def = NULL) const;
983 	void SetTag(const char *def);
984 
985 	// Triggers SECSPAC_Exit/SECSPAC_Enter and related events if oldsec != current sector
986 	void CheckSectorTransition(sector_t *oldsec);
987 
988 // info for drawing
989 // NOTE: The first member variable *must* be snext.
990 	AActor			*snext, **sprev;	// links in sector (if needed)
991 	fixedvec3		__pos;				// double underscores so that it won't get used by accident. Access to this should be exclusively through the designated access functions.
992 
993 	angle_t			angle;
994 	WORD			sprite;				// used to find patch_t and flip value
995 	BYTE			frame;				// sprite frame to draw
996 	fixed_t			scaleX, scaleY;		// Scaling values; FRACUNIT is normal size
997 	FRenderStyle	RenderStyle;		// Style to draw this actor with
998 	ActorRenderFlags	renderflags;		// Different rendering flags
999 	FTextureID		picnum;				// Draw this instead of sprite if valid
1000 	DWORD			effects;			// [RH] see p_effect.h
1001 	fixed_t			alpha;
1002 	DWORD			fillcolor;			// Color to draw when STYLE_Shaded
1003 
1004 // interaction info
1005 	fixed_t			pitch;
1006 	angle_t			roll;	// This was fixed_t before, which is probably wrong
1007 	FBlockNode		*BlockNode;			// links in blocks (if needed)
1008 	struct sector_t	*Sector;
1009 	subsector_t *		subsector;
1010 	fixed_t			floorz, ceilingz;	// closest together of contacted secs
1011 	fixed_t			dropoffz;		// killough 11/98: the lowest floor over all contacted Sectors.
1012 
1013 	struct sector_t	*floorsector;
1014 	FTextureID		floorpic;			// contacted sec floorpic
1015 	int				floorterrain;
1016 	struct sector_t	*ceilingsector;
1017 	FTextureID		ceilingpic;			// contacted sec ceilingpic
1018 	fixed_t			radius, height;		// for movement checking
1019 	fixed_t			projectilepassheight;	// height for clipping projectile movement against this actor
1020 	fixed_t			velx, vely, velz;	// velocity
1021 	SDWORD			tics;				// state tic counter
1022 	FState			*state;
1023 	SDWORD			Damage;			// For missiles and monster railgun
1024 	int				projectileKickback;
1025 	ActorFlags		flags;
1026 	ActorFlags2		flags2;			// Heretic flags
1027 	ActorFlags3		flags3;			// [RH] Hexen/Heretic actor-dependant behavior made flaggable
1028 	ActorFlags4		flags4;			// [RH] Even more flags!
1029 	ActorFlags5		flags5;			// OMG! We need another one.
1030 	ActorFlags6		flags6;			// Shit! Where did all the flags go?
1031 	ActorFlags7		flags7;			// WHO WANTS TO BET ON 8!?
1032 
1033 	// [BB] If 0, everybody can see the actor, if > 0, only members of team (VisibleToTeam-1) can see it.
1034 	DWORD			VisibleToTeam;
1035 
1036 	int				special1;		// Special info
1037 	int				special2;		// Special info
1038 	int				weaponspecial;	// Special info for weapons.
1039 	int 			health;
1040 	BYTE			movedir;		// 0-7
1041 	SBYTE			visdir;
1042 	SWORD			movecount;		// when 0, select a new dir
1043 	SWORD			strafecount;	// for MF3_AVOIDMELEE
1044 	TObjPtr<AActor> target;			// thing being chased/attacked (or NULL)
1045 									// also the originator for missiles
1046 	TObjPtr<AActor>	lastenemy;		// Last known enemy -- killough 2/15/98
1047 	TObjPtr<AActor> LastHeard;		// [RH] Last actor this one heard
1048 	SDWORD			reactiontime;	// if non 0, don't attack yet; used by
1049 									// player to freeze a bit after teleporting
1050 	SDWORD			threshold;		// if > 0, the target will be chased
1051 									// no matter what (even if shot)
1052 	player_t		*player;		// only valid if type of APlayerPawn
1053 	TObjPtr<AActor>	LastLookActor;	// Actor last looked for (if TIDtoHate != 0)
1054 	fixed_t			SpawnPoint[3]; 	// For nightmare respawn
1055 	WORD			SpawnAngle;
1056 	int				StartHealth;
1057 	BYTE			WeaveIndexXY;	// Separated from special2 because it's used by globally accessible functions.
1058 	BYTE			WeaveIndexZ;
1059 	int				skillrespawncount;
1060 	int				TIDtoHate;			// TID of things to hate (0 if none)
1061 	FNameNoInit		Species;		// For monster families
1062 	TObjPtr<AActor>	tracer;			// Thing being chased/attacked for tracers
1063 	TObjPtr<AActor>	master;			// Thing which spawned this one (prevents mutual attacks)
1064 	fixed_t			floorclip;		// value to use for floor clipping
1065 	int				tid;			// thing identifier
1066 	int				special;		// special
1067 	int				args[5];		// special arguments
1068 
1069 	int		accuracy, stamina;		// [RH] Strife stats -- [XA] moved here for DECORATE/ACS access.
1070 
1071 	AActor			*inext, **iprev;// Links to other mobjs in same bucket
1072 	TObjPtr<AActor> goal;			// Monster's goal if not chasing anything
1073 	int				waterlevel;		// 0=none, 1=feet, 2=waist, 3=eyes
1074 	BYTE			boomwaterlevel;	// splash information for non-swimmable water sectors
1075 	BYTE			MinMissileChance;// [RH] If a random # is > than this, then missile attack.
1076 	SBYTE			LastLookPlayerNumber;// Player number last looked for (if TIDtoHate == 0)
1077 	ActorBounceFlags	BounceFlags;	// which bouncing type?
1078 	DWORD			SpawnFlags;		// Increased to DWORD because of Doom 64
1079 	fixed_t			meleerange;		// specifies how far a melee attack reaches.
1080 	fixed_t			meleethreshold;	// Distance below which a monster doesn't try to shoot missiles anynore
1081 									// but instead tries to come closer for a melee attack.
1082 									// This is not the same as meleerange
1083 	fixed_t			maxtargetrange;	// any target farther away cannot be attacked
1084 	fixed_t			bouncefactor;	// Strife's grenades use 50%, Hexen's Flechettes 70.
1085 	fixed_t			wallbouncefactor;	// The bounce factor for walls can be different.
1086 	int				bouncecount;	// Strife's grenades only bounce twice before exploding
1087 	fixed_t			gravity;		// [GRB] Gravity factor
1088 	fixed_t			Friction;
1089 	int 			FastChaseStrafeCount;
1090 	fixed_t			pushfactor;
1091 	int				lastpush;
1092 	int				activationtype;	// How the thing behaves when activated with USESPECIAL or BUMPSPECIAL
1093 	int				lastbump;		// Last time the actor was bumped, used to control BUMPSPECIAL
1094 	int				Score;			// manipulated by score items, ACS or DECORATE. The engine doesn't use this itself for anything.
1095 	FString *		Tag;			// Strife's tag name.
1096 	int				DesignatedTeam;	// Allow for friendly fire cacluations to be done on non-players.
1097 
1098 	AActor			*BlockingMobj;	// Actor that blocked the last move
1099 	line_t			*BlockingLine;	// Line that blocked the last move
1100 
1101 	int PoisonDamage; // Damage received per tic from poison.
1102 	FNameNoInit PoisonDamageType; // Damage type dealt by poison.
1103 	int PoisonDuration; // Duration left for receiving poison damage.
1104 	int PoisonPeriod; // How often poison damage is applied. (Every X tics.)
1105 
1106 	int PoisonDamageReceived; // Damage received per tic from poison.
1107 	FNameNoInit PoisonDamageTypeReceived; // Damage type received by poison.
1108 	int PoisonDurationReceived; // Duration left for receiving poison damage.
1109 	int PoisonPeriodReceived; // How often poison damage is applied. (Every X tics.)
1110 	TObjPtr<AActor> Poisoner; // Last source of received poison damage.
1111 
1112 	// a linked list of sectors where this object appears
1113 	struct msecnode_t	*touching_sectorlist;				// phares 3/14/98
1114 
1115 	TObjPtr<AInventory>	Inventory;		// [RH] This actor's inventory
1116 	DWORD			InventoryID;	// A unique ID to keep track of inventory items
1117 
1118 	BYTE smokecounter;
1119 	BYTE FloatBobPhase;
1120 	BYTE FriendPlayer;				// [RH] Player # + 1 this friendly monster works for (so 0 is no player, 1 is player 0, etc)
1121 	DWORD Translation;
1122 
1123 	// [RH] Stuff that used to be part of an Actor Info
1124 	FSoundIDNoInit SeeSound;
1125 	FSoundIDNoInit AttackSound;
1126 	FSoundIDNoInit PainSound;
1127 	FSoundIDNoInit DeathSound;
1128 	FSoundIDNoInit ActiveSound;
1129 	FSoundIDNoInit UseSound;		// [RH] Sound to play when an actor is used.
1130 	FSoundIDNoInit BounceSound;
1131 	FSoundIDNoInit WallBounceSound;
1132 	FSoundIDNoInit CrushPainSound;
1133 
1134 	fixed_t Speed;
1135 	fixed_t FloatSpeed;
1136 	fixed_t MaxDropOffHeight, MaxStepHeight;
1137 	SDWORD Mass;
1138 	SWORD PainChance;
1139 	int PainThreshold;
1140 	FNameNoInit DamageType;
1141 	FNameNoInit DamageTypeReceived;
1142 	fixed_t DamageFactor;
1143 	fixed_t DamageMultiply;
1144 
1145 	FNameNoInit PainType;
1146 	FNameNoInit DeathType;
1147 	const PClass *TeleFogSourceType;
1148 	const PClass *TeleFogDestType;
1149 	int RipperLevel;
1150 	int RipLevelMin;
1151 	int RipLevelMax;
1152 
1153 	FState *SpawnState;
1154 	FState *SeeState;
1155 	FState *MeleeState;
1156 	FState *MissileState;
1157 
1158 
1159 	int ConversationRoot;				// THe root of the current dialogue
1160 	FStrifeDialogueNode *Conversation;	// [RH] The dialogue to show when this actor is "used."
1161 
1162 	// [RH] Decal(s) this weapon/projectile generates on impact.
1163 	FDecalBase *DecalGenerator;
1164 
1165 	// [RH] Used to interpolate the view to get >35 FPS
1166 	fixed_t PrevX, PrevY, PrevZ;
1167 	angle_t PrevAngle;
1168 
1169 	// ThingIDs
1170 	static void ClearTIDHashes ();
1171 	void AddToHash ();
1172 	void RemoveFromHash ();
1173 
1174 private:
1175 	static AActor *TIDHash[128];
TIDHASH(int key)1176 	static inline int TIDHASH (int key) { return key & 127; }
1177 	static FSharedStringArena mStringPropertyData;
1178 
1179 	friend class FActorIterator;
1180 	friend bool P_IsTIDUsed(int tid);
1181 
1182 	sector_t *LinkToWorldForMapThing ();
1183 
1184 public:
1185 	void LinkToWorld (bool buggy=false);
1186 	void LinkToWorld (sector_t *sector);
1187 	void UnlinkFromWorld ();
1188 	void AdjustFloorClip ();
1189 	void SetOrigin (fixed_t x, fixed_t y, fixed_t z, bool moving = false);
1190 	bool InStateSequence(FState * newstate, FState * basestate);
1191 	int GetTics(FState * newstate);
1192 	bool SetState (FState *newstate, bool nofunction=false);
1193 	virtual bool UpdateWaterLevel (fixed_t oldz, bool splash=true);
1194 	bool isFast();
1195 	bool isSlow();
1196 	void SetIdle(bool nofunction=false);
1197 	void ClearCounters();
1198 	FState *GetRaiseState();
1199 	void Revive();
1200 
FindState(FName label)1201 	FState *FindState (FName label) const
1202 	{
1203 		return GetClass()->ActorInfo->FindState(1, &label);
1204 	}
1205 
1206 	FState *FindState (FName label, FName sublabel, bool exact = false) const
1207 	{
1208 		FName names[] = { label, sublabel };
1209 		return GetClass()->ActorInfo->FindState(2, names, exact);
1210 	}
1211 
1212 	FState *FindState(int numnames, FName *names, bool exact = false) const
1213 	{
1214 		return GetClass()->ActorInfo->FindState(numnames, names, exact);
1215 	}
1216 
1217 	bool HasSpecialDeathStates () const;
1218 
X()1219 	fixed_t X() const
1220 	{
1221 		return __pos.x;
1222 	}
Y()1223 	fixed_t Y() const
1224 	{
1225 		return __pos.y;
1226 	}
Z()1227 	fixed_t Z() const
1228 	{
1229 		return __pos.z;
1230 	}
Pos()1231 	fixedvec3 Pos() const
1232 	{
1233 		fixedvec3 ret = { X(), Y(), Z() };
1234 		return ret;
1235 	}
PosRelative(AActor * other)1236 	fixedvec3 PosRelative(AActor *other) const
1237 	{
1238 		fixedvec3 ret = { X(), Y(), Z() };
1239 		return ret;
1240 	}
PosRelative(sector_t * sec)1241 	fixedvec3 PosRelative(sector_t *sec) const
1242 	{
1243 		fixedvec3 ret = { X(), Y(), Z() };
1244 		return ret;
1245 	}
PosRelative(line_t * line)1246 	fixedvec3 PosRelative(line_t *line) const
1247 	{
1248 		fixedvec3 ret = { X(), Y(), Z() };
1249 		return ret;
1250 	}
SoundX()1251 	fixed_t SoundX() const
1252 	{
1253 		return X();
1254 	}
SoundY()1255 	fixed_t SoundY() const
1256 	{
1257 		return Y();
1258 	}
SoundZ()1259 	fixed_t SoundZ() const
1260 	{
1261 		return Z();
1262 	}
InterpolatedPosition(fixed_t ticFrac)1263 	fixedvec3 InterpolatedPosition(fixed_t ticFrac) const
1264 	{
1265 		fixedvec3 ret;
1266 
1267 		ret.x = PrevX + FixedMul (ticFrac, X() - PrevX);
1268 		ret.y = PrevY + FixedMul (ticFrac, Y() - PrevY);
1269 		ret.z = PrevZ + FixedMul (ticFrac, Z() - PrevZ);
1270 		return ret;
1271 	}
PosPlusZ(fixed_t zadd)1272 	fixedvec3 PosPlusZ(fixed_t zadd) const
1273 	{
1274 		fixedvec3 ret = { X(), Y(), Z() + zadd };
1275 		return ret;
1276 	}
Top()1277 	fixed_t Top() const
1278 	{
1279 		return Z() + height;
1280 	}
1281 	void SetZ(fixed_t newz, bool moving = true)
1282 	{
1283 		__pos.z = newz;
1284 	}
1285 	void AddZ(fixed_t newz, bool moving = true)
1286 	{
1287 		__pos.z += newz;
1288 	}
1289 
1290 	// These are not for general use as they do not link the actor into the world!
SetXY(fixed_t xx,fixed_t yy)1291 	void SetXY(fixed_t xx, fixed_t yy)
1292 	{
1293 		__pos.x = xx;
1294 		__pos.y = yy;
1295 	}
SetXYZ(fixed_t xx,fixed_t yy,fixed_t zz)1296 	void SetXYZ(fixed_t xx, fixed_t yy, fixed_t zz)
1297 	{
1298 		__pos.x = xx;
1299 		__pos.y = yy;
1300 		__pos.z = zz;
1301 	}
SetXY(const fixedvec2 & npos)1302 	void SetXY(const fixedvec2 &npos)
1303 	{
1304 		__pos.x = npos.x;
1305 		__pos.y = npos.y;
1306 	}
SetXYZ(const fixedvec3 & npos)1307 	void SetXYZ(const fixedvec3 &npos)
1308 	{
1309 		__pos.x = npos.x;
1310 		__pos.y = npos.y;
1311 		__pos.z = npos.z;
1312 	}
SetMovement(fixed_t x,fixed_t y,fixed_t z)1313 	void SetMovement(fixed_t x, fixed_t y, fixed_t z)
1314 	{
1315 		// not yet implemented
1316 	}
1317 
1318 };
1319 
1320 class FActorIterator
1321 {
1322 public:
FActorIterator(int i)1323 	FActorIterator (int i) : base (NULL), id (i)
1324 	{
1325 	}
FActorIterator(int i,AActor * start)1326 	FActorIterator (int i, AActor *start) : base (start), id (i)
1327 	{
1328 	}
Next()1329 	AActor *Next ()
1330 	{
1331 		if (id == 0)
1332 			return NULL;
1333 		if (!base)
1334 			base = AActor::TIDHash[id & 127];
1335 		else
1336 			base = base->inext;
1337 
1338 		while (base && base->tid != id)
1339 			base = base->inext;
1340 
1341 		return base;
1342 	}
1343 private:
1344 	AActor *base;
1345 	int id;
1346 };
1347 
1348 template<class T>
1349 class TActorIterator : public FActorIterator
1350 {
1351 public:
TActorIterator(int id)1352 	TActorIterator (int id) : FActorIterator (id) {}
Next()1353 	T *Next ()
1354 	{
1355 		AActor *actor;
1356 		do
1357 		{
1358 			actor = FActorIterator::Next ();
1359 		} while (actor && !actor->IsKindOf (RUNTIME_CLASS(T)));
1360 		return static_cast<T *>(actor);
1361 	}
1362 };
1363 
1364 class NActorIterator : public FActorIterator
1365 {
1366 	const PClass *type;
1367 public:
NActorIterator(const PClass * cls,int id)1368 	NActorIterator (const PClass *cls, int id) : FActorIterator (id) { type = cls; }
NActorIterator(FName cls,int id)1369 	NActorIterator (FName cls, int id) : FActorIterator (id) { type = PClass::FindClass(cls); }
NActorIterator(const char * cls,int id)1370 	NActorIterator (const char *cls, int id) : FActorIterator (id) { type = PClass::FindClass(cls); }
Next()1371 	AActor *Next ()
1372 	{
1373 		AActor *actor;
1374 		if (type == NULL) return NULL;
1375 		do
1376 		{
1377 			actor = FActorIterator::Next ();
1378 		} while (actor && !actor->IsKindOf (type));
1379 		return actor;
1380 	}
1381 };
1382 
1383 bool P_IsTIDUsed(int tid);
1384 int P_FindUniqueTID(int start_tid, int limit);
1385 
Spawn(const PClass * type,fixed_t x,fixed_t y,fixed_t z,replace_t allowreplacement)1386 inline AActor *Spawn (const PClass *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement)
1387 {
1388 	return AActor::StaticSpawn (type, x, y, z, allowreplacement);
1389 }
1390 
Spawn(const PClass * type,const fixedvec3 & pos,replace_t allowreplacement)1391 inline AActor *Spawn (const PClass *type, const fixedvec3 &pos, replace_t allowreplacement)
1392 {
1393 	return AActor::StaticSpawn (type, pos.x, pos.y, pos.z, allowreplacement);
1394 }
1395 
1396 AActor *Spawn (const char *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement);
1397 AActor *Spawn (FName classname, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement);
1398 
Spawn(const char * type,const fixedvec3 & pos,replace_t allowreplacement)1399 inline AActor *Spawn (const char *type, const fixedvec3 &pos, replace_t allowreplacement)
1400 {
1401 	return Spawn (type, pos.x, pos.y, pos.z, allowreplacement);
1402 }
1403 
Spawn(FName classname,const fixedvec3 & pos,replace_t allowreplacement)1404 inline AActor *Spawn (FName classname, const fixedvec3 &pos, replace_t allowreplacement)
1405 {
1406 	return Spawn (classname, pos.x, pos.y, pos.z, allowreplacement);
1407 }
1408 
1409 
1410 template<class T>
Spawn(fixed_t x,fixed_t y,fixed_t z,replace_t allowreplacement)1411 inline T *Spawn (fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement)
1412 {
1413 	return static_cast<T *>(AActor::StaticSpawn (RUNTIME_CLASS(T), x, y, z, allowreplacement));
1414 }
1415 
1416 template<class T>
Spawn(const fixedvec3 & pos,replace_t allowreplacement)1417 inline T *Spawn (const fixedvec3 &pos, replace_t allowreplacement)
1418 {
1419 	return static_cast<T *>(AActor::StaticSpawn (RUNTIME_CLASS(T), pos.x, pos.y, pos.z, allowreplacement));
1420 }
1421 
Vec2Angle(fixed_t length,angle_t angle)1422 inline fixedvec2 Vec2Angle(fixed_t length, angle_t angle)
1423 {
1424 	fixedvec2 ret = { FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]),
1425 						FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]) };
1426 	return ret;
1427 }
1428 
1429 inline fixedvec3 PosRelative(const fixedvec3 &pos, line_t *line, sector_t *refsec = NULL)
1430 {
1431 	return pos;
1432 }
1433 
1434 void PrintMiscActorInfo(AActor * query);
1435 
1436 #define S_FREETARGMOBJ	1
1437 
1438 #endif // __P_MOBJ_H__
1439