RingRacers/src/p_spec.h
2025-02-13 15:48:11 -06:00

1248 lines
30 KiB
C

// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
// Copyright (C) 2000 by DooM Legacy Team.
// Copyright (C) 1996 by id Software, Inc.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file p_spec.h
/// \brief Implements special effects:
/// Texture animation, height or lighting changes
/// according to adjacent sectors, respective
/// utility functions, etc.
#ifndef __P_SPEC__
#define __P_SPEC__
#ifdef __cplusplus
extern "C" {
#endif
extern mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs
extern mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs
void P_InitSkyboxPoint(mobj_t *mobj, mapthing_t *mthing);
// Amount (dx, dy) vector linedef is shifted right to get scroll amount
#define SCROLL_SHIFT 5
typedef enum
{
TMM_DOUBLESIZE = 1,
TMM_SILENT = 1<<1,
TMM_ALLOWYAWCONTROL = 1<<2,
TMM_SWING = 1<<3,
TMM_MACELINKS = 1<<4,
TMM_CENTERLINK = 1<<5,
TMM_CLIP = 1<<6,
TMM_ALWAYSTHINK = 1<<7,
} textmapmaceflags_t;
typedef enum
{
TMDA_BOTTOMOFFSET = 1,
TMDA_BOTTOM = 1<<1,
TMDA_MIDDLE = 1<<2,
TMDA_TOP = 1<<3,
} textmapdronealignment_t;
typedef enum
{
TMSF_RETRACTED = 1,
TMSF_INTANGIBLE = 1<<1,
} textmapspikeflags_t;
typedef enum
{
TMFF_AIMLESS = 1,
TMFF_STATIONARY = 1<<1,
TMFF_HOP = 1<<2,
} textmapflickyflags_t;
typedef enum
{
TMFH_NOFLAME = 1,
TMFH_CORONA = 1<<1,
} textmapflameholderflags_t;
typedef enum
{
TMDS_NOGRAVITY = 1,
TMDS_ROTATEEXTRA = 1<<1,
} textmapdiagonalspringflags_t;
typedef enum
{
TMF_INVISIBLE = 1,
TMF_NODISTANCECHECK = 1<<1,
} textmapfanflags_t;
typedef enum
{
TMGD_BACK = 0,
TMGD_RIGHT = 1,
TMGD_LEFT = 2,
} textmapguarddirection_t;
typedef enum
{
TMNI_BONUSONLY = 1,
TMNI_REVEAL = 1<<1,
} textmapnightsitem_t;
typedef enum
{
TMP_NORMAL = 0,
TMP_SLIDE = 1,
TMP_IMMOVABLE = 2,
TMP_CLASSIC = 3,
} textmappushabletype_t;
typedef enum
{
TMED_NONE = 0,
TMED_RIGHT = 1,
TMED_LEFT = 2,
} textmapeggrobodirection_t;
typedef enum
{
TMMR_SAME = 0,
TMMR_WEAK = 1,
TMMR_STRONG = 2,
} textmapmonitorrespawn_t;
typedef enum
{
TMF_GRAYSCALE = 1,
TMF_SKIPINTRO = 1<<1,
} textmapfangflags_t;
typedef enum
{
TMB_NODEATHFLING = 1,
TMB_BARRIER = 1<<1,
} textmapbrakflags_t;
typedef enum
{
TMWPF_DISABLED = 1,
TMWPF_SHORTCUT = 1<<1,
TMWPF_NORESPAWN = 1<<2,
TMWPF_FINISHLINE = 1<<3,
TMWPF_BLOCKLIGHTSNAKE = 1<<4
} textmapwaypointflags_t;
typedef enum
{
TMAUDIM_FLOAT = 1,
TMAUDIM_BORED = 1<<1,
} textmapaudiencemovementflags_t;
typedef enum
{
TMBCF_BACKANDFORTH = 1,
TMBCF_REVERSE = 1<<1,
} textmapbattlecapsuleflags_t;
typedef enum
{
//TMICF_UNUSED = 1,
TMICF_INVERTSIZE = 1<<1,
} textmapitemcapsuleflags_t;
typedef enum
{
TMICM_DEFAULT = 0, // Time Attack only has rings, multiplayer has everything
TMICM_MULTIPLAYER = 1,
TMICM_TIMEATTACK = 1<<1,
} textmapitemcapsulemodes_t;
typedef enum
{
TMMA_WARN = 1,
TMMA_FLIP = 2,
} textmapmayarrow_t;
typedef enum
{
TMEF_SKIPTALLY = 1,
TMEF_EMERALDCHECK = 1<<1,
} textmapexitflags_t;
typedef enum
{
TMSP_NOTELEPORT = 1,
TMSP_FORCESPIN = 1<<1,
} textmapspeedpadflags_t;
//FOF flags
typedef enum
{
TMFA_NOPLANES = 1,
TMFA_NOSIDES = 1<<1,
TMFA_INSIDES = 1<<2,
TMFA_ONLYINSIDES = 1<<3,
TMFA_NOSHADE = 1<<4,
TMFA_SPLAT = 1<<5,
} textmapfofappearance_t;
typedef enum
{
TMFT_INTANGIBLETOP = 1,
TMFT_INTANGIBLEBOTTOM = 1<<1,
TMFT_DONTBLOCKPLAYER = 1<<2,
TMFT_VISIBLEFROMINSIDE = (TMFT_INTANGIBLETOP|TMFT_INTANGIBLEBOTTOM|TMFT_DONTBLOCKPLAYER),
TMFT_DONTBLOCKOTHERS = 1<<3,
TMFT_INTANGIBLE = (TMFT_DONTBLOCKPLAYER|TMFT_DONTBLOCKOTHERS),
} textmapfoftangibility_t;
typedef enum
{
TMFW_NOSIDES = 1,
TMFW_DOUBLESHADOW = 1<<1,
TMFW_COLORMAPONLY = 1<<2,
TMFW_NORIPPLE = 1<<3,
TMFW_GOOWATER = 1<<4,
TMFW_SPLAT = 1<<5,
} textmapfofwater_t;
typedef enum
{
TMFB_REVERSE = 1,
TMFB_SPINDASH = 1<<1,
TMFB_DYNAMIC = 1<<2,
} textmapfofbobbing_t;
typedef enum
{
TMFC_NOSHADE = 1,
TMFC_NORETURN = 1<<1,
TMFC_AIRBOB = 1<<2,
TMFC_FLOATBOB = 1<<3,
TMFC_SPLAT = 1<<4,
} textmapfofcrumbling_t;
typedef enum
{
TMFR_REVERSE = 1,
TMFR_SPINDASH = 1<<1,
} textmapfofrising_t;
typedef enum
{
TMFM_BRICK = 1,
TMFM_INVISIBLE = 1<<1,
} textmapfofmario_t;
typedef enum
{
TMFB_TOUCH,
TMFB_SPIN,
TMFB_REGULAR,
TMFB_STRONG,
} textmapfofbusttype_t;
typedef enum
{
TMFB_PUSHABLES = 1,
TMFB_EXECUTOR = 1<<1,
TMFB_ONLYBOTTOM = 1<<2,
TMFB_SPLAT = 1<<3,
} textmapfofbustflags_t;
typedef enum
{
TMFL_NOBOSSES = 1,
TMFL_SPLAT = 1<<1,
} textmapfoflaserflags_t;
typedef enum
{
TMT_CONTINUOUS = 0,
TMT_ONCE = 1,
TMT_EACHTIMEMASK = TMT_ONCE,
TMT_EACHTIMEENTER = 2,
TMT_EACHTIMEENTERANDEXIT = 3,
} textmaptriggertype_t;
typedef enum
{
TMXT_CONTINUOUS = 0,
TMXT_EACHTIMEMASK = TMXT_CONTINUOUS,
TMXT_EACHTIMEENTER = 1,
TMXT_EACHTIMEENTERANDEXIT = 2,
} textmapxtriggertype_t;
typedef enum
{
TMF_HASALL = 0,
TMF_HASANY = 1,
TMF_HASEXACTLY = 2,
TMF_DOESNTHAVEALL = 3,
TMF_DOESNTHAVEANY = 4,
} textmapflagcheck_t;
typedef enum
{
TMT_ORANGE = 0,
TMT_BLUE = 1,
} textmapteam_t;
typedef enum
{
TMC_EQUAL = 0,
TMC_LTE = 1,
TMC_GTE = 2,
} textmapcomparison_t;
typedef enum
{
TMNP_FASTEST = 0,
TMNP_SLOWEST = 1,
TMNP_TRIGGERER = 2,
} textmapnightsplayer_t;
typedef enum
{
TMN_ALWAYS = 0,
TMN_FROMNONIGHTS = 1,
TMN_FROMNIGHTS = 2,
} textmapnighterizeoptions_t;
typedef enum
{
TMN_BONUSLAPS = 1,
TMN_LEVELCOMPLETION = 1<<2,
} textmapnightserizeflags_t;
typedef enum
{
TMD_ALWAYS = 0,
TMD_NOBODYNIGHTS = 1,
TMD_SOMEBODYNIGHTS = 2,
} textmapdenighterizeoptions_t;
typedef enum
{
TMS_IFENOUGH = 0,
TMS_IFNOTENOUGH = 1,
TMS_ALWAYS = 2,
} textmapspherescheck_t;
typedef enum
{
TMI_BONUSLAPS = 1,
TMI_ENTER = 1<<2,
} textmapideyacaptureflags_t;
typedef enum
{
TMP_FLOOR = 0,
TMP_CEILING = 1,
TMP_BOTH = 2,
} textmapplanes_t;
typedef enum
{
TMT_ADD = 0,
TMT_REMOVE = 1,
TMT_REPLACEFIRST = 2,
} textmaptagoptions_t;
typedef enum
{
TMT_SILENT = 1,
TMT_KEEPANGLE = 1<<1,
TMT_KEEPMOMENTUM = 1<<2,
TMT_RELATIVE = 1<<3,
} textmapteleportflags_t;
typedef enum
{
TMM_ALLPLAYERS = 1,
TMM_OFFSET = 1<<1,
TMM_FADE = 1<<2,
TMM_NORELOAD = 1<<3,
TMM_FORCERESET = 1<<4,
TMM_NOLOOP = 1<<5,
TMM_NOCREDIT = 1<<6,
} textmapmusicflags_t;
typedef enum
{
TMSS_TRIGGERMOBJ = 0,
TMSS_TRIGGERSECTOR = 1,
TMSS_NOWHERE = 2,
TMSS_TAGGEDSECTOR = 3,
} textmapsoundsource_t;
typedef enum
{
TMSL_EVERYONE = 0,
TMSL_TRIGGERER = 1,
TMSL_TAGGEDSECTOR = 2,
} textmapsoundlistener_t;
typedef enum
{
TML_SECTOR = 0,
TML_FLOOR = 1,
TML_CEILING = 2,
} textmaplightareas_t;
typedef enum
{
TMLC_NOSECTOR = 1,
TMLC_NOFLOOR = 1<<1,
TMLC_NOCEILING = 1<<2,
} textmaplightcopyflags_t;
typedef enum
{
TMF_RELATIVE = 1,
TMF_OVERRIDE = 1<<1,
TMF_TICBASED = 1<<2,
} textmapfadeflags_t;
typedef enum
{
TMB_USETARGET = 1,
TMB_SYNC = 1<<1,
} textmapblinkinglightflags_t;
typedef enum
{
TMFR_NORETURN = 1,
TMFR_CHECKFLAG = 1<<1,
} textmapfofrespawnflags_t;
typedef enum
{
TMST_RELATIVE = 1,
TMST_DONTDOTRANSLUCENT = 1<<1,
} textmapsettranslucencyflags_t;
typedef enum
{
TMFT_RELATIVE = 1,
TMFT_OVERRIDE = 1<<1,
TMFT_TICBASED = 1<<2,
TMFT_IGNORECOLLISION = 1<<3,
TMFT_GHOSTFADE = 1<<4,
TMFT_DONTDOTRANSLUCENT = 1<<5,
TMFT_DONTDOEXISTS = 1<<6,
TMFT_DONTDOLIGHTING = 1<<7,
TMFT_DONTDOCOLORMAP = 1<<8,
TMFT_USEEXACTALPHA = 1<<9,
} textmapfadetranslucencyflags_t;
typedef enum
{
TMS_VIEWPOINT = 0,
TMS_CENTERPOINT = 1,
TMS_BOTH = 2,
} textmapskybox_t;
typedef enum
{
TMP_CLOSE = 1,
TMP_RUNPOSTEXEC = 1<<1,
TMP_CALLBYNAME = 1<<2,
TMP_KEEPCONTROLS = 1<<3,
TMP_KEEPREALTIME = 1<<4,
//TMP_ALLPLAYERS = 1<<5,
//TMP_FREEZETHINKERS = 1<<6,
} textmappromptflags_t;
typedef enum
{
TMF_NOCHANGE = 0,
TMF_ADD = 1,
TMF_REMOVE = 2,
} textmapsetflagflags_t;
typedef enum
{
TMSD_FRONT = 0,
TMSD_BACK = 1,
TMSD_FRONTBACK = 2,
} textmapsides_t;
typedef enum
{
TMS_SCROLLCARRY = 0,
TMS_SCROLLONLY = 1,
TMS_CARRYONLY = 2,
} textmapscroll_t;
typedef enum
{
TMST_REGULAR = 0,
TMST_ACCELERATIVE = 1,
TMST_DISPLACEMENT = 2,
TMST_TYPEMASK = 3,
TMST_NONEXCLUSIVE = 4,
} textmapscrolltype_t;
typedef enum
{
TMPF_SLIDE = 1,
TMPF_NONEXCLUSIVE = 1<<1,
} textmappusherflags_t;
typedef enum
{
TMPP_NOZFADE = 1,
TMPP_PUSHZ = 1<<1,
TMPP_NONEXCLUSIVE = 1<<2,
} textmappointpushflags_t;
typedef enum
{
TMB_TRANSLUCENT = 0,
TMB_ADD = 1,
TMB_SUBTRACT = 2,
TMB_REVERSESUBTRACT = 3,
TMB_MODULATE = 4,
} textmapblendmodes_t;
typedef enum
{
TMCFF_FLIP = 1,
} textmapcrossfinishflags_t;
typedef enum
{
TMCRF_FRONTONLY = 1,
} textmapcrossrespawnflags_t;
typedef enum
{
TMBOT_NORUBBERBAND = 1,
TMBOT_NOCONTROL = 1<<1,
TMBOT_FORCEDIR = 1<<2,
TMBOT_FASTFALL = 1<<3,
} textmapbotcontroller_t;
typedef enum
{
TMBOTTR_NONE = 0,
TMBOTTR_LEFT = 1,
TMBOTTR_RIGHT = 2,
TMBOTTR_UP = 3,
TMBOTTR_DOWN = 4,
} textmapbottrick_t;
typedef enum
{
TMLOOP_ALPHA = 0,
TMLOOP_BETA = 1,
} textmaploopendpointtype_t;
typedef enum
{
TMCAM_FIRST = -1,
TMCAM_SECOND = -2,
TMCAM_THIRD = -3,
TMCAM_CONSOLE = -4,
} textmapcamerafollow_t;
// GETSECSPECIAL (specialval, section)
//
// Pulls out the special # from a particular section.
//
#define GETSECSPECIAL(i,j) ((i >> ((j-1)*4))&15)
// This must be updated whenever we up the max flat size - quicker to assume rather than figuring out the sqrt of the specific flat's filesize.
#define MAXFLATSIZE (2048<<FRACBITS)
// create earthquakes
void P_StartQuake(tic_t time, fixed_t intensity, fixed_t radius, mappoint_t *epicenter);
void P_StartQuakeFromMobj(tic_t time, fixed_t intensity, fixed_t radius, mobj_t *mobj);
void P_DoQuakeOffset(UINT8 view, mappoint_t *viewPos, mappoint_t *offset);
void P_FreeQuake(quake_t *remove);
// at game start
void P_InitPicAnims(void);
// at map load (sectors)
void P_SetupLevelFlatAnims(void);
// at map load
void P_InitSpecials(void);
void P_ApplyFlatAlignment(sector_t* sector, angle_t flatangle, fixed_t xoffs, fixed_t yoffs, boolean floor, boolean ceiling);
fixed_t P_GetSectorGravityFactor(sector_t *sec);
void P_SpawnSpecials(boolean fromnetsave);
void P_SpawnSpecialsThatRequireObjects(boolean fromnetsave);
// every tic
void P_UpdateSpecials(void);
sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number);
sector_t *P_MobjTouchingSectorSpecialFlag(mobj_t *mo, sectorspecialflags_t flag);
sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 number);
sector_t *P_PlayerTouchingSectorSpecialFlag(player_t *player, sectorspecialflags_t flag);
void P_PlayerInSpecialSector(player_t *player);
void P_CheckMobjTrigger(mobj_t *mobj, boolean pushable);
void P_CheckMobjTouchingSectorActions(mobj_t *mobj, boolean continuous, boolean sectorchanged);
sector_t *P_FindPlayerTrigger(player_t *player, line_t *sourceline);
boolean P_IsPlayerValid(size_t playernum);
boolean P_CanPlayerTrigger(size_t playernum);
void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *roversector);
void P_CheckSectorTransitionalEffects(mobj_t *thing, sector_t *prevsec, boolean wasgrounded);
fixed_t P_FindLowestFloorSurrounding(sector_t *sec);
fixed_t P_FindHighestFloorSurrounding(sector_t *sec);
fixed_t P_FindNextHighestFloor(sector_t *sec, fixed_t currentheight);
fixed_t P_FindNextLowestFloor(sector_t *sec, fixed_t currentheight);
fixed_t P_FindLowestCeilingSurrounding(sector_t *sec);
fixed_t P_FindHighestCeilingSurrounding(sector_t *sec);
INT32 P_FindMinSurroundingLight(sector_t *sector, INT32 max);
void P_CrossSpecialLine(line_t *line, INT32 side, mobj_t *thing);
void P_PushSpecialLine(line_t *line, mobj_t *thing);
void P_ActivateThingSpecial(mobj_t *mo, mobj_t *source);
mobj_t* P_FindObjectTypeFromTag(mobjtype_t type, mtag_t tag);
//
// Special activation info
//
struct activator_t
{
mobj_t *mo;
line_t *line;
UINT8 side;
sector_t *sector;
polyobj_t *po;
boolean fromLineSpecial; // Backwards compat for ACS
};
boolean P_CanActivateSpecial(INT16 special);
boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, char **stringargs);
void P_SetupSignExit(player_t *player, boolean tie);
boolean P_IsMobjTouchingSectorPlane(mobj_t *mo, sector_t *sec);
boolean P_IsMobjTouching3DFloor(mobj_t *mo, ffloor_t *ffloor, sector_t *sec);
boolean P_IsMobjTouchingPolyobj(mobj_t *mo, polyobj_t *po, sector_t *polysec);
void P_SwitchWeather(preciptype_t newWeather);
boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller);
void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller);
void P_RunNightserizeExecutors(mobj_t *actor);
void P_RunDeNightserizeExecutors(mobj_t *actor);
void P_RunNightsLapExecutors(mobj_t *actor);
void P_RunNightsCapsuleTouchExecutors(mobj_t *actor, boolean entering, boolean enoughspheres);
UINT16 P_GetFFloorID(ffloor_t *fflr);
ffloor_t *P_GetFFloorByID(sector_t *sec, UINT16 id);
// Use this when you don't know the type of your thinker data struct but need to access its thinker.
struct thinkerdata_t
{
thinker_t thinker;
};
//
// P_LIGHTS
//
/** Fire flicker action structure.
*/
struct fireflicker_t
{
thinker_t thinker; ///< The thinker in use for the effect.
sector_t *sector; ///< The sector where action is taking place.
INT32 count;
INT32 resetcount;
INT16 maxlight; ///< The brightest light level to use.
INT16 minlight; ///< The darkest light level to use.
};
struct lightflash_t
{
thinker_t thinker;
sector_t *sector;
INT32 maxlight;
INT32 minlight;
};
/** Laser block thinker.
*/
struct laserthink_t
{
thinker_t thinker; ///< Thinker structure for laser.
INT16 tag;
line_t *sourceline;
UINT8 nobosses;
};
/** Strobe light action structure..
*/
struct strobe_t
{
thinker_t thinker; ///< The thinker in use for the effect.
sector_t *sector; ///< The sector where the action is taking place.
INT32 count;
INT16 minlight; ///< The minimum light level to use.
INT16 maxlight; ///< The maximum light level to use.
INT32 darktime; ///< How INT32 to use minlight.
INT32 brighttime; ///< How INT32 to use maxlight.
};
struct glow_t
{
thinker_t thinker;
sector_t *sector;
INT16 minlight;
INT16 maxlight;
INT16 direction;
INT16 speed;
};
/** Thinker struct for fading lights.
*/
struct lightlevel_t
{
thinker_t thinker; ///< Thinker in use for the effect.
sector_t *sector; ///< Sector where action is taking place.
INT16 sourcelevel; ///< Light level we're fading from.
INT16 destlevel; ///< Light level we're fading to.
fixed_t fixedcurlevel; ///< Fixed point for current light level.
fixed_t fixedpertic; ///< Fixed point for increment per tic.
// The reason for those two above to be fixed point is to deal with decimal values that would otherwise get trimmed away.
INT32 timer; ///< Internal timer.
};
#define GLOWSPEED 8
#define STROBEBRIGHT 5
#define FASTDARK 15
#define SLOWDARK 35
void P_RemoveLighting(sector_t *sector);
void T_FireFlicker(fireflicker_t *flick);
fireflicker_t *P_SpawnAdjustableFireFlicker(sector_t *sector, INT16 lighta, INT16 lightb, INT32 length);
void T_LightningFlash(lightflash_t *flash);
void T_StrobeFlash(strobe_t *flash);
void P_SpawnLightningFlash(sector_t *sector);
strobe_t * P_SpawnAdjustableStrobeFlash(sector_t *sector, INT16 lighta, INT16 lightb, INT32 darktime, INT32 brighttime, boolean inSync);
void T_Glow(glow_t *g);
glow_t *P_SpawnAdjustableGlowingLight(sector_t *sector, INT16 lighta, INT16 lightb, INT32 length);
void P_FadeLightBySector(sector_t *sector, INT32 destvalue, INT32 speed, boolean ticbased);
void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed, boolean ticbased, boolean force, boolean relative);
void T_LightFade(lightlevel_t *ll);
typedef enum
{
floor_special,
ceiling_special,
lighting_special,
} special_e;
//
// P_CEILNG
//
typedef enum
{
raiseToHighest,
lowerToLowestFast,
instantRaise, // instant-move for ceilings
crushAndRaise,
raiseAndCrush,
crushCeilOnce,
crushBothOnce,
moveCeilingByFrontSector,
instantMoveCeilingByFrontSector,
moveCeilingByDistance,
bounceCeiling,
bounceCeilingCrush,
} ceiling_e;
/** Ceiling movement structure.
*/
struct ceiling_t
{
thinker_t thinker; ///< Thinker for the type of movement.
ceiling_e type; ///< Type of movement.
sector_t *sector; ///< Sector where the action is taking place.
fixed_t bottomheight; ///< The lowest height to move to.
fixed_t topheight; ///< The highest height to move to.
fixed_t speed; ///< Ceiling speed.
fixed_t delay;
fixed_t delaytimer;
UINT8 crush; ///< Whether to crush things or not.
INT32 texture; ///< The number of a flat to use when done.
INT32 direction; ///< 1 = up, 0 = waiting, -1 = down.
// ID
INT16 tag; ///< Tag of linedef executor to run when movement is done.
fixed_t origspeed; ///< The original, "real" speed.
fixed_t crushHeight; ///< Crusher height
fixed_t crushSpeed; ///< Crusher speed
fixed_t returnHeight; ///< Crusher return height
fixed_t returnSpeed; ///< Crusher return speed
};
#define CEILSPEED (FRACUNIT)
INT32 EV_DoCeiling(mtag_t tag, line_t *line, ceiling_e type);
void T_MoveCeiling(ceiling_t *ceiling);
boolean EV_DoRaiseCeilingToHighest(mtag_t tag);
boolean EV_DoLowerCeilingToLowestFast(mtag_t tag);
boolean EV_DoInstantRaiseCeiling(mtag_t tag);
boolean EV_DoMoveCeilingByHeight(mtag_t tag, fixed_t height, fixed_t speed, mtag_t chain, INT32 texture);
boolean EV_DoInstantMoveCeilingByHeight(mtag_t tag, fixed_t height, INT32 texture);
boolean EV_DoMoveCeilingByDistance(mtag_t tag, fixed_t distance, fixed_t speed, boolean instant);
boolean EV_DoBounceCeiling(mtag_t tag, boolean crush, fixed_t crushHeight, fixed_t crushSpeed, fixed_t returnHeight, fixed_t returnSpeed, INT32 delayInit, INT32 delay);
INT32 EV_DoCrush(mtag_t tag, line_t *line, ceiling_e type);
void T_CrushCeiling(ceiling_t *ceiling);
boolean EV_DoRaiseAndCrushCeiling(mtag_t tag, fixed_t speed, fixed_t returnSpeed);
boolean EV_DoCrushBothOnce(mtag_t tag, fixed_t speed);
boolean EV_DoCrushCeilingOnce(mtag_t tag, fixed_t speed);
//
// P_FLOOR
//
typedef enum
{
// raise floor to next highest surrounding floor
raiseFloorToNearestFast,
// move the floor down instantly
instantLower,
moveFloorByFrontSector,
instantMoveFloorByFrontSector,
moveFloorByDistance,
bounceFloor,
bounceFloorCrush,
crushFloorOnce,
} floor_e;
typedef enum
{
elevateUp,
elevateDown,
elevateContinuous,
elevateBounce,
elevateHighest,
bridgeFall,
} elevator_e;
struct floormove_t
{
thinker_t thinker;
floor_e type;
UINT8 crush;
sector_t *sector;
INT32 direction;
INT32 texture;
fixed_t floordestheight;
fixed_t speed;
fixed_t origspeed;
fixed_t delay;
fixed_t delaytimer;
INT16 tag;
fixed_t crushHeight;
fixed_t crushSpeed;
fixed_t returnHeight;
fixed_t returnSpeed;
};
struct elevator_t
{
thinker_t thinker;
elevator_e type;
sector_t *sector;
sector_t *actionsector; // The sector the rover action is taking place in.
INT32 direction;
fixed_t floordestheight;
fixed_t ceilingdestheight;
fixed_t speed;
fixed_t origspeed;
fixed_t low;
fixed_t high;
fixed_t distance;
fixed_t delay;
fixed_t delaytimer;
fixed_t floorwasheight; // Height the floor WAS at
fixed_t ceilingwasheight; // Height the ceiling WAS at
};
typedef enum
{
CF_RETURN = 1, // Return after crumbling
CF_FLOATBOB = 1<<1, // Float on water
CF_REVERSE = 1<<2, // Reverse gravity
} crumbleflag_t;
struct crumble_t
{
thinker_t thinker;
line_t *sourceline;
sector_t *sector;
sector_t *actionsector; // The sector the rover action is taking place in.
player_t *player; // Player who initiated the thinker (used for airbob)
INT32 direction;
INT32 origalpha;
INT32 timer;
fixed_t speed;
fixed_t floorwasheight; // Height the floor WAS at
fixed_t ceilingwasheight; // Height the ceiling WAS at
UINT8 flags;
};
struct noenemies_t
{
thinker_t thinker;
line_t *sourceline; // Source line of the thinker
};
struct continuousfall_t
{
thinker_t thinker;
sector_t *sector;
fixed_t speed;
INT32 direction;
fixed_t floorstartheight;
fixed_t ceilingstartheight;
fixed_t destheight;
};
struct bouncecheese_t
{
thinker_t thinker;
line_t *sourceline;
sector_t *sector;
fixed_t speed;
fixed_t distance;
fixed_t floorwasheight;
fixed_t ceilingwasheight;
boolean low;
};
struct mariothink_t
{
thinker_t thinker;
sector_t *sector;
fixed_t speed;
INT32 direction;
fixed_t floorstartheight;
fixed_t ceilingstartheight;
INT16 tag;
};
struct mariocheck_t
{
thinker_t thinker;
line_t *sourceline;
sector_t *sector;
};
struct thwomp_t
{
thinker_t thinker;
line_t *sourceline;
sector_t *sector;
fixed_t crushspeed;
fixed_t retractspeed;
INT32 direction;
fixed_t floorstartheight;
fixed_t ceilingstartheight;
INT32 delay;
INT16 tag;
UINT16 sound;
INT32 initDelay;
};
struct floatthink_t
{
thinker_t thinker;
line_t *sourceline;
sector_t *sector;
INT16 tag;
};
struct eachtime_t
{
thinker_t thinker;
line_t *sourceline; // Source line of the thinker
boolean playersInArea[MAXPLAYERS];
boolean triggerOnExit;
};
typedef enum
{
RF_REVERSE = 1, //Lower when stood on
RF_SPINDASH = 1<<1, //Require spindash to move
RF_DYNAMIC = 1<<2, //Dynamically sinking platform
} raiseflag_t;
struct raise_t
{
thinker_t thinker;
INT16 tag;
sector_t *sector;
fixed_t ceilingbottom;
fixed_t ceilingtop;
fixed_t basespeed;
fixed_t extraspeed; //For dynamically sinking platform
UINT8 shaketimer; //For dynamically sinking platform
UINT8 flags;
};
#define ELEVATORSPEED (FRACUNIT*4)
#define FLOORSPEED (FRACUNIT)
typedef enum
{
ok,
crushed,
pastdest
} result_e;
result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crush,
boolean ceiling, INT32 direction);
void EV_DoFloor(mtag_t tag, line_t *line, floor_e floortype);
void EV_DoRaiseFloorToNearestFast(mtag_t tag);
void EV_DoInstantLowerFloor(mtag_t tag);
void EV_DoInstantMoveFloorByHeight(mtag_t tag, fixed_t height, INT32 texture);
void EV_DoMoveFloorByHeight(mtag_t tag, fixed_t height, fixed_t speed, mtag_t chain, INT32 texture);
void EV_DoMoveFloorByDistance(mtag_t tag, fixed_t distance, fixed_t speed, boolean instant);
void EV_DoBounceFloor(mtag_t tag, boolean crush, fixed_t crushHeight, fixed_t crushSpeed, fixed_t returnHeight, fixed_t returnSpeed, INT32 delayInit, INT32 delay);
void EV_DoCrushFloorOnce(mtag_t tag, fixed_t speed);
void EV_DoElevator(mtag_t tag, line_t *line, elevator_e elevtype);
void EV_DoElevateDown(mtag_t tag);
void EV_DoElevateUp(mtag_t tag);
void EV_DoElevateHighest(mtag_t tag);
void EV_DoContinuousElevator(mtag_t tag, fixed_t speed, INT32 delayInit, INT32 delay, boolean lowFirst);
void EV_DoBridgeFall(mtag_t tag);
void EV_CrumbleChain(sector_t *sec, ffloor_t *rover);
void EV_BounceSector(sector_t *sector, fixed_t momz, line_t *sourceline);
// Some other special 3dfloor types
INT32 EV_StartCrumble(sector_t *sector, ffloor_t *rover,
boolean floating, player_t *player, fixed_t origalpha, boolean crumblereturn);
void EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, boolean backwards);
void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher);
void T_MoveFloor(floormove_t *movefloor);
void T_MoveElevator(elevator_t *elevator);
void T_ContinuousFalling(continuousfall_t *faller);
void T_BounceCheese(bouncecheese_t *bouncer);
void T_StartCrumble(crumble_t *crumble);
void T_MarioBlock(mariothink_t *block);
void T_FloatSector(floatthink_t *floater);
void T_MarioBlockChecker(mariocheck_t *block);
void T_ThwompSector(thwomp_t *thwomp);
void T_NoEnemiesSector(noenemies_t *nobaddies);
void T_EachTimeThinker(eachtime_t *eachtime);
void T_CameraScanner(elevator_t *elevator);
void T_RaiseSector(raise_t *raise);
struct executor_t
{
thinker_t thinker; // Thinker for linedef executor delay
line_t *line; // Pointer to line that is waiting.
mobj_t *caller; // Pointer to calling mobj
sector_t *sector; // Pointer to triggering sector
INT32 timer; // Delay timer
};
void T_ExecutorDelay(executor_t *e);
/** Generalized scroller.
*/
struct scroll_t
{
thinker_t thinker; ///< Thinker structure for scrolling.
fixed_t dx, dy; ///< (dx,dy) scroll speeds.
INT32 affectee; ///< Number of affected sidedef or sector.
INT32 control; ///< Control sector (-1 if none) used to control scrolling.
fixed_t last_height; ///< Last known height of control sector.
fixed_t vdx, vdy; ///< Accumulated velocity if accelerative.
INT32 accel; ///< Whether it's accelerative.
INT32 exclusive; ///< If a conveyor, same property as in pusher_t
/** Types of generalized scrollers.
*/
enum
{
sc_side, ///< Scroll wall texture on a sidedef.
sc_floor, ///< Scroll floor.
sc_ceiling, ///< Scroll ceiling.
sc_carry, ///< Carry objects on floor.
sc_carry_ceiling,///< Carry objects on ceiling (for 3Dfloor conveyors).
} type;
};
void T_Scroll(scroll_t *s);
void T_LaserFlash(laserthink_t *flash);
/** Friction for ice/sludge effects.
*/
struct friction_t
{
thinker_t thinker; ///< Thinker structure for friction.
INT32 friction; ///< Friction value, 0xe800 = normal.
INT32 movefactor; ///< Inertia factor when adding to momentum, FRACUNIT = normal.
INT32 affectee; ///< Number of affected sector.
INT32 referrer; ///< If roverfriction == true, then this will contain the sector # of the control sector where the effect was applied.
UINT8 roverfriction; ///< flag for whether friction originated from a FOF or not
};
// Friction defines.
#define ORIG_FRICTION (0xF5 << (FRACBITS-8)) ///< Original value.
void T_Friction(friction_t *f);
typedef enum
{
p_wind, ///< Wind.
p_current, ///< Current.
} pushertype_e;
// Model for pushers for push/pull effects
struct pusher_t
{
thinker_t thinker; ///< Thinker structure for pusher effect.
pushertype_e type; ///< Type of pusher effect.
fixed_t x_mag; ///< X strength.
fixed_t y_mag; ///< Y strength.
fixed_t z_mag; ///< Z strength.
INT32 affectee; ///< Number of affected sector.
UINT8 roverpusher; ///< flag for whether pusher originated from a FOF or not
INT32 referrer; ///< If roverpusher == true, then this will contain the sector # of the control sector where the effect was applied.
INT32 exclusive; /// < Once this affect has been applied to a mobj, no other pushers may affect it.
INT32 slider; /// < Should the player go into an uncontrollable slide?
};
// Model for disappearing/reappearing FOFs
struct disappear_t
{
thinker_t thinker; ///< Thinker structure for effect.
tic_t appeartime; ///< Tics to be appeared for
tic_t disappeartime;///< Tics to be disappeared for
tic_t offset; ///< Time to wait until thinker starts
tic_t timer; ///< Timer between states
INT32 affectee; ///< Number of affected line
INT32 sourceline; ///< Number of source line
INT32 exists; ///< Exists toggle
};
void T_Disappear(disappear_t *d);
// Model for fading FOFs
struct fade_t
{
thinker_t thinker; ///< Thinker structure for effect.
ffloor_t *rover; ///< Target ffloor
extracolormap_t *dest_exc; ///< Colormap to fade to
UINT32 sectornum; ///< Number of ffloor target sector
UINT32 ffloornum; ///< Number of ffloor of target sector
INT32 alpha; ///< Internal alpha counter
INT16 sourcevalue; ///< Transparency value to fade from
INT16 destvalue; ///< Transparency value to fade to
INT16 destlightlevel; ///< Light level to fade to
INT16 speed; ///< Speed to fade by
boolean ticbased; ///< Tic-based logic toggle
INT32 timer; ///< Timer for tic-based logic
boolean doexists; ///< Handle FOF_EXISTS
boolean dotranslucent; ///< Handle FOF_TRANSLUCENT
boolean dolighting; ///< Handle shadows and light blocks
boolean docolormap; ///< Handle colormaps
boolean docollision; ///< Handle interactive flags
boolean doghostfade; ///< No interactive flags during fading
boolean exactalpha; ///< Use exact alpha values (opengl)
};
void T_Fade(fade_t *d);
// Model for fading colormaps
struct fadecolormap_t
{
thinker_t thinker; ///< Thinker structure for effect.
sector_t *sector; ///< Sector where action is taking place.
extracolormap_t *source_exc;
extracolormap_t *dest_exc;
boolean ticbased; ///< Tic-based timing
INT32 duration; ///< Total duration for tic-based logic (OR: speed increment)
INT32 timer; ///< Timer for tic-based logic (OR: internal speed counter)
};
void T_FadeColormap(fadecolormap_t *d);
// Prototype function for pushers
void T_Pusher(pusher_t *p);
// Plane displacement
struct planedisplace_t
{
thinker_t thinker; ///< Thinker structure for plane displacement effect.
INT32 affectee; ///< Number of affected sector.
INT32 control; ///< Control sector used to control plane positions.
fixed_t last_height; ///< Last known height of control sector.
fixed_t speed; ///< Plane movement speed.
UINT8 reverse; ///< Move in reverse direction to control sector?
/** Types of plane displacement effects.
*/
enum
{
pd_floor, ///< Displace floor.
pd_ceiling, ///< Displace ceiling.
pd_both, ///< Displace both floor AND ceiling.
} type;
};
void T_PlaneDisplace(planedisplace_t *pd);
void P_CalcHeight(player_t *player);
/* line specials */
enum
{
LT_SLOPE_ANCHORS = 777,
// binary converter
LT_SLOPE_ANCHORS_OLD_FLOOR = 777,
LT_SLOPE_ANCHORS_OLD_CEILING = 778,
LT_SLOPE_ANCHORS_OLD = 779,
};
#ifdef __cplusplus
} // extern "C"
#endif
#endif