2006-02-24 04:48:15 +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__
2008-06-03 21:35:30 +00:00
# ifndef __R_LOCAL__
2006-02-24 04:48:15 +00:00
# include "r_local.h"
# endif
2008-04-08 08:53:42 +00:00
# include "a_morph.h"
2006-02-24 04:48:15 +00:00
# include <stdlib.h>
# define STEEPSLOPE 46341 // [RH] Minimum floorplane.c value for walking
# define BONUSADD 6
// mapblocks are used to check movement
// against lines and things
# define MAPBLOCKUNITS 128
# define MAPBLOCKSIZE (MAPBLOCKUNITS*FRACUNIT)
# define MAPBLOCKSHIFT (FRACBITS+7)
# define MAPBMASK (MAPBLOCKSIZE-1)
# define MAPBTOFRAC (MAPBLOCKSHIFT-FRACBITS)
// MAXRADIUS is for precalculated sector block boxes
// the spider demon is larger,
// but we do not have any moving sectors nearby
# define MAXRADIUS 0 /*32*FRACUNIT*/
//#define GRAVITY FRACUNIT
# define MAXMOVE (30*FRACUNIT)
# define USERANGE (64*FRACUNIT)
# define MELEERANGE (64*FRACUNIT)
# define MISSILERANGE (32*64*FRACUNIT)
# define PLAYERMISSILERANGE (8192*FRACUNIT) // [RH] New MISSILERANGE for players
// follow a player exlusively for 3 seconds
# define BASETHRESHOLD 100
//
// P_PSPR
//
void P_SetupPsprites ( player_t * curplayer ) ;
void P_MovePsprites ( player_t * curplayer ) ;
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 ( ) ;
//
// P_MOBJ
//
# define ONFLOORZ FIXED_MIN
# define ONCEILINGZ FIXED_MAX
# define FLOATRANDZ (FIXED_MAX-1)
extern fixed_t FloatBobOffsets [ 64 ] ;
2008-05-08 08:06:26 +00:00
APlayerPawn * P_SpawnPlayer ( FMapThing * mthing , bool tempplayer = false ) ;
2006-05-11 05:00:35 +00:00
2006-02-24 04:48:15 +00:00
void P_ThrustMobj ( AActor * mo , angle_t angle , fixed_t move ) ;
int P_FaceMobj ( AActor * source , AActor * target , angle_t * delta ) ;
bool P_SeekerMissile ( AActor * actor , angle_t thresh , angle_t turnMax ) ;
2008-04-04 14:31:20 +00:00
enum EPuffFlags
{
PF_HITTHING = 1 ,
PF_MELEERANGE = 2 ,
PF_TEMPORARY = 4
} ;
AActor * P_SpawnPuff ( const PClass * pufftype , fixed_t x , fixed_t y , fixed_t z , angle_t dir , int updown , int flags = 0 ) ;
2006-02-24 04:48:15 +00:00
void P_SpawnBlood ( fixed_t x , fixed_t y , fixed_t z , angle_t dir , int damage , AActor * originator ) ;
void P_BloodSplatter ( fixed_t x , fixed_t y , fixed_t z , AActor * originator ) ;
void P_BloodSplatter2 ( fixed_t x , fixed_t y , fixed_t z , AActor * originator ) ;
void P_RipperBlood ( AActor * mo , AActor * bleeder ) ;
int P_GetThingFloorType ( AActor * thing ) ;
2006-10-22 10:32:41 +00:00
void P_ExplodeMissile ( AActor * missile , line_t * explodeline , AActor * target ) ;
2006-02-24 04:48:15 +00:00
2006-05-10 02:40:43 +00:00
AActor * P_SpawnMissile ( AActor * source , AActor * dest , const PClass * type ) ;
AActor * P_SpawnMissileZ ( AActor * source , fixed_t z , AActor * dest , const PClass * type ) ;
AActor * P_SpawnMissileXYZ ( fixed_t x , fixed_t y , fixed_t z , AActor * source , AActor * dest , const PClass * type ) ;
AActor * P_SpawnMissileAngle ( AActor * source , const PClass * type , angle_t angle , fixed_t momz ) ;
AActor * P_SpawnMissileAngleSpeed ( AActor * source , const PClass * type , angle_t angle , fixed_t momz , fixed_t speed ) ;
AActor * P_SpawnMissileAngleZ ( AActor * source , fixed_t z , const PClass * type , angle_t angle , fixed_t momz ) ;
AActor * P_SpawnMissileAngleZSpeed ( AActor * source , fixed_t z , const PClass * type , angle_t angle , fixed_t momz , fixed_t speed , AActor * owner = NULL ) ;
AActor * P_SpawnMissileZAimed ( AActor * source , fixed_t z , AActor * dest , const PClass * type ) ;
2006-02-24 04:48:15 +00:00
2006-05-10 02:40:43 +00:00
AActor * P_SpawnPlayerMissile ( AActor * source , const PClass * type ) ;
AActor * P_SpawnPlayerMissile ( AActor * source , const PClass * type , angle_t angle ) ;
2008-04-10 14:38:43 +00:00
AActor * P_SpawnPlayerMissile ( AActor * source , fixed_t x , fixed_t y , fixed_t z , const PClass * type , angle_t angle ,
AActor * * pLineTarget = NULL , AActor * * MissileActor = NULL ) ;
2006-02-24 04:48:15 +00:00
2007-12-09 03:40:02 +00:00
void P_CheckFakeFloorTriggers ( AActor * mo , fixed_t oldz , bool oldz_has_viewheight = false ) ;
2006-02-24 04:48:15 +00:00
//
// [RH] P_THINGS
//
# define MAX_SPAWNABLES (256)
2006-05-10 02:40:43 +00:00
extern const PClass * SpawnableThings [ MAX_SPAWNABLES ] ;
2006-02-24 04:48:15 +00:00
2006-10-27 03:03:34 +00:00
bool P_Thing_Spawn ( int tid , AActor * source , int type , angle_t angle , bool fog , int newtid ) ;
bool P_Thing_Projectile ( int tid , AActor * source , int type , const char * type_name , angle_t angle ,
2006-02-24 04:48:15 +00:00
fixed_t speed , fixed_t vspeed , int dest , AActor * forcedest , int gravity , int newtid ,
bool leadTarget ) ;
2006-10-27 03:03:34 +00:00
bool P_MoveThing ( AActor * source , fixed_t x , fixed_t y , fixed_t z , bool fog ) ;
bool P_Thing_Move ( int tid , AActor * source , int mapspot , bool fog ) ;
- Moved the implementation for the Thing_Damage special into another function
so that I can create the ACS function Thing_Damage2. It's exactly the same as
Thing_Damage, except the damage type is specified by name. When I did this,
I noticed that it didn't do anything useful for a TID of 0, so I made it
affect the activator in that case.
- Added a new SetActorState ACS function:
int SetActorState (int tid, str statename, optional bool exact);
If tid is 0, it affects the script activator, otherwise it affects all the
matching actors. Statename is the name of the state you want to put the
actor in. The final parameter, exact, specifies whether or not partial
state name matches are accepted. If you don't specify it or set it to
false, if you try to do something like:
SetActorState (0, "Foo.Bar");
And the actor has a Foo state but no Foo.Bar state, it will enter the Foo
state. If you set exact to true:
SetActorState (0, "Foo.Bar", true);
Then the actor must have a Foo.Bar state, or it will not change state at
all, even if it has a Foo state.
The return value for this function is the number of actors that successfully
changed state. Note that you should refrain from using this function to
enter special states such as Death, or unpredictable results could occur.
SVN r505 (trunk)
2007-03-23 22:26:14 +00:00
int P_Thing_Damage ( int tid , AActor * whofor0 , int amount , FName type ) ;
2006-02-24 04:48:15 +00:00
//
// P_ENEMY
//
void P_NoiseAlert ( AActor * target , AActor * emmiter , bool splash ) ;
//
// P_MAPUTL
//
typedef struct
{
fixed_t x ;
fixed_t y ;
fixed_t dx ;
fixed_t dy ;
} divline_t ;
typedef struct
{
fixed_t frac ; // along trace line
bool isaline ;
2008-04-09 18:35:21 +00:00
bool done ;
2006-02-24 04:48:15 +00:00
union {
AActor * thing ;
line_t * line ;
} d ;
} intercept_t ;
2006-09-14 00:02:31 +00:00
typedef bool ( * traverser_t ) ( intercept_t * in ) ;
2006-02-24 04:48:15 +00:00
fixed_t P_AproxDistance ( fixed_t dx , fixed_t dy ) ;
//==========================================================================
//
// P_PointOnLineSide
//
// Returns 0 (front/on) or 1 (back)
// [RH] inlined, stripped down, and made more precise
//
//==========================================================================
inline int P_PointOnLineSide ( fixed_t x , fixed_t y , const line_t * line )
{
return DMulScale32 ( y - line - > v1 - > y , line - > dx , line - > v1 - > x - x , line - > dy ) > 0 ;
}
//==========================================================================
//
// P_PointOnDivlineSide
//
// Same as P_PointOnLineSide except it uses divlines
// [RH] inlined, stripped down, and made more precise
//
//==========================================================================
inline int P_PointOnDivlineSide ( fixed_t x , fixed_t y , const divline_t * line )
{
return DMulScale32 ( y - line - > y , line - > dx , line - > x - x , line - > dy ) > 0 ;
}
//==========================================================================
//
// P_MakeDivline
//
//==========================================================================
inline void P_MakeDivline ( const line_t * li , divline_t * dl )
{
dl - > x = li - > v1 - > x ;
dl - > y = li - > v1 - > y ;
dl - > dx = li - > dx ;
dl - > dy = li - > dy ;
}
fixed_t P_InterceptVector ( const divline_t * v2 , const divline_t * v1 ) ;
2008-03-18 18:18:18 +00:00
struct FLineOpening
{
fixed_t top ;
fixed_t bottom ;
fixed_t range ;
fixed_t lowfloor ;
sector_t * bottomsec ;
sector_t * topsec ;
2008-06-15 18:36:26 +00:00
FTextureID ceilingpic ;
FTextureID floorpic ;
2008-03-18 18:18:18 +00:00
bool touchmidtex ;
} ;
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 ) ;
2006-02-24 04:48:15 +00:00
2008-04-06 17:33:43 +00:00
class FBoundingBox ;
class FBlockLinesIterator
{
int minx , maxx ;
int miny , maxy ;
int curx , cury ;
polyblock_t * polyLink ;
int polyIndex ;
int * list ;
void StartBlock ( int x , int y ) ;
public :
FBlockLinesIterator ( int minx , int miny , int maxx , int maxy , bool keepvalidcount = false ) ;
FBlockLinesIterator ( const FBoundingBox & box ) ;
line_t * Next ( ) ;
void Reset ( ) { StartBlock ( minx , miny ) ; }
} ;
2008-04-07 21:14:28 +00:00
class FBlockThingsIterator
{
2008-04-09 18:35:21 +00:00
static TArray < AActor * > CheckArray ;
2008-04-07 21:14:28 +00:00
int minx , maxx ;
int miny , maxy ;
int curx , cury ;
bool dontfreecheck ;
2008-04-09 18:35:21 +00:00
int checkindex ;
2008-04-07 21:14:28 +00:00
FBlockNode * block ;
2006-02-24 04:48:15 +00:00
2008-04-07 21:14:28 +00:00
void StartBlock ( int x , int y ) ;
2008-04-09 18:35:21 +00:00
// The following 3 functions are only for use in the path traverser
// and therefore declared private.
static int GetCheckIndex ( ) ;
static void SetCheckIndex ( int newvalue ) ;
FBlockThingsIterator ( int x , int y , int checkindex ) ;
friend class FPathTraverse ;
2008-04-07 21:14:28 +00:00
public :
2008-04-09 18:35:21 +00:00
FBlockThingsIterator ( int minx , int miny , int maxx , int maxy ) ;
2008-04-07 21:14:28 +00:00
FBlockThingsIterator ( const FBoundingBox & box ) ;
2008-04-09 18:35:21 +00:00
~ FBlockThingsIterator ( ) ;
2008-04-07 21:14:28 +00:00
AActor * Next ( ) ;
void Reset ( ) { StartBlock ( minx , miny ) ; }
} ;
2008-04-09 18:35:21 +00:00
class FPathTraverse
{
static TArray < intercept_t > intercepts ;
2006-02-24 04:48:15 +00:00
2008-04-09 18:35:21 +00:00
divline_t trace ;
unsigned int intercept_index ;
unsigned int intercept_count ;
fixed_t maxfrac ;
unsigned int count ;
2006-02-24 04:48:15 +00:00
2008-04-09 18:35:21 +00:00
void AddLineIntercepts ( int bx , int by ) ;
void AddThingIntercepts ( int bx , int by , int checkindex ) ;
public :
intercept_t * Next ( ) ;
FPathTraverse ( fixed_t x1 , fixed_t y1 , fixed_t x2 , fixed_t y2 , int flags ) ;
~ FPathTraverse ( ) ;
const divline_t & Trace ( ) const { return trace ; }
} ;
# define PT_ADDLINES 1
# define PT_ADDTHINGS 2
2006-02-24 04:48:15 +00:00
AActor * P_BlockmapSearch ( AActor * origin , int distance , AActor * ( * func ) ( AActor * , int ) ) ;
AActor * P_RoughMonsterSearch ( AActor * mo , int distance ) ;
//
// P_MAP
//
2008-04-08 10:47:28 +00:00
struct FCheckPosition
{
// in
AActor * thing ;
fixed_t x ;
fixed_t y ;
fixed_t z ;
// out
sector_t * sector ;
fixed_t floorz ;
fixed_t ceilingz ;
fixed_t dropoffz ;
2008-06-15 18:36:26 +00:00
FTextureID floorpic ;
2008-04-08 10:47:28 +00:00
sector_t * floorsector ;
2008-06-15 18:36:26 +00:00
FTextureID ceilingpic ;
2008-04-08 10:47:28 +00:00
sector_t * ceilingsector ;
bool touchmidtex ;
2008-04-08 20:52:49 +00:00
bool floatok ;
line_t * ceilingline ;
2008-04-10 14:38:43 +00:00
AActor * stepthing ;
// [RH] These are used by PIT_CheckThing and P_XYMovement to apply
// ripping damage once per tic instead of once per move.
bool DoRipping ;
AActor * LastRipped ;
FCheckPosition ( bool rip = false )
{
DoRipping = rip ;
LastRipped = NULL ;
}
2008-04-08 10:47:28 +00:00
} ;
2006-02-24 04:48:15 +00:00
// If "floatok" true, move would be ok
// if within "tmfloorz - tmceilingz".
extern msecnode_t * sector_list ; // phares 3/16/98
extern TArray < line_t * > spechit ;
2006-09-14 00:02:31 +00:00
bool P_TestMobjLocation ( AActor * mobj ) ;
2008-04-10 14:38:43 +00:00
bool P_TestMobjZ ( AActor * mobj , bool quick = true , AActor * * pOnmobj = NULL ) ;
2008-04-08 20:52:49 +00:00
bool P_CheckPosition ( AActor * thing , fixed_t x , fixed_t y , FCheckPosition & tm ) ;
2006-09-14 00:02:31 +00:00
bool P_CheckPosition ( AActor * thing , fixed_t x , fixed_t y ) ;
2006-02-24 04:48:15 +00:00
AActor * P_CheckOnmobj ( AActor * thing ) ;
void P_FakeZMovement ( AActor * mo ) ;
2008-04-08 20:52:49 +00:00
bool P_TryMove ( AActor * thing , fixed_t x , fixed_t y , bool dropoff , bool onfloor , FCheckPosition & tm ) ;
2006-09-14 00:02:31 +00:00
bool P_TryMove ( AActor * thing , fixed_t x , fixed_t y , bool dropoff , bool onfloor = false ) ;
bool P_TeleportMove ( AActor * thing , fixed_t x , fixed_t y , fixed_t z , bool telefrag ) ; // [RH] Added z and telefrag parameters
2006-02-24 04:48:15 +00:00
void P_PlayerStartStomp ( AActor * actor ) ; // [RH] Stomp on things for a newly spawned player
void P_SlideMove ( AActor * mo , fixed_t tryx , fixed_t tryy , int numsteps ) ;
bool P_BounceWall ( AActor * mo ) ;
bool P_CheckSight ( const AActor * t1 , const AActor * t2 , int flags = 0 ) ;
void P_ResetSightCounters ( bool full ) ;
void P_UseLines ( player_t * player ) ;
bool P_UsePuzzleItem ( AActor * actor , int itemType ) ;
2008-05-14 07:45:40 +00:00
void P_FindFloorCeiling ( AActor * actor , bool onlymidtex = false ) ;
2006-02-24 04:48:15 +00:00
2008-03-22 12:17:52 +00:00
bool P_ChangeSector ( sector_t * sector , int crunch , int amt , int floorOrCeil , bool isreset ) ;
2006-02-24 04:48:15 +00:00
2008-04-10 14:38:43 +00:00
fixed_t P_AimLineAttack ( AActor * t1 , angle_t angle , fixed_t distance , AActor * * pLineTarget = NULL , fixed_t vrange = 0 , bool forcenosmart = false ) ;
2008-04-04 14:31:20 +00:00
AActor * P_LineAttack ( AActor * t1 , angle_t angle , fixed_t distance , int pitch , int damage , FName damageType , const PClass * pufftype , bool ismelee = false ) ;
AActor * P_LineAttack ( AActor * t1 , angle_t angle , fixed_t distance , int pitch , int damage , FName damageType , FName pufftype , bool ismelee = false ) ;
2006-02-24 04:48:15 +00:00
void P_TraceBleed ( int damage , fixed_t x , fixed_t y , fixed_t z , AActor * target , angle_t angle , int pitch ) ;
void P_TraceBleed ( int damage , AActor * target , angle_t angle , int pitch ) ;
void P_TraceBleed ( int damage , AActor * target , AActor * missile ) ; // missile version
void P_TraceBleed ( int damage , AActor * target ) ; // random direction version
2006-11-29 10:03:35 +00:00
void P_RailAttack ( AActor * source , int damage , int offset , int color1 = 0 , int color2 = 0 , float maxdiff = 0 , bool silent = false , FName puff = NAME_BulletPuff ) ; // [RH] Shoot a railgun
2006-02-24 04:48:15 +00:00
bool P_HitFloor ( AActor * thing ) ;
2007-01-07 09:43:58 +00:00
bool P_HitWater ( AActor * thing , sector_t * sec , fixed_t splashz = FIXED_MIN ) ;
2006-02-24 04:48:15 +00:00
bool P_CheckMissileSpawn ( AActor * missile ) ;
2006-11-25 12:25:05 +00:00
void P_PlaySpawnSound ( AActor * missile , AActor * spawner ) ;
2006-02-24 04:48:15 +00:00
// [RH] Position the chasecam
2008-04-09 18:35:21 +00:00
void P_AimCamera ( AActor * t1 , fixed_t & x , fixed_t & y , fixed_t & z , sector_t * & sec ) ;
2006-02-24 04:48:15 +00:00
// [RH] Means of death
2006-10-31 14:53:21 +00:00
void P_RadiusAttack ( AActor * spot , AActor * source , int damage , int distance , FName damageType , bool hurtSelf , bool dodamage = true ) ;
2006-02-24 04:48:15 +00:00
2006-05-18 04:25:26 +00:00
void P_DelSector_List ( ) ;
2006-02-24 04:48:15 +00:00
void P_DelSeclist ( msecnode_t * ) ; // phares 3/16/98
void P_CreateSecNodeList ( AActor * , fixed_t , fixed_t ) ; // phares 3/14/98
int P_GetMoveFactor ( const AActor * mo , int * frictionp ) ; // phares 3/6/98
int P_GetFriction ( const AActor * mo , int * frictionfactor ) ;
2006-09-14 00:02:31 +00:00
bool Check_Sides ( AActor * , int , int ) ; // phares
2006-02-24 04:48:15 +00:00
// [RH]
bool P_CheckSlopeWalk ( AActor * actor , fixed_t & xmove , fixed_t & ymove ) ;
2007-12-25 10:07:58 +00:00
//----------------------------------------------------------------------------------
//
// Added so that in the source there's a clear distinction between
// game engine and renderer specific calls.
// (For ZDoom itself this doesn't make any difference here but for GZDoom it does.)
//
//----------------------------------------------------------------------------------
inline sector_t * P_PointInSector ( fixed_t x , fixed_t y )
{
return R_PointInSubsector ( x , y ) - > sector ;
}
2006-02-24 04:48:15 +00:00
//
// P_SETUP
//
2006-09-14 00:02:31 +00:00
extern BYTE * rejectmatrix ; // for fast sight rejection
2006-02-24 04:48:15 +00:00
extern int * blockmaplump ; // offsets in blockmap are from here
extern int * blockmap ;
extern int bmapwidth ;
extern int bmapheight ; // in mapblocks
extern fixed_t bmaporgx ;
extern fixed_t bmaporgy ; // origin of block map
extern FBlockNode * * blocklinks ; // for thing chains
//
// P_INTER
//
void P_TouchSpecialThing ( AActor * special , AActor * toucher ) ;
2006-10-31 14:53:21 +00:00
void P_DamageMobj ( AActor * target , AActor * inflictor , AActor * source , int damage , FName mod , int flags = 0 ) ;
2006-02-24 04:48:15 +00:00
bool P_GiveBody ( AActor * actor , int num ) ;
void P_PoisonPlayer ( player_t * player , AActor * poisoner , AActor * source , int poison ) ;
void P_PoisonDamage ( player_t * player , AActor * source , int damage , bool playPainSound ) ;
2008-06-02 16:56:53 +00:00
enum EDmgFlags
{
DMG_NO_ARMOR = 1 ,
DMG_INFLICTOR_IS_PUFF = 2 ,
DMG_THRUSTLESS = 4 ,
} ;
2006-02-24 04:48:15 +00:00
// ===== PO_MAN =====
typedef enum
{
PODOOR_NONE ,
PODOOR_SLIDE ,
PODOOR_SWING ,
} podoortype_t ;
2006-09-14 00:02:31 +00:00
bool EV_RotatePoly ( line_t * line , int polyNum , int speed , int byteAngle , int direction , bool overRide ) ;
bool EV_MovePoly ( line_t * line , int polyNum , int speed , angle_t angle , fixed_t dist , bool overRide ) ;
2008-06-01 20:43:02 +00:00
bool EV_OpenPolyDoor ( line_t * line , int polyNum , int speed , angle_t angle , int delay , int distance , podoortype_t type ) ;
2006-05-26 04:38:22 +00:00
2006-02-24 04:48:15 +00:00
2006-05-26 04:38:22 +00:00
2006-02-24 04:48:15 +00:00
// [RH] Data structure for P_SpawnMapThing() to keep track
// of polyobject-related things.
typedef struct polyspawns_s
{
struct polyspawns_s * next ;
fixed_t x ;
fixed_t y ;
short angle ;
short type ;
} polyspawns_t ;
enum
{
PO_HEX_ANCHOR_TYPE = 3000 ,
PO_HEX_SPAWN_TYPE ,
PO_HEX_SPAWNCRUSH_TYPE ,
// [RH] Thing numbers that don't conflict with Doom things
PO_ANCHOR_TYPE = 9300 ,
PO_SPAWN_TYPE ,
PO_SPAWNCRUSH_TYPE ,
PO_SPAWNHURT_TYPE
} ;
extern int po_NumPolyobjs ;
extern polyspawns_t * polyspawns ; // [RH] list of polyobject things to spawn
2006-11-21 05:43:34 +00:00
bool PO_MovePolyobj ( int num , int x , int y , bool force = false ) ;
2006-09-14 00:02:31 +00:00
bool PO_RotatePolyobj ( int num , angle_t angle ) ;
2006-02-24 04:48:15 +00:00
void PO_Init ( ) ;
2006-09-14 00:02:31 +00:00
bool PO_Busy ( int polyobj ) ;
2006-02-24 04:48:15 +00:00
//
// P_SPEC
//
# include "p_spec.h"
# endif // __P_LOCAL__