1 // SONIC ROBO BLAST 2
2 //-----------------------------------------------------------------------------
3 // Copyright (C) 1993-1996 by id Software, Inc.
4 // Copyright (C) 1998-2000 by DooM Legacy Team.
5 // Copyright (C) 1999-2020 by Sonic Team Junior.
6 //
7 // This program is free software distributed under the
8 // terms of the GNU General Public License, version 2.
9 // See the 'LICENSE' file for more details.
10 //-----------------------------------------------------------------------------
11 /// \file  p_mobj.h
12 /// \brief Map Objects, MObj, definition and handling
13 
14 #ifndef __P_MOBJ__
15 #define __P_MOBJ__
16 
17 // Basics.
18 #include "tables.h"
19 #include "m_fixed.h"
20 
21 // We need the thinker_t stuff.
22 #include "d_think.h"
23 
24 // We need the WAD data structure for Map things, from the THINGS lump.
25 #include "doomdata.h"
26 
27 // States are tied to finite states are tied to animation frames.
28 // Needs precompiled tables/data structures.
29 #include "info.h"
30 
31 //
32 // NOTES: mobj_t
33 //
34 // mobj_ts are used to tell the refresh where to draw an image,
35 // tell the world simulation when objects are contacted,
36 // and tell the sound driver how to position a sound.
37 //
38 // The refresh uses the next and prev links to follow
39 // lists of things in sectors as they are being drawn.
40 // The sprite, frame, and angle elements determine which patch_t
41 // is used to draw the sprite if it is visible.
42 // The sprite and frame values are allmost allways set
43 // from state_t structures.
44 // The statescr.exe utility generates the states.h and states.c
45 // files that contain the sprite/frame numbers from the
46 // statescr.txt source file.
47 // The xyz origin point represents a point at the bottom middle
48 // of the sprite (between the feet of a biped).
49 // This is the default origin position for patch_ts grabbed
50 // with lumpy.exe.
51 // A walking creature will have its z equal to the floor
52 // it is standing on.
53 //
54 // The sound code uses the x,y, and subsector fields
55 // to do stereo positioning of any sound effited by the mobj_t.
56 //
57 // The play simulation uses the blocklinks, x,y,z, radius, height
58 // to determine when mobj_ts are touching each other,
59 // touching lines in the map, or hit by trace lines (gunshots,
60 // lines of sight, etc).
61 // The mobj_t->flags element has various bit flags
62 // used by the simulation.
63 //
64 // Every mobj_t is linked into a single sector
65 // based on its origin coordinates.
66 // The subsector_t is found with R_PointInSubsector(x,y),
67 // and the sector_t can be found with subsector->sector.
68 // The sector links are only used by the rendering code,
69 // the play simulation does not care about them at all.
70 //
71 // Any mobj_t that needs to be acted upon by something else
72 // in the play world (block movement, be shot, etc) will also
73 // need to be linked into the blockmap.
74 // If the thing has the MF_NOBLOCK flag set, it will not use
75 // the block links. It can still interact with other things,
76 // but only as the instigator (missiles will run into other
77 // things, but nothing can run into a missile).
78 // Each block in the grid is 128*128 units, and knows about
79 // every line_t that it contains a piece of, and every
80 // interactable mobj_t that has its origin contained.
81 //
82 // A valid mobj_t is a mobj_t that has the proper subsector_t
83 // filled in for its xy coordinates and is linked into the
84 // sector from which the subsector was made, or has the
85 // MF_NOSECTOR flag set (the subsector_t needs to be valid
86 // even if MF_NOSECTOR is set), and is linked into a blockmap
87 // block or has the MF_NOBLOCKMAP flag set.
88 // Links should only be modified by the P_[Un]SetThingPosition()
89 // functions.
90 // Do not change the MF_NO? flags while a thing is valid.
91 //
92 // Any questions?
93 //
94 
95 //
96 // Misc. mobj flags
97 //
98 typedef enum
99 {
100 	// Call P_TouchSpecialThing when touched.
101 	MF_SPECIAL          = 1,
102 	// Blocks.
103 	MF_SOLID            = 1<<1,
104 	// Can be hit.
105 	MF_SHOOTABLE        = 1<<2,
106 	// Don't use the sector links (invisible but touchable).
107 	MF_NOSECTOR         = 1<<3,
108 	// Don't use the blocklinks (inert but displayable)
109 	MF_NOBLOCKMAP       = 1<<4,
110 	// Thin, paper-like collision bound (for visual equivalent, see FF_PAPERSPRITE)
111 	MF_PAPERCOLLISION            = 1<<5,
112 	// You can push this object. It can activate switches and things by pushing it on top.
113 	MF_PUSHABLE         = 1<<6,
114 	// Object is a boss.
115 	MF_BOSS             = 1<<7,
116 	// On level spawning (initial position), hang from ceiling instead of stand on floor.
117 	MF_SPAWNCEILING     = 1<<8,
118 	// Don't apply gravity (every tic); object will float, keeping current height
119 	//  or changing it actively.
120 	MF_NOGRAVITY        = 1<<9,
121 	// This object is an ambient sound.
122 	MF_AMBIENT          = 1<<10,
123 	// Slide this object when it hits a wall.
124 	MF_SLIDEME          = 1<<11,
125 	// Player cheat.
126 	MF_NOCLIP           = 1<<12,
127 	// Allow moves to any height, no gravity. For active floaters.
128 	MF_FLOAT            = 1<<13,
129 	// Monitor powerup icon. These rise a bit.
130 	MF_BOXICON          = 1<<14,
131 	// Don't hit same species, explode on block.
132 	// Player missiles as well as fireballs of various kinds.
133 	MF_MISSILE          = 1<<15,
134 	// Item is a spring.
135 	MF_SPRING           = 1<<16,
136 	// Bounce off walls and things.
137 	MF_BOUNCE           = 1<<17,
138 	// Item box
139 	MF_MONITOR          = 1<<18,
140 	// Don't run the thinker for this object.
141 	MF_NOTHINK          = 1<<19,
142 	// Fire object. Doesn't harm if you have fire shield.
143 	MF_FIRE             = 1<<20,
144 	// Don't adjust z if below or above floorz/ceilingz
145 	MF_NOCLIPHEIGHT     = 1<<21,
146 	// This mobj is an enemy!
147 	MF_ENEMY            = 1<<22,
148 	// Scenery (uses scenery thinker).
149 	MF_SCENERY          = 1<<23,
150 	// Painful (shit hurts).
151 	MF_PAIN             = 1<<24,
152 	// This mobj will stick to any surface or solid object it touches.
153 	MF_STICKY           = 1<<25,
154 	// NiGHTS hidden item. Goes to seestate and turns MF_SPECIAL when paralooped.
155 	MF_NIGHTSITEM       = 1<<26,
156 	// for chase camera, don't be blocked by things (partial clipping)
157 	MF_NOCLIPTHING      = 1<<27,
158 	// Missile bounces like a grenade.
159 	MF_GRENADEBOUNCE    = 1<<28,
160 	// Run the action thinker on spawn.
161 	MF_RUNSPAWNFUNC     = 1<<29,
162 	// free: 1<<30 and 1<<31
163 } mobjflag_t;
164 
165 typedef enum
166 {
167 	MF2_AXIS           = 1,     // It's a NiGHTS axis! (For faster checking)
168 	MF2_TWOD           = 1<<1,  // Moves like it's in a 2D level
169 	MF2_DONTRESPAWN    = 1<<2,  // Don't respawn this object!
170 	MF2_DONTDRAW       = 1<<3,  // Don't generate a vissprite
171 	MF2_AUTOMATIC      = 1<<4,  // Thrown ring has automatic properties
172 	MF2_RAILRING       = 1<<5,  // Thrown ring has rail properties
173 	MF2_BOUNCERING     = 1<<6,  // Thrown ring has bounce properties
174 	MF2_EXPLOSION      = 1<<7,  // Thrown ring has explosive properties
175 	MF2_SCATTER        = 1<<8,  // Thrown ring has scatter properties
176 	MF2_BEYONDTHEGRAVE = 1<<9,  // Source of this missile has died and has since respawned.
177 	MF2_SLIDEPUSH      = 1<<10, // MF_PUSHABLE that pushes continuously.
178 	MF2_CLASSICPUSH    = 1<<11, // Drops straight down when object has negative momz.
179 	MF2_INVERTAIMABLE  = 1<<12, // Flips whether it's targetable by A_LookForEnemies (enemies no, decoys yes)
180 	MF2_INFLOAT        = 1<<13, // Floating to a height for a move, don't auto float to target's height.
181 	MF2_DEBRIS         = 1<<14, // Splash ring from explosion ring
182 	MF2_NIGHTSPULL     = 1<<15, // Attracted from a paraloop
183 	MF2_JUSTATTACKED   = 1<<16, // can be pushed by other moving mobjs
184 	MF2_FIRING         = 1<<17, // turret fire
185 	MF2_SUPERFIRE      = 1<<18, // Firing something with Super Sonic-stopping properties. Or, if mobj has MF_MISSILE, this is the actual fire from it.
186 	MF2_SHADOW         = 1<<19, // Fuzzy draw, makes targeting harder.
187 	MF2_STRONGBOX      = 1<<20, // Flag used for "strong" random monitors.
188 	MF2_OBJECTFLIP     = 1<<21, // Flag for objects that always have flipped gravity.
189 	MF2_SKULLFLY       = 1<<22, // Special handling: skull in flight.
190 	MF2_FRET           = 1<<23, // Flashing from a previous hit
191 	MF2_BOSSNOTRAP     = 1<<24, // No Egg Trap after boss
192 	MF2_BOSSFLEE       = 1<<25, // Boss is fleeing!
193 	MF2_BOSSDEAD       = 1<<26, // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.)
194 	MF2_AMBUSH         = 1<<27, // Alternate behaviour typically set by MTF_AMBUSH
195 	MF2_LINKDRAW       = 1<<28, // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position)
196 	MF2_SHIELD         = 1<<29, // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use)
197 	MF2_SPLAT          = 1<<30, // Renders as a splat
198 	// free: to and including 1<<31
199 } mobjflag2_t;
200 
201 typedef enum
202 {
203 	DI_NODIR = -1,
204 	DI_EAST = 0,
205 	DI_NORTHEAST = 1,
206 	DI_NORTH = 2,
207 	DI_NORTHWEST = 3,
208 	DI_WEST = 4,
209 	DI_SOUTHWEST = 5,
210 	DI_SOUTH = 6,
211 	DI_SOUTHEAST = 7,
212 	NUMDIRS = 8,
213 } dirtype_t;
214 
215 //
216 // Mobj extra flags
217 //
218 typedef enum
219 {
220 	// The mobj stands on solid floor (not on another mobj or in air)
221 	MFE_ONGROUND          = 1,
222 	// The mobj just hit the floor while falling, this is cleared on next frame
223 	// (instant damage in lava/slime sectors to prevent jump cheat..)
224 	MFE_JUSTHITFLOOR      = 1<<1,
225 	// The mobj stands in a sector with water, and touches the surface
226 	// this bit is set once and for all at the start of mobjthinker
227 	MFE_TOUCHWATER        = 1<<2,
228 	// The mobj stands in a sector with water, and his waist is BELOW the water surface
229 	// (for player, allows swimming up/down)
230 	MFE_UNDERWATER        = 1<<3,
231 	// used for ramp sectors
232 	MFE_JUSTSTEPPEDDOWN   = 1<<4,
233 	// Vertically flip sprite/allow upside-down physics
234 	MFE_VERTICALFLIP      = 1<<5,
235 	// Goo water
236 	MFE_GOOWATER          = 1<<6,
237 	// The mobj is touching a lava block
238 	MFE_TOUCHLAVA         = 1<<7,
239 	// Mobj was already pushed this tic
240 	MFE_PUSHED            = 1<<8,
241 	// Mobj was already sprung this tic
242 	MFE_SPRUNG            = 1<<9,
243 	// Platform movement
244 	MFE_APPLYPMOMZ        = 1<<10,
245 	// Compute and trigger on mobj angle relative to tracer
246 	// See Linedef Exec 457 (Track mobj angle to point)
247 	MFE_TRACERANGLE       = 1<<11,
248 	// free: to and including 1<<15
249 } mobjeflag_t;
250 
251 //
252 // PRECIPITATION flags ?! ?! ?!
253 //
254 typedef enum {
255 	// Don't draw.
256 	PCF_INVISIBLE = 1,
257 	// Above pit.
258 	PCF_PIT = 2,
259 	// Above FOF.
260 	PCF_FOF = 4,
261 	// Above MOVING FOF (this means we need to keep floorz up to date...)
262 	PCF_MOVINGFOF = 8,
263 	// Is rain.
264 	PCF_RAIN = 16,
265 	// Ran the thinker this tic.
266 	PCF_THUNK = 32,
267 } precipflag_t;
268 
269 // Map Object definition.
270 typedef struct mobj_s
271 {
272 	// List: thinker links.
273 	thinker_t thinker;
274 
275 	// Info for drawing: position.
276 	fixed_t x, y, z;
277 
278 	// More list: links in sector (if needed)
279 	struct mobj_s *snext;
280 	struct mobj_s **sprev; // killough 8/11/98: change to ptr-to-ptr
281 
282 	// More drawing info: to determine current sprite.
283 	angle_t angle, pitch, roll; // orientation
284 	angle_t rollangle;
285 	spritenum_t sprite; // used to find patch_t and flip value
286 	UINT32 frame; // frame number, plus bits see p_pspr.h
287 	UINT8 sprite2; // player sprites
288 	UINT16 anim_duration; // for FF_ANIMATE states
289 
290 	UINT32 renderflags; // render flags
291 	INT32 blendmode; // blend mode
292 	fixed_t spritexscale, spriteyscale;
293 	fixed_t spritexoffset, spriteyoffset;
294 	struct pslope_s *floorspriteslope; // The slope that the floorsprite is rotated by
295 
296 	struct msecnode_s *touching_sectorlist; // a linked list of sectors where this object appears
297 
298 	struct subsector_s *subsector; // Subsector the mobj resides in.
299 
300 	// The closest interval over all contacted sectors (or things).
301 	fixed_t floorz; // Nearest floor below.
302 	fixed_t ceilingz; // Nearest ceiling above.
303 	struct ffloor_s *floorrover; // FOF referred by floorz
304 	struct ffloor_s *ceilingrover; // FOF referred by ceilingz
305 
306 	// For movement checking.
307 	fixed_t radius;
308 	fixed_t height;
309 
310 	// Momentums, used to update position.
311 	fixed_t momx, momy, momz;
312 	fixed_t pmomz; // If you're on a moving floor, its "momz" would be here
313 
314 	INT32 tics; // state tic counter
315 	state_t *state;
316 	UINT32 flags; // flags from mobjinfo tables
317 	UINT32 flags2; // MF2_ flags
318 	UINT16 eflags; // extra flags
319 
320 	void *skin; // overrides 'sprite' when non-NULL (for player bodies to 'remember' the skin)
321 	// Player and mobj sprites in multiplayer modes are modified
322 	//  using an internal color lookup table for re-indexing.
323 	UINT16 color; // This replaces MF_TRANSLATION. Use 0 for default (no translation).
324 
325 	// Interaction info, by BLOCKMAP.
326 	// Links in blocks (if needed).
327 	struct mobj_s *bnext;
328 	struct mobj_s **bprev; // killough 8/11/98: change to ptr-to-ptr
329 
330 	// Additional pointers for NiGHTS hoops
331 	struct mobj_s *hnext;
332 	struct mobj_s *hprev;
333 
334 	mobjtype_t type;
335 	const mobjinfo_t *info; // &mobjinfo[mobj->type]
336 
337 	INT32 health; // for player this is rings + 1 -- no it isn't, not any more!!
338 
339 	// Movement direction, movement generation (zig-zagging).
340 	angle_t movedir; // dirtype_t 0-7; also used by Deton for up/down angle
341 	INT32 movecount; // when 0, select a new dir
342 
343 	struct mobj_s *target; // Thing being chased/attacked (or NULL), and originator for missiles.
344 
345 	INT32 reactiontime; // If not 0, don't attack yet.
346 
347 	INT32 threshold; // If >0, the target will be chased no matter what.
348 
349 	// Additional info record for player avatars only.
350 	// Only valid if type == MT_PLAYER
351 	struct player_s *player;
352 
353 	INT32 lastlook; // Player number last looked for.
354 
355 	mapthing_t *spawnpoint; // Used for CTF flags, objectplace, and a handful other applications.
356 
357 	struct mobj_s *tracer; // Thing being chased/attacked for tracers.
358 
359 	fixed_t friction;
360 	fixed_t movefactor;
361 
362 	INT32 fuse; // Does something in P_MobjThinker on reaching 0.
363 	fixed_t watertop; // top of the water FOF the mobj is in
364 	fixed_t waterbottom; // bottom of the water FOF the mobj is in
365 
366 	UINT32 mobjnum; // A unique number for this mobj. Used for restoring pointers on save games.
367 
368 	fixed_t scale;
369 	fixed_t destscale;
370 	fixed_t scalespeed;
371 
372 	// Extra values are for internal use for whatever you want
373 	INT32 extravalue1;
374 	INT32 extravalue2;
375 
376 	// Custom values are not to be altered by us!
377 	// They are for SOCs to store things in.
378 	INT32 cusval;
379 	INT32 cvmem;
380 
381 	struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?)
382 
383 	boolean colorized; // Whether the mobj uses the rainbow colormap
384 	boolean mirrored; // The object's rotations will be mirrored left to right, e.g., see frame AL from the right and AR from the left
385 	fixed_t shadowscale; // If this object casts a shadow, and the size relative to radius
386 
387 	// WARNING: New fields must be added separately to savegame and Lua.
388 } mobj_t;
389 
390 //
391 // For precipitation
392 //
393 // Sometimes this is casted to a mobj_t,
394 // so please keep the start of the
395 // structure the same.
396 //
397 typedef struct precipmobj_s
398 {
399 	// List: thinker links.
400 	thinker_t thinker;
401 
402 	// Info for drawing: position.
403 	fixed_t x, y, z;
404 
405 	// More list: links in sector (if needed)
406 	struct precipmobj_s *snext;
407 	struct precipmobj_s **sprev; // killough 8/11/98: change to ptr-to-ptr
408 
409 	// More drawing info: to determine current sprite.
410 	angle_t angle, pitch, roll; // orientation
411 	angle_t rollangle;
412 	spritenum_t sprite; // used to find patch_t and flip value
413 	UINT32 frame; // frame number, plus bits see p_pspr.h
414 	UINT8 sprite2; // player sprites
415 	UINT16 anim_duration; // for FF_ANIMATE states
416 
417 	UINT32 renderflags; // render flags
418 	INT32 blendmode; // blend mode
419 	fixed_t spritexscale, spriteyscale;
420 	fixed_t spritexoffset, spriteyoffset;
421 	struct pslope_s *floorspriteslope; // The slope that the floorsprite is rotated by
422 
423 	struct mprecipsecnode_s *touching_sectorlist; // a linked list of sectors where this object appears
424 
425 	struct subsector_s *subsector; // Subsector the mobj resides in.
426 
427 	// The closest interval over all contacted sectors (or things).
428 	fixed_t floorz; // Nearest floor below.
429 	fixed_t ceilingz; // Nearest ceiling above.
430 	struct ffloor_s *floorrover; // FOF referred by floorz
431 	struct ffloor_s *ceilingrover; // FOF referred by ceilingz
432 
433 	// For movement checking.
434 	fixed_t radius; // Fixed at 2*FRACUNIT
435 	fixed_t height; // Fixed at 4*FRACUNIT
436 
437 	// Momentums, used to update position.
438 	fixed_t momx, momy, momz;
439 	fixed_t precipflags; // fixed_t so it uses the same spot as "pmomz" even as we use precipflags_t for it
440 
441 	INT32 tics; // state tic counter
442 	state_t *state;
443 	INT32 flags; // flags from mobjinfo tables
444 } precipmobj_t;
445 
446 typedef struct actioncache_s
447 {
448 	struct actioncache_s *next;
449 	struct actioncache_s *prev;
450 	struct mobj_s *mobj;
451 	INT32 statenum;
452 } actioncache_t;
453 
454 extern actioncache_t actioncachehead;
455 
456 void P_InitCachedActions(void);
457 void P_RunCachedActions(void);
458 void P_AddCachedAction(mobj_t *mobj, INT32 statenum);
459 
460 // check mobj against water content, before movement code
461 void P_MobjCheckWater(mobj_t *mobj);
462 
463 // Player spawn points
464 void P_SpawnPlayer(INT32 playernum);
465 void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing);
466 void P_MovePlayerToStarpost(INT32 playernum);
467 void P_AfterPlayerSpawn(INT32 playernum);
468 
469 fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t dz, const fixed_t offset, const boolean flip, const fixed_t scale);
470 fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y);
471 
472 mobj_t *P_SpawnMapThing(mapthing_t *mthing);
473 void P_SpawnHoop(mapthing_t *mthing);
474 void P_SetBonusTime(mobj_t *mobj);
475 void P_SpawnItemPattern(mapthing_t *mthing, boolean bonustime);
476 void P_SpawnHoopOfSomething(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle);
477 void P_SpawnPrecipitation(void);
478 void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, statenum_t nstate, angle_t rotangle, boolean spawncenter);
479 void *P_CreateFloorSpriteSlope(mobj_t *mobj);
480 void P_RemoveFloorSpriteSlope(mobj_t *mobj);
481 boolean P_BossTargetPlayer(mobj_t *actor, boolean closest);
482 boolean P_SupermanLook4Players(mobj_t *actor);
483 void P_DestroyRobots(void);
484 void P_SnowThinker(precipmobj_t *mobj);
485 void P_RainThinker(precipmobj_t *mobj);
486 void P_NullPrecipThinker(precipmobj_t *mobj);
487 void P_RemovePrecipMobj(precipmobj_t *mobj);
488 void P_SetScale(mobj_t *mobj, fixed_t newscale);
489 void P_XYMovement(mobj_t *mo);
490 void P_RingXYMovement(mobj_t *mo);
491 void P_SceneryXYMovement(mobj_t *mo);
492 boolean P_ZMovement(mobj_t *mo);
493 void P_RingZMovement(mobj_t *mo);
494 boolean P_SceneryZMovement(mobj_t *mo);
495 void P_PlayerZMovement(mobj_t *mo);
496 void P_EmeraldManager(void);
497 
498 extern INT32 modulothing;
499 
500 #define MAXHUNTEMERALDS 64
501 extern mapthing_t *huntemeralds[MAXHUNTEMERALDS];
502 extern INT32 numhuntemeralds;
503 extern boolean runemeraldmanager;
504 extern UINT16 emeraldspawndelay;
505 extern INT32 numstarposts;
506 extern UINT16 bossdisabled;
507 extern boolean stoppedclock;
508 #endif
509