blankart/src/p_spec.h
GenericHeroGuy 20396e14cb Operation: Save Megablock Castle
Two new finish line flags:
Single-Use, to make a finish line that only works on lap 0 and nowhere else
Require Sector Special, for the maps with FOF finish lines

For waypoints, the "flip finish line" flag on arg0 has been removed.
Instead, arg4 is now dedicated to holding flags applied to the finish line.
2025-05-06 20:43:31 +02:00

1205 lines
29 KiB
C

// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// 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 *skyboxmo[2]; // current skybox mobjs: 0 = viewpoint, 1 = centerpoint
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
{
TMWPF_DISABLED = 1,
TMWPF_SHORTCUT = 1<<1,
TMWPF_NORESPAWN = 1<<2,
TMWPF_FINISHLINE = 1<<3,
} textmapwaypointflags_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
{
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
{
TMICF_INVERTTIMEATTACK = 1,
TMICF_INVERTSIZE = 1<<1,
} textmapitemcapsuleflags_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_RED = 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,
TMCFF_SINGLEUSE = 1<<1,
TMCFF_NEEDSECTOR = 1<<2,
} textmapcrossfinishflags_t;
typedef enum
{
TMCRF_FRONTONLY = 1,
} textmapcrossrespawnflags_t;
typedef enum
{
TMBOT_NORUBBERBAND = 1,
TMBOT_NOCONTROL = 1<<1,
TMBOT_FORCEDIR = 1<<2,
} textmapbotcontroller_t;
typedef enum
{
TMLOOP_ALPHA = 0,
TMLOOP_BETA = 1,
} textmaploopendpointtype_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)
// Something that should've been done long ago???
// We won't be using epicenter or radius anytime soon so I don't think it's worth it yet.
void P_StartQuake(fixed_t intensity, tic_t time);
// 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);
sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo);
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_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, char **stringargs);
boolean P_CanActivateSpecial(INT16 special);
void P_SetupSignExit(player_t *player);
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.
INT32 sourceline; ///< Index of the source linedef
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);
INT32 EV_DoCeilingOLD(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);
INT32 EV_DoCrushOLD(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;
INT32 sourceline;
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
line_t *sourceline;
};
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
//free = 1<<1,
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_DoFloorOLD(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_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 (62914) ///< 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