1 // Emacs style mode select   -*- C++ -*-
2 //-----------------------------------------------------------------------------
3 //
4 // $Id: actor.h 4542 2014-02-09 17:39:42Z dr_sean $
5 //
6 // Copyright (C) 1993-1996 by id Software, Inc.
7 // Copyright (C) 2006-2014 by The Odamex Team.
8 //
9 // This program is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
13 //
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 // GNU General Public License for more details.
18 //
19 // DESCRIPTION:
20 //		Map Objects, MObj, definition and handling.
21 //
22 //-----------------------------------------------------------------------------
23 
24 
25 #ifndef __ACTOR_H__
26 #define __ACTOR_H__
27 
28 // Basics.
29 #include "tables.h"
30 #include "m_fixed.h"
31 
32 // We need the thinker_t stuff.
33 #include "dthinker.h"
34 
35 // We need the WAD data structure for Map things,
36 // from the THINGS lump.
37 #include "doomdata.h"
38 
39 // States are tied to finite states are
40 //	tied to animation frames.
41 // Needs precompiled tables/data structures.
42 #include "info.h"
43 
44 #include "szp.h"
45 
46 // STL
47 #include <vector>
48 #include <map>
49 
50 //
51 // NOTES: AActor
52 //
53 // Actors are used to tell the refresh where to draw an image,
54 // tell the world simulation when objects are contacted,
55 // and tell the sound driver how to position a sound.
56 //
57 // The refresh uses the next and prev links to follow
58 // lists of things in sectors as they are being drawn.
59 // The sprite, frame, and angle elements determine which patch_t
60 // is used to draw the sprite if it is visible.
61 // The sprite and frame values are almost always set
62 // from state_t structures.
63 // The statescr.exe utility generates the states.h and states.c
64 // files that contain the sprite/frame numbers from the
65 // statescr.txt source file.
66 // The xyz origin point represents a point at the bottom middle
67 // of the sprite (between the feet of a biped).
68 // This is the default origin position for patch_ts grabbed
69 // with lumpy.exe.
70 // A walking creature will have its z equal to the floor
71 // it is standing on.
72 //
73 // The sound code uses the x,y, and subsector fields
74 // to do stereo positioning of any sound effited by the AActor.
75 //
76 // The play simulation uses the blocklinks, x,y,z, radius, height
77 // to determine when AActors are touching each other,
78 // touching lines in the map, or hit by trace lines (gunshots,
79 // lines of sight, etc).
80 // The AActor->flags element has various bit flags
81 // used by the simulation.
82 //
83 // Every actor is linked into a single sector
84 // based on its origin coordinates.
85 // The subsector_t is found with P_PointInSubsector(x,y),
86 // and the sector_t can be found with subsector->sector.
87 // The sector links are only used by the rendering code,
88 // the play simulation does not care about them at all.
89 //
90 // Any actor that needs to be acted upon by something else
91 // in the play world (block movement, be shot, etc) will also
92 // need to be linked into the blockmap.
93 // If the thing has the MF_NOBLOCK flag set, it will not use
94 // the block links. It can still interact with other things,
95 // but only as the instigator (missiles will run into other
96 // things, but nothing can run into a missile).
97 // Each block in the grid is 128*128 units, and knows about
98 // every line_t that it contains a piece of, and every
99 // interactable actor that has its origin contained.
100 //
101 // A valid actor is an actor that has the proper subsector_t
102 // filled in for its xy coordinates and is linked into the
103 // sector from which the subsector was made, or has the
104 // MF_NOSECTOR flag set (the subsector_t needs to be valid
105 // even if MF_NOSECTOR is set), and is linked into a blockmap
106 // block or has the MF_NOBLOCKMAP flag set.
107 // Links should only be modified by the P_[Un]SetThingPosition()
108 // functions.
109 // Do not change the MF_NO* flags while a thing is valid.
110 //
111 // Any questions?
112 //
113 
114 //
115 // [SL] 2012-04-30 - A bit field to store a bool value for every player.
116 //
117 class PlayerBitField
118 {
119 public:
PlayerBitField()120 	PlayerBitField() { clear(); }
121 
clear()122 	void clear()
123 	{
124 		memset(bitfield, 0, sizeof(bitfield));
125 	}
126 
set(byte id)127 	void set(byte id)
128 	{
129 		int bytenum = id >> 3;
130 		int bitnum = id & bytemask;
131 
132 		bitfield[bytenum] |= (1 << bitnum);
133 	}
134 
unset(byte id)135 	void unset(byte id)
136 	{
137 		int bytenum = id >> 3;
138 		int bitnum = id & bytemask;
139 
140 		bitfield[bytenum] &= ~(1 << bitnum);
141 	}
142 
get(byte id)143 	bool get(byte id) const
144 	{
145 		int bytenum = id >> 3;
146 		int bitnum = id & bytemask;
147 
148 		return ((bitfield[bytenum] & (1 << bitnum)) != 0);
149 	}
150 
151 private:
152 	static const int bytesize = 8*sizeof(byte);
153 	static const int bytemask = bytesize - 1;
154 
155 	// Hacky way of getting ceil() at compile-time
156 	static const size_t fieldsize = (MAXPLAYERS + bytemask) / bytesize;
157 
158 	byte	bitfield[fieldsize];
159 };
160 
161 //
162 // Misc. mobj flags
163 //
164 typedef enum
165 {
166 // --- mobj.flags ---
167 
168 	MF_SPECIAL		= 0x00000001,	// call P_SpecialThing when touched
169 	MF_SOLID		= 0x00000002,
170 	MF_SHOOTABLE	= 0x00000004,
171 	MF_NOSECTOR		= 0x00000008,	// don't use the sector links
172 									// (invisible but touchable)
173 	MF_NOBLOCKMAP	= 0x00000010,	// don't use the blocklinks
174 									// (inert but displayable)
175 	MF_AMBUSH		= 0x00000020,	// not activated by sound; deaf monster
176 	MF_JUSTHIT		= 0x00000040,	// try to attack right back
177 	MF_JUSTATTACKED	= 0x00000080,	// take at least one step before attacking
178 	MF_SPAWNCEILING	= 0x00000100,	// hang from ceiling instead of floor
179 	MF_NOGRAVITY	= 0x00000200,	// don't apply gravity every tic
180 
181 // movement flags
182 	MF_DROPOFF		= 0x00000400,	// allow jumps from high places
183 	MF_PICKUP		= 0x00000800,	// for players to pick up items
184 	MF_NOCLIP		= 0x00001000,	// player cheat
185 	MF_SLIDE		= 0x00002000,	// keep info about sliding along walls
186 	MF_FLOAT		= 0x00004000,	// allow moves to any height, no gravity
187 	MF_TELEPORT		= 0x00008000,	// don't cross lines or look at heights
188 	MF_MISSILE		= 0x00010000,	// don't hit same species, explode on block
189 
190 	MF_DROPPED		= 0x00020000,	// dropped by a demon, not level spawned
191 	MF_SHADOW		= 0x00040000,	// actor is hard for monsters to see
192 	MF_NOBLOOD		= 0x00080000,	// don't bleed when shot (use puff)
193 	MF_CORPSE		= 0x00100000,	// don't stop moving halfway off a step
194 	MF_INFLOAT		= 0x00200000,	// floating to a height for a move, don't
195 									// auto float to target's height
196 
197 	MF_COUNTKILL	= 0x00400000,	// count towards intermission kill total
198 	MF_COUNTITEM	= 0x00800000,	// count towards intermission item total
199 
200 	MF_SKULLFLY		= 0x01000000,	// skull in flight
201 	MF_NOTDMATCH	= 0x02000000,	// don't spawn in death match (key cards)
202 
203     // Player sprites in multiplayer modes are modified
204     //  using an internal color lookup table for re-indexing.
205     // If 0x4 0x8 or 0xc, use a translation table for player colormaps
206     MF_TRANSLATION	= 0xc000000,
207 
208 	MF_UNMORPHED	= 0x10000000,	// [RH] Actor is the unmorphed version of something else
209 	MF_FALLING		= 0x20000000,
210     MF_SPECTATOR	= 0x40000000,	// GhostlyDeath -- thing is/was a spectator and can't be seen!
211 	MF_ICECORPSE	= 0x80000000,	// a frozen corpse (for blasting) [RH] was 0x800000
212 
213 // --- mobj.flags2 ---
214 
215 	MF2_LOGRAV			= 0x00000001,	// alternate gravity setting
216 	MF2_WINDTHRUST		= 0x00000002,	// gets pushed around by the wind
217 										// specials
218 	MF2_FLOORBOUNCE		= 0x00000004,	// bounces off the floor
219 	MF2_BLASTED			= 0x00000008,	// missile will pass through ghosts
220 	MF2_FLY				= 0x00000010,	// fly mode is active
221 	MF2_FLOORCLIP		= 0x00000020,	// if feet are allowed to be clipped
222 	MF2_SPAWNFLOAT		= 0x00000040,	// spawn random float z
223 	MF2_NOTELEPORT		= 0x00000080,	// does not teleport
224 	MF2_RIP				= 0x00000100,	// missile rips through solid
225 										// targets
226 	MF2_PUSHABLE		= 0x00000200,	// can be pushed by other moving
227 										// mobjs
228 	MF2_SLIDE			= 0x00000400,	// slides against walls
229 	MF2_ONMOBJ			= 0x00000800,	// mobj is resting on top of another
230 										// mobj
231 	MF2_PASSMOBJ		= 0x00001000,	// Enable z block checking.  If on,
232 										// this flag will allow the mobj to
233 										// pass over/under other mobjs.
234 	MF2_CANNOTPUSH		= 0x00002000,	// cannot push other pushable mobjs
235 	MF2_THRUGHOST		= 0x00004000,	// missile will pass through ghosts [RH] was 8
236 	MF2_BOSS			= 0x00008000,	// mobj is a major boss
237 	MF2_FIREDAMAGE		= 0x00010000,	// does fire damage
238 	MF2_NODMGTHRUST		= 0x00020000,	// does not thrust target when damaging
239 	MF2_TELESTOMP		= 0x00040000,	// mobj can stomp another
240 	MF2_FLOATBOB		= 0x00080000,	// use float bobbing z movement
241 	MF2_DONTDRAW		= 0x00100000,	// don't generate a vissprite
242 	MF2_IMPACT			= 0x00200000, 	// an MF_MISSILE mobj can activate SPAC_IMPACT
243 	MF2_PUSHWALL		= 0x00400000, 	// mobj can push walls
244 	MF2_MCROSS			= 0x00800000,	// can activate monster cross lines
245 	MF2_PCROSS			= 0x01000000,	// can activate projectile cross lines
246 	MF2_CANTLEAVEFLOORPIC = 0x02000000,	// stay within a certain floor type
247 	MF2_NONSHOOTABLE	= 0x04000000,	// mobj is totally non-shootable,
248 										// but still considered solid
249 	MF2_INVULNERABLE	= 0x08000000,	// mobj is invulnerable
250 	MF2_DORMANT			= 0x10000000,	// thing is dormant
251 	MF2_ICEDAMAGE		= 0x20000000,	// does ice damage
252 	MF2_SEEKERMISSILE	= 0x40000000,	// is a seeker (for reflection)
253 	MF2_REFLECTIVE		= 0x80000000	// reflects missiles
254 
255 } mobjflag_t;
256 
257 #define MF_TRANSSHIFT	0x1A
258 
259 #define TRANSLUC25			(FRACUNIT/4)
260 #define TRANSLUC33			(FRACUNIT/3)
261 #define TRANSLUC50			(FRACUNIT/2)
262 #define TRANSLUC66			((FRACUNIT*2)/3)
263 #define TRANSLUC75			((FRACUNIT*3)/4)
264 
265 // killough 11/98: For torque simulation:
266 #define OVERDRIVE 6
267 #define MAXGEAR (OVERDRIVE+16)
268 
269 // Map Object definition.
270 class AActor : public DThinker
271 {
272 	DECLARE_SERIAL (AActor, DThinker)
273 	typedef szp<AActor> AActorPtr;
274 	AActorPtr self;
275 
276 	class AActorPtrCounted
277 	{
278 		AActorPtr ptr;
279 
280 		public:
281 
AActorPtrCounted()282 		AActorPtrCounted() {}
283 
284 		AActorPtr &operator= (AActorPtr other)
285 		{
286 			if(ptr)
287 				ptr->refCount--;
288 			if(other)
289 				other->refCount++;
290 			ptr = other;
291 			return ptr;
292 		}
293 
294 		AActorPtr &operator= (AActorPtrCounted other)
295 		{
296 			if(ptr)
297 				ptr->refCount--;
298 			if(other)
299 				other->refCount++;
300 			ptr = other.ptr;
301 			return ptr;
302 		}
303 
~AActorPtrCounted()304 		~AActorPtrCounted()
305 		{
306 			if(ptr)
307 				ptr->refCount--;
308 		}
309 
AActorPtr()310 		operator AActorPtr()
311 		{
312 			return ptr;
313 		}
314 		operator AActor*()
315 		{
316 			return ptr;
317 		}
318 
319 		AActor &operator *()
320 		{
321 			return *ptr;
322 		}
323 		AActor *operator ->()
324 		{
325 			return ptr;
326 		}
327 	};
328 
329 public:
330 	AActor ();
331 	AActor (const AActor &other);
332 	AActor &operator= (const AActor &other);
333 	AActor (fixed_t x, fixed_t y, fixed_t z, mobjtype_t type);
334 	void Destroy ();
335 	~AActor ();
336 
337 	virtual void RunThink ();
338 
339     // Info for drawing: position.
340     fixed_t		x;
341     fixed_t		y;
342     fixed_t		z;
343 
344 	fixed_t		prevx;
345 	fixed_t		prevy;
346 	fixed_t		prevz;
347 
348 	AActor			*snext, **sprev;	// links in sector (if needed)
349 
350     //More drawing info: to determine current sprite.
351     angle_t		angle;	// orientation
352 	angle_t		prevangle;
353     spritenum_t		sprite;	// used to find patch_t and flip value
354     int			frame;	// might be ORed with FF_FULLBRIGHT
355 	fixed_t		pitch;
356 	angle_t		prevpitch;
357 
358 	DWORD			effects;			// [RH] see p_effect.h
359 
360     // Interaction info, by BLOCKMAP.
361     // Links in blocks (if needed).
362 	struct subsector_s		*subsector;
363 
364     // The closest interval over all contacted Sectors.
365     fixed_t		floorz;
366     fixed_t		ceilingz;
367 	fixed_t		dropoffz;
368 	struct sector_s		*floorsector;
369 
370     // For movement checking.
371     fixed_t		radius;
372     fixed_t		height;
373 
374     // Momentums, used to update position.
375     fixed_t		momx;
376     fixed_t		momy;
377     fixed_t		momz;
378 
379     // If == validcount, already checked.
380     int			validcount;
381 
382 	mobjtype_t		type;
383     mobjinfo_t*		info;	// &mobjinfo[mobj->type]
384     int				tics;	// state tic counter
385 	state_t			*state;
386 	int				damage;			// For missiles
387 	int				flags;
388 	int				flags2;	// Heretic flags
389 	int				special1;		// Special info
390 	int				special2;		// Special info
391 	int 			health;
392 
393     // Movement direction, movement generation (zig-zagging).
394     byte			movedir;	// 0-7
395     int				movecount;	// when 0, select a new dir
396 	char			visdir;
397 
398     // Thing being chased/attacked (or NULL),
399     // also the originator for missiles.
400 	AActorPtr		target;
401 	AActorPtr		lastenemy;		// Last known enemy -- killogh 2/15/98
402 
403     // Reaction time: if non 0, don't attack yet.
404     // Used by player to freeze a bit after teleporting.
405     int				reactiontime;
406 
407     // If >0, the target will be chased
408     // no matter what (even if shot)
409     int			threshold;
410 
411     // Additional info record for player avatars only.
412     // Only valid if type == MT_PLAYER
413 	player_s*	player;
414 
415     // Player number last looked for.
416     unsigned int	lastlook;
417 
418     // For nightmare respawn.
419     mapthing2_t		spawnpoint;
420 
421 	// Thing being chased/attacked for tracers.
422 	AActorPtr		tracer;
423 	byte			special;		// special
424 	byte			args[5];		// special arguments
425 
426 	AActor			*inext, *iprev;	// Links to other mobjs in same bucket
427 
428 	// denis - playerids of players to whom this object has been sent
429 	// [SL] changed to use a bitfield instead of a vector for O(1) lookups
430 	PlayerBitField	players_aware;
431 
432 	AActorPtr		goal;			// Monster's goal if not chasing anything
433 	translationref_t translation;	// Translation table (or NULL)
434 	fixed_t			translucency;	// 65536=fully opaque, 0=fully invisible
435 	byte			waterlevel;		// 0=none, 1=feet, 2=waist, 3=eyes
436 	SWORD			gear;			// killough 11/98: used in torque simulation
437 
438 	bool			onground;		// NES - Fixes infinite jumping bug like a charm.
439 
440 	// a linked list of sectors where this object appears
441 	struct msecnode_s	*touching_sectorlist;				// phares 3/14/98
442 
443 	short           deadtic;        // tics after player's death
444 	int             oldframe;
445 
446 	unsigned char	rndindex;		// denis - because everything should have a random number generator, for prediction
447 
448 	// ThingIDs
449 	static void ClearTIDHashes ();
450 	void AddToHash ();
451 	void RemoveFromHash ();
452 	AActor *FindByTID (int tid) const;
453 	static AActor *FindByTID (const AActor *first, int tid);
454 	AActor *FindGoal (int tid, int kind) const;
455 	static AActor *FindGoal (const AActor *first, int tid, int kind);
456 
457 	int             netid;          // every object has its own netid
458 	short			tid;			// thing identifier
459 
460 private:
461 	static const size_t TIDHashSize = 256;
462 	static const size_t TIDHashMask = TIDHashSize - 1;
463 	static AActor *TIDHash[TIDHashSize];
TIDHASH(int key)464 	static inline int TIDHASH (int key) { return key & TIDHashMask; }
465 
466 	friend class FActorIterator;
467 
468 public:
469 	void LinkToWorld ();
470 	void UnlinkFromWorld ();
471 
472 	void SetOrigin (fixed_t x, fixed_t y, fixed_t z);
473 
ptr()474 	AActorPtr ptr(){ return AActorPtr(self); }
475 
476 	//
477 	// ActorBlockMapListNode
478 	//
479 	// [SL] A container for the linked list nodes for all of the mapblocks that
480 	// an actor can be standing in.  Vanilla Doom only considered an actor to
481 	// be in the mapblock where its center was located, even if it was
482 	// overlapping other blocks.
483 	//
484 	class ActorBlockMapListNode
485 	{
486 	public:
487 		ActorBlockMapListNode(AActor *mo);
488 		void Link();
489 		void Unlink();
490 		AActor* Next(int bmx, int bmy);
491 
492 	private:
493 		void clear();
494 		size_t getIndex(int bmx, int bmy);
495 
496 		static const size_t BLOCKSX = 3;
497 		static const size_t BLOCKSY = 3;
498 
499 		AActor		*actor;
500 
501 		// the top-left blockmap the actor is in
502 		int			originx;
503 		int			originy;
504 		// the number of blocks the actor occupies
505 		int			blockcntx;
506 		int			blockcnty;
507 
508 		// the next and previous actors in each of the possible blockmaps
509 		// this actor can inhabit
510 		AActor		*next[BLOCKSX * BLOCKSY];
511 		AActor		**prev[BLOCKSX * BLOCKSY];
512 	};
513 
514 	ActorBlockMapListNode bmapnode;
515 };
516 
517 
518 class FActorIterator
519 {
520 public:
FActorIterator(int i)521 	FActorIterator (int i) : base (NULL), id (i)
522 	{
523 	}
Next()524 	AActor *Next ()
525 	{
526 		if (id == 0)
527 			return NULL;
528 		if (!base)
529 			base = AActor::FindByTID(NULL, id);
530 		else
531 			base = base->inext;
532 
533 		while (base && base->tid != id)
534 			base = base->inext;
535 
536 		return base;
537 	}
538 private:
539 	AActor *base;
540 	int id;
541 };
542 
543 
544 template<class T>
545 class TActorIterator : public FActorIterator
546 {
547 public:
TActorIterator(int id)548 	TActorIterator (int id) : FActorIterator (id) {}
Next()549 	T *Next ()
550 	{
551 		AActor *actor;
552 		do
553 		{
554 			actor = FActorIterator::Next ();
555 		} while (actor && !actor->IsKindOf (RUNTIME_CLASS(T)));
556 		return static_cast<T *>(actor);
557 	}
558 };
559 
560 
561 #endif
562 
563 
564 
565