1 // SONIC ROBO BLAST 2
2 //-----------------------------------------------------------------------------
3 // Copyright (C) 2006      by James Haley
4 // Copyright (C) 2006-2020 by Sonic Team Junior.
5 //
6 // This program is free software distributed under the
7 // terms of the GNU General Public License, version 2.
8 // See the 'LICENSE' file for more details.
9 //-----------------------------------------------------------------------------
10 /// \file  p_polyobj.h
11 /// \brief Movable segs like in Hexen, but more flexible
12 ///        due to application of dynamic binary space partitioning theory.
13 
14 #ifndef POLYOBJ_H__
15 #define POLYOBJ_H__
16 
17 #include "m_dllist.h"
18 #include "p_mobj.h"
19 #include "r_defs.h"
20 
21 //
22 // Defines
23 //
24 
25 // haleyjd: use zdoom-compatible doomednums
26 
27 #define POLYOBJ_ANCHOR_DOOMEDNUM     760
28 #define POLYOBJ_SPAWN_DOOMEDNUM      761
29 
30 #define POLYOBJ_START_LINE    20
31 
32 typedef enum
33 {
34 	POF_CLIPLINES         = 0x1,       ///< Test against lines for collision
35 	POF_CLIPPLANES        = 0x2,       ///< Test against tops and bottoms for collision
36 	POF_SOLID             = 0x3,       ///< Clips things.
37 	POF_TESTHEIGHT        = 0x4,       ///< Test line collision with heights
38 	POF_RENDERSIDES       = 0x8,       ///< Renders the sides.
39 	POF_RENDERTOP         = 0x10,      ///< Renders the top.
40 	POF_RENDERBOTTOM      = 0x20,      ///< Renders the bottom.
41 	POF_RENDERPLANES      = 0x30,      ///< Renders top and bottom.
42 	POF_RENDERALL         = 0x38,      ///< Renders everything.
43 	POF_INVERT            = 0x40,      ///< Inverts collision (like a cage).
44 	POF_INVERTPLANES      = 0x80,      ///< Render inside planes.
45 	POF_INVERTPLANESONLY  = 0x100,     ///< Only render inside planes.
46 	POF_PUSHABLESTOP      = 0x200,     ///< Pushables will stop movement.
47 	POF_LDEXEC            = 0x400,     ///< This PO triggers a linedef executor.
48 	POF_ONESIDE           = 0x800,     ///< Only use the first side of the linedef.
49 	POF_NOSPECIALS        = 0x1000,    ///< Don't apply sector specials.
50 	POF_SPLAT             = 0x2000,    ///< Use splat flat renderer (treat cyan pixels as invisible).
51 } polyobjflags_e;
52 
53 typedef enum
54 {
55 	TMPF_NOINSIDES       = 1,
56 	TMPF_INTANGIBLE      = 1<<1,
57 	TMPF_PUSHABLESTOP    = 1<<2,
58 	TMPF_INVISIBLEPLANES = 1<<3,
59 	TMPF_EXECUTOR        = 1<<4,
60 	TMPF_CRUSH           = 1<<5,
61 	TMPF_SPLAT           = 1<<6,
62 	//TMPF_DONTCLIPPLANES  = 1<<7,
63 } textmappolyobjectflags_t;
64 
65 //
66 // Polyobject Structure
67 //
68 
69 typedef struct polyobj_s
70 {
71 	mdllistitem_t link; // for subsector links; must be first
72 
73 	INT32 id;    // numeric id
74 	INT32 first; // for hashing: index of first polyobject in this hash chain
75 	INT32 next;  // for hashing: next polyobject in this hash chain
76 
77 	INT32 parent; // numeric id of parent polyobject
78 
79 	size_t segCount;        // number of segs in polyobject
80 	size_t numSegsAlloc;    // number of segs allocated
81 	struct seg_s **segs; // the segs, a reallocating array.
82 
83 	size_t numVertices;            // number of vertices (generally == segCount)
84 	size_t numVerticesAlloc;       // number of vertices allocated
85 	vertex_t *origVerts; // original positions relative to spawn spot
86 	vertex_t *tmpVerts;  // temporary vertex backups for rotation
87 	vertex_t **vertices; // vertices this polyobject must move
88 
89 	size_t numLines;          // number of linedefs (generally <= segCount)
90 	size_t numLinesAlloc;     // number of linedefs allocated
91 	struct line_s **lines; // linedefs this polyobject must move
92 
93 	degenmobj_t spawnSpot; // location of spawn spot
94 	vertex_t    centerPt;  // center point
95 	fixed_t zdist;         // viewz distance for sorting
96 	angle_t angle;         // for rotation
97 	UINT8 attached;         // if true, is attached to a subsector
98 
99 	fixed_t blockbox[4]; // bounding box for clipping
100 	UINT8 linked;         // is linked to blockmap
101 	size_t validcount;   // for clipping: prevents multiple checks
102 	INT32 damage;        // damage to inflict on stuck things
103 	fixed_t thrust;      // amount of thrust to put on blocking objects
104 	INT32 flags;         // Flags for this polyobject
105 
106 	thinker_t *thinker;  // pointer to a thinker affecting this polyobj
107 
108 	UINT8 isBad;         // a bad polyobject: should not be rendered/manipulated
109 	INT32 translucency; // index to translucency tables
110 	INT16 triggertag;   // Tag of linedef executor to trigger on touch
111 
112 	struct visplane_s *visplane; // polyobject's visplane, for ease of putting into the list later
113 
114 	// these are saved for netgames, so do not let Lua touch these!
115 	INT32 spawnflags; // Flags the polyobject originally spawned with
116 	INT32 spawntrans; // Translucency the polyobject originally spawned with
117 } polyobj_t;
118 
119 //
120 // Polyobject Blockmap Link Structure
121 //
122 
123 typedef struct polymaplink_s
124 {
125 	mdllistitem_t link; // for blockmap links
126 	polyobj_t *po;      // pointer to polyobject
127 } polymaplink_t;
128 
129 //
130 // Polyobject Special Thinkers
131 //
132 
133 typedef struct polyrotate_s
134 {
135 	thinker_t thinker; // must be first
136 
137 	INT32 polyObjNum;    // numeric id of polyobject (avoid C pointers here)
138 	INT32 speed;         // speed of movement per frame
139 	INT32 distance;      // distance to move
140 	UINT8 turnobjs;      // turn objects? 0=no, 1=everything but players, 2=everything
141 } polyrotate_t;
142 
143 typedef struct polymove_s
144 {
145 	thinker_t thinker;  // must be first
146 
147 	INT32 polyObjNum;   // numeric id of polyobject
148 	INT32 speed;        // resultant velocity
149 	fixed_t momx;       // x component of speed along angle
150 	fixed_t momy;       // y component of speed along angle
151 	INT32 distance;     // total distance to move
152 	UINT32 angle;       // angle along which to move
153 } polymove_t;
154 
155 // PolyObject waypoint movement return behavior
156 typedef enum
157 {
158 	PWR_STOP,     // Stop after reaching last waypoint
159 	PWR_WRAP,     // Wrap back to first waypoint
160 	PWR_COMEBACK, // Repeat sequence in reverse
161 } polywaypointreturn_e;
162 
163 typedef struct polywaypoint_s
164 {
165 	thinker_t thinker; // must be first
166 
167 	INT32 polyObjNum;      // numeric id of polyobject
168 	INT32 speed;           // resultant velocity
169 	INT32 sequence;        // waypoint sequence #
170 	INT32 pointnum;        // waypoint #
171 	INT32 direction;       // 1 for normal, -1 for backwards
172 	UINT8 returnbehavior;  // behavior after reaching the last waypoint
173 	UINT8 continuous;      // continuously move - used with PWR_WRAP or PWR_COMEBACK
174 	UINT8 stophere;        // Will stop after it reaches the next waypoint
175 } polywaypoint_t;
176 
177 typedef struct polyslidedoor_s
178 {
179 	thinker_t thinker;      // must be first
180 
181 	INT32 polyObjNum;         // numeric id of affected polyobject
182 	INT32 delay;              // delay time
183 	INT32 delayCount;         // delay counter
184 	INT32 initSpeed;          // initial speed
185 	INT32 speed;              // speed of motion
186 	INT32 initDistance;       // initial distance to travel
187 	INT32 distance;           // current distance to travel
188 	UINT32 initAngle;         // intial angle
189 	UINT32 angle;             // angle of motion
190 	UINT32 revAngle;          // reversed angle to avoid roundoff error
191 	fixed_t momx;             // x component of speed along angle
192 	fixed_t momy;             // y component of speed along angle
193 	UINT8 closing;             // if true, is closing
194 } polyslidedoor_t;
195 
196 typedef struct polyswingdoor_s
197 {
198 	thinker_t thinker; // must be first
199 
200 	INT32 polyObjNum;    // numeric id of affected polyobject
201 	INT32 delay;         // delay time
202 	INT32 delayCount;    // delay counter
203 	INT32 initSpeed;     // initial speed
204 	INT32 speed;         // speed of rotation
205 	INT32 initDistance;  // initial distance to travel
206 	INT32 distance;      // current distance to travel
207 	UINT8 closing;        // if true, is closing
208 } polyswingdoor_t;
209 
210 typedef struct polydisplace_s
211 {
212 	thinker_t thinker; // must be first
213 
214 	INT32 polyObjNum;
215 	struct sector_s *controlSector;
216 	fixed_t dx;
217 	fixed_t dy;
218 	fixed_t oldHeights;
219 } polydisplace_t;
220 
221 typedef struct polyrotdisplace_s
222 {
223 	thinker_t thinker; // must be first
224 
225 	INT32 polyObjNum;
226 	struct sector_s *controlSector;
227 	fixed_t rotscale;
228 	UINT8 turnobjs;
229 	fixed_t oldHeights;
230 } polyrotdisplace_t;
231 
232 typedef struct polyfade_s
233 {
234 	thinker_t thinker; // must be first
235 
236 	INT32 polyObjNum;
237 	INT32 sourcevalue;
238 	INT32 destvalue;
239 	boolean docollision;
240 	boolean doghostfade;
241 	boolean ticbased;
242 	INT32 duration;
243 	INT32 timer;
244 } polyfade_t;
245 
246 //
247 // Line Activation Data Structures
248 //
249 
250 typedef struct polyrotdata_s
251 {
252 	INT32 polyObjNum;   // numeric id of polyobject to affect
253 	INT32 direction;    // direction of rotation
254 	INT32 speed;        // angular speed
255 	INT32 distance;     // distance to move
256 	UINT8 turnobjs;     // rotate objects being carried?
257 	UINT8 overRide;     // if true, will override any action on the object
258 } polyrotdata_t;
259 
260 typedef struct polymovedata_s
261 {
262 	INT32 polyObjNum;   // numeric id of polyobject to affect
263 	fixed_t distance;   // distance to move
264 	fixed_t speed;      // linear speed
265 	angle_t angle;      // angle of movement
266 	UINT8 overRide;     // if true, will override any action on the object
267 } polymovedata_t;
268 
269 typedef enum
270 {
271 	PWF_REVERSE = 1,    // Move through waypoints in reverse order
272 	PWF_LOOP    = 1<<1, // Loop movement (used with PWR_WRAP or PWR_COMEBACK)
273 } polywaypointflags_e;
274 
275 typedef struct polywaypointdata_s
276 {
277 	INT32 polyObjNum;     // numeric id of polyobject to affect
278 	INT32 sequence;       // waypoint sequence #
279 	fixed_t speed;        // linear speed
280 	UINT8 returnbehavior; // behavior after reaching the last waypoint
281 	UINT8 flags;          // PWF_ flags
282 } polywaypointdata_t;
283 
284 // polyobject door types
285 typedef enum
286 {
287 	POLY_DOOR_SLIDE,
288 	POLY_DOOR_SWING,
289 } polydoor_e;
290 
291 typedef struct polydoordata_s
292 {
293 	INT32 polyObjNum;     // numeric id of polyobject to affect
294 	INT32 doorType;       // polyobj door type
295 	INT32 speed;          // linear or angular speed
296 	angle_t angle;        // for slide door only, angle of motion
297 	INT32 distance;       // distance to move
298 	INT32 delay;          // delay time after opening
299 } polydoordata_t;
300 
301 typedef struct polydisplacedata_s
302 {
303 	INT32 polyObjNum;
304 	struct sector_s *controlSector;
305 	fixed_t dx;
306 	fixed_t dy;
307 } polydisplacedata_t;
308 
309 typedef struct polyrotdisplacedata_s
310 {
311 	INT32 polyObjNum;
312 	struct sector_s *controlSector;
313 	fixed_t rotscale;
314 	UINT8 turnobjs;
315 } polyrotdisplacedata_t;
316 
317 typedef struct polyflagdata_s
318 {
319 	INT32 polyObjNum;
320 	INT32 speed;
321 	UINT32 angle;
322 	fixed_t momx;
323 } polyflagdata_t;
324 
325 typedef struct polyfadedata_s
326 {
327 	INT32 polyObjNum;
328 	INT32 destvalue;
329 	boolean docollision;
330 	boolean doghostfade;
331 	boolean ticbased;
332 	INT32 speed;
333 } polyfadedata_t;
334 
335 //
336 // Functions
337 //
338 
339 boolean Polyobj_moveXY(polyobj_t *po, fixed_t x, fixed_t y, boolean checkmobjs);
340 boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings, boolean checkmobjs);
341 polyobj_t *Polyobj_GetForNum(INT32 id);
342 void Polyobj_InitLevel(void);
343 void Polyobj_MoveOnLoad(polyobj_t *po, angle_t angle, fixed_t x, fixed_t y);
344 boolean P_PointInsidePolyobj(polyobj_t *po, fixed_t x, fixed_t y);
345 boolean P_MobjTouchingPolyobj(polyobj_t *po, mobj_t *mo);
346 boolean P_MobjInsidePolyobj(polyobj_t *po, mobj_t *mo);
347 boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox);
348 
349 // thinkers (needed in p_saveg.c)
350 void T_PolyObjRotate(polyrotate_t *);
351 void T_PolyObjMove  (polymove_t *);
352 void T_PolyObjWaypoint (polywaypoint_t *);
353 void T_PolyDoorSlide(polyslidedoor_t *);
354 void T_PolyDoorSwing(polyswingdoor_t *);
355 void T_PolyObjDisplace  (polydisplace_t *);
356 void T_PolyObjRotDisplace  (polyrotdisplace_t *);
357 void T_PolyObjFlag  (polymove_t *);
358 void T_PolyObjFade  (polyfade_t *);
359 
360 boolean EV_DoPolyDoor(polydoordata_t *);
361 boolean EV_DoPolyObjMove(polymovedata_t *);
362 boolean EV_DoPolyObjWaypoint(polywaypointdata_t *);
363 boolean EV_DoPolyObjRotate(polyrotdata_t *);
364 boolean EV_DoPolyObjDisplace(polydisplacedata_t *);
365 boolean EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *);
366 boolean EV_DoPolyObjFlag(polyflagdata_t *);
367 boolean EV_DoPolyObjFade(polyfadedata_t *);
368 
369 
370 //
371 // External Variables
372 //
373 
374 extern polyobj_t *PolyObjects;
375 extern INT32 numPolyObjects;
376 extern polymaplink_t **polyblocklinks; // polyobject blockmap
377 
378 #endif
379 
380 // EOF
381