// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2006 by James Haley // Copyright (C) 2006-2023 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. // See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- /// \file p_polyobj.h /// \brief Movable segs like in Hexen, but more flexible /// due to application of dynamic binary space partitioning theory. #ifndef POLYOBJ_H__ #define POLYOBJ_H__ #include "m_dllist.h" #include "p_mobj.h" #include "r_defs.h" // // Defines // // haleyjd: use zdoom-compatible doomednums #define POLYOBJ_ANCHOR_DOOMEDNUM 760 #define POLYOBJ_SPAWN_DOOMEDNUM 761 #define POLYOBJ_START_LINE 20 typedef enum { POF_CLIPLINES = 0x1, ///< Test against lines for collision POF_CLIPPLANES = 0x2, ///< Test against tops and bottoms for collision POF_SOLID = 0x3, ///< Clips things. POF_TESTHEIGHT = 0x4, ///< Test line collision with heights POF_RENDERSIDES = 0x8, ///< Renders the sides. POF_RENDERTOP = 0x10, ///< Renders the top. POF_RENDERBOTTOM = 0x20, ///< Renders the bottom. POF_RENDERPLANES = 0x30, ///< Renders top and bottom. POF_RENDERALL = 0x38, ///< Renders everything. POF_INVERT = 0x40, ///< Inverts collision (like a cage). POF_INVERTPLANES = 0x80, ///< Render inside planes. POF_INVERTPLANESONLY = 0x100, ///< Only render inside planes. POF_PUSHABLESTOP = 0x200, ///< Pushables will stop movement. POF_LDEXEC = 0x400, ///< This PO triggers a linedef executor. POF_ONESIDE = 0x800, ///< Only use the first side of the linedef. POF_NOSPECIALS = 0x1000, ///< Don't apply sector specials. POF_SPLAT = 0x2000, ///< Use splat flat renderer (treat cyan pixels as invisible). } polyobjflags_e; typedef enum { TMPF_NOINSIDES = 1, TMPF_INTANGIBLE = 1<<1, TMPF_PUSHABLESTOP = 1<<2, TMPF_INVISIBLEPLANES = 1<<3, TMPF_EXECUTOR = 1<<4, TMPF_CRUSH = 1<<5, TMPF_SPLAT = 1<<6, //TMPF_DONTCLIPPLANES = 1<<7, } textmappolyobjectflags_t; // // Polyobject Structure // typedef struct polyobj_s { mdllistitem_t link; // for subsector links; must be first INT32 id; // numeric id INT32 first; // for hashing: index of first polyobject in this hash chain INT32 next; // for hashing: next polyobject in this hash chain INT32 parent; // numeric id of parent polyobject size_t segCount; // number of segs in polyobject size_t numSegsAlloc; // number of segs allocated struct seg_s **segs; // the segs, a reallocating array. size_t numVertices; // number of vertices (generally == segCount) size_t numVerticesAlloc; // number of vertices allocated vertex_t *origVerts; // original positions relative to spawn spot vertex_t *tmpVerts; // temporary vertex backups for rotation vertex_t **vertices; // vertices this polyobject must move size_t numLines; // number of linedefs (generally <= segCount) size_t numLinesAlloc; // number of linedefs allocated struct line_s **lines; // linedefs this polyobject must move degenmobj_t spawnSpot; // location of spawn spot vertex_t centerPt; // center point fixed_t zdist; // viewz distance for sorting angle_t angle; // for rotation UINT8 attached; // if true, is attached to a subsector fixed_t blockbox[4]; // bounding box for clipping UINT8 linked; // is linked to blockmap size_t validcount; // for clipping: prevents multiple checks INT32 damage; // damage to inflict on stuck things fixed_t thrust; // amount of thrust to put on blocking objects INT32 flags; // Flags for this polyobject thinker_t *thinker; // pointer to a thinker affecting this polyobj UINT8 isBad; // a bad polyobject: should not be rendered/manipulated INT32 translucency; // index to translucency tables INT16 triggertag; // Tag of linedef executor to trigger on touch struct visplane_s *visplane; // polyobject's visplane, for ease of putting into the list later // these are saved for netgames, so do not let Lua touch these! INT32 spawnflags; // Flags the polyobject originally spawned with INT32 spawntrans; // Translucency the polyobject originally spawned with } polyobj_t; // // Polyobject Blockmap Link Structure // typedef struct polymaplink_s { mdllistitem_t link; // for blockmap links polyobj_t *po; // pointer to polyobject } polymaplink_t; // // Polyobject Special Thinkers // typedef struct polyrotate_s { thinker_t thinker; // must be first INT32 polyObjNum; // numeric id of polyobject (avoid C pointers here) INT32 speed; // speed of movement per frame INT32 distance; // distance to move UINT8 turnobjs; // turn objects? PTF_ flags } polyrotate_t; typedef struct polymove_s { thinker_t thinker; // must be first INT32 polyObjNum; // numeric id of polyobject INT32 speed; // resultant velocity fixed_t momx; // x component of speed along angle fixed_t momy; // y component of speed along angle INT32 distance; // total distance to move UINT32 angle; // angle along which to move } polymove_t; // PolyObject waypoint movement return behavior typedef enum { PWR_STOP, // Stop after reaching last waypoint PWR_WRAP, // Wrap back to first waypoint PWR_COMEBACK, // Repeat sequence in reverse } polywaypointreturn_e; typedef struct polywaypoint_s { thinker_t thinker; // must be first INT32 polyObjNum; // numeric id of polyobject INT32 speed; // resultant velocity INT32 sequence; // waypoint sequence # INT32 pointnum; // waypoint # INT32 direction; // 1 for normal, -1 for backwards UINT8 returnbehavior; // behavior after reaching the last waypoint UINT8 continuous; // continuously move - used with PWR_WRAP or PWR_COMEBACK UINT8 stophere; // Will stop after it reaches the next waypoint } polywaypoint_t; typedef struct polyslidedoor_s { thinker_t thinker; // must be first INT32 polyObjNum; // numeric id of affected polyobject INT32 delay; // delay time INT32 delayCount; // delay counter INT32 initSpeed; // initial speed INT32 speed; // speed of motion INT32 initDistance; // initial distance to travel INT32 distance; // current distance to travel UINT32 initAngle; // intial angle UINT32 angle; // angle of motion UINT32 revAngle; // reversed angle to avoid roundoff error fixed_t momx; // x component of speed along angle fixed_t momy; // y component of speed along angle UINT8 closing; // if true, is closing } polyslidedoor_t; typedef struct polyswingdoor_s { thinker_t thinker; // must be first INT32 polyObjNum; // numeric id of affected polyobject INT32 delay; // delay time INT32 delayCount; // delay counter INT32 initSpeed; // initial speed INT32 speed; // speed of rotation INT32 initDistance; // initial distance to travel INT32 distance; // current distance to travel UINT8 closing; // if true, is closing } polyswingdoor_t; typedef struct polydisplace_s { thinker_t thinker; // must be first INT32 polyObjNum; struct sector_s *controlSector; fixed_t dx; fixed_t dy; fixed_t oldHeights; } polydisplace_t; typedef struct polyrotdisplace_s { thinker_t thinker; // must be first INT32 polyObjNum; struct sector_s *controlSector; fixed_t rotscale; UINT8 turnobjs; fixed_t oldHeights; } polyrotdisplace_t; typedef struct polyfade_s { thinker_t thinker; // must be first INT32 polyObjNum; INT32 sourcevalue; INT32 destvalue; boolean docollision; boolean doghostfade; boolean ticbased; INT32 duration; INT32 timer; } polyfade_t; // // Line Activation Data Structures // typedef enum { TMPR_DONTROTATEOTHERS = 1, TMPR_ROTATEPLAYERS = 1<<1, TMPR_CONTINUOUS = 1<<2, TMPR_OVERRIDE = 1<<3, } textmappolyrotate_t; typedef enum { PTF_PLAYERS = 1, // Turn players with movement PTF_OTHERS = 1<<1, // Turn other mobjs with movement } polyturnflags_e; typedef struct polyrotdata_s { INT32 polyObjNum; // numeric id of polyobject to affect INT32 direction; // direction of rotation INT32 speed; // angular speed INT32 distance; // distance to move UINT8 flags; // TMPR_ flags } polyrotdata_t; typedef struct polymovedata_s { INT32 polyObjNum; // numeric id of polyobject to affect fixed_t distance; // distance to move fixed_t speed; // linear speed angle_t angle; // angle of movement UINT8 overRide; // if true, will override any action on the object } polymovedata_t; typedef enum { PWF_REVERSE = 1, // Move through waypoints in reverse order PWF_LOOP = 1<<1, // Loop movement (used with PWR_WRAP or PWR_COMEBACK) } polywaypointflags_e; typedef struct polywaypointdata_s { INT32 polyObjNum; // numeric id of polyobject to affect INT32 sequence; // waypoint sequence # fixed_t speed; // linear speed UINT8 returnbehavior; // behavior after reaching the last waypoint UINT8 flags; // PWF_ flags } polywaypointdata_t; typedef enum { TMPV_NOCHANGE = 0, TMPV_VISIBLE = 1, TMPV_INVISIBLE = 2, } textmappolyvisibility_t; typedef enum { TMPT_NOCHANGE = 0, TMPT_TANGIBLE = 1, TMPT_INTANGIBLE = 2, } textmappolytangibility_t; // polyobject door types typedef enum { POLY_DOOR_SLIDE, POLY_DOOR_SWING, } polydoor_e; typedef struct polydoordata_s { INT32 polyObjNum; // numeric id of polyobject to affect INT32 doorType; // polyobj door type INT32 speed; // linear or angular speed angle_t angle; // for slide door only, angle of motion INT32 distance; // distance to move INT32 delay; // delay time after opening } polydoordata_t; typedef struct polydisplacedata_s { INT32 polyObjNum; struct sector_s *controlSector; fixed_t dx; fixed_t dy; } polydisplacedata_t; typedef struct polyrotdisplacedata_s { INT32 polyObjNum; struct sector_s *controlSector; fixed_t rotscale; UINT8 turnobjs; } polyrotdisplacedata_t; typedef struct polyflagdata_s { INT32 polyObjNum; INT32 speed; UINT32 angle; fixed_t momx; } polyflagdata_t; typedef enum { TMPF_RELATIVE = 1, TMPF_OVERRIDE = 1<<1, TMPF_TICBASED = 1<<2, TMPF_IGNORECOLLISION = 1<<3, TMPF_GHOSTFADE = 1<<4, } textmappolyfade_t; typedef struct polyfadedata_s { INT32 polyObjNum; INT32 destvalue; boolean docollision; boolean doghostfade; boolean ticbased; INT32 speed; } polyfadedata_t; // // Functions // boolean Polyobj_moveXY(polyobj_t *po, fixed_t x, fixed_t y, boolean checkmobjs); boolean Polyobj_rotate(polyobj_t *po, angle_t delta, boolean turnplayers, boolean turnothers, boolean checkmobjs); polyobj_t *Polyobj_GetForNum(INT32 id); void Polyobj_InitLevel(void); void Polyobj_MoveOnLoad(polyobj_t *po, angle_t angle, fixed_t x, fixed_t y); boolean P_PointInsidePolyobj(polyobj_t *po, fixed_t x, fixed_t y); boolean P_MobjTouchingPolyobj(polyobj_t *po, mobj_t *mo); boolean P_MobjInsidePolyobj(polyobj_t *po, mobj_t *mo); boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox); // thinkers (needed in p_saveg.c) void T_PolyObjRotate(polyrotate_t *); void T_PolyObjMove (polymove_t *); void T_PolyObjWaypoint (polywaypoint_t *); void T_PolyDoorSlide(polyslidedoor_t *); void T_PolyDoorSwing(polyswingdoor_t *); void T_PolyObjDisplace (polydisplace_t *); void T_PolyObjRotDisplace (polyrotdisplace_t *); void T_PolyObjFlag (polymove_t *); void T_PolyObjFade (polyfade_t *); boolean EV_DoPolyDoor(polydoordata_t *); boolean EV_DoPolyObjMove(polymovedata_t *); boolean EV_DoPolyObjWaypoint(polywaypointdata_t *); boolean EV_DoPolyObjRotate(polyrotdata_t *); boolean EV_DoPolyObjDisplace(polydisplacedata_t *); boolean EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *); boolean EV_DoPolyObjFlag(polyflagdata_t *); boolean EV_DoPolyObjFade(polyfadedata_t *); // // External Variables // extern polyobj_t *PolyObjects; extern INT32 numPolyObjects; extern polymaplink_t **polyblocklinks; // polyobject blockmap #endif // EOF