qzdoom/src/p_spec.h
Christoph Oelckers e77f83fbf6 - Added new Scroll_Wall special to allow more control over wall scrolling.
Since it uses fixed point parameters it can only be used in scripts though.
- Added flags parameters to all wall scroller specials that didn't use
  all 5 args.
- Separated scrolling of the 3 different texture parts of a sidedef.
  While doing this I did some more restructuring of the sidedef structure
  and changed it so that all state changes to sidedefs that affect rendering 
  have to be made with access functions. This is not of much use to the
  software renderer but it allows far easier caching of rendering data
  for OpenGL because the only place I need to check is in the access functions.


SVN r832 (trunk)
2008-03-21 17:35:49 +00:00

970 lines
23 KiB
C++

// 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: none
// Implements special effects:
// Texture animation, height or lighting changes
// according to adjacent sectors, respective
// utility functions, etc.
//
//-----------------------------------------------------------------------------
#ifndef __P_SPEC__
#define __P_SPEC__
#include "dsectoreffect.h"
class FScanner;
//jff 2/23/98 identify the special classes that can share sectors
typedef enum
{
floor_special,
ceiling_special,
lighting_special,
} special_e;
// killough 3/7/98: Add generalized scroll effects
class DScroller : public DThinker
{
DECLARE_CLASS (DScroller, DThinker)
public:
enum EScrollType
{
sc_side,
sc_floor,
sc_ceiling,
sc_carry,
sc_carry_ceiling, // killough 4/11/98: carry objects hanging on ceilings
};
enum EScrollPos
{
scw_top=1,
scw_mid=2,
scw_bottom=4,
scw_all=7,
};
DScroller (EScrollType type, fixed_t dx, fixed_t dy, int control, int affectee, int accel, int scrollpos = scw_all);
DScroller (fixed_t dx, fixed_t dy, const line_t *l, int control, int accel, int scrollpos = scw_all);
~DScroller ();
void Serialize (FArchive &arc);
void Tick ();
bool AffectsWall (int wallnum) const { return m_Type == sc_side && m_Affectee == wallnum; }
int GetWallNum () const { return m_Type == sc_side ? m_Affectee : -1; }
void SetRate (fixed_t dx, fixed_t dy) { m_dx = dx; m_dy = dy; }
bool IsType (EScrollType type) const { return type == m_Type; }
int GetAffectee () const { return m_Affectee; }
int GetScrollParts() const { return m_Parts; }
protected:
EScrollType m_Type; // Type of scroll effect
fixed_t m_dx, m_dy; // (dx,dy) scroll speeds
int m_Affectee; // Number of affected sidedef, sector, tag, or whatever
int m_Control; // Control sector (-1 if none) used to control scrolling
fixed_t m_LastHeight; // Last known height of control sector
fixed_t m_vdx, m_vdy; // Accumulated velocity if accelerative
int m_Accel; // Whether it's accelerative
int m_Parts; // Which parts of a sidedef are being scrolled?
private:
DScroller ();
};
// Factor to scale scrolling effect into mobj-carrying properties = 3/32.
// (This is so scrolling floors and objects on them can move at same speed.)
enum { CARRYFACTOR = ((fixed_t)(FRACUNIT*.09375)) };
inline FArchive &operator<< (FArchive &arc, DScroller::EScrollType &type)
{
BYTE val = (BYTE)type;
arc << val;
type = (DScroller::EScrollType)val;
return arc;
}
// phares 3/20/98: added new model of Pushers for push/pull effects
class DPusher : public DThinker
{
DECLARE_CLASS (DPusher, DThinker)
HAS_OBJECT_POINTERS
public:
enum EPusher
{
p_push,
p_pull,
p_wind,
p_current
};
DPusher ();
DPusher (EPusher type, line_t *l, int magnitude, int angle, AActor *source, int affectee);
void Serialize (FArchive &arc);
int CheckForSectorMatch (EPusher type, int tag)
{
if (m_Type == type && sectors[m_Affectee].tag == tag)
return m_Affectee;
else
return -1;
}
void ChangeValues (int magnitude, int angle)
{
angle_t ang = ((angle_t)(angle<<24)) >> ANGLETOFINESHIFT;
m_Xmag = (magnitude * finecosine[ang]) >> FRACBITS;
m_Ymag = (magnitude * finesine[ang]) >> FRACBITS;
m_Magnitude = magnitude;
}
void Tick ();
protected:
EPusher m_Type;
TObjPtr<AActor> m_Source;// Point source if point pusher
int m_Xmag; // X Strength
int m_Ymag; // Y Strength
int m_Magnitude; // Vector strength for point pusher
int m_Radius; // Effective radius for point pusher
int m_X; // X of point source if point pusher
int m_Y; // Y of point source if point pusher
int m_Affectee; // Number of affected sector
friend bool PIT_PushThing (AActor *thing);
};
bool PIT_PushThing (AActor *thing);
inline FArchive &operator<< (FArchive &arc, DPusher::EPusher &type)
{
BYTE val = (BYTE)type;
arc << val;
type = (DPusher::EPusher)val;
return arc;
}
// Define values for map objects
#define MO_TELEPORTMAN 14
// [RH] If a deathmatch game, checks to see if noexit is enabled.
// If so, it kills the player and returns false. Otherwise,
// it returns true, and the player is allowed to live.
bool CheckIfExitIsGood (AActor *self, level_info_t *info);
// at map load
void P_SpawnSpecials (void);
// every tic
void P_UpdateSpecials (void);
// when needed
bool P_ActivateLine (line_t *ld, AActor *mo, int side, int activationType);
bool P_TestActivateLine (line_t *ld, AActor *mo, int side, int activationType);
void P_PlayerInSpecialSector (player_t *player);
void P_PlayerOnSpecialFlat (player_t *player, int floorType);
void P_SetSectorFriction (int tag, int amount, bool alterFlag);
//
// getSide()
// Will return a side_t*
// given the number of the current sector,
// the line number, and the side (0/1) that you want.
//
inline side_t *getSide (int currentSector, int line, int side)
{
return &sides[ (sectors[currentSector].lines[line])->sidenum[side] ];
}
//
// getSector()
// Will return a sector_t*
// given the number of the current sector,
// the line number and the side (0/1) that you want.
//
inline sector_t *getSector (int currentSector, int line, int side)
{
return sides[ (sectors[currentSector].lines[line])->sidenum[side] ].sector;
}
//
// twoSided()
// Given the sector number and the line number,
// it will tell you whether the line is two-sided or not.
//
inline int twoSided (int sector, int line)
{
return (sectors[sector].lines[line])->flags & ML_TWOSIDED;
}
//
// getNextSector()
// Return sector_t * of sector next to current.
// NULL if not two-sided line
//
inline sector_t *getNextSector (line_t *line, const sector_t *sec)
{
if (!(line->flags & ML_TWOSIDED))
return NULL;
return line->frontsector == sec ?
(line->backsector != sec ? line->backsector : NULL) :
line->frontsector;
}
int P_FindSectorFromTag (int tag, int start);
int P_FindLineFromID (int id, int start);
//
// P_LIGHTS
//
class DLighting : public DSectorEffect
{
DECLARE_CLASS (DLighting, DSectorEffect)
public:
DLighting (sector_t *sector);
protected:
DLighting ();
};
class DFireFlicker : public DLighting
{
DECLARE_CLASS (DFireFlicker, DLighting)
public:
DFireFlicker (sector_t *sector);
DFireFlicker (sector_t *sector, int upper, int lower);
void Serialize (FArchive &arc);
void Tick ();
protected:
int m_Count;
int m_MaxLight;
int m_MinLight;
private:
DFireFlicker ();
};
class DFlicker : public DLighting
{
DECLARE_CLASS (DFlicker, DLighting)
public:
DFlicker (sector_t *sector, int upper, int lower);
void Serialize (FArchive &arc);
void Tick ();
protected:
int m_Count;
int m_MaxLight;
int m_MinLight;
private:
DFlicker ();
};
class DLightFlash : public DLighting
{
DECLARE_CLASS (DLightFlash, DLighting)
public:
DLightFlash (sector_t *sector);
DLightFlash (sector_t *sector, int min, int max);
void Serialize (FArchive &arc);
void Tick ();
protected:
int m_Count;
int m_MaxLight;
int m_MinLight;
int m_MaxTime;
int m_MinTime;
private:
DLightFlash ();
};
class DStrobe : public DLighting
{
DECLARE_CLASS (DStrobe, DLighting)
public:
DStrobe (sector_t *sector, int utics, int ltics, bool inSync);
DStrobe (sector_t *sector, int upper, int lower, int utics, int ltics);
void Serialize (FArchive &arc);
void Tick ();
protected:
int m_Count;
int m_MinLight;
int m_MaxLight;
int m_DarkTime;
int m_BrightTime;
private:
DStrobe ();
};
class DGlow : public DLighting
{
DECLARE_CLASS (DGlow, DLighting)
public:
DGlow (sector_t *sector);
void Serialize (FArchive &arc);
void Tick ();
protected:
int m_MinLight;
int m_MaxLight;
int m_Direction;
private:
DGlow ();
};
// [RH] Glow from Light_Glow and Light_Fade specials
class DGlow2 : public DLighting
{
DECLARE_CLASS (DGlow2, DLighting)
public:
DGlow2 (sector_t *sector, int start, int end, int tics, bool oneshot);
void Serialize (FArchive &arc);
void Tick ();
protected:
int m_Start;
int m_End;
int m_MaxTics;
int m_Tics;
bool m_OneShot;
private:
DGlow2 ();
};
// [RH] Phased light thinker
class DPhased : public DLighting
{
DECLARE_CLASS (DPhased, DLighting)
public:
DPhased (sector_t *sector);
DPhased (sector_t *sector, int baselevel, int phase);
void Serialize (FArchive &arc);
void Tick ();
protected:
BYTE m_BaseLevel;
BYTE m_Phase;
private:
DPhased ();
DPhased (sector_t *sector, int baselevel);
int PhaseHelper (sector_t *sector, int index, int light, sector_t *prev);
};
#define GLOWSPEED 8
#define STROBEBRIGHT 5
#define FASTDARK 15
#define SLOWDARK TICRATE
void EV_StartLightFlickering (int tag, int upper, int lower);
void EV_StartLightStrobing (int tag, int upper, int lower, int utics, int ltics);
void EV_StartLightStrobing (int tag, int utics, int ltics);
void EV_TurnTagLightsOff (int tag);
void EV_LightTurnOn (int tag, int bright);
void EV_LightTurnOnPartway (int tag, fixed_t frac); // killough 10/98
void EV_LightChange (int tag, int value);
void EV_StopLightEffect (int tag);
void P_SpawnGlowingLight (sector_t *sector);
void EV_StartLightGlowing (int tag, int upper, int lower, int tics);
void EV_StartLightFading (int tag, int value, int tics);
//
// P_SWITCH
//
#define BUTTONTIME TICRATE // 1 second, in ticks.
bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *quest=NULL);
bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno);
void P_InitSwitchList ();
void P_ProcessSwitchDef (FScanner &sc);
//
// P_PLATS
//
class DPlat : public DMovingFloor
{
DECLARE_CLASS (DPlat, DMovingFloor)
public:
enum EPlatState
{
up,
down,
waiting,
in_stasis
};
enum EPlatType
{
platPerpetualRaise,
platDownWaitUpStay,
platDownWaitUpStayStone,
platUpWaitDownStay,
platUpNearestWaitDownStay,
platDownByValue,
platUpByValue,
platUpByValueStay,
platRaiseAndStay,
platToggle,
platDownToNearestFloor,
platDownToLowestCeiling,
};
void Serialize (FArchive &arc);
void Tick ();
bool IsLift() const { return m_Type == platDownWaitUpStay || m_Type == platDownWaitUpStayStone; }
protected:
DPlat (sector_t *sector);
fixed_t m_Speed;
fixed_t m_Low;
fixed_t m_High;
int m_Wait;
int m_Count;
EPlatState m_Status;
EPlatState m_OldStatus;
int m_Crush;
int m_Tag;
EPlatType m_Type;
void PlayPlatSound (const char *sound);
void Reactivate ();
void Stop ();
private:
DPlat ();
friend bool EV_DoPlat (int tag, line_t *line, EPlatType type,
int height, int speed, int delay, int lip, int change);
friend void EV_StopPlat (int tag);
friend void P_ActivateInStasis (int tag);
};
bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type,
int height, int speed, int delay, int lip, int change);
void EV_StopPlat (int tag);
void P_ActivateInStasis (int tag);
inline FArchive &operator<< (FArchive &arc, DPlat::EPlatType &type)
{
BYTE val = (BYTE)type;
arc << val;
type = (DPlat::EPlatType)val;
return arc;
}
inline FArchive &operator<< (FArchive &arc, DPlat::EPlatState &state)
{
BYTE val = (BYTE)state;
arc << val;
state = (DPlat::EPlatState)val;
return arc;
}
//
// [RH]
// P_PILLAR
//
class DPillar : public DMover
{
DECLARE_CLASS (DPillar, DMover)
public:
enum EPillar
{
pillarBuild,
pillarOpen
};
DPillar (sector_t *sector, EPillar type, fixed_t speed, fixed_t height,
fixed_t height2, int crush, bool hexencrush);
void Serialize (FArchive &arc);
void Tick ();
protected:
EPillar m_Type;
fixed_t m_FloorSpeed;
fixed_t m_CeilingSpeed;
fixed_t m_FloorTarget;
fixed_t m_CeilingTarget;
int m_Crush;
bool m_Hexencrush;
private:
DPillar ();
};
inline FArchive &operator<< (FArchive &arc, DPillar::EPillar &type)
{
BYTE val = (BYTE)type;
arc << val;
type = (DPillar::EPillar)val;
return arc;
}
bool EV_DoPillar (DPillar::EPillar type, int tag, fixed_t speed, fixed_t height,
fixed_t height2, int crush, bool hexencrush);
//
// P_DOORS
//
class DDoor : public DMovingCeiling
{
DECLARE_CLASS (DDoor, DMovingCeiling)
public:
enum EVlDoor
{
doorClose,
doorOpen,
doorRaise,
doorRaiseIn5Mins,
doorCloseWaitOpen,
};
DDoor (sector_t *sector);
DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int lightTag);
void Serialize (FArchive &arc);
void Tick ();
protected:
EVlDoor m_Type;
fixed_t m_TopDist;
fixed_t m_BotDist, m_OldFloorDist;
vertex_t *m_BotSpot;
fixed_t m_Speed;
// 1 = up, 0 = waiting at top, -1 = down
int m_Direction;
// tics to wait at the top
int m_TopWait;
// (keep in case a door going down is reset)
// when it reaches 0, start going down
int m_TopCountdown;
int m_LightTag;
void DoorSound (bool raise) const;
friend bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing,
int tag, int speed, int delay, int lock,
int lightTag);
friend void P_SpawnDoorCloseIn30 (sector_t *sec);
friend void P_SpawnDoorRaiseIn5Mins (sector_t *sec);
private:
DDoor ();
};
bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing,
int tag, int speed, int delay, int lock,
int lightTag);
void P_SpawnDoorCloseIn30 (sector_t *sec);
void P_SpawnDoorRaiseIn5Mins (sector_t *sec);
inline FArchive &operator<< (FArchive &arc, DDoor::EVlDoor &type)
{
BYTE val = (BYTE)type;
arc << val;
type = (DDoor::EVlDoor)val;
return arc;
}
struct FDoorAnimation
{
int BaseTexture;
int *TextureFrames;
int NumTextureFrames;
char *OpenSound;
char *CloseSound;
};
void P_ParseAnimatedDoor (FScanner &sc);
class DAnimatedDoor : public DMovingCeiling
{
DECLARE_CLASS (DAnimatedDoor, DMovingCeiling)
public:
DAnimatedDoor (sector_t *sector);
DAnimatedDoor (sector_t *sector, line_t *line, int speed, int delay);
void Serialize (FArchive &arc);
void Tick ();
bool StartClosing ();
protected:
line_t *m_Line1, *m_Line2;
int m_Frame;
int m_WhichDoorIndex;
int m_Timer;
fixed_t m_BotDist;
int m_Status;
enum
{
Opening,
Waiting,
Closing,
Dead
};
int m_Speed;
int m_Delay;
friend bool EV_SlidingDoor (line_t *line, AActor *thing, int tag, int speed, int delay);
private:
DAnimatedDoor ();
};
bool EV_SlidingDoor (line_t *line, AActor *thing, int tag, int speed, int delay);
//
// P_CEILNG
//
// [RH] Changed these
class DCeiling : public DMovingCeiling
{
DECLARE_CLASS (DCeiling, DMovingCeiling)
public:
enum ECeiling
{
ceilLowerByValue,
ceilRaiseByValue,
ceilMoveToValue,
ceilLowerToHighestFloor,
ceilLowerInstant,
ceilRaiseInstant,
ceilCrushAndRaise,
ceilLowerAndCrush,
ceilCrushRaiseAndStay,
ceilRaiseToNearest,
ceilLowerToLowest,
ceilLowerToFloor,
// The following are only used by Generic_Ceiling
ceilRaiseToHighest,
ceilLowerToHighest,
ceilRaiseToLowest,
ceilLowerToNearest,
ceilRaiseToHighestFloor,
ceilRaiseToFloor,
ceilRaiseByTexture,
ceilLowerByTexture,
genCeilingChg0,
genCeilingChgT,
genCeilingChg
};
DCeiling (sector_t *sec);
DCeiling (sector_t *sec, fixed_t speed1, fixed_t speed2, int silent);
void Serialize (FArchive &arc);
void Tick ();
protected:
ECeiling m_Type;
fixed_t m_BottomHeight;
fixed_t m_TopHeight;
fixed_t m_Speed;
fixed_t m_Speed1; // [RH] dnspeed of crushers
fixed_t m_Speed2; // [RH] upspeed of crushers
int m_Crush;
bool m_Hexencrush;
int m_Silent;
int m_Direction; // 1 = up, 0 = waiting, -1 = down
// [RH] Need these for BOOM-ish transferring ceilings
int m_Texture;
int m_NewSpecial;
// ID
int m_Tag;
int m_OldDirection;
void PlayCeilingSound ();
private:
DCeiling ();
friend bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line,
int tag, fixed_t speed, fixed_t speed2, fixed_t height,
int crush, int silent, int change, bool hexencrush);
friend bool EV_CeilingCrushStop (int tag);
friend void P_ActivateInStasisCeiling (int tag);
};
bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line,
int tag, fixed_t speed, fixed_t speed2, fixed_t height,
int crush, int silent, int change, bool hexencrush);
bool EV_CeilingCrushStop (int tag);
void P_ActivateInStasisCeiling (int tag);
inline FArchive &operator<< (FArchive &arc, DCeiling::ECeiling &type)
{
BYTE val = (BYTE)type;
arc << val;
type = (DCeiling::ECeiling)val;
return arc;
}
//
// P_FLOOR
//
class DFloor : public DMovingFloor
{
DECLARE_CLASS (DFloor, DMovingFloor)
public:
enum EFloor
{
floorLowerToLowest,
floorLowerToNearest,
floorLowerToHighest,
floorLowerByValue,
floorRaiseByValue,
floorRaiseToHighest,
floorRaiseToNearest,
floorRaiseAndCrush,
floorCrushStop,
floorLowerInstant,
floorRaiseInstant,
floorMoveToValue,
floorRaiseToLowestCeiling,
floorRaiseByTexture,
floorLowerAndChange,
floorRaiseAndChange,
floorRaiseToLowest,
floorRaiseToCeiling,
floorLowerToLowestCeiling,
floorLowerByTexture,
floorLowerToCeiling,
donutRaise,
buildStair,
waitStair,
resetStair,
// Not to be used as parameters to EV_DoFloor()
genFloorChg0,
genFloorChgT,
genFloorChg
};
// [RH] Changed to use Hexen-ish specials
enum EStair
{
buildUp,
buildDown
};
DFloor (sector_t *sec);
void Serialize (FArchive &arc);
void Tick ();
protected:
EFloor m_Type;
int m_Crush;
bool m_Hexencrush;
int m_Direction;
short m_NewSpecial;
short m_Texture;
fixed_t m_FloorDestDist;
fixed_t m_Speed;
// [RH] New parameters used to reset and delay stairs
int m_ResetCount;
int m_OrgDist;
int m_Delay;
int m_PauseTime;
int m_StepTime;
int m_PerStepTime;
void StartFloorSound ();
void SetFloorChangeType (sector_t *sec, int change);
friend bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line,
fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt,
int usespecials);
friend bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag,
fixed_t speed, fixed_t height, int crush, int change, bool hexencrush);
friend bool EV_FloorCrushStop (int tag);
friend bool EV_DoDonut (int tag, fixed_t pillarspeed, fixed_t slimespeed);
private:
DFloor ();
};
bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line,
fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt,
int usespecials);
bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag,
fixed_t speed, fixed_t height, int crush, int change, bool hexencrush);
bool EV_FloorCrushStop (int tag);
bool EV_DoDonut (int tag, fixed_t pillarspeed, fixed_t slimespeed);
inline FArchive &operator<< (FArchive &arc, DFloor::EFloor &type)
{
BYTE val = (BYTE)type;
arc << val;
type = (DFloor::EFloor)val;
return arc;
}
class DElevator : public DMover
{
DECLARE_CLASS (DElevator, DMover)
public:
enum EElevator
{
elevateUp,
elevateDown,
elevateCurrent,
// [RH] For FloorAndCeiling_Raise/Lower
elevateRaise,
elevateLower
};
DElevator (sector_t *sec);
void Serialize (FArchive &arc);
void Tick ();
protected:
EElevator m_Type;
int m_Direction;
fixed_t m_FloorDestDist;
fixed_t m_CeilingDestDist;
fixed_t m_Speed;
void StartFloorSound ();
friend bool EV_DoElevator (line_t *line, DElevator::EElevator type, fixed_t speed,
fixed_t height, int tag);
private:
DElevator ();
};
bool EV_DoElevator (line_t *line, DElevator::EElevator type, fixed_t speed,
fixed_t height, int tag);
inline FArchive &operator<< (FArchive &arc, DElevator::EElevator &type)
{
BYTE val = (BYTE)type;
arc << val;
type = (DElevator::EElevator)val;
return arc;
}
class DWaggleBase : public DMover
{
DECLARE_CLASS (DWaggleBase, DMover)
public:
DWaggleBase (sector_t *sec);
void Serialize (FArchive &arc);
protected:
fixed_t m_OriginalDist;
fixed_t m_Accumulator;
fixed_t m_AccDelta;
fixed_t m_TargetScale;
fixed_t m_Scale;
fixed_t m_ScaleDelta;
int m_Ticker;
int m_State;
friend bool EV_StartWaggle (int tag, int height, int speed,
int offset, int timer, bool ceiling);
void DoWaggle (bool ceiling);
DWaggleBase ();
};
bool EV_StartWaggle (int tag, int height, int speed,
int offset, int timer, bool ceiling);
class DFloorWaggle : public DWaggleBase
{
DECLARE_CLASS (DFloorWaggle, DWaggleBase)
public:
DFloorWaggle (sector_t *sec);
void Tick ();
private:
DFloorWaggle ();
};
class DCeilingWaggle : public DWaggleBase
{
DECLARE_CLASS (DCeilingWaggle, DWaggleBase)
public:
DCeilingWaggle (sector_t *sec);
void Tick ();
private:
DCeilingWaggle ();
};
//jff 3/15/98 pure texture/type change for better generalized support
enum EChange
{
trigChangeOnly,
numChangeOnly,
};
bool EV_DoChange (line_t *line, EChange changetype, int tag);
//
// P_TELEPT
//
bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, bool useFog, bool sourceFog, bool keepOrientation);
bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, bool fog, bool sourceFog, bool keepOrientation);
bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBOOL reverse);
bool EV_TeleportOther (int other_tid, int dest_tid, bool fog);
bool EV_TeleportGroup (int group_tid, AActor *victim, int source_tid, int dest_tid, bool moveSource, bool fog);
bool EV_TeleportSector (int tag, int source_tid, int dest_tid, bool fog, int group_tid);
//
// [RH] ACS (see also p_acs.h)
//
int P_StartScript (AActor *who, line_t *where, int script, char *map, bool backSide,
int arg0, int arg1, int arg2, int always, bool wantResultCode, bool net=false);
void P_SuspendScript (int script, char *map);
void P_TerminateScript (int script, char *map);
void P_DoDeferedScripts (void);
//
// [RH] p_quake.c
//
bool P_StartQuake (AActor *activator, int tid, int intensity, int duration, int damrad, int tremrad);
#endif