ref: 0a94c0f99d6c34b30d2ac6fd7d5e516bd14dffb5
dir: /src/hexen/p_spec.h/
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright(C) 1993-1996 Id Software, Inc.
// Copyright(C) 1993-2008 Raven Software
// Copyright(C) 2008 Simon Howard
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
//-----------------------------------------------------------------------------
extern int *TerrainTypes;
//
// scrolling line specials
//
#define MAXLINEANIMS 64
extern short numlinespecials;
extern line_t *linespeciallist[MAXLINEANIMS];
// Define values for map objects
#define MO_TELEPORTMAN 14
// at game start
void P_InitTerrainTypes(void);
void P_InitLava(void);
// at map load
void P_SpawnSpecials(void);
// every tic
void P_UpdateSpecials(void);
// when needed
boolean P_ExecuteLineSpecial(int special, byte * args, line_t * line,
int side, mobj_t * mo);
boolean P_ActivateLine(line_t * ld, mobj_t * mo, int side,
int activationType);
//boolean P_UseSpecialLine ( mobj_t *thing, line_t *line);
//void P_ShootSpecialLine ( mobj_t *thing, line_t *line);
//void P_CrossSpecialLine (int linenum, int side, mobj_t *thing);
void P_PlayerInSpecialSector(player_t * player);
void P_PlayerOnSpecialFlat(player_t * player, int floorType);
//int twoSided(int sector,int line);
//sector_t *getSector(int currentSector,int line,int side);
//side_t *getSide(int currentSector,int line, int side);
fixed_t P_FindLowestFloorSurrounding(sector_t * sec);
fixed_t P_FindHighestFloorSurrounding(sector_t * sec);
fixed_t P_FindNextHighestFloor(sector_t * sec, int currentheight);
fixed_t P_FindLowestCeilingSurrounding(sector_t * sec);
fixed_t P_FindHighestCeilingSurrounding(sector_t * sec);
//int P_FindSectorFromLineTag(line_t *line,int start);
int P_FindSectorFromTag(int tag, int start);
//int P_FindMinSurroundingLight(sector_t *sector,int max);
sector_t *getNextSector(line_t * line, sector_t * sec);
line_t *P_FindLine(int lineTag, int *searchPosition);
//
// SPECIAL
//
//int EV_DoDonut(line_t *line);
//-------------------------------
// P_anim.c
//-------------------------------
void P_AnimateSurfaces(void);
void P_InitFTAnims(void);
void P_InitLightning(void);
void P_ForceLightning(void);
/*
===============================================================================
P_LIGHTS
===============================================================================
*/
typedef enum
{
LITE_RAISEBYVALUE,
LITE_LOWERBYVALUE,
LITE_CHANGETOVALUE,
LITE_FADE,
LITE_GLOW,
LITE_FLICKER,
LITE_STROBE
} lighttype_t;
typedef struct
{
thinker_t thinker;
sector_t *sector;
lighttype_t type;
int value1;
int value2;
int tics1;
int tics2;
int count;
} light_t;
typedef struct
{
thinker_t thinker;
sector_t *sector;
int index;
int base;
} phase_t;
#define LIGHT_SEQUENCE_START 2
#define LIGHT_SEQUENCE 3
#define LIGHT_SEQUENCE_ALT 4
void T_Phase(phase_t * phase);
void T_Light(light_t * light);
void P_SpawnPhasedLight(sector_t * sector, int base, int index);
void P_SpawnLightSequence(sector_t * sector, int indexStep);
boolean EV_SpawnLight(line_t * line, byte * arg, lighttype_t type);
#if 0
typedef struct
{
thinker_t thinker;
sector_t *sector;
int count;
int maxlight;
int minlight;
int maxtime;
int mintime;
} lightflash_t;
typedef struct
{
thinker_t thinker;
sector_t *sector;
int count;
int minlight;
int maxlight;
int darktime;
int brighttime;
} strobe_t;
typedef struct
{
thinker_t thinker;
sector_t *sector;
int minlight;
int maxlight;
int direction;
} glow_t;
typedef struct
{
thinker_t thinker;
sector_t *sector;
int index;
int base;
} phase_t;
#define GLOWSPEED 8
#define STROBEBRIGHT 5
#define FASTDARK 15
#define SLOWDARK 35
#define LIGHT_SEQUENCE_START 2
#define LIGHT_SEQUENCE 3
#define LIGHT_SEQUENCE_ALT 4
void T_LightFlash(lightflash_t * flash);
void P_SpawnLightFlash(sector_t * sector);
void T_StrobeFlash(strobe_t * flash);
void P_SpawnStrobeFlash(sector_t * sector, int fastOrSlow, int inSync);
void EV_StartLightStrobing(line_t * line);
void EV_TurnTagLightsOff(line_t * line);
void EV_LightTurnOn(line_t * line, int bright);
void T_Glow(glow_t * g);
void P_SpawnGlowingLight(sector_t * sector);
void T_Phase(phase_t * phase);
void P_SpawnPhasedLight(sector_t * sector, int base, int index);
void P_SpawnLightSequence(sector_t * sector, int indexStep);
#endif
/*
===============================================================================
P_SWITCH
===============================================================================
*/
typedef struct
{
char name1[9];
char name2[9];
int soundID;
} switchlist_t;
typedef enum
{
SWTCH_TOP,
SWTCH_MIDDLE,
SWTCH_BOTTOM
} bwhere_e;
typedef struct
{
line_t *line;
bwhere_e where;
int btexture;
int btimer;
mobj_t *soundorg;
} button_t;
#define MAXSWITCHES 50 // max # of wall switches in a level
#define MAXBUTTONS 16 // 4 players, 4 buttons each at once, max.
#define BUTTONTIME 35 // 1 second
extern button_t buttonlist[MAXBUTTONS];
void P_ChangeSwitchTexture(line_t * line, int useAgain);
void P_InitSwitchList(void);
/*
===============================================================================
P_PLATS
===============================================================================
*/
typedef enum
{
PLAT_UP,
PLAT_DOWN,
PLAT_WAITING,
// PLAT_IN_STASIS
} plat_e;
typedef enum
{
PLAT_PERPETUALRAISE,
PLAT_DOWNWAITUPSTAY,
PLAT_DOWNBYVALUEWAITUPSTAY,
PLAT_UPWAITDOWNSTAY,
PLAT_UPBYVALUEWAITDOWNSTAY,
//PLAT_RAISEANDCHANGE,
//PLAT_RAISETONEARESTANDCHANGE
} plattype_e;
typedef struct
{
thinker_t thinker;
sector_t *sector;
fixed_t speed;
fixed_t low;
fixed_t high;
int wait;
int count;
plat_e status;
plat_e oldstatus;
int crush;
int tag;
plattype_e type;
} plat_t;
#define PLATWAIT 3
#define PLATSPEED FRACUNIT
#define MAXPLATS 30
extern plat_t *activeplats[MAXPLATS];
void T_PlatRaise(plat_t * plat);
int EV_DoPlat(line_t * line, byte * args, plattype_e type, int amount);
void P_AddActivePlat(plat_t * plat);
void P_RemoveActivePlat(plat_t * plat);
void EV_StopPlat(line_t * line, byte * args);
/*
===============================================================================
P_DOORS
===============================================================================
*/
typedef enum
{
DREV_NORMAL,
DREV_CLOSE30THENOPEN,
DREV_CLOSE,
DREV_OPEN,
DREV_RAISEIN5MINS,
} vldoor_e;
typedef struct
{
thinker_t thinker;
sector_t *sector;
vldoor_e type;
fixed_t topheight;
fixed_t speed;
int direction; // 1 = up, 0 = waiting at top, -1 = down
int topwait; // tics to wait at the top (keep in case a door going down is reset)
int topcountdown; // when it reaches 0, start going down
} vldoor_t;
#define VDOORSPEED FRACUNIT*2
#define VDOORWAIT 150
boolean EV_VerticalDoor(line_t * line, mobj_t * thing);
int EV_DoDoor(line_t * line, byte * args, vldoor_e type);
void T_VerticalDoor(vldoor_t * door);
//void P_SpawnDoorCloseIn30(sector_t *sec);
//void P_SpawnDoorRaiseIn5Mins(sector_t *sec, int secnum);
/*
===============================================================================
P_CEILNG
===============================================================================
*/
typedef enum
{
CLEV_LOWERTOFLOOR,
CLEV_RAISETOHIGHEST,
CLEV_LOWERANDCRUSH,
CLEV_CRUSHANDRAISE,
CLEV_LOWERBYVALUE,
CLEV_RAISEBYVALUE,
CLEV_CRUSHRAISEANDSTAY,
CLEV_MOVETOVALUETIMES8
} ceiling_e;
typedef struct
{
thinker_t thinker;
sector_t *sector;
ceiling_e type;
fixed_t bottomheight, topheight;
fixed_t speed;
int crush;
int direction; // 1 = up, 0 = waiting, -1 = down
int tag; // ID
int olddirection;
} ceiling_t;
#define CEILSPEED FRACUNIT
#define CEILWAIT 150
#define MAXCEILINGS 30
extern ceiling_t *activeceilings[MAXCEILINGS];
int EV_DoCeiling(line_t * line, byte * args, ceiling_e type);
void T_MoveCeiling(ceiling_t * ceiling);
void P_AddActiveCeiling(ceiling_t * c);
void P_RemoveActiveCeiling(ceiling_t * c);
int EV_CeilingCrushStop(line_t * line, byte * args);
/*
===============================================================================
P_FLOOR
===============================================================================
*/
typedef enum
{
FLEV_LOWERFLOOR, // lower floor to highest surrounding floor
FLEV_LOWERFLOORTOLOWEST, // lower floor to lowest surrounding floor
FLEV_LOWERFLOORBYVALUE,
FLEV_RAISEFLOOR, // raise floor to lowest surrounding CEILING
FLEV_RAISEFLOORTONEAREST, // raise floor to next highest surrounding floor
FLEV_RAISEFLOORBYVALUE,
FLEV_RAISEFLOORCRUSH,
FLEV_RAISEBUILDSTEP, // One step of a staircase
FLEV_RAISEBYVALUETIMES8,
FLEV_LOWERBYVALUETIMES8,
FLEV_LOWERTIMES8INSTANT,
FLEV_RAISETIMES8INSTANT,
FLEV_MOVETOVALUETIMES8
} floor_e;
typedef struct
{
thinker_t thinker;
sector_t *sector;
floor_e type;
int crush;
int direction;
int newspecial;
short texture;
fixed_t floordestheight;
fixed_t speed;
int delayCount;
int delayTotal;
fixed_t stairsDelayHeight;
fixed_t stairsDelayHeightDelta;
fixed_t resetHeight;
short resetDelay;
short resetDelayCount;
byte textureChange;
} floormove_t;
typedef struct
{
thinker_t thinker;
sector_t *sector;
int ceilingSpeed;
int floorSpeed;
int floordest;
int ceilingdest;
int direction;
int crush;
} pillar_t;
typedef struct
{
thinker_t thinker;
sector_t *sector;
fixed_t originalHeight;
fixed_t accumulator;
fixed_t accDelta;
fixed_t targetScale;
fixed_t scale;
fixed_t scaleDelta;
int ticker;
int state;
} floorWaggle_t;
#define FLOORSPEED FRACUNIT
typedef enum
{
RES_OK,
RES_CRUSHED,
RES_PASTDEST
} result_e;
typedef enum
{
STAIRS_NORMAL,
STAIRS_SYNC,
STAIRS_PHASED
} stairs_e;
result_e T_MovePlane(sector_t * sector, fixed_t speed,
fixed_t dest, int crush, int floorOrCeiling,
int direction);
int EV_BuildStairs(line_t * line, byte * args, int direction, stairs_e type);
int EV_DoFloor(line_t * line, byte * args, floor_e floortype);
void T_MoveFloor(floormove_t * floor);
void T_BuildPillar(pillar_t * pillar);
void T_FloorWaggle(floorWaggle_t * waggle);
int EV_BuildPillar(line_t * line, byte * args, boolean crush);
int EV_OpenPillar(line_t * line, byte * args);
int EV_DoFloorAndCeiling(line_t * line, byte * args, boolean raise);
int EV_FloorCrushStop(line_t * line, byte * args);
boolean EV_StartFloorWaggle(int tag, int height, int speed, int offset,
int timer);
//--------------------------------------------------------------------------
//
// p_telept
//
//--------------------------------------------------------------------------
boolean P_Teleport(mobj_t * thing, fixed_t x, fixed_t y, angle_t angle,
boolean useFog);
boolean EV_Teleport(int tid, mobj_t * thing, boolean fog);
//--------------------------------------------------------------------------
//
// p_acs
//
//--------------------------------------------------------------------------
#define MAX_ACS_SCRIPT_VARS 10
#define MAX_ACS_MAP_VARS 32
#define MAX_ACS_WORLD_VARS 64
#define ACS_STACK_DEPTH 32
#define MAX_ACS_STORE 20
typedef enum
{
ASTE_INACTIVE,
ASTE_RUNNING,
ASTE_SUSPENDED,
ASTE_WAITINGFORTAG,
ASTE_WAITINGFORPOLY,
ASTE_WAITINGFORSCRIPT,
ASTE_TERMINATING
} aste_t;
typedef struct acs_s acs_t;
typedef struct acsInfo_s acsInfo_t;
struct acsInfo_s
{
int number;
int *address;
int argCount;
aste_t state;
int waitValue;
};
struct acs_s
{
thinker_t thinker;
mobj_t *activator;
line_t *line;
int side;
int number;
int infoIndex;
int delayCount;
int stack[ACS_STACK_DEPTH];
int stackPtr;
int vars[MAX_ACS_SCRIPT_VARS];
int *ip;
};
typedef struct
{
int map; // Target map
int script; // Script number on target map
byte args[4]; // Padded to 4 for alignment
} acsstore_t;
void P_LoadACScripts(int lump);
boolean P_StartACS(int number, int map, byte * args, mobj_t * activator,
line_t * line, int side);
boolean P_StartLockedACS(line_t * line, byte * args, mobj_t * mo, int side);
boolean P_TerminateACS(int number, int map);
boolean P_SuspendACS(int number, int map);
void T_InterpretACS(acs_t * script);
void P_TagFinished(int tag);
void P_PolyobjFinished(int po);
void P_ACSInitNewGame(void);
void P_CheckACSStore(void);
extern int ACScriptCount;
extern byte *ActionCodeBase;
extern acsInfo_t *ACSInfo;
extern int MapVars[MAX_ACS_MAP_VARS];
extern int WorldVars[MAX_ACS_WORLD_VARS];
extern acsstore_t ACSStore[MAX_ACS_STORE + 1]; // +1 for termination marker
//--------------------------------------------------------------------------
//
// p_things
//
//--------------------------------------------------------------------------
extern mobjtype_t TranslateThingType[];
boolean EV_ThingProjectile(byte * args, boolean gravity);
boolean EV_ThingSpawn(byte * args, boolean fog);
boolean EV_ThingActivate(int tid);
boolean EV_ThingDeactivate(int tid);
boolean EV_ThingRemove(int tid);
boolean EV_ThingDestroy(int tid);