2016-03-01 15:47:10 +00:00
//-----------------------------------------------------------------------------
//
2017-04-17 11:33:19 +00:00
// Copyright 1993-1996 id Software
// Copyright 1994-1996 Raven Software
// Copyright 1998-1998 Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
// Copyright 1999-2016 Randy Heit
// Copyright 2002-2016 Christoph Oelckers
2016-03-01 15:47:10 +00:00
//
2017-04-17 11:33:19 +00:00
// 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 3 of the License, or
// (at your option) any later version.
2016-03-01 15:47:10 +00:00
//
2017-04-17 11:33:19 +00:00
// This program is distributed in the hope that it will be useful,
2016-03-01 15:47:10 +00:00
// but WITHOUT ANY WARRANTY; without even the implied warranty of
2017-04-17 11:33:19 +00:00
// 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, see http://www.gnu.org/licenses/
//
//-----------------------------------------------------------------------------
2016-03-01 15:47:10 +00:00
//
// 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"
# include "doomdata.h"
# include "r_state.h"
class FScanner ;
struct level_info_t ;
2017-03-10 01:22:42 +00:00
struct FDoorAnimation ;
2016-03-01 15:47:10 +00:00
2016-03-28 15:27:55 +00:00
enum class EScroll : int
2016-03-01 15:47:10 +00:00
{
sc_side ,
sc_floor ,
sc_ceiling ,
sc_carry ,
sc_carry_ceiling , // killough 4/11/98: carry objects hanging on ceilings
2016-03-28 15:27:55 +00:00
} ;
2016-03-01 15:47:10 +00:00
2016-03-28 15:27:55 +00:00
enum EScrollPos : int
2016-03-01 15:47:10 +00:00
{
2016-03-28 15:27:55 +00:00
scw_top = 1 ,
scw_mid = 2 ,
scw_bottom = 4 ,
scw_all = 7 ,
} ;
2016-03-01 15:47:10 +00:00
2016-03-28 15:27:55 +00:00
//jff 2/23/98 identify the special classes that can share sectors
2016-03-01 15:47:10 +00:00
2016-03-28 15:27:55 +00:00
typedef enum
{
floor_special ,
ceiling_special ,
lighting_special ,
} special_e ;
2016-03-01 15:47:10 +00:00
// 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.)
2016-03-19 23:54:18 +00:00
const double CARRYFACTOR = 3 / 32. ;
2016-03-01 15:47:10 +00:00
// Flags for P_SectorDamage
# define DAMAGE_PLAYERS 1
# define DAMAGE_NONPLAYERS 2
# define DAMAGE_IN_AIR 4
# define DAMAGE_SUBCLASSES_PROTECT 8
2017-02-25 18:10:49 +00:00
# define DAMAGE_NO_ARMOR 16
2016-03-01 15:47:10 +00:00
2018-12-27 11:32:35 +00:00
class MapLoader ;
2016-03-01 15:47:10 +00:00
// every tic
2019-01-23 23:02:51 +00:00
void P_UpdateSpecials ( FLevelLocals * ) ;
2016-03-01 15:47:10 +00:00
// when needed
2016-03-27 18:58:01 +00:00
bool P_ActivateLine ( line_t * ld , AActor * mo , int side , int activationType , DVector3 * optpos = NULL ) ;
bool P_TestActivateLine ( line_t * ld , AActor * mo , int side , int activationType , DVector3 * optpos = NULL ) ;
2016-03-01 15:47:10 +00:00
bool P_PredictLine ( line_t * ld , AActor * mo , int side , int activationType ) ;
void P_PlayerInSpecialSector ( player_t * player , sector_t * sector = NULL ) ;
void P_PlayerOnSpecialFlat ( player_t * player , int floorType ) ;
2019-01-23 23:02:51 +00:00
void P_SectorDamage ( FLevelLocals * Level , int tag , int amount , FName type , PClassActor * protectClass , int flags ) ;
void P_SetSectorFriction ( FLevelLocals * level , int tag , int amount , bool alterFlag ) ;
2016-03-24 21:50:03 +00:00
double FrictionToMoveFactor ( double friction ) ;
2019-01-23 23:02:51 +00:00
void P_GiveSecret ( FLevelLocals * Level , AActor * actor , bool printmessage , bool playsound , int sectornum ) ;
2016-03-01 15:47:10 +00:00
//
// 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 ;
}
# include "p_tags.h"
class DLighting : public DSectorEffect
{
2016-04-10 16:29:23 +00:00
DECLARE_CLASS ( DLighting , DSectorEffect )
2016-03-01 15:47:10 +00:00
public :
2019-01-27 00:49:20 +00:00
static const int DEFAULT_STAT = STAT_LIGHT ;
2016-03-01 15:47:10 +00:00
} ;
//
// P_SWITCH
//
# define BUTTONTIME TICRATE // 1 second, in ticks.
2017-03-08 14:20:00 +00:00
bool P_ChangeSwitchTexture ( side_t * side , int useAgain , uint8_t special , bool * quest = NULL ) ;
2016-03-27 18:58:01 +00:00
bool P_CheckSwitchRange ( AActor * user , line_t * line , int sideno , const DVector3 * optpos = NULL ) ;
2016-03-01 15:47:10 +00:00
//
// 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 ,
platRaiseAndStayLockout ,
} ;
2016-09-19 17:14:30 +00:00
void Serialize ( FSerializer & arc ) ;
2016-03-01 15:47:10 +00:00
void Tick ( ) ;
bool IsLift ( ) const { return m_Type = = platDownWaitUpStay | | m_Type = = platDownWaitUpStayStone ; }
2019-01-27 12:08:54 +00:00
void Construct ( sector_t * sector ) ;
2016-03-01 15:47:10 +00:00
protected :
2016-03-30 07:41:46 +00:00
double m_Speed ;
double m_Low ;
double m_High ;
2016-03-01 15:47:10 +00:00
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 ( ) ;
2019-01-26 07:28:45 +00:00
friend struct FLevelLocals ;
2016-03-01 15:47:10 +00:00
} ;
//
// [RH]
// P_PILLAR
//
class DPillar : public DMover
{
DECLARE_CLASS ( DPillar , DMover )
HAS_OBJECT_POINTERS
public :
enum EPillar
{
pillarBuild ,
pillarOpen
} ;
2019-01-27 12:08:54 +00:00
void Construct ( sector_t * sector , EPillar type , double speed , double height , double height2 , int crush , bool hexencrush ) ;
2016-03-01 15:47:10 +00:00
2016-09-19 17:14:30 +00:00
void Serialize ( FSerializer & arc ) ;
2016-03-01 15:47:10 +00:00
void Tick ( ) ;
2017-01-12 21:49:18 +00:00
void OnDestroy ( ) override ;
2016-03-01 15:47:10 +00:00
protected :
EPillar m_Type ;
2016-03-30 07:41:46 +00:00
double m_FloorSpeed ;
double m_CeilingSpeed ;
double m_FloorTarget ;
double m_CeilingTarget ;
2016-03-01 15:47:10 +00:00
int m_Crush ;
bool m_Hexencrush ;
2017-03-08 12:34:26 +00:00
TObjPtr < DInterpolation * > m_Interp_Ceiling ;
TObjPtr < DInterpolation * > m_Interp_Floor ;
2016-03-01 15:47:10 +00:00
} ;
//
// P_DOORS
//
class DDoor : public DMovingCeiling
{
DECLARE_CLASS ( DDoor , DMovingCeiling )
public :
enum EVlDoor
{
doorClose ,
doorOpen ,
doorRaise ,
doorWaitRaise ,
doorCloseWaitOpen ,
doorWaitClose ,
} ;
2019-01-27 12:08:54 +00:00
void Construct ( sector_t * sector ) ;
void Construct ( sector_t * sec , EVlDoor type , double speed , int delay , int lightTag , int topcountdown ) ;
2016-03-01 15:47:10 +00:00
2016-09-19 17:14:30 +00:00
void Serialize ( FSerializer & arc ) ;
2016-03-01 15:47:10 +00:00
void Tick ( ) ;
protected :
EVlDoor m_Type ;
2016-03-30 07:41:46 +00:00
double m_TopDist ;
double m_BotDist , m_OldFloorDist ;
2016-03-01 15:47:10 +00:00
vertex_t * m_BotSpot ;
2016-03-30 07:41:46 +00:00
double m_Speed ;
2016-03-01 15:47:10 +00:00
// 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 , class DSeqNode * curseq = NULL ) const ;
private :
2019-01-26 07:28:45 +00:00
friend struct FLevelLocals ;
2016-03-01 15:47:10 +00:00
} ;
class DAnimatedDoor : public DMovingCeiling
{
DECLARE_CLASS ( DAnimatedDoor , DMovingCeiling )
public :
2017-02-16 17:35:58 +00:00
enum EADType
{
adOpenClose ,
adClose
} ;
2019-01-27 12:08:54 +00:00
void Construct ( sector_t * sector ) ;
void Construct ( sector_t * sec , line_t * line , int speed , int delay , FDoorAnimation * anim , EADType type ) ;
2016-03-01 15:47:10 +00:00
2016-09-19 17:14:30 +00:00
void Serialize ( FSerializer & arc ) ;
2016-03-01 15:47:10 +00:00
void Tick ( ) ;
bool StartClosing ( ) ;
protected :
line_t * m_Line1 , * m_Line2 ;
int m_Frame ;
FDoorAnimation * m_DoorAnim ;
int m_Timer ;
2016-03-30 07:41:46 +00:00
double m_BotDist ;
2016-03-01 15:47:10 +00:00
int m_Status ;
2017-02-16 17:35:58 +00:00
int m_Type ;
2016-03-01 15:47:10 +00:00
enum
{
Opening ,
Waiting ,
Closing ,
Dead
} ;
int m_Speed ;
int m_Delay ;
bool m_SetBlocking1 , m_SetBlocking2 ;
2019-01-26 07:28:45 +00:00
friend struct FLevelLocals ;
2016-03-01 15:47:10 +00:00
} ;
//
2019-01-26 07:28:45 +00:00
// P_CEILING
2016-03-01 15:47:10 +00:00
//
// [RH] Changed these
class DCeiling : public DMovingCeiling
{
DECLARE_CLASS ( DCeiling , DMovingCeiling )
public :
enum ECeiling
{
ceilLowerByValue ,
ceilRaiseByValue ,
ceilMoveToValue ,
ceilLowerToHighestFloor ,
ceilLowerInstant ,
ceilRaiseInstant ,
ceilCrushAndRaise ,
ceilLowerAndCrush ,
2016-03-07 16:24:30 +00:00
ceil_placeholder ,
2016-03-01 15:47:10 +00:00
ceilCrushRaiseAndStay ,
ceilRaiseToNearest ,
ceilLowerToLowest ,
ceilLowerToFloor ,
// The following are only used by Generic_Ceiling
ceilRaiseToHighest ,
ceilLowerToHighest ,
ceilRaiseToLowest ,
ceilLowerToNearest ,
ceilRaiseToHighestFloor ,
ceilRaiseToFloor ,
ceilRaiseByTexture ,
ceilLowerByTexture ,
genCeilingChg0 ,
genCeilingChgT ,
genCeilingChg
} ;
2016-03-25 01:08:22 +00:00
enum class ECrushMode
{
crushDoom = 0 ,
crushHexen = 1 ,
crushSlowdown = 2
} ;
2019-01-27 12:08:54 +00:00
void Construct ( sector_t * sec ) ;
void Construct ( sector_t * sec , double speed1 , double speed2 , int silent ) ;
2016-03-01 15:47:10 +00:00
2016-09-19 17:14:30 +00:00
void Serialize ( FSerializer & arc ) ;
2016-03-01 15:47:10 +00:00
void Tick ( ) ;
protected :
ECeiling m_Type ;
2016-03-30 07:41:46 +00:00
double m_BottomHeight ;
double m_TopHeight ;
double m_Speed ;
double m_Speed1 ; // [RH] dnspeed of crushers
double m_Speed2 ; // [RH] upspeed of crushers
2016-03-01 15:47:10 +00:00
int m_Crush ;
2016-03-25 01:08:22 +00:00
ECrushMode m_CrushMode ;
2016-03-01 15:47:10 +00:00
int m_Silent ;
int m_Direction ; // 1 = up, 0 = waiting, -1 = down
// [RH] Need these for BOOM-ish transferring ceilings
FTextureID m_Texture ;
2018-10-23 17:19:10 +00:00
secspecial_t m_NewSpecial { } ;
2016-03-01 15:47:10 +00:00
// ID
int m_Tag ;
int m_OldDirection ;
void PlayCeilingSound ( ) ;
2019-01-26 07:28:45 +00:00
friend struct FLevelLocals ;
2016-03-01 15:47:10 +00:00
} ;
//
// P_FLOOR
//
class DFloor : public DMovingFloor
{
DECLARE_CLASS ( DFloor , DMovingFloor )
public :
enum EFloor
{
floorLowerToLowest ,
floorLowerToNearest ,
floorLowerToHighest ,
floorLowerByValue ,
floorRaiseByValue ,
floorRaiseToHighest ,
floorRaiseToNearest ,
floorRaiseAndCrush ,
floorRaiseAndCrushDoom ,
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
} ;
enum EStairType
{
stairUseSpecials = 1 ,
2017-01-08 00:15:45 +00:00
stairSync = 2 ,
stairCrush = 4 ,
2016-03-01 15:47:10 +00:00
} ;
2019-01-27 12:08:54 +00:00
void Construct ( sector_t * sec ) ;
2016-03-01 15:47:10 +00:00
2016-09-19 17:14:30 +00:00
void Serialize ( FSerializer & arc ) ;
2016-03-01 15:47:10 +00:00
void Tick ( ) ;
2016-03-30 07:41:46 +00:00
//protected:
2016-03-01 15:47:10 +00:00
EFloor m_Type ;
int m_Crush ;
bool m_Hexencrush ;
2016-12-27 20:16:42 +00:00
bool m_Instant ;
2016-03-01 15:47:10 +00:00
int m_Direction ;
2018-10-23 17:19:10 +00:00
secspecial_t m_NewSpecial { } ;
2016-03-01 15:47:10 +00:00
FTextureID m_Texture ;
2016-03-30 07:41:46 +00:00
double m_FloorDestDist ;
double m_Speed ;
2016-03-01 15:47:10 +00:00
// [RH] New parameters used to reset and delay stairs
2016-03-30 07:41:46 +00:00
double m_OrgDist ;
2016-03-01 15:47:10 +00:00
int m_ResetCount ;
int m_Delay ;
int m_PauseTime ;
int m_StepTime ;
int m_PerStepTime ;
void StartFloorSound ( ) ;
void SetFloorChangeType ( sector_t * sec , int change ) ;
2019-01-26 07:28:45 +00:00
friend struct FLevelLocals ;
2016-03-01 15:47:10 +00:00
} ;
class DElevator : public DMover
{
DECLARE_CLASS ( DElevator , DMover )
HAS_OBJECT_POINTERS
public :
enum EElevator
{
elevateUp ,
elevateDown ,
elevateCurrent ,
// [RH] For FloorAndCeiling_Raise/Lower
elevateRaise ,
elevateLower
} ;
2019-01-27 12:08:54 +00:00
void Construct ( sector_t * sec ) ;
2016-03-01 15:47:10 +00:00
2017-01-12 21:49:18 +00:00
void OnDestroy ( ) override ;
2016-09-19 17:14:30 +00:00
void Serialize ( FSerializer & arc ) ;
2016-03-01 15:47:10 +00:00
void Tick ( ) ;
protected :
EElevator m_Type ;
int m_Direction ;
2016-03-30 07:41:46 +00:00
double m_FloorDestDist ;
double m_CeilingDestDist ;
double m_Speed ;
2017-03-08 12:34:26 +00:00
TObjPtr < DInterpolation * > m_Interp_Ceiling ;
TObjPtr < DInterpolation * > m_Interp_Floor ;
2016-03-01 15:47:10 +00:00
void StartFloorSound ( ) ;
2019-01-26 07:28:45 +00:00
friend struct FLevelLocals ;
2016-03-01 15:47:10 +00:00
} ;
class DWaggleBase : public DMover
{
DECLARE_CLASS ( DWaggleBase , DMover )
HAS_OBJECT_POINTERS
public :
2019-01-27 12:08:54 +00:00
void Construct ( sector_t * sec ) ;
2016-03-01 15:47:10 +00:00
2016-09-19 17:14:30 +00:00
void Serialize ( FSerializer & arc ) ;
2016-03-01 15:47:10 +00:00
protected :
2016-03-30 07:41:46 +00:00
double m_OriginalDist ;
double m_Accumulator ;
double m_AccDelta ;
double m_TargetScale ;
double m_Scale ;
double m_ScaleDelta ;
2016-03-01 15:47:10 +00:00
int m_Ticker ;
int m_State ;
2019-01-26 07:28:45 +00:00
friend struct FLevelLocals ;
2016-03-01 15:47:10 +00:00
void DoWaggle ( bool ceiling ) ;
} ;
class DFloorWaggle : public DWaggleBase
{
DECLARE_CLASS ( DFloorWaggle , DWaggleBase )
public :
2019-01-27 12:08:54 +00:00
void Construct ( sector_t * sec ) ;
2016-03-01 15:47:10 +00:00
void Tick ( ) ;
} ;
class DCeilingWaggle : public DWaggleBase
{
DECLARE_CLASS ( DCeilingWaggle , DWaggleBase )
public :
2019-01-27 12:08:54 +00:00
void Construct ( sector_t * sec ) ;
2016-03-01 15:47:10 +00:00
void Tick ( ) ;
} ;
//jff 3/15/98 pure texture/type change for better generalized support
enum EChange
{
trigChangeOnly ,
numChangeOnly ,
} ;
//
// P_TELEPT
//
enum
{
TELF_DESTFOG = 1 ,
TELF_SOURCEFOG = 2 ,
TELF_KEEPORIENTATION = 4 ,
TELF_KEEPVELOCITY = 8 ,
TELF_KEEPHEIGHT = 16 ,
2016-04-23 19:32:40 +00:00
TELF_ROTATEBOOM = 32 ,
TELF_ROTATEBOOMINVERSE = 64 ,
2016-03-01 15:47:10 +00:00
} ;
2016-03-23 09:42:41 +00:00
//Spawns teleport fog. Pass the actor to pluck TeleFogFromType and TeleFogToType. 'from' determines if this is the fog to spawn at the old position (true) or new (false).
void P_SpawnTeleportFog ( AActor * mobj , const DVector3 & pos , bool beforeTele = true , bool setTarget = false ) ;
2016-04-05 20:27:11 +00:00
bool P_Teleport ( AActor * thing , DVector3 pos , DAngle angle , int flags ) ;
2016-03-01 15:47:10 +00:00
//
// [RH] ACS (see also p_acs.h)
//
# define ACS_BACKSIDE 1
# define ACS_ALWAYS 2
# define ACS_WANTRESULT 4
# define ACS_NET 8
2019-01-27 23:55:21 +00:00
int P_StartScript ( FLevelLocals * Level , AActor * who , line_t * where , int script , const char * map , const int * args , int argcount , int flags ) ;
void P_SuspendScript ( FLevelLocals * Level , int script , const char * map ) ;
void P_TerminateScript ( FLevelLocals * Level , int script , const char * map ) ;
2016-03-01 15:47:10 +00:00
//
// [RH] p_quake.c
//
2019-01-27 20:59:19 +00:00
bool P_StartQuakeXYZ ( FLevelLocals * Level , AActor * activator , int tid , int intensityX , int intensityY , int intensityZ , int duration , int damrad , int tremrad , FSoundID quakesfx , int flags , double waveSpeedX , double waveSpeedY , double waveSpeedZ , int falloff , int highpoint , double rollIntensity , double rollWave ) ;
bool P_StartQuake ( FLevelLocals * Level , AActor * activator , int tid , int intensity , int duration , int damrad , int tremrad , FSoundID quakesfx ) ;
2016-03-01 15:47:10 +00:00
# endif