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