1 // Emacs style mode select -*- C++ -*-
2 //-----------------------------------------------------------------------------
3 //
4 // $Id:$
5 //
6 // Copyright (C) 1993-1996 by id Software, Inc.
7 //
8 // This source is available for distribution and/or modification
9 // only under the terms of the DOOM Source Code License as
10 // published by id Software. All rights reserved.
11 //
12 // The source is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
15 // for more details.
16 //
17 // DESCRIPTION:
18 // Play functions, animation, global header.
19 //
20 //-----------------------------------------------------------------------------
21
22
23 #ifndef __P_LOCAL__
24 #define __P_LOCAL__
25
26 #include "doomtype.h"
27 #include "doomdef.h"
28 #include "tables.h"
29 #include "r_state.h"
30 #include "r_utility.h"
31 #include "d_player.h"
32
33 #include "a_morph.h"
34
35 #include <stdlib.h>
36
37 #define STEEPSLOPE 46342 // [RH] Minimum floorplane.c value for walking
38
39 #define BONUSADD 6
40
41 // mapblocks are used to check movement
42 // against lines and things
43 #define MAPBLOCKUNITS 128
44 #define MAPBLOCKSIZE (MAPBLOCKUNITS*FRACUNIT)
45 #define MAPBLOCKSHIFT (FRACBITS+7)
46 #define MAPBMASK (MAPBLOCKSIZE-1)
47 #define MAPBTOFRAC (MAPBLOCKSHIFT-FRACBITS)
48
49 // Inspired by Maes
50 extern int bmapnegx;
51 extern int bmapnegy;
52
GetSafeBlockX(int blockx)53 inline int GetSafeBlockX(int blockx)
54 {
55 blockx >>= MAPBLOCKSHIFT;
56 return (blockx <= bmapnegx) ? blockx & 0x1FF : blockx;
57 }
GetSafeBlockX(long long blockx)58 inline int GetSafeBlockX(long long blockx)
59 {
60 blockx >>= MAPBLOCKSHIFT;
61 return int((blockx <= bmapnegx) ? blockx & 0x1FF : blockx);
62 }
63
GetSafeBlockY(int blocky)64 inline int GetSafeBlockY(int blocky)
65 {
66 blocky >>= MAPBLOCKSHIFT;
67 return (blocky <= bmapnegy) ? blocky & 0x1FF: blocky;
68 }
GetSafeBlockY(long long blocky)69 inline int GetSafeBlockY(long long blocky)
70 {
71 blocky >>= MAPBLOCKSHIFT;
72 return int((blocky <= bmapnegy) ? blocky & 0x1FF: blocky);
73 }
74
75 // MAXRADIUS is for precalculated sector block boxes
76 // the spider demon is larger,
77 // but we do not have any moving sectors nearby
78 #define MAXRADIUS 0/*32*FRACUNIT*/
79
80 //#define GRAVITY FRACUNIT
81 #define MAXMOVE (30*FRACUNIT)
82
83 #define TALKRANGE (128*FRACUNIT)
84 #define USERANGE (64*FRACUNIT)
85 #define MELEERANGE (64*FRACUNIT)
86 #define MISSILERANGE (32*64*FRACUNIT)
87 #define PLAYERMISSILERANGE (8192*FRACUNIT) // [RH] New MISSILERANGE for players
88
89 // follow a player exlusively for 3 seconds
90 #define BASETHRESHOLD 100
91
92
93 //
94 // P_PSPR
95 //
96 void P_SetupPsprites (player_t* curplayer, bool startweaponup);
97 void P_MovePsprites (player_t* curplayer);
98 void P_DropWeapon (player_t* player);
99
100
101 //
102 // P_USER
103 //
104 void P_FallingDamage (AActor *ent);
105 void P_PlayerThink (player_t *player);
106 void P_PredictPlayer (player_t *player);
107 void P_UnPredictPlayer ();
108 void P_PredictionLerpReset();
109
110 //
111 // P_MOBJ
112 //
113
114 #define ONFLOORZ FIXED_MIN
115 #define ONCEILINGZ FIXED_MAX
116 #define FLOATRANDZ (FIXED_MAX-1)
117
118 #define SPF_TEMPPLAYER 1 // spawning a short-lived dummy player
119 #define SPF_WEAPONFULLYUP 2 // spawn with weapon already raised
120
121 APlayerPawn *P_SpawnPlayer (struct FPlayerStart *mthing, int playernum, int flags=0);
122
123 void P_ThrustMobj (AActor *mo, angle_t angle, fixed_t move);
124 int P_FaceMobj (AActor *source, AActor *target, angle_t *delta);
125 bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool precise = false, bool usecurspeed=false);
126
127 enum EPuffFlags
128 {
129 PF_HITTHING = 1,
130 PF_MELEERANGE = 2,
131 PF_TEMPORARY = 4,
132 PF_HITTHINGBLEED = 8,
133 PF_NORANDOMZ = 16
134 };
135
136 AActor *P_SpawnPuff (AActor *source, const PClass *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags = 0, AActor *vict = NULL);
137 inline AActor *P_SpawnPuff(AActor *source, const PClass *pufftype, const fixedvec3 &pos, angle_t dir, int updown, int flags = 0, AActor *vict = NULL)
138 {
139 return P_SpawnPuff(source, pufftype, pos.x, pos.y, pos.z, dir, updown, flags, vict);
140 }
141 void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AActor *originator);
P_SpawnBlood(const fixedvec3 & pos,angle_t dir,int damage,AActor * originator)142 inline void P_SpawnBlood(const fixedvec3 &pos, angle_t dir, int damage, AActor *originator)
143 {
144 P_SpawnBlood(pos.x, pos.y, pos.z, dir, damage, originator);
145 }
146 void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator);
147 void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator);
148 void P_RipperBlood (AActor *mo, AActor *bleeder);
149 int P_GetThingFloorType (AActor *thing);
150 void P_ExplodeMissile (AActor *missile, line_t *explodeline, AActor *target);
151
152 AActor *P_SpawnMissile (AActor* source, AActor* dest, const PClass *type, AActor* owner = NULL);
153 AActor *P_SpawnMissileZ (AActor* source, fixed_t z, AActor* dest, const PClass *type);
154 AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z, AActor *source, AActor *dest, const PClass *type, bool checkspawn = true, AActor *owner = NULL);
155 inline AActor *P_SpawnMissileXYZ(const fixedvec3 &pos, AActor *source, AActor *dest, const PClass *type, bool checkspawn = true, AActor *owner = NULL)
156 {
157 return P_SpawnMissileXYZ(pos.x, pos.y, pos.z, source, dest, type, checkspawn, owner);
158 }
159 AActor *P_SpawnMissileAngle (AActor *source, const PClass *type, angle_t angle, fixed_t velz);
160 AActor *P_SpawnMissileAngleSpeed (AActor *source, const PClass *type, angle_t angle, fixed_t velz, fixed_t speed);
161 AActor *P_SpawnMissileAngleZ (AActor *source, fixed_t z, const PClass *type, angle_t angle, fixed_t velz);
162 AActor *P_SpawnMissileAngleZSpeed (AActor *source, fixed_t z, const PClass *type, angle_t angle, fixed_t velz, fixed_t speed, AActor *owner=NULL, bool checkspawn = true);
163 AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, const PClass *type);
164
165 AActor *P_SpawnPlayerMissile (AActor* source, const PClass *type);
166 AActor *P_SpawnPlayerMissile (AActor *source, const PClass *type, angle_t angle);
167 AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, const PClass *type, angle_t angle,
168 AActor **pLineTarget = NULL, AActor **MissileActor = NULL, bool nofreeaim = false, bool noautoaim = false);
169
170 void P_CheckFakeFloorTriggers (AActor *mo, fixed_t oldz, bool oldz_has_viewheight=false);
171
172 //
173 // [RH] P_THINGS
174 //
175 extern FClassMap SpawnableThings;
176 extern FClassMap StrifeTypes;
177
178 bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog, int newtid);
179 bool P_Thing_Projectile (int tid, AActor *source, int type, const char * type_name, angle_t angle,
180 fixed_t speed, fixed_t vspeed, int dest, AActor *forcedest, int gravity, int newtid,
181 bool leadTarget);
182 bool P_MoveThing(AActor *source, fixed_t x, fixed_t y, fixed_t z, bool fog);
183 bool P_Thing_Move (int tid, AActor *source, int mapspot, bool fog);
184 int P_Thing_Damage (int tid, AActor *whofor0, int amount, FName type);
185 void P_Thing_SetVelocity(AActor *actor, fixed_t vx, fixed_t vy, fixed_t vz, bool add, bool setbob);
186 void P_RemoveThing(AActor * actor);
187 bool P_Thing_Raise(AActor *thing, AActor *raiser);
188 bool P_Thing_CanRaise(AActor *thing);
189 const PClass *P_GetSpawnableType(int spawnnum);
190 void InitSpawnablesFromMapinfo();
191 int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t zofs, angle_t angle, int flags, fixed_t heightoffset, fixed_t radiusoffset, angle_t pitch);
192
193 enum WARPF
194 {
195 WARPF_ABSOLUTEOFFSET = 0x1,
196 WARPF_ABSOLUTEANGLE = 0x2,
197 WARPF_USECALLERANGLE = 0x4,
198
199 WARPF_NOCHECKPOSITION = 0x8,
200
201 WARPF_INTERPOLATE = 0x10,
202 WARPF_WARPINTERPOLATION = 0x20,
203 WARPF_COPYINTERPOLATION = 0x40,
204
205 WARPF_STOP = 0x80,
206 WARPF_TOFLOOR = 0x100,
207 WARPF_TESTONLY = 0x200,
208 WARPF_ABSOLUTEPOSITION = 0x400,
209 WARPF_BOB = 0x800,
210 WARPF_MOVEPTR = 0x1000,
211 WARPF_USEPTR = 0x2000,
212 WARPF_USETID = 0x2000,
213 WARPF_COPYVELOCITY = 0x4000,
214 WARPF_COPYPITCH = 0x8000,
215 };
216
217
218
219 //
220 // P_MAPUTL
221 //
222 struct divline_t
223 {
224 fixed_t x;
225 fixed_t y;
226 fixed_t dx;
227 fixed_t dy;
228
229 };
230
231 struct intercept_t
232 {
233 fixed_t frac; // along trace line
234 bool isaline;
235 bool done;
236 union {
237 AActor *thing;
238 line_t *line;
239 } d;
240 };
241
242 typedef bool (*traverser_t) (intercept_t *in);
243
244 fixed_t P_AproxDistance (fixed_t dx, fixed_t dy);
245
246 //==========================================================================
247 //
248 // P_PointOnLineSide
249 //
250 // Returns 0 (front/on) or 1 (back)
251 // [RH] inlined, stripped down, and made more precise
252 //
253 //==========================================================================
254
P_PointOnLineSide(fixed_t x,fixed_t y,const line_t * line)255 inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line)
256 {
257 extern int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line);
258
259 return i_compatflags2 & COMPATF2_POINTONLINE
260 ? P_VanillaPointOnLineSide(x, y, line)
261 : DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0;
262 }
263
P_PointOnLineSidePrecise(fixed_t x,fixed_t y,const line_t * line)264 inline int P_PointOnLineSidePrecise (fixed_t x, fixed_t y, const line_t *line)
265 {
266 return DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0;
267 }
268
269
270 //==========================================================================
271 //
272 // P_PointOnDivlineSide
273 //
274 // Same as P_PointOnLineSide except it uses divlines
275 // [RH] inlined, stripped down, and made more precise
276 //
277 //==========================================================================
278
P_PointOnDivlineSide(fixed_t x,fixed_t y,const divline_t * line)279 inline int P_PointOnDivlineSide (fixed_t x, fixed_t y, const divline_t *line)
280 {
281 extern int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const divline_t* line);
282
283 return (i_compatflags2 & COMPATF2_POINTONLINE)
284 ? P_VanillaPointOnDivlineSide(x, y, line)
285 : (DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0);
286 }
287
P_PointOnDivlineSidePrecise(fixed_t x,fixed_t y,const divline_t * line)288 inline int P_PointOnDivlineSidePrecise (fixed_t x, fixed_t y, const divline_t *line)
289 {
290 return DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0;
291 }
292
293
294 //==========================================================================
295 //
296 // P_MakeDivline
297 //
298 //==========================================================================
299
P_MakeDivline(const line_t * li,divline_t * dl)300 inline void P_MakeDivline (const line_t *li, divline_t *dl)
301 {
302 dl->x = li->v1->x;
303 dl->y = li->v1->y;
304 dl->dx = li->dx;
305 dl->dy = li->dy;
306 }
307
308 fixed_t P_InterceptVector (const divline_t *v2, const divline_t *v1);
309
310 struct FLineOpening
311 {
312 fixed_t top;
313 fixed_t bottom;
314 fixed_t range;
315 fixed_t lowfloor;
316 sector_t *bottomsec;
317 sector_t *topsec;
318 FTextureID ceilingpic;
319 FTextureID floorpic;
320 int floorterrain;
321 bool touchmidtex;
322 bool abovemidtex;
323 };
324
325 void P_LineOpening (FLineOpening &open, AActor *thing, const line_t *linedef, fixed_t x, fixed_t y, fixed_t refx=FIXED_MIN, fixed_t refy=0, int flags=0);
326
327 class FBoundingBox;
328 struct polyblock_t;
329
330 class FBlockLinesIterator
331 {
332 int minx, maxx;
333 int miny, maxy;
334
335 int curx, cury;
336 polyblock_t *polyLink;
337 int polyIndex;
338 int *list;
339
340 void StartBlock(int x, int y);
341
342 public:
343 FBlockLinesIterator(int minx, int miny, int maxx, int maxy, bool keepvalidcount = false);
344 FBlockLinesIterator(const FBoundingBox &box);
345 line_t *Next();
Reset()346 void Reset() { StartBlock(minx, miny); }
347 };
348
349 class FBlockThingsIterator
350 {
351 int minx, maxx;
352 int miny, maxy;
353
354 int curx, cury;
355
356 FBlockNode *block;
357
358 int Buckets[32];
359
360 struct HashEntry
361 {
362 AActor *Actor;
363 int Next;
364 };
365 HashEntry FixedHash[10];
366 int NumFixedHash;
367 TArray<HashEntry> DynHash;
368
GetHashEntry(int i)369 HashEntry *GetHashEntry(int i) { return i < (int)countof(FixedHash) ? &FixedHash[i] : &DynHash[i - countof(FixedHash)]; }
370
371 void StartBlock(int x, int y);
372 void SwitchBlock(int x, int y);
373 void ClearHash();
374
375 // The following is only for use in the path traverser
376 // and therefore declared private.
377 FBlockThingsIterator();
378
379 friend class FPathTraverse;
380
381 public:
382 FBlockThingsIterator(int minx, int miny, int maxx, int maxy);
383 FBlockThingsIterator(const FBoundingBox &box);
384 AActor *Next(bool centeronly = false);
Reset()385 void Reset() { StartBlock(minx, miny); }
386 };
387
388 class FPathTraverse
389 {
390 static TArray<intercept_t> intercepts;
391
392 divline_t trace;
393 unsigned int intercept_index;
394 unsigned int intercept_count;
395 unsigned int count;
396
397 void AddLineIntercepts(int bx, int by);
398 void AddThingIntercepts(int bx, int by, FBlockThingsIterator &it, bool compatible);
399 public:
400
401 intercept_t *Next();
402
403 FPathTraverse(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags);
404 ~FPathTraverse();
Trace()405 const divline_t &Trace() const { return trace; }
406 };
407
408
409 #define PT_ADDLINES 1
410 #define PT_ADDTHINGS 2
411 #define PT_COMPATIBLE 4
412 #define PT_DELTA 8 // x2,y2 is passed as a delta, not as an endpoint
413
414 AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, int, void *), void *params = NULL);
415 AActor *P_RoughMonsterSearch (AActor *mo, int distance, bool onlyseekable=false);
416
417 //
418 // P_MAP
419 //
420
421 struct FCheckPosition
422 {
423 // in
424 AActor *thing;
425 fixed_t x;
426 fixed_t y;
427 fixed_t z;
428
429 // out
430 sector_t *sector;
431 fixed_t floorz;
432 fixed_t ceilingz;
433 fixed_t dropoffz;
434 FTextureID floorpic;
435 int floorterrain;
436 sector_t *floorsector;
437 FTextureID ceilingpic;
438 sector_t *ceilingsector;
439 bool touchmidtex;
440 bool abovemidtex;
441 bool floatok;
442 bool FromPMove;
443 line_t *ceilingline;
444 AActor *stepthing;
445 // [RH] These are used by PIT_CheckThing and P_XYMovement to apply
446 // ripping damage once per tic instead of once per move.
447 bool DoRipping;
448 TMap<AActor*, bool> LastRipped;
449 int PushTime;
450
451 FCheckPosition(bool rip=false)
452 {
453 DoRipping = rip;
454 PushTime = 0;
455 FromPMove = false;
456 }
457 };
458
459
460
461 // If "floatok" true, move would be ok
462 // if within "tmfloorz - tmceilingz".
463 extern msecnode_t *sector_list; // phares 3/16/98
464
465 extern TArray<line_t *> spechit;
466
467
468 bool P_TestMobjLocation (AActor *mobj);
469 bool P_TestMobjZ (AActor *mobj, bool quick=true, AActor **pOnmobj = NULL);
470 bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bool actorsonly=false);
471 bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, bool actorsonly=false);
472 inline bool P_CheckPosition(AActor *thing, const fixedvec3 &pos, bool actorsonly = false)
473 {
474 return P_CheckPosition(thing, pos.x, pos.y, actorsonly);
475 }
476 AActor *P_CheckOnmobj (AActor *thing);
477 void P_FakeZMovement (AActor *mo);
478 bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, int dropoff, const secplane_t * onfloor, FCheckPosition &tm, bool missileCheck = false);
479 bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, int dropoff, const secplane_t * onfloor = NULL);
480 bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y);
481 void P_ApplyTorque(AActor *mo);
482 bool P_TeleportMove (AActor* thing, fixed_t x, fixed_t y, fixed_t z, bool telefrag, bool modifyactor = true); // [RH] Added z and telefrag parameters
483 inline bool P_TeleportMove(AActor* thing, const fixedvec3 &pos, bool telefrag, bool modifyactor = true)
484 {
485 return P_TeleportMove(thing, pos.x, pos.y, pos.z, telefrag, modifyactor);
486 }
487 void P_PlayerStartStomp (AActor *actor, bool mononly=false); // [RH] Stomp on things for a newly spawned player
488 void P_SlideMove (AActor* mo, fixed_t tryx, fixed_t tryy, int numsteps);
489 bool P_BounceWall (AActor *mo);
490 bool P_BounceActor (AActor *mo, AActor *BlockingMobj, bool ontop);
491 bool P_CheckSight (const AActor *t1, const AActor *t2, int flags=0);
492
493 enum ESightFlags
494 {
495 SF_IGNOREVISIBILITY=1,
496 SF_SEEPASTSHOOTABLELINES=2,
497 SF_SEEPASTBLOCKEVERYTHING=4,
498 SF_IGNOREWATERBOUNDARY=8
499 };
500
501 void P_ResetSightCounters (bool full);
502 bool P_TalkFacing (AActor *player);
503 void P_UseLines (player_t* player);
504 bool P_UsePuzzleItem (AActor *actor, int itemType);
505
506 enum
507 {
508 FFCF_ONLYSPAWNPOS = 1,
509 FFCF_SAMESECTOR = 2,
510 FFCF_ONLY3DFLOORS = 4, // includes 3D midtexes
511 FFCF_3DRESTRICT = 8, // ignore 3D midtexes and floors whose floorz are above thing's z
512 };
513 void P_FindFloorCeiling (AActor *actor, int flags=0);
514
515 bool P_ChangeSector (sector_t* sector, int crunch, int amt, int floorOrCeil, bool isreset);
516
517 fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget = NULL, fixed_t vrange=0, int flags = 0, AActor *target=NULL, AActor *friender=NULL);
518
519 enum // P_AimLineAttack flags
520 {
521 ALF_FORCENOSMART = 1,
522 ALF_CHECK3D = 2,
523 ALF_CHECKNONSHOOTABLE = 4,
524 ALF_CHECKCONVERSATION = 8,
525 ALF_NOFRIENDS = 16,
526 };
527
528 enum // P_LineAttack flags
529 {
530 LAF_ISMELEEATTACK = 1,
531 LAF_NORANDOMPUFFZ = 2,
532 LAF_NOIMPACTDECAL = 4
533 };
534
535 AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, const PClass *pufftype, int flags = 0, AActor **victim = NULL, int *actualdamage = NULL);
536 AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype, int flags = 0, AActor **victim = NULL, int *actualdamage = NULL);
537 AActor *P_LinePickActor (AActor *t1, angle_t angle, fixed_t distance, int pitch, ActorFlags actorMask, DWORD wallMask);
538 void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target, angle_t angle, int pitch);
539 void P_TraceBleed (int damage, AActor *target, angle_t angle, int pitch);
540 void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile version
541 void P_TraceBleed (int damage, AActor *target); // random direction version
542 bool P_HitFloor (AActor *thing);
543 bool P_HitWater (AActor *thing, sector_t *sec, fixed_t splashx = FIXED_MIN, fixed_t splashy = FIXED_MIN, fixed_t splashz=FIXED_MIN, bool checkabove = false, bool alert = true, bool force = false);
544 void P_CheckSplash(AActor *self, fixed_t distance);
545 void P_RailAttack (AActor *source, int damage, int offset_xy, fixed_t offset_z = 0, int color1 = 0, int color2 = 0, double maxdiff = 0, int flags = 0, const PClass *puff = NULL, angle_t angleoffset = 0, angle_t pitchoffset = 0, fixed_t distance = 8192*FRACUNIT, int duration = 0, double sparsity = 1.0, double drift = 1.0, const PClass *spawnclass = NULL, int SpiralOffset = 270); // [RH] Shoot a railgun
546
547 enum // P_RailAttack / A_RailAttack / A_CustomRailgun / P_DrawRailTrail flags
548 {
549 RAF_SILENT = 1,
550 RAF_NOPIERCE = 2,
551 RAF_EXPLICITANGLE = 4,
552 RAF_FULLBRIGHT = 8,
553 RAF_CENTERZ = 16,
554 };
555
556
557 bool P_CheckMissileSpawn (AActor *missile, fixed_t maxdist);
558 void P_PlaySpawnSound(AActor *missile, AActor *spawner);
559
560 // [RH] Position the chasecam
561 void P_AimCamera (AActor *t1, fixed_t &x, fixed_t &y, fixed_t &z, sector_t *&sec);
562
563 // [RH] Means of death
564 enum
565 {
566 RADF_HURTSOURCE = 1,
567 RADF_NOIMPACTDAMAGE = 2,
568 RADF_SOURCEISSPOT = 4,
569 RADF_NODAMAGE = 8,
570 };
571 void P_RadiusAttack (AActor *spot, AActor *source, int damage, int distance,
572 FName damageType, int flags, int fulldamagedistance=0);
573
574 void P_DelSector_List();
575 void P_DelSeclist(msecnode_t *); // phares 3/16/98
576 msecnode_t* P_DelSecnode(msecnode_t *);
577 void P_CreateSecNodeList(AActor*,fixed_t,fixed_t); // phares 3/14/98
578 int P_GetMoveFactor(const AActor *mo, int *frictionp); // phares 3/6/98
579 int P_GetFriction(const AActor *mo, int *frictionfactor);
580 bool Check_Sides(AActor *, int, int); // phares
581
582 // [RH]
583 const secplane_t * P_CheckSlopeWalk (AActor *actor, fixed_t &xmove, fixed_t &ymove);
584
585 //----------------------------------------------------------------------------------
586 //
587 // Added so that in the source there's a clear distinction between
588 // game engine and renderer specific calls.
589 // (For ZDoom itself this doesn't make any difference here but for GZDoom it does.)
590 //
591 //----------------------------------------------------------------------------------
592 subsector_t *P_PointInSubsector (fixed_t x, fixed_t y);
P_PointInSector(fixed_t x,fixed_t y)593 inline sector_t *P_PointInSector(fixed_t x, fixed_t y)
594 {
595 return P_PointInSubsector(x,y)->sector;
596 }
597
598 //
599 // P_SETUP
600 //
601 extern BYTE* rejectmatrix; // for fast sight rejection
602 extern int* blockmaplump; // offsets in blockmap are from here
603
604 extern int* blockmap;
605 extern int bmapwidth;
606 extern int bmapheight; // in mapblocks
607 extern fixed_t bmaporgx;
608 extern fixed_t bmaporgy; // origin of block map
609 extern FBlockNode** blocklinks; // for thing chains
610
611
612
613 //
614 // P_INTER
615 //
616 void P_TouchSpecialThing (AActor *special, AActor *toucher);
617 int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags=0);
618 void P_PoisonMobj (AActor *target, AActor *inflictor, AActor *source, int damage, int duration, int period, FName type);
619 bool P_GiveBody (AActor *actor, int num, int max=0);
620 bool P_PoisonPlayer (player_t *player, AActor *poisoner, AActor *source, int poison);
621 void P_PoisonDamage (player_t *player, AActor *source, int damage, bool playPainSound);
622
623 enum EDmgFlags
624 {
625 DMG_NO_ARMOR = 1,
626 DMG_INFLICTOR_IS_PUFF = 2,
627 DMG_THRUSTLESS = 4,
628 DMG_FORCED = 8,
629 DMG_NO_FACTOR = 16,
630 DMG_PLAYERATTACK = 32,
631 DMG_FOILINVUL = 64,
632 DMG_FOILBUDDHA = 128,
633 DMG_NO_PROTECT = 256,
634 };
635
636
637 // ===== PO_MAN =====
638
639 typedef enum
640 {
641 PODOOR_NONE,
642 PODOOR_SLIDE,
643 PODOOR_SWING,
644 } podoortype_t;
645
646 bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle, int direction, bool overRide);
647 bool EV_MovePoly (line_t *line, int polyNum, int speed, angle_t angle, fixed_t dist, bool overRide);
648 bool EV_MovePolyTo (line_t *line, int polyNum, int speed, fixed_t x, fixed_t y, bool overRide);
649 bool EV_OpenPolyDoor (line_t *line, int polyNum, int speed, angle_t angle, int delay, int distance, podoortype_t type);
650 bool EV_StopPoly (int polyNum);
651
652
653 // [RH] Data structure for P_SpawnMapThing() to keep track
654 // of polyobject-related things.
655 struct polyspawns_t
656 {
657 polyspawns_t *next;
658 fixed_t x;
659 fixed_t y;
660 short angle;
661 short type;
662 };
663
664 extern int po_NumPolyobjs;
665 extern polyspawns_t *polyspawns; // [RH] list of polyobject things to spawn
666
667
668 void PO_Init ();
669 bool PO_Busy (int polyobj);
670 FPolyObj *PO_GetPolyobj(int polyNum);
671
672 //
673 // P_SPEC
674 //
675 #include "p_spec.h"
676
677 bool P_AlignFlat (int linenum, int side, int fc);
678
679 #endif // __P_LOCAL__
680