2016-03-01 15:47:10 +00:00
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// $Id:$
//
// Copyright (C) 1993-1996 by id Software, Inc.
//
// This source is available for distribution and/or modification
// only under the terms of the DOOM Source Code License as
// published by id Software. All rights reserved.
//
// The source is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
// for more details.
//
// DESCRIPTION:
// Play functions, animation, global header.
//
//-----------------------------------------------------------------------------
# ifndef __P_LOCAL__
# define __P_LOCAL__
2016-03-23 09:42:41 +00:00
# include <float.h>
2016-03-01 15:47:10 +00:00
# include "doomtype.h"
2016-03-16 11:41:26 +00:00
# include "vectors.h"
2016-05-09 06:41:35 +00:00
# include "dobject.h"
2016-03-01 15:47:10 +00:00
2016-03-23 09:42:41 +00:00
const double NO_VALUE = FLT_MAX ;
2016-03-01 15:47:10 +00:00
class player_t ;
class AActor ;
struct FPlayerStart ;
class PClassActor ;
class APlayerPawn ;
struct line_t ;
struct sector_t ;
struct msecnode_t ;
struct secplane_t ;
struct FCheckPosition ;
struct FTranslatedLineTarget ;
# include <stdlib.h>
2016-03-30 07:41:46 +00:00
# define STEEPSLOPE (46342 / 65536.) // [RH] Minimum floorplane.c value for walking
2016-03-01 15:47:10 +00:00
# define BONUSADD 6
// mapblocks are used to check movement
// against lines and things
# define MAPBLOCKUNITS 128
// Inspired by Maes
extern int bmapnegx ;
extern int bmapnegy ;
//#define GRAVITY FRACUNIT
2016-03-19 23:54:18 +00:00
# define MAXMOVE (30.)
2016-03-01 15:47:10 +00:00
2016-03-17 10:38:56 +00:00
# define TALKRANGE (128.)
2016-03-27 18:58:01 +00:00
# define USERANGE (64.)
2016-03-17 10:38:56 +00:00
# define MELEERANGE (64.)
# define SAWRANGE (64.+(1. / 65536.)) // use meleerange + 1 so the puff doesn't skip the flash (i.e. plays all states)
# define MISSILERANGE (32*64.)
# define PLAYERMISSILERANGE (8192.) // [RH] New MISSILERANGE for players
2016-03-01 15:47:10 +00:00
// follow a player exlusively for 3 seconds
// No longer used.
// #define BASETHRESHOLD 100
//
// P_PSPR
//
void P_SetupPsprites ( player_t * curplayer , bool startweaponup ) ;
void P_DropWeapon ( player_t * player ) ;
//
// P_USER
//
void P_FallingDamage ( AActor * ent ) ;
void P_PlayerThink ( player_t * player ) ;
void P_PredictPlayer ( player_t * player ) ;
void P_UnPredictPlayer ( ) ;
void P_PredictionLerpReset ( ) ;
//
// P_MOBJ
//
# define SPF_TEMPPLAYER 1 // spawning a short-lived dummy player
# define SPF_WEAPONFULLYUP 2 // spawn with weapon already raised
APlayerPawn * P_SpawnPlayer ( FPlayerStart * mthing , int playernum , int flags = 0 ) ;
2016-03-16 11:41:26 +00:00
int P_FaceMobj ( AActor * source , AActor * target , DAngle * delta ) ;
2016-03-21 21:20:10 +00:00
bool P_SeekerMissile ( AActor * actor , double thresh , double turnMax , bool precise = false , bool usecurspeed = false ) ;
2016-03-01 15:47:10 +00:00
enum EPuffFlags
{
PF_HITTHING = 1 ,
PF_MELEERANGE = 2 ,
PF_TEMPORARY = 4 ,
PF_HITTHINGBLEED = 8 ,
PF_NORANDOMZ = 16
} ;
2016-03-23 12:31:12 +00:00
AActor * P_SpawnPuff ( AActor * source , PClassActor * pufftype , const DVector3 & pos , DAngle hitdir , DAngle particledir , int updown , int flags = 0 , AActor * vict = NULL ) ;
void P_SpawnBlood ( const DVector3 & pos , DAngle angle , int damage , AActor * originator ) ;
void P_BloodSplatter ( const DVector3 & pos , AActor * originator , DAngle hitangle ) ;
void P_BloodSplatter2 ( const DVector3 & pos , AActor * originator , DAngle hitangle ) ;
2016-03-01 15:47:10 +00:00
void P_RipperBlood ( AActor * mo , AActor * bleeder ) ;
int P_GetThingFloorType ( AActor * thing ) ;
void P_ExplodeMissile ( AActor * missile , line_t * explodeline , AActor * target ) ;
AActor * P_OldSpawnMissile ( AActor * source , AActor * owner , AActor * dest , PClassActor * type ) ;
AActor * P_SpawnMissile ( AActor * source , AActor * dest , PClassActor * type , AActor * owner = NULL ) ;
2016-03-28 10:03:07 +00:00
AActor * P_SpawnMissileZ ( AActor * source , double z , AActor * dest , PClassActor * type ) ;
AActor * P_SpawnMissileXYZ ( DVector3 pos , AActor * source , AActor * dest , PClassActor * type , bool checkspawn = true , AActor * owner = NULL ) ;
AActor * P_SpawnMissileAngle ( AActor * source , PClassActor * type , DAngle angle , double vz ) ;
AActor * P_SpawnMissileAngleZ ( AActor * source , double z , PClassActor * type , DAngle angle , double vz ) ;
AActor * P_SpawnMissileAngleZSpeed ( AActor * source , double z , PClassActor * type , DAngle angle , double vz , double speed , AActor * owner = NULL , bool checkspawn = true ) ;
AActor * P_SpawnMissileZAimed ( AActor * source , double z , AActor * dest , PClassActor * type ) ;
2016-03-20 15:51:42 +00:00
2016-03-01 15:47:10 +00:00
AActor * P_SpawnPlayerMissile ( AActor * source , PClassActor * type ) ;
2016-03-17 10:38:56 +00:00
AActor * P_SpawnPlayerMissile ( AActor * source , PClassActor * type , DAngle angle ) ;
2016-03-21 23:30:56 +00:00
AActor * P_SpawnPlayerMissile ( AActor * source , double x , double y , double z , PClassActor * type , DAngle angle ,
2016-03-01 15:47:10 +00:00
FTranslatedLineTarget * pLineTarget = NULL , AActor * * MissileActor = NULL , bool nofreeaim = false , bool noautoaim = false , int aimflags = 0 ) ;
2016-03-21 23:30:56 +00:00
2016-03-27 20:35:58 +00:00
void P_CheckFakeFloorTriggers ( AActor * mo , double oldz , bool oldz_has_viewheight = false ) ;
2016-03-01 15:47:10 +00:00
AActor * P_SpawnSubMissile ( AActor * source , PClassActor * type , AActor * target ) ; // Strife uses it
//
// [RH] P_THINGS
//
extern FClassMap SpawnableThings ;
extern FClassMap StrifeTypes ;
2016-03-16 11:41:26 +00:00
bool P_Thing_Spawn ( int tid , AActor * source , int type , DAngle angle , bool fog , int newtid ) ;
bool P_Thing_Projectile ( int tid , AActor * source , int type , const char * type_name , DAngle angle ,
2016-03-26 11:36:15 +00:00
double speed , double vspeed , int dest , AActor * forcedest , int gravity , int newtid ,
2016-03-01 15:47:10 +00:00
bool leadTarget ) ;
2016-03-26 11:36:15 +00:00
2016-03-23 12:31:12 +00:00
bool P_MoveThing ( AActor * source , const DVector3 & pos , bool fog ) ;
2016-03-01 15:47:10 +00:00
bool P_Thing_Move ( int tid , AActor * source , int mapspot , bool fog ) ;
int P_Thing_Damage ( int tid , AActor * whofor0 , int amount , FName type ) ;
2016-03-19 23:54:18 +00:00
void P_Thing_SetVelocity ( AActor * actor , const DVector3 & vec , bool add , bool setbob ) ;
2016-03-01 15:47:10 +00:00
void P_RemoveThing ( AActor * actor ) ;
bool P_Thing_Raise ( AActor * thing , AActor * raiser ) ;
bool P_Thing_CanRaise ( AActor * thing ) ;
PClassActor * P_GetSpawnableType ( int spawnnum ) ;
void InitSpawnablesFromMapinfo ( ) ;
2016-06-20 14:41:46 +00:00
int P_Thing_CheckInputNum ( player_t * p , int inputnum ) ;
2016-03-25 11:57:22 +00:00
int P_Thing_Warp ( AActor * caller , AActor * reference , double xofs , double yofs , double zofs , DAngle angle , int flags , double heightoffset , double radiusoffset , DAngle pitch ) ;
2016-07-29 17:50:15 +00:00
int P_Thing_CheckProximity ( AActor * self , PClass * classname , double distance , int count , int flags , int ptr , bool counting = false ) ;
2016-05-09 06:41:35 +00:00
2016-06-20 13:49:57 +00:00
enum
{
// These are the original inputs sent by the player.
INPUT_OLDBUTTONS ,
INPUT_BUTTONS ,
INPUT_PITCH ,
INPUT_YAW ,
INPUT_ROLL ,
INPUT_FORWARDMOVE ,
INPUT_SIDEMOVE ,
INPUT_UPMOVE ,
// These are the inputs, as modified by P_PlayerThink().
// Most of the time, these will match the original inputs, but
// they can be different if a player is frozen or using a
// chainsaw.
MODINPUT_OLDBUTTONS ,
MODINPUT_BUTTONS ,
MODINPUT_PITCH ,
MODINPUT_YAW ,
MODINPUT_ROLL ,
MODINPUT_FORWARDMOVE ,
MODINPUT_SIDEMOVE ,
MODINPUT_UPMOVE
} ;
2016-05-09 06:41:35 +00:00
enum CPXF
{
CPXF_ANCESTOR = 1 < < 0 ,
CPXF_LESSOREQUAL = 1 < < 1 ,
CPXF_NOZ = 1 < < 2 ,
CPXF_COUNTDEAD = 1 < < 3 ,
CPXF_DEADONLY = 1 < < 4 ,
CPXF_EXACT = 1 < < 5 ,
CPXF_SETTARGET = 1 < < 6 ,
CPXF_SETMASTER = 1 < < 7 ,
CPXF_SETTRACER = 1 < < 8 ,
CPXF_FARTHEST = 1 < < 9 ,
CPXF_CLOSEST = 1 < < 10 ,
CPXF_SETONPTR = 1 < < 11 ,
CPXF_CHECKSIGHT = 1 < < 12 ,
} ;
2016-03-01 15:47:10 +00:00
enum WARPF
{
WARPF_ABSOLUTEOFFSET = 0x1 ,
WARPF_ABSOLUTEANGLE = 0x2 ,
WARPF_USECALLERANGLE = 0x4 ,
WARPF_NOCHECKPOSITION = 0x8 ,
WARPF_INTERPOLATE = 0x10 ,
WARPF_WARPINTERPOLATION = 0x20 ,
WARPF_COPYINTERPOLATION = 0x40 ,
WARPF_STOP = 0x80 ,
WARPF_TOFLOOR = 0x100 ,
WARPF_TESTONLY = 0x200 ,
WARPF_ABSOLUTEPOSITION = 0x400 ,
WARPF_BOB = 0x800 ,
WARPF_MOVEPTR = 0x1000 ,
WARPF_USEPTR = 0x2000 ,
WARPF_USETID = 0x2000 ,
WARPF_COPYVELOCITY = 0x4000 ,
WARPF_COPYPITCH = 0x8000 ,
} ;
2016-04-10 16:51:40 +00:00
enum PCM
{
PCM_DROPOFF = 1 ,
PCM_NOACTORS = 1 < < 1 ,
PCM_NOLINES = 1 < < 2 ,
} ;
2016-03-01 15:47:10 +00:00
AActor * P_BlockmapSearch ( AActor * mo , int distance , AActor * ( * check ) ( AActor * , int , void * ) , void * params = NULL ) ;
AActor * P_RoughMonsterSearch ( AActor * mo , int distance , bool onlyseekable = false ) ;
//
// P_MAP
//
// If "floatok" true, move would be ok
2016-03-31 14:52:25 +00:00
// if within "tmfloorz - tmceilingz".
2016-03-01 15:47:10 +00:00
extern msecnode_t * sector_list ; // phares 3/16/98
struct spechit_t
{
line_t * line ;
2016-03-26 22:19:38 +00:00
DVector2 Oldrefpos ;
DVector2 Refpos ;
2016-03-01 15:47:10 +00:00
} ;
extern TArray < spechit_t > spechit ;
extern TArray < spechit_t > portalhit ;
bool P_TestMobjLocation ( AActor * mobj ) ;
bool P_TestMobjZ ( AActor * mobj , bool quick = true , AActor * * pOnmobj = NULL ) ;
2016-03-27 00:06:54 +00:00
bool P_CheckPosition ( AActor * thing , const DVector2 & pos , bool actorsonly = false ) ;
2016-03-31 07:23:14 +00:00
bool P_CheckPosition ( AActor * thing , const DVector2 & pos , FCheckPosition & tm , bool actorsonly = false ) ;
2016-03-01 15:47:10 +00:00
AActor * P_CheckOnmobj ( AActor * thing ) ;
void P_FakeZMovement ( AActor * mo ) ;
2016-03-27 11:29:58 +00:00
bool P_TryMove ( AActor * thing , const DVector2 & pos , int dropoff , const secplane_t * onfloor , FCheckPosition & tm , bool missileCheck = false ) ;
bool P_TryMove ( AActor * thing , const DVector2 & pos , int dropoff , const secplane_t * onfloor = NULL ) ;
2016-04-10 16:51:40 +00:00
bool P_CheckMove ( AActor * thing , const DVector2 & pos , int flags = 0 ) ;
2016-03-01 15:47:10 +00:00
void P_ApplyTorque ( AActor * mo ) ;
2016-03-26 22:19:38 +00:00
bool P_TeleportMove ( AActor * thing , const DVector3 & pos , bool telefrag , bool modifyactor = true ) ; // [RH] Added z and telefrag parameters
2016-03-01 15:47:10 +00:00
void P_PlayerStartStomp ( AActor * actor , bool mononly = false ) ; // [RH] Stomp on things for a newly spawned player
2016-03-27 11:29:58 +00:00
void P_SlideMove ( AActor * mo , const DVector2 & pos , int numsteps ) ;
2016-03-01 15:47:10 +00:00
bool P_BounceWall ( AActor * mo ) ;
bool P_BounceActor ( AActor * mo , AActor * BlockingMobj , bool ontop ) ;
2016-03-07 20:58:34 +00:00
bool P_CheckSight ( AActor * t1 , AActor * t2 , int flags = 0 ) ;
2016-03-01 15:47:10 +00:00
enum ESightFlags
{
SF_IGNOREVISIBILITY = 1 ,
SF_SEEPASTSHOOTABLELINES = 2 ,
SF_SEEPASTBLOCKEVERYTHING = 4 ,
SF_IGNOREWATERBOUNDARY = 8
} ;
void P_ResetSightCounters ( bool full ) ;
bool P_TalkFacing ( AActor * player ) ;
void P_UseLines ( player_t * player ) ;
bool P_UsePuzzleItem ( AActor * actor , int itemType ) ;
enum
{
FFCF_ONLYSPAWNPOS = 1 ,
FFCF_SAMESECTOR = 2 ,
FFCF_ONLY3DFLOORS = 4 , // includes 3D midtexes
FFCF_3DRESTRICT = 8 , // ignore 3D midtexes and floors whose floorz are above thing's z
FFCF_NOPORTALS = 16 , // ignore portals (considers them impassable.)
FFCF_NOFLOOR = 32 ,
FFCF_NOCEILING = 64 ,
FFCF_RESTRICTEDPORTAL = 128 , // current values in the iterator's return are through a restricted portal type (i.e. some features are blocked.)
2016-03-02 19:44:02 +00:00
FFCF_NODROPOFF = 256 , // Caller does not need a dropoff (saves some time when checking portals)
2016-03-01 15:47:10 +00:00
} ;
void P_FindFloorCeiling ( AActor * actor , int flags = 0 ) ;
2016-03-27 20:35:58 +00:00
bool P_ChangeSector ( sector_t * sector , int crunch , double amt , int floorOrCeil , bool isreset ) ;
2016-03-01 15:47:10 +00:00
2016-03-17 10:38:56 +00:00
DAngle P_AimLineAttack ( AActor * t1 , DAngle angle , double distance , FTranslatedLineTarget * pLineTarget = NULL , DAngle vrange = 0. , int flags = 0 , AActor * target = NULL , AActor * friender = NULL ) ;
2016-03-01 15:47:10 +00:00
enum // P_AimLineAttack flags
{
ALF_FORCENOSMART = 1 ,
ALF_CHECK3D = 2 ,
ALF_CHECKNONSHOOTABLE = 4 ,
ALF_CHECKCONVERSATION = 8 ,
ALF_NOFRIENDS = 16 ,
ALF_PORTALRESTRICT = 32 , // only work through portals with a global offset (to be used for stuff that cannot remember the calculated FTranslatedLineTarget info)
} ;
enum // P_LineAttack flags
{
LAF_ISMELEEATTACK = 1 ,
LAF_NORANDOMPUFFZ = 2 ,
2016-06-19 15:59:00 +00:00
LAF_NOIMPACTDECAL = 4 ,
LAF_NOINTERACT = 8 ,
2016-03-01 15:47:10 +00:00
} ;
2016-03-17 10:38:56 +00:00
AActor * P_LineAttack ( AActor * t1 , DAngle angle , double distance , DAngle pitch , int damage , FName damageType , PClassActor * pufftype , int flags = 0 , FTranslatedLineTarget * victim = NULL , int * actualdamage = NULL ) ;
AActor * P_LineAttack ( AActor * t1 , DAngle angle , double distance , DAngle pitch , int damage , FName damageType , FName pufftype , int flags = 0 , FTranslatedLineTarget * victim = NULL , int * actualdamage = NULL ) ;
2016-03-27 18:58:01 +00:00
void P_TraceBleed ( int damage , const DVector3 & pos , AActor * target , DAngle angle , DAngle pitch ) ;
void P_TraceBleed ( int damage , AActor * target , DAngle angle , DAngle pitch ) ;
2016-03-01 15:47:10 +00:00
void P_TraceBleed ( int damage , AActor * target , AActor * missile ) ; // missile version
void P_TraceBleed ( int damage , FTranslatedLineTarget * t , AActor * puff ) ; // hitscan version
void P_TraceBleed ( int damage , AActor * target ) ; // random direction version
bool P_HitFloor ( AActor * thing ) ;
2016-03-23 12:31:12 +00:00
bool P_HitWater ( AActor * thing , sector_t * sec , const DVector3 & pos , bool checkabove = false , bool alert = true , bool force = false ) ;
2016-03-20 15:51:42 +00:00
void P_CheckSplash ( AActor * self , double distance ) ;
2016-03-24 23:59:14 +00:00
struct FRailParams
{
AActor * source = nullptr ;
int damage = 0 ;
double offset_xy = 0 ;
double offset_z = 0 ;
int color1 = 0 , color2 = 0 ;
double maxdiff = 0 ;
int flags = 0 ;
PClassActor * puff = nullptr ;
DAngle angleoffset = 0. ;
DAngle pitchoffset = 0. ;
double distance = 8192 ;
int duration = 0 ;
double sparsity = 1.0 ;
double drift = 1.0 ;
PClassActor * spawnclass = nullptr ;
int SpiralOffset = 270 ;
2016-06-14 23:20:43 +00:00
int limit = 0 ;
2016-03-24 23:59:14 +00:00
} ; // [RH] Shoot a railgun
void P_RailAttack ( FRailParams * params ) ;
2016-03-01 15:47:10 +00:00
enum // P_RailAttack / A_RailAttack / A_CustomRailgun / P_DrawRailTrail flags
{
RAF_SILENT = 1 ,
RAF_NOPIERCE = 2 ,
RAF_EXPLICITANGLE = 4 ,
RAF_FULLBRIGHT = 8 ,
RAF_CENTERZ = 16 ,
2016-07-22 08:35:44 +00:00
RAF_NORANDOMPUFFZ = 32 ,
2016-03-01 15:47:10 +00:00
} ;
2016-03-20 14:04:13 +00:00
bool P_CheckMissileSpawn ( AActor * missile , double maxdist ) ;
2016-03-01 15:47:10 +00:00
void P_PlaySpawnSound ( AActor * missile , AActor * spawner ) ;
// [RH] Position the chasecam
2016-04-16 20:54:47 +00:00
void P_AimCamera ( AActor * t1 , DVector3 & , DAngle & , sector_t * & sec , bool & unlinked ) ;
2016-03-01 15:47:10 +00:00
// [RH] Means of death
enum
{
RADF_HURTSOURCE = 1 ,
RADF_NOIMPACTDAMAGE = 2 ,
RADF_SOURCEISSPOT = 4 ,
RADF_NODAMAGE = 8 ,
2016-05-11 11:59:11 +00:00
RADF_THRUSTZ = 16 ,
2016-03-01 15:47:10 +00:00
} ;
2016-08-08 18:01:43 +00:00
int P_RadiusAttack ( AActor * spot , AActor * source , int damage , int distance ,
2016-03-01 15:47:10 +00:00
FName damageType , int flags , int fulldamagedistance = 0 ) ;
void P_DelSector_List ( ) ;
void P_DelSeclist ( msecnode_t * ) ; // phares 3/16/98
2016-04-17 21:48:04 +00:00
msecnode_t * P_AddSecnode ( sector_t * s , AActor * thing , msecnode_t * nextnode , msecnode_t * & sec_thinglist ) ;
msecnode_t * P_DelSecnode ( msecnode_t * , msecnode_t * sector_t : : * head ) ;
2016-03-27 20:49:59 +00:00
void P_CreateSecNodeList ( AActor * ) ; // phares 3/14/98
2016-03-24 21:50:03 +00:00
double P_GetMoveFactor ( const AActor * mo , double * frictionp ) ; // phares 3/6/98
double P_GetFriction ( const AActor * mo , double * frictionfactor ) ;
2016-03-01 15:47:10 +00:00
// [RH]
2016-03-27 12:07:35 +00:00
const secplane_t * P_CheckSlopeWalk ( AActor * actor , DVector2 & move ) ;
2016-03-01 15:47:10 +00:00
//
// P_SETUP
//
extern BYTE * rejectmatrix ; // for fast sight rejection
//
// P_INTER
//
void P_TouchSpecialThing ( AActor * special , AActor * toucher ) ;
2016-03-19 23:54:18 +00:00
int P_DamageMobj ( AActor * target , AActor * inflictor , AActor * source , int damage , FName mod , int flags = 0 , DAngle angle = 0. ) ;
2016-03-01 15:47:10 +00:00
void P_PoisonMobj ( AActor * target , AActor * inflictor , AActor * source , int damage , int duration , int period , FName type ) ;
bool P_GiveBody ( AActor * actor , int num , int max = 0 ) ;
bool P_PoisonPlayer ( player_t * player , AActor * poisoner , AActor * source , int poison ) ;
void P_PoisonDamage ( player_t * player , AActor * source , int damage , bool playPainSound ) ;
enum EDmgFlags
{
DMG_NO_ARMOR = 1 ,
DMG_INFLICTOR_IS_PUFF = 2 ,
DMG_THRUSTLESS = 4 ,
DMG_FORCED = 8 ,
DMG_NO_FACTOR = 16 ,
DMG_PLAYERATTACK = 32 ,
DMG_FOILINVUL = 64 ,
DMG_FOILBUDDHA = 128 ,
DMG_NO_PROTECT = 256 ,
DMG_USEANGLE = 512 ,
} ;
//
// P_SPEC
//
bool P_AlignFlat ( int linenum , int side , int fc ) ;
# endif // __P_LOCAL__