From 7b5a77a8d8aa0c0a096c4f2b3ceb7a8f49bbb789 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 25 Jan 2016 00:45:59 +0100 Subject: [PATCH] - added various action specials and parameter extensions defined by Eternity Engine. The reason for defining them is to be able to fill out the Eternity translation table for GZDoom's Extradata parser. Most of the new specials are mere specializations of ZDoom's Generic_* functions and occupy positions above 255 to avoid filling up the last remaining free slots available for Hexen format maps. Allowing action specials greater than 255 required a few changes: * all access to action specials is now through a small set of access functions. * Two new PCodes were added to ACC to handle these new specials from scripts. * a minor change to the network protocol, so netgame and demo version numbers were bumped. * FS_Execute is now properly defined in p_lnspec.cpp. Two of the newly added specials - generalizations of the special 'close Door in 30 seconds' and 'raise door in 5 minutes' sector types, will also be available to Hexen format maps. The rest are limited to use in ACS, UDMF and DECORATE. This also adds 'change' and 'crush' parameters to most Floor_* and Ceiling_* specials, again to match Eternity's feature set. --- src/actionspecials.h | 72 ++++--- src/am_map.cpp | 5 +- src/c_cmds.cpp | 2 +- src/d_net.cpp | 4 +- src/d_protocol.h | 2 +- src/fragglescript/t_fs.h | 1 + src/fragglescript/t_func.cpp | 5 +- src/fragglescript/t_script.cpp | 21 +- src/p_acs.cpp | 20 ++ src/p_acs.h | 2 + src/p_doors.cpp | 55 ++---- src/p_floor.cpp | 8 +- src/p_lnspec.cpp | 342 ++++++++++++++++++++++++++------- src/p_lnspec.h | 7 +- src/p_mobj.cpp | 4 +- src/p_spec.cpp | 11 +- src/p_spec.h | 21 +- src/version.h | 6 +- 18 files changed, 407 insertions(+), 181 deletions(-) diff --git a/src/actionspecials.h b/src/actionspecials.h index 752ef77eb..ba1862023 100644 --- a/src/actionspecials.h +++ b/src/actionspecials.h @@ -18,12 +18,12 @@ DEFINE_SPECIAL(Transfer_WallLight, 16, -1, -1, 2) DEFINE_SPECIAL(Thing_Raise, 17, 1, 1, 1) DEFINE_SPECIAL(StartConversation, 18, 1, 2, 2) DEFINE_SPECIAL(Thing_Stop, 19, 1, 1, 1) -DEFINE_SPECIAL(Floor_LowerByValue, 20, 3, 3, 3) -DEFINE_SPECIAL(Floor_LowerToLowest, 21, 2, 2, 2) -DEFINE_SPECIAL(Floor_LowerToNearest, 22, 2, 2, 2) -DEFINE_SPECIAL(Floor_RaiseByValue, 23, 3, 3, 3) -DEFINE_SPECIAL(Floor_RaiseToHighest, 24, 2, 2, 2) -DEFINE_SPECIAL(Floor_RaiseToNearest, 25, 2, 2, 2) +DEFINE_SPECIAL(Floor_LowerByValue, 20, 3, 4, 4) +DEFINE_SPECIAL(Floor_LowerToLowest, 21, 2, 3, 3) +DEFINE_SPECIAL(Floor_LowerToNearest, 22, 2, 3, 3) +DEFINE_SPECIAL(Floor_RaiseByValue, 23, 3, 5, 5) +DEFINE_SPECIAL(Floor_RaiseToHighest, 24, 2, 5, 5) +DEFINE_SPECIAL(Floor_RaiseToNearest, 25, 2, 4, 4) DEFINE_SPECIAL(Stairs_BuildDown, 26, 5, 5, 5) DEFINE_SPECIAL(Stairs_BuildUp, 27, 5, 5, 5) DEFINE_SPECIAL(Floor_RaiseAndCrush, 28, 3, 4, 4) @@ -33,19 +33,19 @@ DEFINE_SPECIAL(Stairs_BuildDownSync, 31, 4, 4, 4) DEFINE_SPECIAL(Stairs_BuildUpSync, 32, 4, 4, 4) DEFINE_SPECIAL(ForceField, 33, 0, 0, 0) // [RH] Strife's forcefield special (148) DEFINE_SPECIAL(ClearForceField, 34, 1, 1, 1) // [RH] Remove Strife's forcefield from tagged sectors -DEFINE_SPECIAL(Floor_RaiseByValueTimes8, 35, 3, 3, 3) -DEFINE_SPECIAL(Floor_LowerByValueTimes8, 36, 3, 3, 3) -DEFINE_SPECIAL(Floor_MoveToValue, 37, 3, 4, 4) +DEFINE_SPECIAL(Floor_RaiseByValueTimes8, 35, 3, 5, 5) +DEFINE_SPECIAL(Floor_LowerByValueTimes8, 36, 3, 4, 4) +DEFINE_SPECIAL(Floor_MoveToValue, 37, 3, 4, 5) DEFINE_SPECIAL(Ceiling_Waggle, 38, 5, 5, 5) // [RH] Complement of Floor_Waggle DEFINE_SPECIAL(Teleport_ZombieChanger, 39, 2, 2, 2) // [RH] Needed for Strife -DEFINE_SPECIAL(Ceiling_LowerByValue, 40, 3, 3, 3) -DEFINE_SPECIAL(Ceiling_RaiseByValue, 41, 3, 3, 3) +DEFINE_SPECIAL(Ceiling_LowerByValue, 40, 3, 4, 4) +DEFINE_SPECIAL(Ceiling_RaiseByValue, 41, 3, 4, 4) DEFINE_SPECIAL(Ceiling_CrushAndRaise, 42, 3, 4, 4) DEFINE_SPECIAL(Ceiling_LowerAndCrush, 43, 3, 4, 4) DEFINE_SPECIAL(Ceiling_CrushStop, 44, 1, 1, 1) DEFINE_SPECIAL(Ceiling_CrushRaiseAndStay, 45, 3, 4, 4) DEFINE_SPECIAL(Floor_CrushStop, 46, 1, 1, 1) -DEFINE_SPECIAL(Ceiling_MoveToValue, 47, 3, 4, 4) +DEFINE_SPECIAL(Ceiling_MoveToValue, 47, 3, 5, 5) DEFINE_SPECIAL(Sector_Attach3dMidtex, 48, -1, -1, 3) DEFINE_SPECIAL(GlassBreak, 49, 0, 1, 1) DEFINE_SPECIAL(ExtraFloor_LightOnly, 50, -1, -1, 2) @@ -64,10 +64,10 @@ DEFINE_SPECIAL(Plat_DownWaitUpStay, 62, 3, 3, 3) DEFINE_SPECIAL(Plat_DownByValue, 63, 4, 4, 4) DEFINE_SPECIAL(Plat_UpWaitDownStay, 64, 3, 3, 3) DEFINE_SPECIAL(Plat_UpByValue, 65, 4, 4, 4) -DEFINE_SPECIAL(Floor_LowerInstant, 66, 3, 3, 3) -DEFINE_SPECIAL(Floor_RaiseInstant, 67, 3, 3, 3) -DEFINE_SPECIAL(Floor_MoveToValueTimes8, 68, 4, 4, 4) -DEFINE_SPECIAL(Ceiling_MoveToValueTimes8, 69, 4, 4, 4) +DEFINE_SPECIAL(Floor_LowerInstant, 66, 3, 4, 4) +DEFINE_SPECIAL(Floor_RaiseInstant, 67, 3, 5, 5) +DEFINE_SPECIAL(Floor_MoveToValueTimes8, 68, 4, 5, 5) +DEFINE_SPECIAL(Ceiling_MoveToValueTimes8, 69, 4, 5, 5) DEFINE_SPECIAL(Teleport, 70, 1, 3, 3) DEFINE_SPECIAL(Teleport_NoFog, 71, 1, 4, 4) DEFINE_SPECIAL(ThrustThing, 72, 2, 4, 4) @@ -103,6 +103,8 @@ DEFINE_SPECIAL(Scroll_Texture_Right, 101, -1, -1, 2) DEFINE_SPECIAL(Scroll_Texture_Up, 102, -1, -1, 2) DEFINE_SPECIAL(Scroll_Texture_Down, 103, -1, -1, 2) DEFINE_SPECIAL(Ceiling_CrushAndRaiseSilentDist, 104, 3, 5, 5) +DEFINE_SPECIAL(Door_WaitRaise, 105, 4, 5, 5) +DEFINE_SPECIAL(Door_WaitClose, 106, 4, 5, 5) DEFINE_SPECIAL(Light_ForceLightning, 109, 1, 1, 1) DEFINE_SPECIAL(Light_RaiseByValue, 110, 2, 2, 2) @@ -171,14 +173,14 @@ DEFINE_SPECIAL(Sector_SetCeilingScale, 188, 5, 5, 5) DEFINE_SPECIAL(Sector_SetFloorScale, 189, 5, 5, 5) DEFINE_SPECIAL(Static_Init, 190, -1, -1, 4) DEFINE_SPECIAL(SetPlayerProperty, 191, 3, 3, 3) -DEFINE_SPECIAL(Ceiling_LowerToHighestFloor, 192, 2, 2, 2) -DEFINE_SPECIAL(Ceiling_LowerInstant, 193, 3, 3, 3) -DEFINE_SPECIAL(Ceiling_RaiseInstant, 194, 3, 3, 3) +DEFINE_SPECIAL(Ceiling_LowerToHighestFloor, 192, 2, 4, 4) +DEFINE_SPECIAL(Ceiling_LowerInstant, 193, 3, 5, 5) +DEFINE_SPECIAL(Ceiling_RaiseInstant, 194, 3, 4, 4) DEFINE_SPECIAL(Ceiling_CrushRaiseAndStayA, 195, 4, 5, 5) DEFINE_SPECIAL(Ceiling_CrushAndRaiseA, 196, 4, 5, 5) DEFINE_SPECIAL(Ceiling_CrushAndRaiseSilentA, 197, 4, 5, 5) -DEFINE_SPECIAL(Ceiling_RaiseByValueTimes8, 198, 3, 3, 3) -DEFINE_SPECIAL(Ceiling_LowerByValueTimes8, 199, 3, 3, 3) +DEFINE_SPECIAL(Ceiling_RaiseByValueTimes8, 198, 3, 4, 4) +DEFINE_SPECIAL(Ceiling_LowerByValueTimes8, 199, 3, 4, 4) DEFINE_SPECIAL(Generic_Floor, 200, 5, 5, 5) DEFINE_SPECIAL(Generic_Ceiling, 201, 5, 5, 5) DEFINE_SPECIAL(Generic_Door, 202, 5, 5, 5) @@ -217,9 +219,9 @@ DEFINE_SPECIAL(Light_MaxNeighbor, 234, 1, 1, 1) DEFINE_SPECIAL(Floor_TransferTrigger, 235, 1, 1, 1) DEFINE_SPECIAL(Floor_TransferNumeric, 236, 1, 1, 1) DEFINE_SPECIAL(ChangeCamera, 237, 3, 3, 3) -DEFINE_SPECIAL(Floor_RaiseToLowestCeiling, 238, 2, 2, 2) +DEFINE_SPECIAL(Floor_RaiseToLowestCeiling, 238, 2, 4, 4) DEFINE_SPECIAL(Floor_RaiseByValueTxTy, 239, 3, 3, 3) -DEFINE_SPECIAL(Floor_RaiseByTexture, 240, 2, 2, 2) +DEFINE_SPECIAL(Floor_RaiseByTexture, 240, 2, 4, 4) DEFINE_SPECIAL(Floor_LowerToLowestTxTy, 241, 2, 2, 2) DEFINE_SPECIAL(Floor_LowerToHighest, 242, 3, 4, 4) DEFINE_SPECIAL(Exit_Normal, 243, 1, 1, 1) @@ -231,9 +233,27 @@ DEFINE_SPECIAL(HealThing, 248, 1, 2, 2) DEFINE_SPECIAL(Door_CloseWaitOpen, 249, 3, 4, 4) DEFINE_SPECIAL(Floor_Donut, 250, 3, 3, 3) DEFINE_SPECIAL(FloorAndCeiling_LowerRaise, 251, 3, 4, 4) -DEFINE_SPECIAL(Ceiling_RaiseToNearest, 252, 2, 2, 2) -DEFINE_SPECIAL(Ceiling_LowerToLowest, 253, 2, 2, 2) -DEFINE_SPECIAL(Ceiling_LowerToFloor, 254, 2, 2, 2) +DEFINE_SPECIAL(Ceiling_RaiseToNearest, 252, 2, 3, 3) +DEFINE_SPECIAL(Ceiling_LowerToLowest, 253, 2, 4, 4) +DEFINE_SPECIAL(Ceiling_LowerToFloor, 254, 2, 4, 4) DEFINE_SPECIAL(Ceiling_CrushRaiseAndStaySilA, 255, 4, 5, 5) +DEFINE_SPECIAL(Floor_LowerToHighestEE, 256, 2, 3, 3) +DEFINE_SPECIAL(Floor_RaiseToLowest, 257, 1, 3, 3) +DEFINE_SPECIAL(Floor_LowerToLowestCeiling, 258, 2, 3, 3) +DEFINE_SPECIAL(Floor_RaiseToCeiling, 259, 2, 4, 4) +DEFINE_SPECIAL(Floor_ToCeilingInstant, 260, 1, 3, 3) +DEFINE_SPECIAL(Floor_LowerByTexture, 261, 2, 3, 3) +DEFINE_SPECIAL(Ceiling_RaiseToHighest, 262, 2, 3, 3) +DEFINE_SPECIAL(Ceiling_ToHighestInstant, 263, 1, 3, 3) +DEFINE_SPECIAL(Ceiling_LowerToNearest, 264, 2, 4, 4) +DEFINE_SPECIAL(Ceiling_RaiseToLowest, 265, 2, 3, 3) +DEFINE_SPECIAL(Ceiling_RaiseToHighestFloor, 266, 2, 3, 3) +DEFINE_SPECIAL(Ceiling_ToFloorInstant, 267, 1, 3, 3) +DEFINE_SPECIAL(Ceiling_RaiseByTexture, 268, 2, 3, 3) +DEFINE_SPECIAL(Ceiling_LowerByTexture, 269, 2, 4, 4) +DEFINE_SPECIAL(Stairs_BuildDownDoom, 270, 5, 5, 5) +DEFINE_SPECIAL(Stairs_BuildUpDoomSync, 271, 4, 4, 4) +DEFINE_SPECIAL(Stairs_BuildDownDoomSync, 272, 4, 4, 4) + #undef DEFINE_SPECIAL diff --git a/src/am_map.cpp b/src/am_map.cpp index 64d5420b0..3768af858 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -2307,8 +2307,9 @@ bool AM_isExitBoundary (line_t& line) bool AM_isTriggerSpecial (int special, int *) { - return LineSpecialsInfo[special] != NULL - && LineSpecialsInfo[special]->max_args >= 0 + FLineSpecial *spec = P_GetLineSpecialInfo(special); + return spec != NULL + && spec->max_args >= 0 && special != Door_Open && special != Door_Close && special != Door_CloseWaitOpen diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 233c31d29..8d0d87d41 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -605,7 +605,7 @@ CCMD (special) } } Net_WriteByte(DEM_RUNSPECIAL); - Net_WriteByte(specnum); + Net_WriteWord(specnum); Net_WriteByte(argc - 2); for (int i = 2; i < argc; ++i) { diff --git a/src/d_net.cpp b/src/d_net.cpp index 5e8a635d5..6ac581151 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2503,7 +2503,7 @@ void Net_DoCommand (int type, BYTE **stream, int player) case DEM_RUNSPECIAL: { - int snum = ReadByte(stream); + int snum = ReadWord(stream); int argn = ReadByte(stream); int arg[5] = { 0, 0, 0, 0, 0 }; @@ -2794,7 +2794,7 @@ void Net_SkipCommand (int type, BYTE **stream) break; case DEM_RUNSPECIAL: - skip = 2 + *(*stream + 1) * 4; + skip = 3 + *(*stream + 2) * 4; break; case DEM_CONVREPLY: diff --git a/src/d_protocol.h b/src/d_protocol.h index 73b042470..77a64ee16 100644 --- a/src/d_protocol.h +++ b/src/d_protocol.h @@ -158,7 +158,7 @@ enum EDemoCommand DEM_CONVREPLY, // 59 Word: Dialogue node, Byte: Reply number DEM_CONVCLOSE, // 60 DEM_CONVNULL, // 61 - DEM_RUNSPECIAL, // 62 Byte: Special number, Byte: Arg count, Ints: Args + DEM_RUNSPECIAL, // 62 Word: Special number, Byte: Arg count, Ints: Args DEM_SETPITCHLIMIT, // 63 Byte: Up limit, Byte: Down limit (in degrees) DEM_ADVANCEINTER, // 64 Advance intermission screen state DEM_RUNNAMEDSCRIPT, // 65 String: Script name, Byte: Arg count + Always flag; each arg is a 4-byte int diff --git a/src/fragglescript/t_fs.h b/src/fragglescript/t_fs.h index 91f90edb3..45507bdf7 100644 --- a/src/fragglescript/t_fs.h +++ b/src/fragglescript/t_fs.h @@ -10,5 +10,6 @@ class AActor; void T_PreprocessScripts(); void T_LoadScripts(MapData * map); void T_AddSpawnedThing(AActor * ); +bool T_RunScript(int snum, AActor * t_trigger); #endif diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 0945b1b4f..38f32bded 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -4619,9 +4619,10 @@ void init_functions(void) gscr->NewVariable("trigger", svt_pMobj)->value.pMobj = &trigger_obj; // Create constants for all existing line specials - for(int i=0; i<256; i++) + int max = P_GetMaxLineSpecial(); + for(int i=0; i<=max; i++) { - const FLineSpecial *ls = LineSpecialsInfo[i]; + const FLineSpecial *ls = P_GetLineSpecialInfo(i); if (ls != NULL && ls->max_args >= 0) // specials with max args set to -1 can only be used in a map and are of no use hee. { diff --git a/src/fragglescript/t_script.cpp b/src/fragglescript/t_script.cpp index 98911a418..07f6cc3be 100644 --- a/src/fragglescript/t_script.cpp +++ b/src/fragglescript/t_script.cpp @@ -621,7 +621,7 @@ void T_PreprocessScripts() // //========================================================================== -static bool RunScript(int snum, AActor * t_trigger) +bool T_RunScript(int snum, AActor * t_trigger) { DFraggleThinker *th = DFraggleThinker::ActiveThinker; if (th) @@ -649,21 +649,6 @@ static bool RunScript(int snum, AActor * t_trigger) // //========================================================================== -static int LS_FS_Execute (line_t *ln, AActor *it, bool backSide, - int arg0, int arg1, int arg2, int arg3, int arg4) -// FS_Execute(script#,firstsideonly,lock,msgtype) -{ - if (arg1 && ln && backSide) return false; - if (arg2!=0 && !P_CheckKeys(it, arg2, !!arg3)) return false; - return RunScript(arg0,it); -} - -//========================================================================== -// -// -// -//========================================================================== - void FS_Close() { int i; @@ -695,8 +680,6 @@ void T_Init() if (global_script == NULL) { - // I'd rather link the special here than make another source file depend on FS! - LineSpecials[FS_Execute]=LS_FS_Execute; global_script = new DFsScript; GC::AddSoftRoot(global_script); init_functions(); @@ -720,6 +703,6 @@ CCMD(fpuke) } else { - RunScript(atoi(argv[1]), players[consoleplayer].mo); + T_RunScript(atoi(argv[1]), players[consoleplayer].mo); } } diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 931f3a127..318636847 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -6326,6 +6326,26 @@ int DLevelScript::RunScript () sp -= 4; break; + case PCD_LSPEC5EX: + P_ExecuteSpecial(NEXTWORD, activationline, activator, backSide, + STACK(5) & specialargmask, + STACK(4) & specialargmask, + STACK(3) & specialargmask, + STACK(2) & specialargmask, + STACK(1) & specialargmask); + sp -= 5; + break; + + case PCD_LSPEC5EXRESULT: + STACK(5) = P_ExecuteSpecial(NEXTWORD, activationline, activator, backSide, + STACK(5) & specialargmask, + STACK(4) & specialargmask, + STACK(3) & specialargmask, + STACK(2) & specialargmask, + STACK(1) & specialargmask); + sp -= 4; + break; + case PCD_LSPEC1DIRECT: temp = NEXTBYTE; P_ExecuteSpecial(temp, activationline, activator, backSide, diff --git a/src/p_acs.h b/src/p_acs.h index 3188e46aa..34a826726 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -769,6 +769,8 @@ public: PCD_PRINTSCRIPTCHARARRAY, PCD_PRINTSCRIPTCHRANGE, /*380*/ PCD_STRCPYTOSCRIPTCHRANGE, + PCD_LSPEC5EX, + PCD_LSPEC5EXRESULT, /*381*/ PCODE_COMMAND_COUNT }; diff --git a/src/p_doors.cpp b/src/p_doors.cpp index bce324902..51f0f58d5 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -121,7 +121,7 @@ void DDoor::Tick () { switch (m_Type) { - case doorRaiseIn5Mins: + case doorWaitRaise: m_Direction = 1; m_Type = doorRaise; DoorSound (true); @@ -215,7 +215,7 @@ void DDoor::Tick () switch (m_Type) { case doorRaise: - case doorRaiseIn5Mins: + case doorWaitRaise: m_Direction = -1; DoorSound(false); break; @@ -348,9 +348,9 @@ DDoor::DDoor (sector_t *sector) // //============================================================================ -DDoor::DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int lightTag) +DDoor::DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int lightTag, int topcountdown) : DMovingCeiling (sec), - m_Type (type), m_Speed (speed), m_TopWait (delay), m_LightTag (lightTag) + m_Type (type), m_Speed (speed), m_TopWait (delay), m_TopCountdown(topcountdown), m_LightTag (lightTag) { vertex_t *spot; fixed_t height; @@ -384,12 +384,21 @@ DDoor::DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int lightTa DoorSound (false); break; - case doorRaiseIn5Mins: + case doorWaitRaise: m_Direction = 2; height = sec->FindLowestCeilingSurrounding (&spot); m_TopDist = sec->ceilingplane.PointToDist (spot, height - 4*FRACUNIT); - m_TopCountdown = 5 * 60 * TICRATE; break; + + case doorWaitClose: + m_Direction = 0; + m_Type = DDoor::doorRaise; + height = sec->FindHighestFloorPoint (&m_BotSpot); + m_BotDist = sec->ceilingplane.PointToDist (m_BotSpot, height); + m_OldFloorDist = sec->floorplane.d; + m_TopDist = sec->ceilingplane.d; + break; + } if (!m_Sector->floordata || !m_Sector->floordata->IsKindOf(RUNTIME_CLASS(DPlat)) || @@ -414,7 +423,7 @@ DDoor::DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int lightTa //============================================================================ bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, - int tag, int speed, int delay, int lock, int lightTag, bool boomgen) + int tag, int speed, int delay, int lock, int lightTag, bool boomgen, int topcountdown) { bool rtn = false; int secnum; @@ -480,7 +489,7 @@ bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, } return false; } - if (new DDoor (sec, type, speed, delay, lightTag)) + if (new DDoor (sec, type, speed, delay, lightTag, topcountdown)) rtn = true; } else @@ -494,7 +503,7 @@ bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, if (sec->PlaneMoving(sector_t::ceiling)) continue; - if (new DDoor (sec, type, speed, delay, lightTag)) + if (new DDoor (sec, type, speed, delay, lightTag, topcountdown)) rtn = true; } @@ -508,35 +517,11 @@ bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, // //============================================================================ -void P_SpawnDoorCloseIn30 (sector_t *sec) +void P_SpawnDoorClose (sector_t *sec) { - fixed_t height; - DDoor *door = new DDoor (sec); - - door->m_Sector = sec; - door->m_Direction = 0; - door->m_Type = DDoor::doorRaise; - door->m_Speed = FRACUNIT*2; - door->m_TopCountdown = 30 * TICRATE; - height = sec->FindHighestFloorPoint (&door->m_BotSpot); - door->m_BotDist = sec->ceilingplane.PointToDist (door->m_BotSpot, height); - door->m_OldFloorDist = sec->floorplane.d; - door->m_TopDist = sec->ceilingplane.d; - door->m_LightTag = 0; + DDoor *door = new DDoor(sec, DDoor::doorWaitClose, FRACUNIT * 2, 0, 0, 30 * TICRATE); } -//============================================================================ -// -// Spawn a door that opens after 5 minutes -// -//============================================================================ - -void P_SpawnDoorRaiseIn5Mins (sector_t *sec) -{ - new DDoor (sec, DDoor::doorRaiseIn5Mins, 2*FRACUNIT, TICRATE*30/7, 0); -} - - //============================================================================ // // animated doors diff --git a/src/p_floor.cpp b/src/p_floor.cpp index e3763e677..7284024cc 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -614,7 +614,7 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, floor->m_PauseTime = 0; floor->m_StepTime = floor->m_PerStepTime = persteptime; - floor->m_Crush = (!usespecials && speed == 4*FRACUNIT) ? 10 : -1; //jff 2/27/98 fix uninitialized crush field + floor->m_Crush = (!(usespecials & DFloor::stairUseSpecials) && speed == 4*FRACUNIT) ? 10 : -1; //jff 2/27/98 fix uninitialized crush field floor->m_Hexencrush = false; floor->m_Speed = speed; @@ -632,7 +632,7 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, { ok = 0; - if (usespecials) + if (usespecials & DFloor::stairUseSpecials) { // [RH] Find the next sector by scanning for Stairs_Special? tsec = sec->NextSpecialSector ( @@ -715,7 +715,7 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, floor->m_PauseTime = 0; floor->m_StepTime = floor->m_PerStepTime = persteptime; - if (usespecials == 2) + if (usespecials & DFloor::stairSync) { // [RH] fixed_t rise = height - sec->CenterFloor(); @@ -727,7 +727,7 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, } floor->m_Type = DFloor::buildStair; //jff 3/31/98 do not leave uninited //jff 2/27/98 fix uninitialized crush field - floor->m_Crush = (!usespecials && speed == 4*FRACUNIT) ? 10 : -1; + floor->m_Crush = (!(usespecials & DFloor::stairUseSpecials) && speed == 4*FRACUNIT) ? 10 : -1; //jff 2/27/98 fix uninitialized crush field floor->m_Hexencrush = false; floor->m_ResetCount = reset; // [RH] Tics until reset (0 if never) floor->m_OrgDist = sec->floorplane.d; // [RH] Height to reset to diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 05259ba3e..3b99ae44b 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -58,6 +58,19 @@ #include "d_event.h" #include "gstrings.h" #include "r_data/colormaps.h" +#include "fragglescript/t_fs.h" + +// Remaps EE sector change types to Generic_Floor values. According to the Eternity Wiki: +/* + 0 : No texture or type change. ( = 0) + 1 : Copy texture, zero type; trigger model. ( = 1) + 2 : Copy texture, zero type; numeric model. ( = 1+4) + 3 : Copy texture, preserve type; trigger model. ( = 3) + 4 : Copy texture, preserve type; numeric model. ( = 3+4) + 5 : Copy texture and type; trigger model. ( = 2) + 6 : Copy texture and type; numeric model. ( = 2+4) +*/ +static const BYTE ChangeMap[8] = { 0, 1, 5, 3, 7, 2, 6, 0 }; #define FUNC(a) static int a (line_t *ln, AActor *it, bool backSide, \ int arg0, int arg1, int arg2, int arg3, int arg4) @@ -66,7 +79,9 @@ #define TICS(a) (((a)*TICRATE)/35) #define OCTICS(a) (((a)*TICRATE)/8) #define BYTEANGLE(a) ((angle_t)((a)<<24)) +#define CRUSH(a) ((a) > 0? (a) : -1) #define CRUSHTYPE(a) ((a)==1? false : (a)==2? true : gameinfo.gametype == GAME_Hexen) +#define CHANGE(a) (((a) >= 0 && (a)<=7)? ChangeMap[a]:0) static FRandom pr_glass ("GlassBreak"); @@ -239,6 +254,18 @@ FUNC(LS_Door_CloseWaitOpen) return EV_DoDoor (DDoor::doorCloseWaitOpen, ln, it, arg0, SPEED(arg1), OCTICS(arg2), 0, arg3); } +FUNC(LS_Door_WaitRaise) +// Door_WaitRaise(tag, speed, delay, wait, lighttag) +{ + return EV_DoDoor(DDoor::doorWaitRaise, ln, it, arg0, SPEED(arg1), TICS(arg2), 0, arg4, false, TICS(arg3)); +} + +FUNC(LS_Door_WaitClose) +// Door_WaitRaise(tag, speed, wait, lighttag) +{ + return EV_DoDoor(DDoor::doorWaitClose, ln, it, arg0, SPEED(arg1), 0, 0, arg3, false, TICS(arg2)); +} + FUNC(LS_Door_Animated) // Door_Animated (tag, speed, delay, lock) { @@ -280,15 +307,15 @@ FUNC(LS_Generic_Door) } FUNC(LS_Floor_LowerByValue) -// Floor_LowerByValue (tag, speed, height) +// Floor_LowerByValue (tag, speed, height, change) { - return EV_DoFloor (DFloor::floorLowerByValue, ln, arg0, SPEED(arg1), FRACUNIT*arg2, -1, 0, false); + return EV_DoFloor (DFloor::floorLowerByValue, ln, arg0, SPEED(arg1), FRACUNIT*arg2, -1, CHANGE(arg3), false); } FUNC(LS_Floor_LowerToLowest) -// Floor_LowerToLowest (tag, speed) +// Floor_LowerToLowest (tag, speed, change) { - return EV_DoFloor (DFloor::floorLowerToLowest, ln, arg0, SPEED(arg1), 0, -1, 0, false); + return EV_DoFloor (DFloor::floorLowerToLowest, ln, arg0, SPEED(arg1), 0, -1, CHANGE(arg2), false); } FUNC(LS_Floor_LowerToHighest) @@ -297,28 +324,41 @@ FUNC(LS_Floor_LowerToHighest) return EV_DoFloor (DFloor::floorLowerToHighest, ln, arg0, SPEED(arg1), (arg2-128)*FRACUNIT, -1, 0, false, arg3==1); } -FUNC(LS_Floor_LowerToNearest) -// Floor_LowerToNearest (tag, speed) +FUNC(LS_Floor_LowerToHighestEE) +// Floor_LowerToHighest (tag, speed, change) { - return EV_DoFloor (DFloor::floorLowerToNearest, ln, arg0, SPEED(arg1), 0, -1, 0, false); + return EV_DoFloor (DFloor::floorLowerToHighest, ln, arg0, SPEED(arg1), 0, -1, CHANGE(arg2), false); +} + +FUNC(LS_Floor_LowerToNearest) +// Floor_LowerToNearest (tag, speed, change) +{ + return EV_DoFloor (DFloor::floorLowerToNearest, ln, arg0, SPEED(arg1), 0, -1, CHANGE(arg2), false); } FUNC(LS_Floor_RaiseByValue) -// Floor_RaiseByValue (tag, speed, height) +// Floor_RaiseByValue (tag, speed, height, change, crush) { - return EV_DoFloor (DFloor::floorRaiseByValue, ln, arg0, SPEED(arg1), FRACUNIT*arg2, -1, 0, false); + return EV_DoFloor (DFloor::floorRaiseByValue, ln, arg0, SPEED(arg1), FRACUNIT*arg2, CRUSH(arg4), CHANGE(arg3), true); } FUNC(LS_Floor_RaiseToHighest) -// Floor_RaiseToHighest (tag, speed) +// Floor_RaiseToHighest (tag, speed, change, crush) { - return EV_DoFloor (DFloor::floorRaiseToHighest, ln, arg0, SPEED(arg1), 0, -1, 0, false); + return EV_DoFloor (DFloor::floorRaiseToHighest, ln, arg0, SPEED(arg1), 0, CRUSH(arg3), CHANGE(arg2), true); } FUNC(LS_Floor_RaiseToNearest) -// Floor_RaiseToNearest (tag, speed) +// Floor_RaiseToNearest (tag, speed, change, crush) { - return EV_DoFloor (DFloor::floorRaiseToNearest, ln, arg0, SPEED(arg1), 0, -1, 0, false); + return EV_DoFloor (DFloor::floorRaiseToNearest, ln, arg0, SPEED(arg1), 0, CRUSH(arg3), CHANGE(arg2), true); +} + +FUNC(LS_Floor_RaiseToLowest) +// Floor_RaiseToLowest (tag, change, crush) +{ + // This is merely done for completeness as it's a rather pointless addition. + return EV_DoFloor (DFloor::floorRaiseToLowest, ln, arg0, 2*FRACUNIT, 0, CRUSH(arg3), CHANGE(arg2), true); } FUNC(LS_Floor_RaiseAndCrush) @@ -334,15 +374,15 @@ FUNC(LS_Floor_RaiseAndCrushDoom) } FUNC(LS_Floor_RaiseByValueTimes8) -// FLoor_RaiseByValueTimes8 (tag, speed, height) +// FLoor_RaiseByValueTimes8 (tag, speed, height, change, crush) { - return EV_DoFloor (DFloor::floorRaiseByValue, ln, arg0, SPEED(arg1), FRACUNIT*arg2*8, -1, 0, false); + return EV_DoFloor (DFloor::floorRaiseByValue, ln, arg0, SPEED(arg1), FRACUNIT*arg2*8, CRUSH(arg4), CHANGE(arg3), true); } FUNC(LS_Floor_LowerByValueTimes8) -// Floor_LowerByValueTimes8 (tag, speed, height) +// Floor_LowerByValueTimes8 (tag, speed, height, change) { - return EV_DoFloor (DFloor::floorLowerByValue, ln, arg0, SPEED(arg1), FRACUNIT*arg2*8, -1, 0, false); + return EV_DoFloor (DFloor::floorLowerByValue, ln, arg0, SPEED(arg1), FRACUNIT*arg2*8, -1, CHANGE(arg3), false); } FUNC(LS_Floor_CrushStop) @@ -352,41 +392,65 @@ FUNC(LS_Floor_CrushStop) } FUNC(LS_Floor_LowerInstant) -// Floor_LowerInstant (tag, unused, height) +// Floor_LowerInstant (tag, unused, height, change) { - return EV_DoFloor (DFloor::floorLowerInstant, ln, arg0, 0, arg2*FRACUNIT*8, -1, 0, false); + return EV_DoFloor (DFloor::floorLowerInstant, ln, arg0, 0, arg2*FRACUNIT*8, -1, CHANGE(arg3), false); } FUNC(LS_Floor_RaiseInstant) -// Floor_RaiseInstant (tag, unused, height) +// Floor_RaiseInstant (tag, unused, height, change, crush) { - return EV_DoFloor (DFloor::floorRaiseInstant, ln, arg0, 0, arg2*FRACUNIT*8, -1, 0, false); + return EV_DoFloor (DFloor::floorRaiseInstant, ln, arg0, 0, arg2*FRACUNIT*8, CRUSH(arg4), CHANGE(arg3), true); +} + +FUNC(LS_Floor_ToCeilingInstant) +// Floor_ToCeilingInstant (tag, change, crush) +{ + return EV_DoFloor (DFloor::floorLowerToCeiling, ln, arg0, 0, 0, CRUSH(arg2), CHANGE(arg1), true); } FUNC(LS_Floor_MoveToValueTimes8) -// Floor_MoveToValueTimes8 (tag, speed, height, negative) +// Floor_MoveToValueTimes8 (tag, speed, height, negative, change) { return EV_DoFloor (DFloor::floorMoveToValue, ln, arg0, SPEED(arg1), - arg2*FRACUNIT*8*(arg3?-1:1), -1, 0, false); + arg2*FRACUNIT*8*(arg3?-1:1), -1, CHANGE(arg4), false); } FUNC(LS_Floor_MoveToValue) -// Floor_MoveToValue (tag, speed, height, negative) +// Floor_MoveToValue (tag, speed, height, negative, change) { return EV_DoFloor (DFloor::floorMoveToValue, ln, arg0, SPEED(arg1), - arg2*FRACUNIT*(arg3?-1:1), -1, 0, false); + arg2*FRACUNIT*(arg3?-1:1), -1, CHANGE(arg4), false); } FUNC(LS_Floor_RaiseToLowestCeiling) -// Floor_RaiseToLowestCeiling (tag, speed) +// Floor_RaiseToLowestCeiling (tag, speed, change, crush) { - return EV_DoFloor (DFloor::floorRaiseToLowestCeiling, ln, arg0, SPEED(arg1), 0, -1, 0, false); + return EV_DoFloor (DFloor::floorRaiseToLowestCeiling, ln, arg0, SPEED(arg1), 0, CRUSH(arg3), CHANGE(arg2), true); +} + +FUNC(LS_Floor_LowerToLowestCeiling) +// Floor_LowerToLowestCeiling (tag, speed, change) +{ + return EV_DoFloor (DFloor::floorLowerToLowestCeiling, ln, arg0, SPEED(arg1), 0, -1, CHANGE(arg2), true); } FUNC(LS_Floor_RaiseByTexture) -// Floor_RaiseByTexture (tag, speed) +// Floor_RaiseByTexture (tag, speed, change, crush) { - return EV_DoFloor (DFloor::floorRaiseByTexture, ln, arg0, SPEED(arg1), 0, -1, 0, false); + return EV_DoFloor (DFloor::floorRaiseByTexture, ln, arg0, SPEED(arg1), 0, CRUSH(arg3), CHANGE(arg2), true); +} + +FUNC(LS_Floor_LowerByTexture) +// Floor_LowerByTexture (tag, speed, change, crush) +{ + return EV_DoFloor (DFloor::floorLowerByTexture, ln, arg0, SPEED(arg1), 0, -1, CHANGE(arg2), true); +} + +FUNC(LS_Floor_RaiseToCeiling) +// Floor_RaiseToCeiling (tag, speed, change, crush) +{ + return EV_DoFloor (DFloor::floorRaiseToCeiling, ln, arg0, SPEED(arg1), 0, CRUSH(arg3), CHANGE(arg2), true); } FUNC(LS_Floor_RaiseByValueTxTy) @@ -472,28 +536,28 @@ FUNC(LS_Stairs_BuildDown) // Stair_BuildDown (tag, speed, height, delay, reset) { return EV_BuildStairs (arg0, DFloor::buildDown, ln, - arg2 * FRACUNIT, SPEED(arg1), TICS(arg3), arg4, 0, 1); + arg2 * FRACUNIT, SPEED(arg1), TICS(arg3), arg4, 0, DFloor::stairUseSpecials); } FUNC(LS_Stairs_BuildUp) // Stairs_BuildUp (tag, speed, height, delay, reset) { return EV_BuildStairs (arg0, DFloor::buildUp, ln, - arg2 * FRACUNIT, SPEED(arg1), TICS(arg3), arg4, 0, 1); + arg2 * FRACUNIT, SPEED(arg1), TICS(arg3), arg4, 0, DFloor::stairUseSpecials); } FUNC(LS_Stairs_BuildDownSync) // Stairs_BuildDownSync (tag, speed, height, reset) { return EV_BuildStairs (arg0, DFloor::buildDown, ln, - arg2 * FRACUNIT, SPEED(arg1), 0, arg3, 0, 2); + arg2 * FRACUNIT, SPEED(arg1), 0, arg3, 0, DFloor::stairUseSpecials|DFloor::stairSync); } FUNC(LS_Stairs_BuildUpSync) // Stairs_BuildUpSync (tag, speed, height, reset) { return EV_BuildStairs (arg0, DFloor::buildUp, ln, - arg2 * FRACUNIT, SPEED(arg1), 0, arg3, 0, 2); + arg2 * FRACUNIT, SPEED(arg1), 0, arg3, 0, DFloor::stairUseSpecials|DFloor::stairSync); } FUNC(LS_Stairs_BuildUpDoom) @@ -503,6 +567,28 @@ FUNC(LS_Stairs_BuildUpDoom) arg2 * FRACUNIT, SPEED(arg1), TICS(arg3), arg4, 0, 0); } +FUNC(LS_Stairs_BuildDownDoom) +// Stair_BuildDownDoom (tag, speed, height, delay, reset) +{ + return EV_BuildStairs (arg0, DFloor::buildDown, ln, + arg2 * FRACUNIT, SPEED(arg1), TICS(arg3), arg4, 0, 0); +} + +FUNC(LS_Stairs_BuildDownDoomSync) +// Stairs_BuildDownDoomSync (tag, speed, height, reset) +{ + return EV_BuildStairs (arg0, DFloor::buildDown, ln, + arg2 * FRACUNIT, SPEED(arg1), 0, arg3, 0, DFloor::stairSync); +} + +FUNC(LS_Stairs_BuildUpDoomSync) +// Stairs_BuildUpDoomSync (tag, speed, height, reset) +{ + return EV_BuildStairs (arg0, DFloor::buildUp, ln, + arg2 * FRACUNIT, SPEED(arg1), 0, arg3, 0, DFloor::stairSync); +} + + FUNC(LS_Generic_Stairs) // Generic_Stairs (tag, speed, step, dir/igntxt, reset) { @@ -536,27 +622,27 @@ FUNC(LS_Pillar_Open) } FUNC(LS_Ceiling_LowerByValue) -// Ceiling_LowerByValue (tag, speed, height) +// Ceiling_LowerByValue (tag, speed, height, change) { - return EV_DoCeiling (DCeiling::ceilLowerByValue, ln, arg0, SPEED(arg1), 0, arg2*FRACUNIT, -1, 0, 0, false); + return EV_DoCeiling (DCeiling::ceilLowerByValue, ln, arg0, SPEED(arg1), 0, arg2*FRACUNIT, -1, 0, CHANGE(arg3), false); } FUNC(LS_Ceiling_RaiseByValue) -// Ceiling_RaiseByValue (tag, speed, height) +// Ceiling_RaiseByValue (tag, speed, height, change) { - return EV_DoCeiling (DCeiling::ceilRaiseByValue, ln, arg0, SPEED(arg1), 0, arg2*FRACUNIT, -1, 0, 0, false); + return EV_DoCeiling (DCeiling::ceilRaiseByValue, ln, arg0, SPEED(arg1), 0, arg2*FRACUNIT, -1, 0, CHANGE(arg3), false); } FUNC(LS_Ceiling_LowerByValueTimes8) -// Ceiling_LowerByValueTimes8 (tag, speed, height) +// Ceiling_LowerByValueTimes8 (tag, speed, height, change) { - return EV_DoCeiling (DCeiling::ceilLowerByValue, ln, arg0, SPEED(arg1), 0, arg2*FRACUNIT*8, -1, 0, 0, false); + return EV_DoCeiling (DCeiling::ceilLowerByValue, ln, arg0, SPEED(arg1), 0, arg2*FRACUNIT*8, -1, 0, CHANGE(arg3), false); } FUNC(LS_Ceiling_RaiseByValueTimes8) -// Ceiling_RaiseByValueTimes8 (tag, speed, height) +// Ceiling_RaiseByValueTimes8 (tag, speed, height, change) { - return EV_DoCeiling (DCeiling::ceilRaiseByValue, ln, arg0, SPEED(arg1), 0, arg2*FRACUNIT*8, -1, 0, 0, false); + return EV_DoCeiling (DCeiling::ceilRaiseByValue, ln, arg0, SPEED(arg1), 0, arg2*FRACUNIT*8, -1, 0, CHANGE(arg3), false); } FUNC(LS_Ceiling_CrushAndRaise) @@ -590,35 +676,35 @@ FUNC(LS_Ceiling_CrushRaiseAndStay) } FUNC(LS_Ceiling_MoveToValueTimes8) -// Ceiling_MoveToValueTimes8 (tag, speed, height, negative) +// Ceiling_MoveToValueTimes8 (tag, speed, height, negative, change) { return EV_DoCeiling (DCeiling::ceilMoveToValue, ln, arg0, SPEED(arg1), 0, - arg2*FRACUNIT*8*((arg3) ? -1 : 1), -1, 0, 0, false); + arg2*FRACUNIT*8*((arg3) ? -1 : 1), -1, 0, CHANGE(arg4), false); } FUNC(LS_Ceiling_MoveToValue) -// Ceiling_MoveToValue (tag, speed, height, negative) +// Ceiling_MoveToValue (tag, speed, height, negative, change) { return EV_DoCeiling (DCeiling::ceilMoveToValue, ln, arg0, SPEED(arg1), 0, - arg2*FRACUNIT*((arg3) ? -1 : 1), -1, 0, 0, false); + arg2*FRACUNIT*((arg3) ? -1 : 1), -1, 0, CHANGE(arg4), false); } FUNC(LS_Ceiling_LowerToHighestFloor) -// Ceiling_LowerToHighestFloor (tag, speed) +// Ceiling_LowerToHighestFloor (tag, speed, change, crush) { - return EV_DoCeiling (DCeiling::ceilLowerToHighestFloor, ln, arg0, SPEED(arg1), 0, 0, -1, 0, 0, false); + return EV_DoCeiling (DCeiling::ceilLowerToHighestFloor, ln, arg0, SPEED(arg1), 0, 0, CRUSH(arg3), 0, CHANGE(arg2), false); } FUNC(LS_Ceiling_LowerInstant) -// Ceiling_LowerInstant (tag, unused, height) +// Ceiling_LowerInstant (tag, unused, height, change, crush) { - return EV_DoCeiling (DCeiling::ceilLowerInstant, ln, arg0, 0, 0, arg2*FRACUNIT*8, -1, 0, 0, false); + return EV_DoCeiling (DCeiling::ceilLowerInstant, ln, arg0, 0, 0, arg2*FRACUNIT*8, CRUSH(arg4), 0, CHANGE(arg3), false); } FUNC(LS_Ceiling_RaiseInstant) -// Ceiling_RaiseInstant (tag, unused, height) +// Ceiling_RaiseInstant (tag, unused, height, change) { - return EV_DoCeiling (DCeiling::ceilRaiseInstant, ln, arg0, 0, 0, arg2*FRACUNIT*8, -1, 0, 0, false); + return EV_DoCeiling (DCeiling::ceilRaiseInstant, ln, arg0, 0, 0, arg2*FRACUNIT*8, -1, 0, CHANGE(arg3), false); } FUNC(LS_Ceiling_CrushRaiseAndStayA) @@ -658,21 +744,69 @@ FUNC(LS_Ceiling_CrushAndRaiseSilentDist) } FUNC(LS_Ceiling_RaiseToNearest) -// Ceiling_RaiseToNearest (tag, speed) +// Ceiling_RaiseToNearest (tag, speed, change) { - return EV_DoCeiling (DCeiling::ceilRaiseToNearest, ln, arg0, SPEED(arg1), 0, 0, -1, 0, 0, false); + return EV_DoCeiling (DCeiling::ceilRaiseToNearest, ln, arg0, SPEED(arg1), 0, 0, -1, CHANGE(arg2), 0, false); +} + +FUNC(LS_Ceiling_RaiseToHighest) +// Ceiling_RaiseToHighest (tag, speed, change) +{ + return EV_DoCeiling (DCeiling::ceilRaiseToHighest, ln, arg0, SPEED(arg1), 0, 0, -1, CHANGE(arg2), 0, false); +} + +FUNC(LS_Ceiling_RaiseToLowest) +// Ceiling_RaiseToLowest (tag, speed, change) +{ + return EV_DoCeiling (DCeiling::ceilRaiseToLowest, ln, arg0, SPEED(arg1), 0, 0, -1, CHANGE(arg2), 0, false); +} + +FUNC(LS_Ceiling_RaiseToHighestFloor) +// Ceiling_RaiseToHighestFloor (tag, speed, change) +{ + return EV_DoCeiling (DCeiling::ceilRaiseToHighestFloor, ln, arg0, SPEED(arg1), 0, 0, -1, CHANGE(arg2), 0, false); +} + +FUNC(LS_Ceiling_RaiseByTexture) +// Ceiling_RaiseByTexture (tag, speed, change) +{ + return EV_DoCeiling (DCeiling::ceilRaiseByTexture, ln, arg0, SPEED(arg1), 0, 0, -1, CHANGE(arg2), 0, false); } FUNC(LS_Ceiling_LowerToLowest) -// Ceiling_LowerToLowest (tag, speed) +// Ceiling_LowerToLowest (tag, speed, change, crush) { - return EV_DoCeiling (DCeiling::ceilLowerToLowest, ln, arg0, SPEED(arg1), 0, 0, -1, 0, 0, false); + return EV_DoCeiling (DCeiling::ceilLowerToLowest, ln, arg0, SPEED(arg1), 0, 0, CRUSH(arg3), 0, CHANGE(arg2), false); +} + +FUNC(LS_Ceiling_LowerToNearest) +// Ceiling_LowerToNearest (tag, speed, change, crush) +{ + return EV_DoCeiling (DCeiling::ceilLowerToNearest, ln, arg0, SPEED(arg1), 0, 0, CRUSH(arg3), 0, CHANGE(arg2), false); +} + +FUNC(LS_Ceiling_ToHighestInstant) +// Ceiling_ToHighestInstant (tag, change, crush) +{ + return EV_DoCeiling (DCeiling::ceilLowerToHighest, ln, arg0, FRACUNIT*2, 0, 0, CRUSH(arg2), 0, CHANGE(arg1), false); +} + +FUNC(LS_Ceiling_ToFloorInstant) +// Ceiling_ToFloorInstant (tag, change, crush) +{ + return EV_DoCeiling (DCeiling::ceilRaiseToFloor, ln, arg0, FRACUNIT*2, 0, 0, CRUSH(arg2), 0, CHANGE(arg1), false); } FUNC(LS_Ceiling_LowerToFloor) -// Ceiling_LowerToFloor (tag, speed) +// Ceiling_LowerToFloor (tag, speed, change, crush) { - return EV_DoCeiling (DCeiling::ceilLowerToFloor, ln, arg0, SPEED(arg1), 0, 0, -1, 0, 0, false); + return EV_DoCeiling (DCeiling::ceilLowerToFloor, ln, arg0, SPEED(arg1), 0, 0, CRUSH(arg3), 0, CHANGE(arg4), false); +} + +FUNC(LS_Ceiling_LowerByTexture) +// Ceiling_LowerByTexture (tag, speed, change, crush) +{ + return EV_DoCeiling (DCeiling::ceilLowerByTexture, ln, arg0, SPEED(arg1), 0, 0, CRUSH(arg3), 0, CHANGE(arg4), false); } FUNC(LS_Generic_Ceiling) @@ -1752,6 +1886,22 @@ FUNC(LS_ACS_Terminate) return true; } +//========================================================================== +// +// +// +//========================================================================== + +FUNC(LS_FS_Execute) +// FS_Execute(script#,firstsideonly,lock,msgtype) +{ + if (arg1 && ln && backSide) return false; + if (arg2!=0 && !P_CheckKeys(it, arg2, !!arg3)) return false; + return T_RunScript(arg0,it); +} + + + FUNC(LS_FloorAndCeiling_LowerByValue) // FloorAndCeiling_LowerByValue (tag, speed, height) { @@ -3215,7 +3365,7 @@ FUNC(LS_Thing_SetConversation) } -lnSpecFunc LineSpecials[256] = +static lnSpecFunc LineSpecials[] = { /* 0 */ LS_NOP, /* 1 */ LS_NOP, // Polyobj_StartLine, @@ -3322,8 +3472,8 @@ lnSpecFunc LineSpecials[256] = /* 102 */ LS_NOP, // Scroll_Texture_Up /* 103 */ LS_NOP, // Scroll_Texture_Down /* 104 */ LS_Ceiling_CrushAndRaiseSilentDist, - /* 105 */ LS_NOP, - /* 106 */ LS_NOP, + /* 105 */ LS_Door_WaitRaise, + /* 106 */ LS_Door_WaitClose, /* 107 */ LS_NOP, /* 108 */ LS_NOP, /* 109 */ LS_Light_ForceLightning, @@ -3375,7 +3525,7 @@ lnSpecFunc LineSpecials[256] = /* 155 */ LS_NOP, /* 156 */ LS_NOP, /* 157 */ LS_NOP, // SetGlobalFogParameter // in GZDoom - /* 158 */ LS_NOP, // FS_Execute + /* 158 */ LS_FS_Execute, /* 159 */ LS_NOP, // Sector_SetPlaneReflection in GZDoom /* 160 */ LS_NOP, // Sector_Set3DFloor /* 161 */ LS_NOP, // Sector_SetContents @@ -3472,24 +3622,56 @@ lnSpecFunc LineSpecials[256] = /* 252 */ LS_Ceiling_RaiseToNearest, /* 253 */ LS_Ceiling_LowerToLowest, /* 254 */ LS_Ceiling_LowerToFloor, - /* 255 */ LS_Ceiling_CrushRaiseAndStaySilA + /* 255 */ LS_Ceiling_CrushRaiseAndStaySilA, + + /* 256 */ LS_Floor_LowerToHighestEE, + /* 257 */ LS_Floor_RaiseToLowest, + /* 258 */ LS_Floor_LowerToLowestCeiling, + /* 259 */ LS_Floor_RaiseToCeiling, + /* 260 */ LS_Floor_ToCeilingInstant, + /* 261 */ LS_Floor_LowerByTexture, + /* 262 */ LS_Ceiling_RaiseToHighest, + /* 263 */ LS_Ceiling_ToHighestInstant, + /* 264 */ LS_Ceiling_LowerToNearest, + /* 265 */ LS_Ceiling_RaiseToLowest, + /* 266 */ LS_Ceiling_RaiseToHighestFloor, + /* 267 */ LS_Ceiling_ToFloorInstant, + /* 268 */ LS_Ceiling_RaiseByTexture, + /* 269 */ LS_Ceiling_LowerByTexture, + /* 270 */ LS_Stairs_BuildDownDoom, + /* 271 */ LS_Stairs_BuildUpDoomSync, + /* 272 */ LS_Stairs_BuildDownDoomSync, + }; #define DEFINE_SPECIAL(name, num, min, max, mmax) {#name, num, min, max, mmax}, static FLineSpecial LineSpecialNames[] = { #include "actionspecials.h" }; -const FLineSpecial *LineSpecialsInfo[256]; static int STACK_ARGS lscmp (const void * a, const void * b) { return stricmp( ((FLineSpecial*)a)->name, ((FLineSpecial*)b)->name); } -static struct InitLineSpecials +static struct LineSpecialTable { - InitLineSpecials() + TArray LineSpecialsInfo; + + LineSpecialTable() { + unsigned int max = 0; + for (size_t i = 0; i < countof(LineSpecialNames); ++i) + { + if (LineSpecialNames[i].number > (int)max) + max = LineSpecialNames[i].number; + } + LineSpecialsInfo.Resize(max + 1); + for (unsigned i = 0; i <= max; i++) + { + LineSpecialsInfo[i] = NULL; + } + qsort(LineSpecialNames, countof(LineSpecialNames), sizeof(FLineSpecial), lscmp); for (size_t i = 0; i < countof(LineSpecialNames); ++i) { @@ -3497,7 +3679,33 @@ static struct InitLineSpecials LineSpecialsInfo[LineSpecialNames[i].number] = &LineSpecialNames[i]; } } -} DoInit; +} LineSpec; + +//========================================================================== +// +// +// +//========================================================================== + +int P_GetMaxLineSpecial() +{ + return LineSpec.LineSpecialsInfo.Size() - 1; +} + +//========================================================================== +// +// +// +//========================================================================== + +FLineSpecial *P_GetLineSpecialInfo(int special) +{ + if ((unsigned) special < LineSpec.LineSpecialsInfo.Size()) + { + return LineSpec.LineSpecialsInfo[special]; + } + return NULL; +} //========================================================================== // @@ -3550,7 +3758,7 @@ int P_ExecuteSpecial(int num, int arg4, int arg5) { - if (num >= 0 && num <= 255) + if (num >= 0 && num < countof(LineSpecials)) { return LineSpecials[num](line, activator, backSide, arg1, arg2, arg3, arg4, arg5); } diff --git a/src/p_lnspec.h b/src/p_lnspec.h index 9fb4c17b3..3b91298d6 100644 --- a/src/p_lnspec.h +++ b/src/p_lnspec.h @@ -46,13 +46,12 @@ typedef enum { struct FLineSpecial { const char *name; - BYTE number; + int number; SBYTE min_args; SBYTE max_args; BYTE map_args; }; -extern const FLineSpecial *LineSpecialsInfo[256]; typedef enum { Init_Gravity = 0, @@ -195,8 +194,6 @@ typedef int (*lnSpecFunc)(struct line_t *line, int arg4, int arg5); -extern lnSpecFunc LineSpecials[256]; - extern BYTE NamedACSToNormalACS[7]; static inline bool P_IsACSSpecial(int specnum) { @@ -204,6 +201,8 @@ static inline bool P_IsACSSpecial(int specnum) specnum == ACS_ExecuteAlways; } +FLineSpecial *P_GetLineSpecialInfo(int num); +int P_GetMaxLineSpecial(); int P_FindLineSpecial (const char *string, int *min_args=NULL, int *max_args=NULL); bool P_ActivateThingSpecial(AActor * thing, AActor * trigger, bool death=false); int P_ExecuteSpecial(int num, diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 67f7d1685..d7307b794 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -6480,6 +6480,8 @@ void PrintMiscActorInfo(AActor *query) "OptFuzzy", "Stencil", "Translucent", "Add", "Shaded", "TranslucentStencil", "Shadow", "Subtract", "AddStencil", "AddShaded"}; + FLineSpecial *spec = P_GetLineSpecialInfo(query->special); + Printf("%s @ %p has the following flags:\n flags: %x", query->GetTag(), query, query->flags.GetValue()); for (flagi = 0; flagi <= 31; flagi++) if (query->flags & ActorFlags::FromInt(1<renderflags & 1<special ? LineSpecialsInfo[query->special]->name : "None"), + (spec ? spec->name : "None"), query->args[0], query->args[1], query->args[2], query->args[3], query->args[4], query->special1, query->special2); Printf("\nTID: %d", query->tid); diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 0dcf5124a..0a2891faf 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -1177,7 +1177,7 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers) break; case dSector_DoorCloseIn30: - P_SpawnDoorCloseIn30 (sector); + new DDoor(sector, DDoor::doorWaitClose, FRACUNIT * 2, 0, 0, 30 * TICRATE); break; case dDamage_End: @@ -1193,7 +1193,7 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers) break; case dSector_DoorRaiseIn5Mins: - P_SpawnDoorRaiseIn5Mins (sector); + new DDoor (sector, DDoor::doorWaitRaise, 2*FRACUNIT, TICRATE*30/7, 5*60*FRACUNIT, 0); break; case dFriction_Low: @@ -1769,15 +1769,16 @@ static void P_SpawnScrollers(void) // Check for undefined parameters that are non-zero and output messages for them. // We don't report for specials we don't understand. - if (special != 0) + FLineSpecial *spec = P_GetLineSpecialInfo(special); + if (spec != NULL) { - int max = LineSpecialsInfo[special] != NULL ? LineSpecialsInfo[special]->map_args : countof(l->args); + int max = spec->map_args; for (unsigned arg = max; arg < countof(l->args); ++arg) { if (l->args[arg] != 0) { Printf("Line %d (type %d:%s), arg %u is %d (should be 0)\n", - i, special, LineSpecialsInfo[special]->name, arg+1, l->args[arg]); + i, special, spec->name, arg+1, l->args[arg]); } } } diff --git a/src/p_spec.h b/src/p_spec.h index 2f99e4889..0c9454e49 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -529,12 +529,13 @@ public: doorClose, doorOpen, doorRaise, - doorRaiseIn5Mins, + doorWaitRaise, doorCloseWaitOpen, + doorWaitClose, }; DDoor (sector_t *sector); - DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int lightTag); + DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int topcountdown, int lightTag); void Serialize (FArchive &arc); void Tick (); @@ -560,9 +561,7 @@ protected: friend bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, int tag, int speed, int delay, int lock, - int lightTag, bool boomgen); - friend void P_SpawnDoorCloseIn30 (sector_t *sec); - friend void P_SpawnDoorRaiseIn5Mins (sector_t *sec); + int lightTag, bool boomgen, int topcountdown); private: DDoor (); @@ -570,9 +569,7 @@ private: bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, int tag, int speed, int delay, int lock, - int lightTag, bool boomgen = false); -void P_SpawnDoorCloseIn30 (sector_t *sec); -void P_SpawnDoorRaiseIn5Mins (sector_t *sec); + int lightTag, bool boomgen = false, int topcountdown = 0); class DAnimatedDoor : public DMovingCeiling { @@ -731,7 +728,7 @@ public: floorLowerToLowestCeiling, floorLowerByTexture, floorLowerToCeiling, - + donutRaise, buildStair, @@ -751,6 +748,12 @@ public: buildDown }; + enum EStairType + { + stairUseSpecials = 1, + stairSync = 2 + }; + DFloor (sector_t *sec); void Serialize (FArchive &arc); diff --git a/src/version.h b/src/version.h index b8c4facb0..86e3698c8 100644 --- a/src/version.h +++ b/src/version.h @@ -51,7 +51,7 @@ const char *GetVersionString(); // Version identifier for network games. // Bump it every time you do a release unless you're certain you // didn't change anything that will affect sync. -#define NETGAMEVERSION 231 +#define NETGAMEVERSION 232 // Version stored in the ini's [LastRun] section. // Bump it if you made some configuration change that you want to @@ -61,11 +61,11 @@ const char *GetVersionString(); // Protocol version used in demos. // Bump it if you change existing DEM_ commands or add new ones. // Otherwise, it should be safe to leave it alone. -#define DEMOGAMEVERSION 0x21C +#define DEMOGAMEVERSION 0x21D // Minimum demo version we can play. // Bump it whenever you change or remove existing DEM_ commands. -#define MINDEMOVERSION 0x21C +#define MINDEMOVERSION 0x21D // SAVEVER is the version of the information stored in level snapshots. // Note that SAVEVER is not directly comparable to VERSION.