From 974c099e8a1d96985a9b2518e0d82350df589880 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 12 Dec 2021 07:02:17 +0100 Subject: [PATCH 01/54] Expose blendmodes to UDMF --- extras/conf/udb/Includes/Kart2_common.cfg | 4 ++-- extras/conf/udb/Includes/Kart2_misc.cfg | 9 ++++++--- src/p_setup.c | 13 +++++++++++++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/extras/conf/udb/Includes/Kart2_common.cfg b/extras/conf/udb/Includes/Kart2_common.cfg index 5b4f645cf..6833f740e 100644 --- a/extras/conf/udb/Includes/Kart2_common.cfg +++ b/extras/conf/udb/Includes/Kart2_common.cfg @@ -139,10 +139,10 @@ mapformat_udmf } // LINEDEF RENDERSTYLES - /*linedefrenderstyles + linedefrenderstyles { include("Kart2_misc.cfg", "linedefrenderstyles"); - }*/ + } // THING FLAGS thingflags diff --git a/extras/conf/udb/Includes/Kart2_misc.cfg b/extras/conf/udb/Includes/Kart2_misc.cfg index 2f93dff72..d8659f4ac 100644 --- a/extras/conf/udb/Includes/Kart2_misc.cfg +++ b/extras/conf/udb/Includes/Kart2_misc.cfg @@ -67,11 +67,14 @@ linedefactivations_udmf nonet = "No Netgame"; } -/*linedefrenderstyles +linedefrenderstyles { translucent = "Translucent"; - fog = "Fog"; -}*/ + add = "Add"; + subtract = "Subtract"; + reversesubtract = "Reverse subtract"; + modulate = "Modulate"; +} sectorflags { diff --git a/src/p_setup.c b/src/p_setup.c index a4f21ee76..aa22f878f 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1526,6 +1526,19 @@ static void ParseTextmapLinedefParameter(UINT32 i, char *param, char *val) lines[i].sidenum[1] = atol(val); else if (fastcmp(param, "alpha")) lines[i].alpha = FLOAT_TO_FIXED(atof(val)); + else if (fastcmp(param, "blendmode") || fastcmp(param, "renderstyle")) + { + if (fastcmp(val, "translucent")) + lines[i].blendmode = AST_COPY; + else if (fastcmp(val, "add")) + lines[i].blendmode = AST_ADD; + else if (fastcmp(val, "subtract")) + lines[i].blendmode = AST_SUBTRACT; + else if (fastcmp(val, "reversesubtract")) + lines[i].blendmode = AST_REVERSESUBTRACT; + else if (fastcmp(val, "modulate")) + lines[i].blendmode = AST_MODULATE; + } else if (fastcmp(param, "executordelay")) lines[i].executordelay = atol(val); From f16c1cd95f9ad7f41492d29332dd428448428da8 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 31 Dec 2021 15:00:27 +0100 Subject: [PATCH 02/54] Turn the fog wall linedef type into a blendmode --- extras/conf/udb/Includes/Kart2_misc.cfg | 1 + src/deh_tables.c | 1 + src/hardware/hw_defs.h | 1 + src/hardware/hw_main.c | 41 ++++++++++----------- src/p_setup.c | 41 +++++++++++++++------ src/r_defs.h | 3 +- src/r_segs.c | 47 ++++++++++--------------- src/r_segs.h | 2 +- 8 files changed, 72 insertions(+), 65 deletions(-) diff --git a/extras/conf/udb/Includes/Kart2_misc.cfg b/extras/conf/udb/Includes/Kart2_misc.cfg index d8659f4ac..f694cc970 100644 --- a/extras/conf/udb/Includes/Kart2_misc.cfg +++ b/extras/conf/udb/Includes/Kart2_misc.cfg @@ -74,6 +74,7 @@ linedefrenderstyles subtract = "Subtract"; reversesubtract = "Reverse subtract"; modulate = "Modulate"; + fog = "Fog"; } sectorflags diff --git a/src/deh_tables.c b/src/deh_tables.c index 2025d4f03..8e2a11517 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -6172,6 +6172,7 @@ struct int_const_s const INT_CONST[] = { {"AST_REVERSESUBTRACT",AST_REVERSESUBTRACT}, {"AST_MODULATE",AST_MODULATE}, {"AST_OVERLAY",AST_OVERLAY}, + {"AST_FOG",AST_FOG}, // Render flags {"RF_HORIZONTALFLIP",RF_HORIZONTALFLIP}, diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 1ba8164a3..74b79c1b5 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -222,6 +222,7 @@ enum EPolyFlags PF_Fog = 0x20000000, // Fog blocks PF_NoAlphaTest = 0x40000000, // Disables alpha testing PF_Blending = (PF_Masked|PF_Translucent|PF_Environment|PF_Additive|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Invert|PF_Fog) & ~PF_NoAlphaTest, + PF_EnvironmentTrans = (PF_Translucent|PF_Additive|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Environment), // other flag bits PF_Occlude = 0x00000100, // Updates the depth buffer diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 91aa8b00e..b9e5e8474 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -503,7 +503,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool lightlevel = HWR_CalcSlopeLight(lightlevel, slope); HWR_Lighting(&Surf, lightlevel, planecolormap); - if (PolyFlags & (PF_Translucent|PF_Additive|PF_Subtractive|PF_Fog)) + if (PolyFlags & PF_EnvironmentTrans) { Surf.PolyColor.s.alpha = (UINT8)alpha; PolyFlags |= PF_Modulated; @@ -932,7 +932,7 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, if (polyflags & PF_Fog) HWR_AddTransparentWall(wallVerts, Surf, texnum, polyflags, true, HWR_CalcWallLight(lightnum, gl_curline), colormap); - else if (polyflags & (PF_Translucent|PF_Additive|PF_Subtractive|PF_Environment)) + else if (polyflags & PF_EnvironmentTrans) HWR_AddTransparentWall(wallVerts, Surf, texnum, polyflags, false, HWR_CalcWallLight(lightnum, gl_curline), colormap); else HWR_ProjectWall(wallVerts, Surf, polyflags, HWR_CalcWallLight(lightnum, gl_curline), colormap); @@ -961,7 +961,7 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, if (polyflags & PF_Fog) HWR_AddTransparentWall(wallVerts, Surf, texnum, polyflags, true, HWR_CalcWallLight(lightnum, gl_curline), colormap); - else if (polyflags & (PF_Translucent|PF_Additive|PF_Subtractive|PF_Environment)) + else if (polyflags & PF_EnvironmentTrans) HWR_AddTransparentWall(wallVerts, Surf, texnum, polyflags, false, HWR_CalcWallLight(lightnum, gl_curline), colormap); else HWR_ProjectWall(wallVerts, Surf, polyflags, HWR_CalcWallLight(lightnum, gl_curline), colormap); @@ -1419,29 +1419,24 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom case 221: case 253: case 256: - blendmode = PF_Translucent; - break; - case 913: - blendmode = PF_Multiplicative; - Surf.PolyColor.s.alpha = 0xff; + if (gl_linedef->blendmode != AST_FOG) + blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), &Surf); + else + blendmode = PF_Translucent; break; default: - { - UINT32 blend = 0; - transnum_t transtable = R_GetLinedefTransTable(gl_linedef); - if (transtable == NUMTRANSMAPS) - transtable = 0; - if (gl_linedef->special == 910 || - P_IsLineTripWire(gl_linedef)) - blend = AST_ADD; - else if (gl_linedef->special == 911) - blend = AST_SUBTRACT; - else if (gl_linedef->special == 912) - blend = AST_REVERSESUBTRACT; - - blendmode = HWR_SurfaceBlend(blend, transtable, &Surf); + if (gl_linedef->blendmode != AST_FOG) + { + if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT) + blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), &Surf); + else + blendmode = HWR_GetBlendModeFlag(gl_linedef->blendmode); + } + else if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT) + blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gl_linedef->alpha), &Surf); + else + blendmode = PF_Masked; break; - } } if (gl_curline->polyseg && gl_curline->polyseg->translucency > 0) diff --git a/src/p_setup.c b/src/p_setup.c index aa22f878f..bd5fa62a8 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1538,6 +1538,8 @@ static void ParseTextmapLinedefParameter(UINT32 i, char *param, char *val) lines[i].blendmode = AST_REVERSESUBTRACT; else if (fastcmp(val, "modulate")) lines[i].blendmode = AST_MODULATE; + if (fastcmp(val, "fog")) + lines[i].blendmode = AST_FOG; } else if (fastcmp(param, "executordelay")) lines[i].executordelay = atol(val); @@ -1939,6 +1941,12 @@ static void P_ProcessLinedefsAfterSidedefs(void) P_CheckLineSideTripWire(ld, 0) || P_CheckLineSideTripWire(ld, 1); + if (ld->tripwire) + { + ld->blendmode = AST_ADD; + ld->alpha = 0; + } + switch (ld->special) { // Compile linedef 'text' from both sidedefs 'text' for appropriate specials. @@ -3279,22 +3287,33 @@ static void P_ConvertBinaryMap(void) lines[i].args[4] |= TMSC_BACKTOFRONTCEILING; lines[i].special = 720; break; - - case 900: //Translucent wall (10%) - case 901: //Translucent wall (20%) - case 902: //Translucent wall (30%) - case 903: //Translucent wall (40%) - case 904: //Translucent wall (50%) - case 905: //Translucent wall (60%) - case 906: //Translucent wall (70%) - case 907: //Translucent wall (80%) - case 908: //Translucent wall (90%) - lines[i].alpha = ((909 - lines[i].special) << FRACBITS)/10; + case 909: //Fog wall + lines[i].blendmode = AST_FOG; break; default: break; } + // Set alpha for translucent walls + if (lines[i].special >= 900 && lines[i].special < 909) + lines[i].alpha = ((909 - lines[i].special) << FRACBITS)/10; + + // Set alpha for additive/subtractive/reverse subtractive walls + if (lines[i].special >= 910 && lines[i].special <= 939) + lines[i].alpha = ((10 - lines[i].special % 10) << FRACBITS)/10; + + if (lines[i].special >= 910 && lines[i].special <= 919) // additive + lines[i].blendmode = AST_ADD; + + if (lines[i].special >= 920 && lines[i].special <= 929) // subtractive + lines[i].blendmode = AST_SUBTRACT; + + if (lines[i].special >= 930 && lines[i].special <= 939) // reverse subtractive + lines[i].blendmode = AST_REVERSESUBTRACT; + + if (lines[i].special == 940) // modulate + lines[i].blendmode = AST_MODULATE; + //Linedef executor delay if (lines[i].special >= 400 && lines[i].special < 500) { diff --git a/src/r_defs.h b/src/r_defs.h index ca2f5152d..6a5de4f41 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -411,6 +411,7 @@ typedef struct line_s // Visual appearance: sidedefs. UINT16 sidenum[2]; // sidenum[1] will be 0xffff if one-sided fixed_t alpha; // translucency + UINT8 blendmode; // blendmode INT32 executordelay; fixed_t bbox[4]; // bounding box for the extent of the linedef @@ -739,7 +740,7 @@ typedef struct #endif // Possible alpha types for a patch. -typedef enum {AST_COPY, AST_TRANSLUCENT, AST_ADD, AST_SUBTRACT, AST_REVERSESUBTRACT, AST_MODULATE, AST_OVERLAY} patchalphastyle_t; +typedef enum {AST_COPY, AST_TRANSLUCENT, AST_ADD, AST_SUBTRACT, AST_REVERSESUBTRACT, AST_MODULATE, AST_OVERLAY, AST_FOG} patchalphastyle_t; typedef enum { diff --git a/src/r_segs.c b/src/r_segs.c index 7f190ea3f..68a58ab7e 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -130,12 +130,15 @@ static void R_Render2sidedMultiPatchColumn(column_t *column, column_t *brightmap } } -transnum_t R_GetLinedefTransTable(line_t *ldef) +transnum_t R_GetLinedefTransTable(fixed_t alpha) { transnum_t transnum = NUMTRANSMAPS; // Send back NUMTRANSMAPS for none - fixed_t alpha = ldef->alpha; + if (alpha > 0 && alpha < FRACUNIT) + { transnum = (20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1); + } + return transnum; } @@ -172,41 +175,27 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) if (!ldef->alpha) return; - transtable = R_GetLinedefTransTable(ldef); - if (ldef->special == 910 || P_IsLineTripWire(ldef)) - { - if (transtable == NUMTRANSMAPS) - transtable = 0; - blendmode = AST_ADD; - } - else if (ldef->special == 911) - { - if (transtable == NUMTRANSMAPS) - transtable = 0; - blendmode = AST_SUBTRACT; - } - else if (ldef->special == 912) - { - if (transtable == NUMTRANSMAPS) - transtable = 0; - blendmode = AST_REVERSESUBTRACT; - } - else if (ldef->special == 913) + transtable = R_GetLinedefTransTable(ldef->alpha); + blendmode = ldef->blendmode; + + if (transtable == NUMTRANSMAPS + || blendmode == AST_MODULATE + || blendmode == AST_FOG) { transtable = 0; - blendmode = AST_MODULATE; } - if (transtable != NUMTRANSMAPS && (blendmode || transtable)) - { - dc_transmap = R_GetBlendTable(blendmode, transtable); - R_SetColumnFunc(COLDRAWFUNC_FUZZY, bmnum != 0); - } - else if (ldef->special == 909) + + if (blendmode == AST_FOG) { R_SetColumnFunc(COLDRAWFUNC_FOG, bmnum != 0); windowtop = frontsector->ceilingheight; windowbottom = frontsector->floorheight; } + else if (transtable != NUMTRANSMAPS && (blendmode || transtable)) + { + dc_transmap = R_GetBlendTable(blendmode, transtable); + R_SetColumnFunc(COLDRAWFUNC_FUZZY, bmnum != 0); + } else { R_SetColumnFunc(BASEDRAWFUNC, bmnum != 0); diff --git a/src/r_segs.h b/src/r_segs.h index 6a79047e0..ace5711d4 100644 --- a/src/r_segs.h +++ b/src/r_segs.h @@ -18,7 +18,7 @@ #pragma interface #endif -transnum_t R_GetLinedefTransTable(line_t *line); +transnum_t R_GetLinedefTransTable(fixed_t alpha); void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2); void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor); void R_StoreWallRange(INT32 start, INT32 stop); From 82c9abfc58d5ffb6c38a2b9ea41b2eca79b64af7 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 9 Jan 2022 13:45:56 +0100 Subject: [PATCH 03/54] Fix blendmode regression in OpenGL caused by faulty fog wall support --- src/hardware/hw_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index b9e5e8474..f9c60f94e 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1419,13 +1419,13 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom case 221: case 253: case 256: - if (gl_linedef->blendmode != AST_FOG) + if (gl_linedef->blendmode && gl_linedef->blendmode != AST_FOG) blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), &Surf); else blendmode = PF_Translucent; break; default: - if (gl_linedef->blendmode != AST_FOG) + if (gl_linedef->blendmode && gl_linedef->blendmode != AST_FOG) { if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT) blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), &Surf); From 5c9599f0a92b4dc3be5cee799a5dda4df11d4d1a Mon Sep 17 00:00:00 2001 From: Nev3r Date: Sun, 1 May 2022 07:36:12 +0000 Subject: [PATCH 04/54] "UDMF: The whole thing" merged See merge request STJr/SRB2!1714 Barely any RR features reimplemented --- extras/conf/D3R-Config.cfg | 119 +- extras/conf/udb/Includes/Kart2_common.cfg | 8 + extras/conf/udb/Includes/Kart2_linedefs.cfg | 2686 ++++- extras/conf/udb/Includes/Kart2_misc.cfg | 221 +- extras/conf/udb/Includes/Kart2_sectors.cfg | 22 +- extras/conf/udb/Includes/Kart2_things.cfg | 10878 +++++++++++++----- extras/conf/udb/Kart2_UDMF.cfg | 6 - src/d_netcmd.c | 2 +- src/deh_lua.c | 75 +- src/deh_tables.c | 111 +- src/deh_tables.h | 6 +- src/doomdata.h | 12 +- src/doomdef.h | 9 +- src/g_demo.c | 2 +- src/hardware/hw_main.c | 87 +- src/info.c | 317 +- src/info.h | 15 +- src/k_bot.c | 4 +- src/k_botsearch.c | 24 +- src/k_brightmap.c | 29 +- src/k_kart.c | 33 +- src/k_race.c | 4 +- src/k_terrain.c | 103 +- src/lua_baselib.c | 72 +- src/lua_maplib.c | 124 +- src/lua_polyobjlib.c | 7 +- src/m_cheat.c | 12 +- src/m_cheat.h | 2 +- src/m_misc.c | 166 +- src/objects/jawz.c | 4 +- src/objects/orbinaut.c | 4 +- src/p_ceilng.c | 489 +- src/p_enemy.c | 608 +- src/p_floor.c | 573 +- src/p_inter.c | 2 +- src/p_lights.c | 114 +- src/p_local.h | 4 +- src/p_map.c | 38 +- src/p_maputl.c | 58 +- src/p_mobj.c | 677 +- src/p_mobj.h | 2 +- src/p_polyobj.c | 38 +- src/p_polyobj.h | 44 +- src/p_saveg.c | 205 +- src/p_setup.c | 3268 +++++- src/p_setup.h | 2 +- src/p_sight.c | 2 +- src/p_slopes.c | 136 +- src/p_slopes.h | 28 +- src/p_spec.c | 5854 +++++----- src/p_spec.h | 550 +- src/p_user.c | 134 +- src/r_bsp.c | 43 +- src/r_defs.h | 122 +- src/r_main.c | 4 +- src/r_plane.c | 2 +- src/r_segs.c | 105 +- src/taglist.c | 48 + src/taglist.h | 5 + 59 files changed, 19323 insertions(+), 8996 deletions(-) diff --git a/extras/conf/D3R-Config.cfg b/extras/conf/D3R-Config.cfg index dac4b0135..0b226309c 100644 --- a/extras/conf/D3R-Config.cfg +++ b/extras/conf/D3R-Config.cfg @@ -448,31 +448,31 @@ sectortypes 6 = "Death Pit (Camera Tilt)"; 7 = "Death Pit (No Camera Tilt)"; 8 = "Instant Kill"; - //9 = "Ring Drainer (Floor Touch)"; - //10 = "Ring Drainer (Anywhere in Sector)"; - //11 = "Special Stage Damage"; + 9 = " Ring Drainer (Floor Touch)"; + 10 = " Ring Drainer (Anywhere in Sector)"; + 11 = " Special Stage Damage"; 12 = "Wall Sector (no step-up/down)"; 13 = "Ramp Sector (double step-up/down)"; 14 = "Non-Ramp Sector (no step-down)"; - 15 = "Bouncy FOF"; + 15 = " Bouncy FOF"; 16 = "Trigger Line Ex. (Pushable Objects)"; 32 = "Trigger Line Ex. (Anywhere, All Players)"; 48 = "Trigger Line Ex. (Floor Touch, All Players)"; 64 = "Trigger Line Ex. (Anywhere in Sector)"; 80 = "Trigger Line Ex. (Floor Touch)"; - //96 = "Trigger Line Ex. (Emerald Check)"; + 96 = " Trigger Line Ex. (Emerald Check)"; 112 = "Trigger Line Ex. (Race Lap)"; 128 = "Check for Linedef Executor on FOFs"; - //144 = "Egg Capsule"; - //160 = "Special Stage Time/Rings Parameters"; - 176 = "Custom Global Gravity"; + 144 = " Egg Capsule"; + 160 = " Special Stage Time/Rings Parameters"; + 176 = " Custom Global Gravity"; 192 = "Invert Encore Remap"; 256 = "Spring Panel"; 512 = "Wind/Current"; 768 = "Spring Panel (Speed Capped)"; 1024 = "Conveyor Belt"; 1280 = "Speed Pad"; - //1536 = "Speed Pad (Spin)"; + 1536 = " Speed Pad (Spin)"; 1792 = "Bustable Block Sprite Parameter (ROIA)"; 2048 = "Bustable Block Sprite Parameter (ROIB)"; 2304 = "Bustable Block Sprite Parameter (ROIC)"; @@ -484,16 +484,16 @@ sectortypes 3840 = "Bustable Block Sprite Parameter (ROII)"; 4096 = "Star Post Activator"; 8192 = "Exit Level"; - //12288 = "CTF Red Team Base"; - //16384 = "CTF Blue Team Base"; + 12288 = " CTF Red Team Base"; + 16384 = " CTF Blue Team Base"; 20480 = "Fan Sector"; 24576 = "Sneaker Panel"; - //28672 = "Force Spin"; + 28672 = " Force Spin"; 32768 = "Zoom Tube Start"; 36864 = "Zoom Tube End"; - 40960 = "Circuit Finish Line (Unused)"; - //45056 = "Rope Hang"; - //49152 = "Intangible to the Camera"; + 40960 = " Circuit Finish Line"; + 45056 = " Rope Hang"; + 49152 = " Intangible to the Camera"; } @@ -511,13 +511,13 @@ gen_sectortypes 6 = "Death Pit (Camera Tilt)"; 7 = "Death Pit (No Camera Tilt)"; 8 = "Instant Kill"; - //9 = "Ring Drainer (Floor Touch)"; - //10 = "Ring Drainer (Anywhere in Sector)"; - //11 = "Special Stage Damage"; + 9 = " Ring Drainer (Floor Touch)"; + 10 = " Ring Drainer (Anywhere in Sector)"; + 11 = " Special Stage Damage"; 12 = "Space Countdown"; 13 = "Ramp Sector (double step-up/down)"; 14 = "Non-Ramp Sector (no step-down)"; - 15 = "Bouncy FOF"; + 15 = " Bouncy FOF"; } second @@ -528,12 +528,12 @@ gen_sectortypes 48 = "Trigger Line Ex. (Floor Touch, All Players)"; 64 = "Trigger Line Ex. (Anywhere in Sector)"; 80 = "Trigger Line Ex. (Floor Touch)"; - 96 = "Trigger Line Ex. (Emerald Check)"; + 96 = " Trigger Line Ex. (Emerald Check)"; 112 = "Trigger Line Ex. (Race Lap)"; 128 = "Check for Linedef Executor on FOFs"; - //144 = "Egg Capsule"; - //160 = "Special Stage Time/Rings Parameters"; - 176 = "Custom Global Gravity"; + 144 = " Egg Capsule"; + 160 = " Special Stage Time/Rings Parameters"; + 176 = " Custom Global Gravity"; 192 = "Invert Encore Remap"; } @@ -545,7 +545,7 @@ gen_sectortypes 768 = "Spring Panel (Speed Capped)"; 1024 = "Conveyor Belt"; 1280 = "Speed Pad"; - //1536 = "Speed Pad (Spin)"; + 1536 = " Speed Pad (Spin)"; 1792 = "Bustable Block Sprite Parameter (ROIA)"; 2048 = "Bustable Block Sprite Parameter (ROIB)"; 2304 = "Bustable Block Sprite Parameter (ROIC)"; @@ -562,16 +562,16 @@ gen_sectortypes 0 = "Normal"; 4096 = "Star Post Activator"; 8192 = "Exit Level"; - //12288 = "CTF Red Team Base"; - //16384 = "CTF Blue Team Base"; + 12288 = " CTF Red Team Base"; + 16384 = " CTF Blue Team Base"; 20480 = "Fan Sector"; 24576 = "Sneaker Panel"; - //28672 = "Force Spin"; + 28672 = " Force Spin"; 32768 = "Zoom Tube Start"; 36864 = "Zoom Tube End"; - 40960 = "Circuit Finish Line (Unused)"; - //45056 = "Rope Hang"; - //49152 = "Intangible to the Camera"; + 40960 = " Circuit Finish Line"; + 45056 = " Rope Hang"; + 49152 = " Intangible to the Camera"; } } @@ -840,9 +840,15 @@ linedeftypes 65 { - title = "Bridge Thinker "; + title = " Bridge Thinker"; prefix = "(65)"; } + + 76 + { + title = "Make FOF Bouncy"; + prefix = "(76)"; + } } polyobject @@ -1284,7 +1290,7 @@ linedeftypes 160 { - title = "Floating, Bobbing"; + title = "Water Bobbing"; prefix = "(160)"; flags32text = "[5] Only block player"; flags128text = "[7] Only block non-players"; @@ -1782,7 +1788,31 @@ linedeftypes prefix = "(322)"; flags64text = "[6] Trigger more than once"; } - + + 334 + { + title = "Object Dye - Continuous"; + prefix = "(334)"; + flags64text = "[6] Disable for this color"; + flags1024text = "[10] Use faster, unordered execution"; + } + + 335 + { + title = "Object Dye - Each Time"; + prefix = "(335)"; + flags64text = "[6] Disable for this color"; + flags1024text = "[10] Use faster, unordered execution"; + } + + 336 + { + title = "Object Dye - Once"; + prefix = "(336)"; + flags64text = "[6] Disable for this color"; + flags1024text = "[10] Use faster, unordered execution"; + } + 399 { title = "Level Load"; @@ -1812,23 +1842,35 @@ linedeftypes 402 { - title = "Set Tagged Sector's Light Level"; + title = "Copy Light Level to Tagged Sectors"; prefix = "(402)"; flags8text = "[3] Set delay by backside sector"; } + 408 + { + title = "Set Tagged Sector's Flats"; + prefix = "(408)"; + flags64text = "[6] Don't set floor flat"; + flags512text = "[9] Don't set ceiling flat"; + } + 409 { title = "Change Tagged Sector's Tag"; prefix = "(409)"; + flags2text = "[1] Remove tag"; flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Add tag"; } 410 { title = "Change Front Sector's Tag"; prefix = "(410)"; + flags2text = "[1] Remove tag"; flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Add tag"; } 416 @@ -1883,6 +1925,14 @@ linedeftypes prefix = "(435)"; flags8text = "[3] Set delay by backside sector"; } + + 467 + { + title = "Set Tagged Sector's Light Level"; + prefix = "(467)"; + flags8text = "[3] Set delay by backside sector"; + flags256text = "[8] Set relative to current"; + } } linedefexecplane @@ -2890,6 +2940,7 @@ linedeftypes { title = "Set Tagged Dynamic Slope Vertex to Front Sector Height"; prefix = "(799)"; + flags64text = "[6] Use relative heights"; } } diff --git a/extras/conf/udb/Includes/Kart2_common.cfg b/extras/conf/udb/Includes/Kart2_common.cfg index 6833f740e..67071c33c 100644 --- a/extras/conf/udb/Includes/Kart2_common.cfg +++ b/extras/conf/udb/Includes/Kart2_common.cfg @@ -115,6 +115,8 @@ mapformat_udmf include("Kart2_misc.cfg", "sectorbrightness"); } + damagetypes = "Generic Water Fire Lava Electric Spike DeathPitTilt DeathPitNoTilt Instakill SpecialStage"; + // SECTOR TYPES sectortypes { @@ -164,6 +166,12 @@ mapformat_udmf include("UDMF_misc.cfg", "thingflagscompare"); } + // THING TYPES + thingtypes + { + include("Kart2_things.cfg", "udmf"); + } + // LINEDEF TYPES linedeftypes { diff --git a/extras/conf/udb/Includes/Kart2_linedefs.cfg b/extras/conf/udb/Includes/Kart2_linedefs.cfg index 0b92442e6..b845b2830 100644 --- a/extras/conf/udb/Includes/Kart2_linedefs.cfg +++ b/extras/conf/udb/Includes/Kart2_linedefs.cfg @@ -16,7 +16,7 @@ doom } 5 { - title = "Camera Scanner"; + title = " Camera Scanner"; prefix = "(5)"; } 7 @@ -127,7 +127,7 @@ doom } 65 { - title = "Bridge Thinker "; + title = " Bridge Thinker"; prefix = "(65)"; } 76 @@ -148,7 +148,7 @@ doom } 21 { - title = "Explicitly Include Line "; + title = " Explicitly Include Line"; prefix = "(21)"; } 22 @@ -739,6 +739,51 @@ doom title = "Player Skin - Once"; prefix = "(333)"; } + 334 + { + title = "Object Dye - Continuous"; + prefix = "(334)"; + } + 335 + { + title = "Object Dye - Each Time"; + prefix = "(335)"; + } + 336 + { + title = "Object Dye - Once"; + prefix = "(336)"; + } + 337 + { + title = "Emerald Check - Continuous"; + prefix = "(337)"; + } + 338 + { + title = "Emerald Check - Each Time"; + prefix = "(338)"; + } + 339 + { + title = "Emerald Check - Once"; + prefix = "(339)"; + } + 340 + { + title = "NiGHTS Mare - Continuous"; + prefix = "(340)"; + } + 341 + { + title = "NiGHTS Mare - Each Time"; + prefix = "(341)"; + } + 342 + { + title = "NiGHTS Mare - Once"; + prefix = "(342)"; + } 399 { title = "Level Load"; @@ -765,6 +810,11 @@ doom title = "Set Tagged Sector's Light Level"; prefix = "(402)"; } + 408 + { + title = "Set Tagged Sector's Flats"; + prefix = "(408)"; + } 409 { title = "Change Tagged Sector's Tag"; @@ -810,6 +860,11 @@ doom title = "Change Plane Scroller Direction"; prefix = "(435)"; } + 467 + { + title = "Set Tagged Sector's Light Level"; + prefix = "(467)"; + } } linedefexecplane @@ -942,6 +997,21 @@ doom title = "Stop Timer/Exit Stage in Record Attack"; prefix = "(462)"; } + 463 + { + title = "Dye Object"; + prefix = "(463)"; + } + 464 + { + title = "Trigger Egg Capsule"; + prefix = "(464)"; + } + 466 + { + title = "Set Level Failure State"; + prefix = "(466)"; + } } linedefexecmisc @@ -1388,7 +1458,7 @@ doom { title = "Slope Frontside Floor and Backside Ceiling"; prefix = "(703)"; -ยด } + } 704 { title = "Slope Frontside Floor by 3 Tagged Vertex Things"; @@ -1505,6 +1575,161 @@ doom title = "Fog Wall"; prefix = "(909)"; } + 910 + { + title = "100% Additive"; + prefix = "(910)"; + } + 911 + { + title = "90% Additive"; + prefix = "(911)"; + } + 912 + { + title = "80% Additive"; + prefix = "(912)"; + } + 913 + { + title = "70% Additive"; + prefix = "(913)"; + } + 914 + { + title = "60% Additive"; + prefix = "(914)"; + } + 915 + { + title = "50% Additive"; + prefix = "(915)"; + } + 916 + { + title = "40% Additive"; + prefix = "(916)"; + } + 917 + { + title = "30% Additive"; + prefix = "(917)"; + } + 918 + { + title = "20% Additive"; + prefix = "(918)"; + } + 919 + { + title = "10% Additive"; + prefix = "(919)"; + } + 920 + { + title = "100% Subtractive"; + prefix = "(920)"; + } + 921 + { + title = "90% Subtractive"; + prefix = "(921)"; + } + 922 + { + title = "80% Subtractive"; + prefix = "(922)"; + } + 923 + { + title = "70% Subtractive"; + prefix = "(923)"; + } + 924 + { + title = "60% Subtractive"; + prefix = "(924)"; + } + 925 + { + title = "50% Subtractive"; + prefix = "(925)"; + } + 926 + { + title = "40% Subtractive"; + prefix = "(926)"; + } + 927 + { + title = "30% Subtractive"; + prefix = "(927)"; + } + 928 + { + title = "20% Subtractive"; + prefix = "(928)"; + } + 929 + { + title = "10% Subtractive"; + prefix = "(929)"; + } + 930 + { + title = "100% Reverse Subtractive"; + prefix = "(930)"; + } + 931 + { + title = "90% Reverse Subtractive"; + prefix = "(931)"; + } + 932 + { + title = "80% Reverse Subtractive"; + prefix = "(932)"; + } + 933 + { + title = "70% Reverse Subtractive"; + prefix = "(933)"; + } + 934 + { + title = "60% Reverse Subtractive"; + prefix = "(934)"; + } + 935 + { + title = "50% Reverse Subtractive"; + prefix = "(935)"; + } + 936 + { + title = "40% Reverse Subtractive"; + prefix = "(936)"; + } + 937 + { + title = "30% Reverse Subtractive"; + prefix = "(937)"; + } + 938 + { + title = "20% Reverse Subtractive"; + prefix = "(938)"; + } + 939 + { + title = "10% Reverse Subtractive"; + prefix = "(939)"; + } + 940 + { + title = "Modulate"; + prefix = "(940)"; + } } } @@ -1519,6 +1744,248 @@ udmf title = "None"; prefix = "(0)"; } + + 7 + { + title = "Sector Flat Alignment"; + prefix = "(7)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Affected planes"; + type = 11; + enum = "floorceiling"; + default = 2; + } + } + + 10 + { + title = "Culling Plane"; + prefix = "(10)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Culling behavior"; + type = 11; + enum + { + 0 = "Always"; + 1 = "Only while in sector"; + } + } + } + + 40 + { + title = "Visual Portal Between Tagged Linedefs"; + prefix = "(40)"; + } + + 41 + { + title = "Horizon Effect"; + prefix = "(41)"; + } + + 63 + { + title = "Fake Floor/Ceiling Planes"; + prefix = "(63)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + } + } + + parameters + { + title = "Parameters"; + + 2 + { + title = "Custom Exit"; + prefix = "(2)"; + arg0 + { + title = "Next map"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Skip score tally"; + 2 = "Check emeralds"; + } + } + arg2 + { + title = "Next map (all emeralds)"; + } + } + + 3 + { + title = "Zoom Tube Parameters"; + prefix = "(3)"; + arg0 + { + title = "Speed"; + } + arg1 + { + title = "Sequence"; + } + arg2 + { + title = "Check player direction?"; + type = 11; + enum = "yesno"; + } + } + + 4 + { + title = "Speed Pad Parameters"; + prefix = "(4)"; + arg0 + { + title = "Speed"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "No teleport to center"; + 2 = "Force spinning frames"; + } + } + stringarg0 + { + title = "Sound"; + type = 2; + } + } + + 8 + { + title = "Set Camera Collision Planes"; + prefix = "(8)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + } + + 11 + { + title = "Rope Hang Parameters"; + prefix = "(11)"; + arg0 + { + title = "Speed"; + } + arg1 + { + title = "Sequence"; + } + arg2 + { + title = "Loop?"; + type = 11; + enum = "yesno"; + } + } + + 14 + { + title = "Bustable Block Parameters"; + prefix = "(14)"; + arg0 + { + title = "Debris spacing"; + } + arg1 + { + title = "Debris lifetime"; + } + arg2 + { + title = "Launch from center?"; + type = 11; + enum = "noyes"; + } + stringarg0 + { + title = "Debris object type"; + type = 2; + } + } + + 15 + { + title = "Fan Particle Generator Heights"; + prefix = "(15)"; + } + + 16 + { + title = "Minecart Parameters"; + prefix = "(16)"; + arg0 + { + title = "Order"; + } + } + + 64 + { + title = "Continuously Appearing/Disappearing FOF"; + prefix = "(64)"; + arg0 + { + title = "Control linedef tag"; + type = 15; + } + arg1 + { + title = "Control sector tag"; + type = 13; + } + arg2 + { + title = "On time"; + } + arg3 + { + title = "Off time"; + } + arg4 + { + title = "Initial delay"; + } + arg5 + { + title = "Play sound?"; + type = 11; + enum = "yesno"; + } + } } polyobject @@ -1733,12 +2200,6 @@ udmf { title = "Bounce strength"; } - arg2 - { - title = "Dampen?"; - type = 11; - enum = "noyes"; - } } } @@ -2242,61 +2703,619 @@ udmf } } - linedefexecmisc + linedeftrigger { - title = "Linedef Executor (misc.)"; + title = "Linedef Executor Trigger"; - 443 + 300 { - title = "Call Lua Function"; - prefix = "(443)"; - stringarg0 + title = "Basic"; + prefix = "(300)"; + arg0 { - title = "Function name"; - type = 2; + title = "Trigger type"; + type = 11; + enum = "triggertype"; } } - 447 + 303 { - title = "Change Tagged Sector's Colormap"; - prefix = "(447)"; + title = "Ring Count"; + prefix = "(303)"; + arg0 + { + title = "Trigger type"; + type = 11; + enum = "triggertype"; + } + arg1 + { + title = "Rings"; + } + arg2 + { + title = "Comparison"; + type = 11; + enum = "comparison"; + } + arg3 + { + title = "Count all players?"; + type = 11; + enum = "noyes"; + } + } + + 305 + { + title = "Character Ability"; + prefix = "(305)"; + arg0 + { + title = "Trigger type"; + type = 11; + enum = "triggertype"; + } + arg1 + { + title = "Ability"; + type = 11; + enum + { + 0 = "None"; + 1 = "Thok"; + 2 = "Fly"; + 3 = "Glide and climb"; + 4 = "Homing attack"; + 5 = "Swim"; + 6 = "Double jump"; + 7 = "Float"; + 8 = "Float with slow descent"; + 9 = "Telekinesis"; + 10 = "Fall switch"; + 11 = "Jump boost"; + 12 = "Air drill"; + 13 = "Jump-thok"; + 14 = "Pogo bounce"; + 15 = "Twin spin"; + } + } + } + + 308 + { + title = "Gametype"; + prefix = "(308)"; + arg0 + { + title = "Trigger type"; + type = 11; + enum = "triggertype"; + } + arg1 + { + title = "Rules"; + type = 12; + enum + { + 1 = "Campaign"; + 2 = "Ringslinger"; + 4 = "Spectators"; + 8 = "Lives"; + 16 = "Teams"; + 32 = "First person"; + 64 = "Match emeralds"; + 128 = "Team flags"; + 256 = "Coop"; + 512 = "Allow special stages"; + 1024 = "Spawn emerald tokens"; + 2048 = "Emerald hunt"; + 4096 = "Race"; + 8192 = "Tag"; + 16384 = "Point limit"; + 32768 = "Time limit"; + 65536 = "Overtime"; + 131072 = "Hurt messages"; + 262144 = "Friendly fire"; + 524288 = "Hide time countdown"; + 1048576 = "Frozen after hide time"; + 2097152 = "Blindfolded view"; + 4194304 = "Respawn delay"; + 8388608 = "Award pity shield"; + 16777216 = "Death score penalty"; + 33554432 = "No spectator spawn"; + 67108864 = "Use match starts"; + 134217728 = "Spawn invincibility"; + 268435456 = "Allow enemies"; + 536870912 = "Allow exit sectors"; + 1073741824 = "No title card"; + 2147483648 = "Allow cutscenes"; + } + } + arg2 + { + title = "Check if"; + type = 11; + enum = "flagcheck"; + } + } + + 309 + { + title = "CTF Team"; + prefix = "(309)"; + arg0 + { + title = "Trigger type"; + type = 11; + enum = "triggertype"; + } + arg1 + { + title = "Team"; + type = 11; + enum = "team"; + } + } + + 313 + { + title = "No More Enemies"; + prefix = "(313)"; arg0 { title = "Target sector tag"; type = 13; } + } + + 314 + { + title = "Number of Pushables"; + prefix = "(314)"; + arg0 + { + title = "Trigger type"; + type = 11; + enum = "triggertype"; + } arg1 { - title = "Colormap sector tag"; - type = 13; + title = "Pushables"; } arg2 + { + title = "Comparison"; + type = 11; + enum = "comparison"; + } + } + + 317 + { + title = "Condition Set Trigger"; + prefix = "(317)"; + arg0 + { + title = "Trigger type"; + type = 11; + enum = "triggertype"; + } + arg1 + { + title = "Trigger ID"; + } + } + + 319 + { + title = "Unlockable"; + prefix = "(319)"; + arg0 + { + title = "Trigger type"; + type = 11; + enum = "triggertype"; + } + arg1 + { + title = "Unlockable ID"; + } + } + + 321 + { + title = "Trigger After X Calls"; + prefix = "(321)"; + arg0 + { + title = "Trigger type"; + type = 11; + enum = "xtriggertype"; + } + arg1 + { + title = "Calls"; + } + arg2 + { + title = "Can retrigger?"; + type = 11; + enum = "noyes"; + } + arg3 + { + title = "Starting calls"; + } + } + + 323 + { + title = "NiGHTSerize"; + prefix = "(323)"; + arg0 + { + title = "Trigger type"; + type = 11; + enum + { + 0 = "Each time"; + 1 = "Once"; + } + } + arg1 + { + title = "Mare number"; + } + arg2 + { + title = "Lap number"; + } + arg3 + { + title = "Mare comparison"; + type = 11; + enum = "comparison"; + } + arg4 + { + title = "Lap comparison"; + type = 11; + enum = "comparison"; + } + arg5 + { + title = "Compared player"; + type = 11; + enum + { + 0 = "Fastest"; + 1 = "Slowest"; + 2 = "Triggerer"; + } + } + arg6 + { + title = "NiGHTS check"; + type = 11; + enum + { + 0 = "No check"; + 1 = "Trigger if player was not NiGHTS"; + 2 = "Trigger if player was already NiGHTS"; + } + } + arg7 { title = "Flags"; type = 12; enum { - 1 = "Add to existing colormap"; - 2 = "Subtract light R"; - 4 = "Subtract light G"; - 8 = "Subtract light B"; - 16 = "Subtract light A"; - 32 = "Subtract fade R"; - 64 = "Subtract fade G"; - 128 = "Subtract fade B"; - 256 = "Subtract fade A"; - 512 = "Subtract fadestart"; - 1024 = "Subtract fadeend"; - 2048 = "Ignore flags"; + 1 = "Only count bonus time laps"; + 2 = "Only trigger if final mare completed"; + } + } + } + 325 + { + title = "De-NiGHTSerize"; + prefix = "(325)"; + arg0 + { + title = "Trigger type"; + type = 11; + enum + { + 0 = "Each time"; + 1 = "Once"; + } + } + arg1 + { + title = "Mare number"; + } + arg2 + { + title = "Lap number"; + } + arg3 + { + title = "Mare comparison"; + type = 11; + enum = "comparison"; + } + arg4 + { + title = "Lap comparison"; + type = 11; + enum = "comparison"; + } + arg5 + { + title = "Compared player"; + type = 11; + enum + { + 0 = "Fastest"; + 1 = "Slowest"; + 2 = "Triggerer"; + } + } + arg6 + { + title = "NiGHTS check"; + type = 11; + enum + { + 0 = "No check"; + 1 = "Trigger if nobody is now NiGHTS"; + 2 = "Trigger if somebody is still NiGHTS"; + } + } + arg7 + { + title = "Only bonus laps?"; + type = 11; + enum = "noyes"; + } + } + 327 + { + title = "NiGHTS Lap"; + prefix = "(327)"; + arg0 + { + title = "Trigger type"; + type = 11; + enum + { + 0 = "Each time"; + 1 = "Once"; + } + } + arg1 + { + title = "Mare number"; + } + arg2 + { + title = "Lap number"; + } + arg3 + { + title = "Mare comparison"; + type = 11; + enum = "comparison"; + } + arg4 + { + title = "Lap comparison"; + type = 11; + enum = "comparison"; + } + arg5 + { + title = "Compared player"; + type = 11; + enum + { + 0 = "Fastest"; + 1 = "Slowest"; + 2 = "Triggerer"; + } + } + arg6 + { + title = "Only bonus laps?"; + type = 11; + enum = "noyes"; + } + } + 329 + { + title = "Ideya Capture Touch"; + prefix = "(329)"; + arg0 + { + title = "Trigger type"; + type = 11; + enum + { + 0 = "Each time"; + 1 = "Once"; + } + } + arg1 + { + title = "Mare number"; + } + arg2 + { + title = "Lap number"; + } + arg3 + { + title = "Mare comparison"; + type = 11; + enum = "comparison"; + } + arg4 + { + title = "Lap comparison"; + type = 11; + enum = "comparison"; + } + arg5 + { + title = "Compared player"; + type = 11; + enum + { + 0 = "Fastest"; + 1 = "Slowest"; + 2 = "Triggerer"; + } + } + arg6 + { + title = "Spheres check"; + type = 11; + enum + { + 0 = "Trigger if enough spheres"; + 1 = "Trigger if not enough spheres"; + 2 = "Trigger regardless of spheres"; + } + } + arg7 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Only count bonus time laps"; + 2 = "Trigger upon entering Ideya Capture"; } } } - 455 + 331 { - title = "Fade Tagged Sector's Colormap"; - prefix = "(455)"; + title = "Player Skin"; + prefix = "(331)"; + arg0 + { + title = "Trigger type"; + type = 11; + enum = "triggertype"; + } + arg1 + { + title = "Invert choice?"; + type = 11; + enum = "noyes"; + } + stringarg0 + { + title = "Skin name"; + type = 2; + } + } + + 334 + { + title = "Object Dye"; + prefix = "(334)"; + arg0 + { + title = "Trigger type"; + type = 11; + enum = "triggertype"; + } + arg1 + { + title = "Invert choice?"; + type = 11; + enum = "noyes"; + } + stringarg0 + { + title = "Color"; + type = 2; + } + } + + 337 + { + title = "Emerald Check"; + prefix = "(337)"; + arg0 + { + title = "Trigger type"; + type = 11; + enum = "triggertype"; + } + arg1 + { + title = "Emeralds"; + type = 12; + enum + { + 1 = "Emerald 1"; + 2 = "Emerald 2"; + 4 = "Emerald 3"; + 8 = "Emerald 4"; + 16 = "Emerald 5"; + 32 = "Emerald 6"; + 64 = "Emerald 7"; + } + } + arg2 + { + title = "Check if"; + type = 11; + enum = "flagcheck"; + } + } + + 340 + { + title = "NiGHTS Mare"; + prefix = "(340)"; + arg0 + { + title = "Trigger type"; + type = 11; + enum = "triggertype"; + } + arg1 + { + title = "Mare"; + } + arg2 + { + title = "Comparison"; + type = 11; + enum = "comparison"; + } + } + + 399 + { + title = "Level Load"; + prefix = "(399)"; + } + } + + linedefexecsector + { + title = "Linedef Executor (sector)"; + + 400 + { + title = "Set Tagged Sector's Heights/Textures"; + prefix = "(400)"; arg0 { title = "Target sector tag"; @@ -2304,12 +3323,217 @@ udmf } arg1 { - title = "Colormap sector tag"; + title = "Affected planes"; + type = 11; + enum = "floorceiling"; + } + arg2 + { + title = "Set flats?"; + type = 11; + enum = "noyes"; + } + } + + 402 + { + title = "Copy Light Level to Tagged Sectors"; + prefix = "(402)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Don't copy main light level"; + 2 = "Don't copy floor light level"; + 4 = "Don't copy ceiling light level"; + } + } + } + + 408 + { + title = "Set Tagged Sector's Flats"; + prefix = "(408)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Affected planes"; + type = 11; + enum = "floorceiling"; + } + } + + 409 + { + title = "Change Tagged Sector's Tag"; + prefix = "(409)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Tag"; type = 13; } arg2 { - title = "Fade duration"; + title = "Behavior"; + type = 11; + enum + { + 0 = "Add tag"; + 1 = "Remove tag"; + 2 = "Replace first tag"; + } + } + } + + 410 + { + title = "Change Front Sector's Tag"; + prefix = "(410)"; + arg0 + { + title = "Tag"; + type = 13; + } + arg1 + { + title = "Behavior"; + type = 11; + enum + { + 0 = "Add tag"; + 1 = "Remove tag"; + 2 = "Replace first tag"; + } + } + } + + 416 + { + title = "Start Adjustable Flickering Light"; + prefix = "(416)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Speed"; + } + arg2 + { + title = "Brightness 1"; + } + arg3 + { + title = "Use target brightness?"; + type = 11; + enum = "noyes"; + } + arg4 + { + title = "Brightness 2"; + } + } + + 417 + { + title = "Start Adjustable Pulsating Light"; + prefix = "(417)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Speed"; + } + arg2 + { + title = "Brightness 1"; + } + arg3 + { + title = "Use target brightness?"; + type = 11; + enum = "noyes"; + } + arg4 + { + title = "Brightness 2"; + } + } + + 418 + { + title = "Start Adjustable Blinking Light"; + prefix = "(418)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Brightness 1 tics"; + } + arg2 + { + title = "Brightness 2 tics"; + } + arg3 + { + title = "Brightness 1"; + } + arg4 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Use target brightness"; + 2 = "Synchronized"; + } + } + arg5 + { + title = "Brightness 2"; + } + } + + 420 + { + title = "Fade Light Level"; + prefix = "(420)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Destination light level"; + } + arg2 + { + title = "Fading speed"; } arg3 { @@ -2317,28 +3541,17 @@ udmf type = 12; enum { - 1 = "Add to existing colormap"; - 2 = "Subtract light R"; - 4 = "Subtract light G"; - 8 = "Subtract light B"; - 16 = "Subtract light A"; - 32 = "Subtract fade R"; - 64 = "Subtract fade G"; - 128 = "Subtract fade B"; - 256 = "Subtract fade A"; - 512 = "Subtract fadestart"; - 1024 = "Subtract fadeend"; - 2048 = "Ignore flags"; - 4096 = "Fade from invisible black"; - 8192 = "Interrupt ongoing fades"; + 1 = "Add to current light level"; + 2 = "Interrupt ongoing fades"; + 4 = "Speed is duration"; } } } - 456 + 421 { - title = "Stop Fading Tagged Sector's Colormap"; - prefix = "(456)"; + title = "Stop Lighting Effect"; + prefix = "(421)"; arg0 { title = "Target sector tag"; @@ -2346,10 +3559,1143 @@ udmf } } - 465 + 435 { - title = "Set Linedef Executor Delay"; - prefix = "(465)"; + title = "Change Plane Scroller Direction"; + prefix = "(435)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Speed"; + } + } + + 467 + { + title = "Set Tagged Sector's Light Level"; + prefix = "(467)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Light level"; + } + arg2 + { + title = "Affected area"; + type = 11; + enum + { + 0 = "Sector"; + 1 = "Floor"; + 2 = "Ceiling"; + } + } + arg3 + { + title = "Set/Add?"; + type = 11; + enum = "setadd"; + } + } + + 469 + { + title = "Change Tagged Sector's Gravity"; + prefix = "(469)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Set/Multiply?"; + type = 11; + enum + { + 0 = "Set"; + 1 = "Multiply"; + } + } + arg2 + { + title = "Flip flag"; + type = 11; + enum + { + 0 = "Don't change"; + 1 = "Set"; + 2 = "Remove"; + } + } + stringarg0 + { + title = "Gravity value"; + type = 2; + } + } + } + + linedefexecplane + { + title = "Linedef Executor (plane movement)"; + + 403 + { + title = "Move Tagged Sector's Planes"; + prefix = "(403)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Affected planes"; + type = 11; + enum = "floorceiling"; + } + arg2 + { + title = "Speed"; + } + arg3 + { + title = "Linedef executor tag"; + type = 15; + } + arg4 + { + title = "Set flats?"; + type = 11; + enum = "noyes"; + } + } + + 405 + { + title = "Move Planes by Distance"; + prefix = "(405)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Affected planes"; + type = 11; + enum = "floorceiling"; + } + arg2 + { + title = "Distance"; + } + arg3 + { + title = "Speed"; + } + arg4 + { + title = "Instant?"; + type = 11; + enum = "noyes"; + } + } + + 411 + { + title = "Stop Plane Movement"; + prefix = "(411)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + } + + 428 + { + title = "Start Platform Movement"; + prefix = "(428)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Speed"; + } + arg2 + { + title = "Starting delay"; + } + arg3 + { + title = "Delay before flip"; + } + arg4 + { + title = "Starting direction"; + type = 11; + enum + { + 0 = "Down"; + 1 = "Up"; + } + } + } + + 429 + { + title = "Crush Planes Once"; + prefix = "(429)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Affected planes"; + type = 11; + enum = "floorceiling"; + } + arg2 + { + title = "Crush speed"; + } + arg3 + { + title = "Retract speed"; + } + } + } + + linedefexecplayer + { + title = "Linedef Executor (player/object)"; + + 412 + { + title = "Teleporter"; + prefix = "(412)"; + arg0 + { + title = "Destination tag"; + type = 14; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Silent"; + 2 = "Keep angle"; + 4 = "Keep momentum"; + 8 = "Relative silent"; + } + } + arg2 + { + title = "X offset"; + } + arg3 + { + title = "Y offset"; + } + arg4 + { + title = "Z offset"; + } + } + + 425 + { + title = "Change Object State"; + prefix = "(425)"; + stringarg0 + { + title = "State"; + type = 2; + } + } + + 426 + { + title = "Stop Object"; + prefix = "(426)"; + arg0 + { + title = "Move to center?"; + type = 11; + enum = "noyes"; + } + } + + 427 + { + title = "Award Score"; + prefix = "(427)"; + arg0 + { + title = "Score"; + } + } + + 432 + { + title = "Enable/Disable 2D Mode"; + prefix = "(432)"; + arg0 + { + title = "Mode"; + type = 11; + enum + { + 0 = "2D"; + 1 = "3D"; + } + } + } + + 433 + { + title = "Enable/Disable Gravity Flip"; + prefix = "(433)"; + arg0 + { + title = "Gravity"; + type = 11; + enum + { + 0 = "Reverse"; + 1 = "Normal"; + } + } + } + + 434 + { + title = "Award Power-Up"; + prefix = "(434)"; + stringarg0 + { + title = "Power"; + type = 2; + } + stringarg1 + { + title = "Duration/Amount"; + type = 2; + } + } + + 437 + { + title = "Disable Player Control"; + prefix = "(437)"; + arg0 + { + title = "Time"; + } + arg1 + { + title = "Allow jumping?"; + type = 11; + enum = "noyes"; + } + } + + 438 + { + title = "Change Object Size"; + prefix = "(438)"; + arg0 + { + title = "Size (%)"; + default = 100; + } + } + + 442 + { + title = "Change Object Type State"; + prefix = "(442)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Change to"; + type = 11; + enum + { + 0 = "Specified state"; + 1 = "Next state"; + } + } + stringarg0 + { + title = "Object type"; + type = 2; + } + stringarg1 + { + title = "State"; + type = 2; + } + } + + 457 + { + title = "Track Object's Angle"; + prefix = "(457)"; + arg0 + { + title = "Anchor tag"; + type = 14; + } + arg1 + { + title = "Angle tolerance"; + type = 8; + } + arg2 + { + title = "Time tolerance"; + } + arg3 + { + title = "Trigger linedef tag"; + type = 15; + } + arg4 + { + title = "Track after failure?"; + type = 11; + enum = "noyes"; + } + } + + 458 + { + title = "Stop Tracking Object's Angle"; + prefix = "(458)"; + } + + 460 + { + title = "Award Rings"; + prefix = "(460)"; + arg0 + { + title = "Rings"; + } + arg1 + { + title = "Periodicity"; + } + } + + 461 + { + title = "Spawn Object"; + prefix = "(461)"; + arg0 + { + title = "X position"; + } + arg1 + { + title = "Y position"; + } + arg2 + { + title = "Z position"; + } + arg3 + { + title = "Angle"; + type = 8; + } + arg4 + { + title = "Randomize position?"; + type = 11; + enum = "noyes"; + } + arg5 + { + title = "Max X position"; + } + arg6 + { + title = "Max Y position"; + } + arg7 + { + title = "Max Z position"; + } + stringarg0 + { + title = "Object type"; + type = 2; + } + } + + 462 + { + title = "Stop Timer/Exit Stage in Record Attack"; + prefix = "(462)"; + } + + 463 + { + title = "Dye Object"; + prefix = "(463)"; + stringarg0 + { + title = "Skin color"; + type = 2; + } + } + + 464 + { + title = "Trigger Egg Capsule"; + prefix = "(464)"; + arg0 + { + title = "Egg Capsule tag"; + type = 14; + } + arg1 + { + title = "End level?"; + type = 11; + enum = "yesno"; + } + } + + 466 + { + title = "Set Level Failure State"; + prefix = "(466)"; + arg0 + { + title = "State"; + type = 11; + enum + { + 0 = "Failure"; + 1 = "Success"; + } + } + } + } + + linedefexecplayer + { + title = "Linedef Executor (player/object)"; + + 412 + { + title = "Teleporter"; + prefix = "(412)"; + arg0 + { + title = "Destination tag"; + type = 14; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Silent"; + 2 = "Keep angle"; + 4 = "Keep momentum"; + 8 = "Relative silent"; + } + } + arg2 + { + title = "X offset"; + } + arg3 + { + title = "Y offset"; + } + arg4 + { + title = "Z offset"; + } + } + + 425 + { + title = "Change Object State"; + prefix = "(425)"; + stringarg0 + { + title = "State"; + type = 2; + } + } + + 426 + { + title = "Stop Object"; + prefix = "(426)"; + arg0 + { + title = "Move to center?"; + type = 11; + enum = "noyes"; + } + } + + 427 + { + title = "Award Score"; + prefix = "(427)"; + arg0 + { + title = "Score"; + } + } + + 432 + { + title = "Enable/Disable 2D Mode"; + prefix = "(432)"; + arg0 + { + title = "Mode"; + type = 11; + enum + { + 0 = "2D"; + 1 = "3D"; + } + } + } + + 433 + { + title = "Enable/Disable Gravity Flip"; + prefix = "(433)"; + arg0 + { + title = "Gravity"; + type = 11; + enum + { + 0 = "Reverse"; + 1 = "Normal"; + } + } + } + + 434 + { + title = "Award Power-Up"; + prefix = "(434)"; + stringarg0 + { + title = "Power"; + type = 2; + } + stringarg1 + { + title = "Duration/Amount"; + type = 2; + } + } + + 437 + { + title = "Disable Player Control"; + prefix = "(437)"; + arg0 + { + title = "Time"; + } + arg1 + { + title = "Allow jumping?"; + type = 11; + enum = "noyes"; + } + } + + 438 + { + title = "Change Object Size"; + prefix = "(438)"; + arg0 + { + title = "Size (%)"; + default = 100; + } + } + + 442 + { + title = "Change Object Type State"; + prefix = "(442)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Change to"; + type = 11; + enum + { + 0 = "Specified state"; + 1 = "Next state"; + } + } + stringarg0 + { + title = "Object type"; + type = 2; + } + stringarg1 + { + title = "State"; + type = 2; + } + } + + 457 + { + title = "Track Object's Angle"; + prefix = "(457)"; + arg0 + { + title = "Anchor tag"; + type = 14; + } + arg1 + { + title = "Angle tolerance"; + type = 8; + } + arg2 + { + title = "Time tolerance"; + } + arg3 + { + title = "Trigger linedef tag"; + type = 15; + } + arg4 + { + title = "Track after failure?"; + type = 11; + enum = "noyes"; + } + } + + 458 + { + title = "Stop Tracking Object's Angle"; + prefix = "(458)"; + } + + 460 + { + title = "Award Rings"; + prefix = "(460)"; + arg0 + { + title = "Rings"; + } + arg1 + { + title = "Periodicity"; + } + } + + 461 + { + title = "Spawn Object"; + prefix = "(461)"; + arg0 + { + title = "X position"; + } + arg1 + { + title = "Y position"; + } + arg2 + { + title = "Z position"; + } + arg3 + { + title = "Angle"; + type = 8; + } + arg4 + { + title = "Randomize position?"; + type = 11; + enum = "noyes"; + } + arg5 + { + title = "Max X position"; + } + arg6 + { + title = "Max Y position"; + } + arg7 + { + title = "Max Z position"; + } + stringarg0 + { + title = "Object type"; + type = 2; + } + } + + 462 + { + title = "Stop Timer/Exit Stage in Record Attack"; + prefix = "(462)"; + } + + 463 + { + title = "Dye Object"; + prefix = "(463)"; + stringarg0 + { + title = "Skin color"; + type = 2; + } + } + + 464 + { + title = "Trigger Egg Capsule"; + prefix = "(464)"; + arg0 + { + title = "Egg Capsule tag"; + type = 14; + } + arg1 + { + title = "End level?"; + type = 11; + enum = "yesno"; + } + } + + 466 + { + title = "Set Level Failure State"; + prefix = "(466)"; + arg0 + { + title = "State"; + type = 11; + enum + { + 0 = "Failure"; + 1 = "Success"; + } + } + } + } + + linedefexecpoly + { + title = "Linedef Executor (polyobject)"; + + 480 + { + title = "Door Slide"; + prefix = "(480)"; + arg0 + { + title = "PolyObject ID"; + type = 14; + } + arg1 + { + title = "Speed"; + } + arg2 + { + title = "Distance"; + } + arg3 + { + title = "Return delay"; + } + } + + 481 + { + title = "Door Swing"; + prefix = "(481)"; + arg0 + { + title = "PolyObject ID"; + type = 14; + } + arg1 + { + title = "Speed"; + } + arg2 + { + title = "Rotation"; + type = 8; + } + arg3 + { + title = "Return delay"; + } + } + + 482 + { + title = "Move"; + prefix = "(482)"; + arg0 + { + title = "PolyObject ID"; + type = 14; + } + arg1 + { + title = "Speed"; + } + arg2 + { + title = "Distance"; + } + arg3 + { + title = "Override?"; + type = 11; + enum = "noyes"; + } + } + + 484 + { + title = "Rotate"; + prefix = "(484)"; + arg0 + { + title = "PolyObject ID"; + type = 14; + } + arg1 + { + title = "Speed"; + } + arg2 + { + title = "Rotation"; + type = 8; + } + arg3 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Don't turn others"; + 2 = "Turn players"; + 4 = "Continuous rotation"; + 8 = "Override"; + } + } + } + + 488 + { + title = "Move by Waypoints"; + prefix = "(488)"; + arg0 + { + title = "PolyObject ID"; + type = 14; + } + arg1 + { + title = "Speed"; + } + arg2 + { + title = "Waypoint sequence"; + } + arg3 + { + title = "Return behavior"; + type = 11; + enum + { + 0 = "Don't return"; + 1 = "Return to first waypoint"; + 2 = "Repeat sequence in reverse"; + } + } + arg4 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Move in reverse"; + 2 = "Loop movement"; + } + } + } + + 489 + { + title = "Set Visibility, Tangibility"; + prefix = "(489)"; + arg0 + { + title = "PolyObject ID"; + type = 14; + } + arg1 + { + title = "Visibility"; + type = 11; + enum + { + 0 = "No change"; + 1 = "Visible"; + 2 = "Invisible"; + } + } + arg2 + { + title = "Tangibility"; + type = 11; + enum + { + 0 = "No change"; + 1 = "Tangible"; + 2 = "Intangible"; + } + } + } + + 491 + { + title = "Set Translucency"; + prefix = "(491)"; + arg0 + { + title = "PolyObject ID"; + type = 14; + } + arg1 + { + title = "Translucency level"; + } + arg2 + { + title = "Set/Add?"; + type = 11; + enum = "setadd"; + } + } + + 492 + { + title = "Fade Translucency"; + prefix = "(492)"; + arg0 + { + title = "PolyObject ID"; + type = 14; + } + arg1 + { + title = "Translucency level"; + } + arg2 + { + title = "Fading speed"; + } + arg3 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Add to current translucency"; + 2 = "Interrupt ongoing fades"; + 4 = "Speed is duration"; + 8 = "Don't change collision"; + 16 = "No collision during fade"; + } + } + } + } + + scrollpush + { + title = "Scrollers and Pushers"; + + 500 + { + title = "Scroll Walls"; + prefix = "(500)"; + arg0 + { + title = "Side"; + type = 11; + enum = "frontbackboth"; + } + arg1 + { + title = "Horizontal speed"; + } + arg2 + { + title = "Vertical speed"; + } + } + + 502 + { + title = "Scroll Walls Remotely"; + prefix = "(502)"; arg0 { title = "Linedef tag"; @@ -2357,16 +4703,98 @@ udmf } arg1 { - title = "Value"; + title = "Side"; + type = 11; + enum = "frontbackboth"; } arg2 { - title = "Set/add?"; + title = "Horizontal speed"; + } + arg3 + { + title = "Vertical speed"; + } + arg4 + { + title = "Type"; + type = 11; + enum = "scrolltype"; + } + } + + 510 + { + title = "Scroll Planes"; + prefix = "(510)"; + arg0 + { + title = "Sector tag"; + type = 13; + } + arg1 + { + title = "Affected planes"; + type = 11; + enum = "floorceiling"; + } + arg2 + { + title = "Scroll/Carry?"; + type = 11; + enum = "scrollcarry"; + } + arg3 + { + title = "Base speed"; + } + arg4 + { + title = "Type"; + type = 26; + enum = "scrolltype"; + flags + { + 4 = "Non-exclusive"; + } + } + } + + 541 + { + title = "Wind/Current"; + prefix = "(541)"; + arg0 + { + title = "Sector tag"; + type = 13; + } + arg1 + { + title = "Horizontal speed"; + } + arg2 + { + title = "Vertical speed"; + } + arg3 + { + title = "Type"; type = 11; enum { - 0 = "Set"; - 1 = "Add"; + 0 = "Wind"; + 1 = "Current"; + } + } + arg4 + { + title = "Flags"; + type = 12; + flags + { + 1 = "Slide"; + 2 = "Non-exclusive"; } } } @@ -2374,6 +4802,120 @@ udmf light { + title = "Lighting"; + + 600 + { + title = "Copy Light Level to Tagged Sector's Planes"; + prefix = "(600)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Affected planes"; + type = 11; + enum = "floorceiling"; + } + } + + 602 + { + title = "Adjustable Pulsating Light"; + prefix = "(602)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Speed"; + } + arg2 + { + title = "Brightness 1"; + } + arg3 + { + title = "Use target brightness?"; + type = 11; + enum = "noyes"; + } + arg4 + { + title = "Brightness 2"; + } + } + + 603 + { + title = "Adjustable Flickering Light"; + prefix = "(603)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Speed"; + } + arg2 + { + title = "Brightness 1"; + } + arg3 + { + title = "Use target brightness?"; + type = 11; + enum = "noyes"; + } + arg4 + { + title = "Brightness 2"; + } + } + + 604 + { + title = "Adjustable Blinking Light"; + prefix = "(604)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Brightness 1 tics"; + } + arg2 + { + title = "Brightness 2 tics"; + } + arg3 + { + title = "Brightness 1"; + } + arg4 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Use target brightness"; + 2 = "Synchronized"; + } + } + arg5 + { + title = "Brightness 2"; + } + } + 606 { title = "Copy Colormap"; @@ -2504,5 +5046,21 @@ udmf } } } + + 799 + { + title = "Set Tagged Dynamic Slope Vertex to Front Sector Height"; + prefix = "(799)"; + arg0 + { + title = "Apply height"; + type = 11; + enum + { + 0 = "Absolute"; + 1 = "Relative"; + } + } + } } } diff --git a/extras/conf/udb/Includes/Kart2_misc.cfg b/extras/conf/udb/Includes/Kart2_misc.cfg index f694cc970..8de7cc3ba 100644 --- a/extras/conf/udb/Includes/Kart2_misc.cfg +++ b/extras/conf/udb/Includes/Kart2_misc.cfg @@ -56,7 +56,8 @@ linedefflags_udmf midpeg = "Peg Midtexture"; midsolid = "Solid Midtexture"; wrapmidtex = "Repeat Midtexture"; -// effect6 = "Effect 6"; + netonly = "Netgame Only"; + nonet = "No Netgame"; bouncy = "Bouncy Wall"; transfer = "Transfer Line"; } @@ -82,6 +83,33 @@ sectorflags colormapfog = "Fog Planes in Colormap"; colormapfadesprites = "Fade Fullbright in Colormap"; colormapprotected = "Protected Colormap"; + flipspecial_nofloor = "No Trigger on Floor Touch"; + flipspecial_ceiling = "Trigger on Ceiling Touch"; + triggerspecial_touch = "Trigger on Edge Touch"; + triggerspecial_headbump = "Trigger on Headbump"; + triggerline_plane = "Linedef Trigger Requires Plane Touch"; + triggerline_mobj = "Non-Pushables Can Trigger Linedef"; + invertprecip = "Invert Precipitation"; + gravityflip = "Flip Objects in Reverse Gravity"; + heatwave = "Heat Wave"; + noclipcamera = "Intangible to the Camera"; + outerspace = "Space Countdown"; + doublestepup = "Ramp Sector (double step-up/down)"; + nostepdown = "Non-Ramp Sector (No step-down)"; + speedpad = "Speed Pad"; + starpostactivator = "Star Post Activator"; + exit = "Exit"; + specialstagepit = "Special Stage Pit"; + returnflag = "Return Flag"; + redteambase = "Red Team Base"; + blueteambase = "Blue Team Base"; + fan = "Fan Sector"; + supertransform = "Super Sonic Transform"; + forcespin = "Force Spin"; + zoomtubestart = "Zoom Tube Start"; + zoomtubeend = "Zoom Tube End"; + finishline = "Circuit Finish Line"; + ropehang = "Rope Hang"; } thingflags @@ -95,10 +123,7 @@ thingflags // THING FLAGS thingflags_udmf { - extra = "Extra"; flip = "Flip"; - special = "Special"; - ambush = "Ambush"; } @@ -231,6 +256,30 @@ universalfields type = 3; default = false; } + + friction + { + type = 1; + default = 0.90625; + } + + triggertag + { + type = 15; + default = 0; + } + + triggerer + { + type = 0; + default = 0; + enum + { + 0 = "Player"; + 1 = "All players"; + 2 = "Object"; + } + } } linedef @@ -240,6 +289,26 @@ universalfields type = 0; default = 0; } + arg6 + { + type = 0; + default = 0; + } + arg7 + { + type = 0; + default = 0; + } + arg8 + { + type = 0; + default = 0; + } + arg9 + { + type = 0; + default = 0; + } stringarg0 { type = 2; @@ -268,6 +337,41 @@ universalfields thing { + arg5 + { + type = 0; + default = 0; + } + arg6 + { + type = 0; + default = 0; + } + arg7 + { + type = 0; + default = 0; + } + arg8 + { + type = 0; + default = 0; + } + arg9 + { + type = 0; + default = 0; + } + stringarg0 + { + type = 2; + default = ""; + } + stringarg1 + { + type = 2; + default = ""; + } } } @@ -414,6 +518,12 @@ enums 1 = "Yes"; } + setadd + { + 0 = "Set"; + 1 = "Add"; + } + onoff { 0 = "On"; @@ -445,6 +555,13 @@ enums 2 = "Back"; } + frontbackboth + { + 0 = "Front"; + 1 = "Back"; + 2 = "Front and back"; + } + tangibility { 1 = "Intangible from top"; @@ -452,6 +569,100 @@ enums 4 = "Don't block players"; 8 = "Don't block non-players"; } + + floorceiling + { + 0 = "Floor"; + 1 = "Ceiling"; + 2 = "Both"; + } + + scrollcarry + { + 0 = "Scroll and carry"; + 1 = "Scroll"; + 2 = "Carry"; + } + + scrolltype + { + 0 = "Regular"; + 1 = "Accelerative"; + 2 = "Displacement"; + } + + comparison + { + 0 = "Equal"; + 1 = "Less than or equal"; + 2 = "Greater than or equal"; + } + + triggertype + { + 0 = "Continuous"; + 1 = "Once"; + 2 = "Each time on entry"; + 3 = "Each time on entry/exit"; + } + + xtriggertype + { + 0 = "Continuous"; + 1 = "Each time on entry"; + 2 = "Each time on entry/exit"; + } + + team + { + 0 = "Red"; + 1 = "Blue"; + } + + flagcheck + { + 0 = "Has all"; + 1 = "Has any"; + 2 = "Has exactly"; + 3 = "Doesn't have all"; + 4 = "Doesn't have any"; + } + + maceflags + { + 1 = "Double size"; + 2 = "No sounds"; + 4 = "Player-turnable chain"; + 8 = "Swing instead of spin"; + 16 = "Make chain from end item"; + 32 = "Spawn link at origin"; + 64 = "Clip inside ground"; + 128 = "No distance check"; + } + + pushablebehavior + { + 0 = "Normal"; + 1 = "Slide"; + 2 = "Immovable"; + 3 = "Classic"; + } + + monitorrespawn + { + 0 = "Same item"; + 1 = "Random (Weak)"; + 2 = "Random (Strong)"; + } + + blendmodes + { + 0 = "Translucent"; + 1 = "Add"; + 2 = "Subtract"; + 3 = "Reverse subtract"; + 4 = "Modulate"; + } } //Default things filters @@ -639,4 +850,4 @@ flats start = "F_START"; end = "FF_END"; } -} \ No newline at end of file +} diff --git a/extras/conf/udb/Includes/Kart2_sectors.cfg b/extras/conf/udb/Includes/Kart2_sectors.cfg index aebc8fa29..f9df297e7 100644 --- a/extras/conf/udb/Includes/Kart2_sectors.cfg +++ b/extras/conf/udb/Includes/Kart2_sectors.cfg @@ -15,19 +15,18 @@ sectortypes 12 = "Space Countdown"; 13 = "Ramp Sector (double step-up/down)"; 14 = "Non-Ramp Sector (no step-down)"; + 15 = "Bouncy FOF "; 16 = "Trigger Line Ex. (Pushable Objects)"; 32 = "Trigger Line Ex. (Anywhere, All Players)"; 48 = "Trigger Line Ex. (Floor Touch, All Players)"; 64 = "Trigger Line Ex. (Anywhere in Sector)"; 80 = "Trigger Line Ex. (Floor Touch)"; - 96 = "Trigger Line Ex. (Emerald Check)"; - 112 = "Trigger Line Ex. (NiGHTS Mare)"; + 96 = "Trigger Line Ex. (Emerald Check) "; + 112 = "Trigger Line Ex. (NiGHTS Mare) "; 128 = "Check for Linedef Executor on FOFs"; 144 = "Egg Capsule"; - 160 = "Special Stage Time/Spheres Parameters"; - 176 = "Custom Global Gravity"; - 512 = "Wind/Current"; - 1024 = "Conveyor Belt"; + 160 = "Special Stage Time/Spheres Parameters "; + 176 = "Custom Global Gravity "; 1280 = "Speed Pad"; 4096 = "Star Post Activator"; 8192 = "Exit/Special Stage Pit/Return Flag"; @@ -62,6 +61,7 @@ gen_sectortypes 12 = "Space Countdown"; 13 = "Ramp Sector (double step-up/down)"; 14 = "Non-Ramp Sector (no step-down)"; + 15 = "Bouncy FOF "; } second @@ -72,19 +72,17 @@ gen_sectortypes 48 = "Trigger Line Ex. (Floor Touch, All Players)"; 64 = "Trigger Line Ex. (Anywhere in Sector)"; 80 = "Trigger Line Ex. (Floor Touch)"; - 96 = "Trigger Line Ex. (Emerald Check)"; - 112 = "Trigger Line Ex. (NiGHTS Mare)"; + 96 = "Trigger Line Ex. (Emerald Check) "; + 112 = "Trigger Line Ex. (NiGHTS Mare) "; 128 = "Check for Linedef Executor on FOFs"; 144 = "Egg Capsule"; - 160 = "Special Stage Time/Spheres Parameters"; - 176 = "Custom Global Gravity"; + 160 = "Special Stage Time/Spheres Parameters "; + 176 = "Custom Global Gravity "; } third { 0 = "Normal"; - 512 = "Wind/Current"; - 1024 = "Conveyor Belt"; 1280 = "Speed Pad"; } diff --git a/extras/conf/udb/Includes/Kart2_things.cfg b/extras/conf/udb/Includes/Kart2_things.cfg index da7e976d3..d9ac72e14 100644 --- a/extras/conf/udb/Includes/Kart2_things.cfg +++ b/extras/conf/udb/Includes/Kart2_things.cfg @@ -3,3045 +3,8073 @@ // 8-Dark_Gray 9-Blue 10-Green 11-Cyan 12-Red 13-Magenta // 14-Yellow 15-White 16-Pink 17-Orange 18-Gold 19-Cream -editor +doom { - color = 15; // White - arrow = 1; - title = ""; - error = -1; - width = 8; - height = 16; - sort = 1; - - 3328 = "3D Mode Start"; -} - -starts -{ - color = 1; // Blue - arrow = 1; - title = "Player Starts"; - width = 16; - height = 56; - flags8text = "[8] Spawn on ceiling"; - sprite = "SIGNE0"; - - 1 + editor { - title = "Player 01 Start"; - sprite = "SIGNE0"; - } - 2 - { - title = "Player 02 Start"; - sprite = "SIGNE0"; - } - 3 - { - title = "Player 03 Start"; - sprite = "SIGNE0"; - } - 4 - { - title = "Player 04 Start"; - sprite = "SIGNE0"; - } - 5 - { - title = "Player 05 Start"; - sprite = "SIGNE0"; - } - 6 - { - title = "Player 06 Start"; - sprite = "SIGNE0"; - } - 7 - { - title = "Player 07 Start"; - sprite = "SIGNE0"; - } - 8 - { - title = "Player 08 Start"; - sprite = "SIGNE0"; - } - 9 - { - title = "Player 09 Start"; - sprite = "SIGNE0"; - } - 10 - { - title = "Player 10 Start"; - sprite = "SIGNE0"; - } - 11 - { - title = "Player 11 Start"; - sprite = "SIGNE0"; - } - 12 - { - title = "Player 12 Start"; - sprite = "SIGNE0"; - } - 13 - { - title = "Player 13 Start"; - sprite = "SIGNE0"; - } - 14 - { - title = "Player 14 Start"; - sprite = "SIGNE0"; - } - 15 - { - title = "Player 15 Start"; - sprite = "SIGNE0"; - } - 16 - { - title = "Player 16 Start"; - sprite = "SIGNE0"; - } - 33 - { - title = "Match Start"; - sprite = "SUPTG0"; - } - /*34 - { - title = "CTF Red Team Start"; - sprite = "SIGNF0"; - } - 35 - { - title = "CTF Blue Team Start"; - sprite = "SIGND0"; - }*/ -} - -enemies -{ - color = 9; // Light_Blue - arrow = 1; - title = "Enemies"; - width = 24; - height = 32; - sprite = "POSSA1"; - - 100 - { - title = "Crawla (Blue)"; - sprite = "POSSA1"; - } - 101 - { - title = "Crawla (Red)"; - sprite = "SPOSA1"; - } - 102 - { - title = "Stupid Dumb Unnamed RoboFish"; - sprite = "FISHA0"; + color = 15; // White + arrow = 1; + title = ""; + error = -1; width = 8; - height = 28; - angletext = "Jump strength"; + height = 16; + sort = 1; + + 3328 = "3D Mode Start"; } - 103 + + starts { - title = "Buzz (Gold)"; - sprite = "BUZZA1"; - width = 20; - height = 24; - flags8text = "[8] Cannot move"; - } - 104 - { - title = "Buzz (Red)"; - sprite = "RBUZA1"; - width = 20; - height = 24; - flags8text = "[8] Cannot move"; - } - 124 - { - title = "Buzz (Aqua)"; - sprite = "BBUZA1"; - width = 20; - height = 24; - } - 105 - { - title = "Jetty-Syn Bomber"; - sprite = "JETBB1"; - width = 20; - height = 48; - flags8text = "[8] Cannot move"; - } - 106 - { - title = "Jetty-Syn Gunner"; - sprite = "JETGB1"; - width = 20; - height = 48; - flags8text = "[8] Cannot move"; - } - 107 - { - title = "Crawla Commander"; - sprite = "CCOMA1"; + color = 1; // Blue + arrow = 1; + title = "Player Starts"; width = 16; + height = 48; + sprite = "PLAYA0"; + + 1 + { + title = "Player 01 Start"; + sprite = "PLAYA0"; + } + 2 + { + title = "Player 02 Start"; + sprite = "PLAYA0"; + } + 3 + { + title = "Player 03 Start"; + sprite = "PLAYA0"; + } + 4 + { + title = "Player 04 Start"; + sprite = "PLAYA0"; + } + 5 + { + title = "Player 05 Start"; + sprite = "PLAYA0"; + } + 6 + { + title = "Player 06 Start"; + sprite = "PLAYA0"; + } + 7 + { + title = "Player 07 Start"; + sprite = "PLAYA0"; + } + 8 + { + title = "Player 08 Start"; + sprite = "PLAYA0"; + } + 9 + { + title = "Player 09 Start"; + sprite = "PLAYA0"; + } + 10 + { + title = "Player 10 Start"; + sprite = "PLAYA0"; + } + 11 + { + title = "Player 11 Start"; + sprite = "PLAYA0"; + } + 12 + { + title = "Player 12 Start"; + sprite = "PLAYA0"; + } + 13 + { + title = "Player 13 Start"; + sprite = "PLAYA0"; + } + 14 + { + title = "Player 14 Start"; + sprite = "PLAYA0"; + } + 15 + { + title = "Player 15 Start"; + sprite = "PLAYA0"; + } + 16 + { + title = "Player 16 Start"; + sprite = "PLAYA0"; + } + 17 + { + title = "Player 17 Start"; + sprite = "PLAYA0"; + } + 18 + { + title = "Player 18 Start"; + sprite = "PLAYA0"; + } + 19 + { + title = "Player 19 Start"; + sprite = "PLAYA0"; + } + 20 + { + title = "Player 20 Start"; + sprite = "PLAYA0"; + } + 21 + { + title = "Player 21 Start"; + sprite = "PLAYA0"; + } + 22 + { + title = "Player 22 Start"; + sprite = "PLAYA0"; + } + 23 + { + title = "Player 23 Start"; + sprite = "PLAYA0"; + } + 24 + { + title = "Player 24 Start"; + sprite = "PLAYA0"; + } + 25 + { + title = "Player 25 Start"; + sprite = "PLAYA0"; + } + 26 + { + title = "Player 26 Start"; + sprite = "PLAYA0"; + } + 27 + { + title = "Player 27 Start"; + sprite = "PLAYA0"; + } + 28 + { + title = "Player 28 Start"; + sprite = "PLAYA0"; + } + 29 + { + title = "Player 29 Start"; + sprite = "PLAYA0"; + } + 30 + { + title = "Player 30 Start"; + sprite = "PLAYA0"; + } + 31 + { + title = "Player 31 Start"; + sprite = "PLAYA0"; + } + 32 + { + title = "Player 32 Start"; + sprite = "PLAYA0"; + } + 33 + { + title = "Match Start"; + sprite = "NDRNA2A8"; + } + 34 + { + title = "CTF Red Team Start"; + sprite = "SIGNG0"; + } + 35 + { + title = "CTF Blue Team Start"; + sprite = "SIGNE0"; + } } - 108 + + enemies { - title = "Deton"; - sprite = "DETNA1"; - width = 20; + color = 9; // Light_Blue + arrow = 1; + title = "Enemies"; + + 100 + { + title = "Crawla (Blue)"; + sprite = "POSSA1"; + width = 24; + height = 32; + } + 101 + { + title = "Crawla (Red)"; + sprite = "SPOSA1"; + width = 24; + height = 32; + } + 102 + { + title = "Stupid Dumb Unnamed RoboFish"; + sprite = "FISHA0"; + width = 8; + height = 28; + } + 103 + { + title = "Buzz (Gold)"; + sprite = "BUZZA1"; + width = 28; + height = 40; + } + 104 + { + title = "Buzz (Red)"; + sprite = "RBUZA1"; + width = 28; + height = 40; + } + 108 + { + title = "Deton"; + sprite = "DETNA1"; + width = 20; + height = 32; + } + 110 + { + title = "Turret"; + sprite = "TRETA1"; + width = 16; + height = 32; + } + 111 + { + title = "Pop-up Turret"; + sprite = "TURRI1"; + width = 12; + height = 64; + } + 122 + { + title = "Spring Shell (Green)"; + sprite = "SSHLA1"; + width = 24; + height = 40; + } + 125 + { + title = "Spring Shell (Yellow)"; + sprite = "SSHLI1"; + width = 24; + height = 40; + } + 109 + { + title = "Skim"; + sprite = "SKIMA1"; + width = 16; + height = 24; + } + 113 + { + title = "Jet Jaw"; + sprite = "JJAWA3A7"; + width = 12; + height = 20; + } + 126 + { + title = "Crushstacean"; + sprite = "CRABA0"; + width = 24; + height = 32; + } + 138 + { + title = "Banpyura"; + sprite = "CR2BA0"; + width = 24; + height = 32; + } + 117 + { + title = "Robo-Hood"; + sprite = "ARCHA1"; + width = 24; + height = 32; + } + 118 + { + title = "Lance-a-Bot"; + sprite = "CBFSA1"; + width = 32; + height = 72; + } + 1113 + { + title = "Suspicious Lance-a-Bot Statue"; + sprite = "CBBSA1"; + width = 32; + height = 72; + } + 119 + { + title = "Egg Guard"; + sprite = "ESHIA1"; + width = 16; + height = 48; + } + 115 + { + title = "Bird Aircraft Strike Hazard"; + sprite = "VLTRF1"; + width = 12; + height = 24; + } + 120 + { + title = "Green Snapper"; + sprite = "GSNPA1"; + width = 24; + height = 24; + } + 121 + { + title = "Minus"; + sprite = "MNUSA0"; + width = 24; + height = 32; + } + 134 + { + title = "Canarivore"; + sprite = "CANAA0"; + width = 12; + height = 80; + hangs = 1; + } + 123 + { + title = "Unidus"; + sprite = "UNIDA1"; + width = 18; + height = 36; + } + 135 + { + title = "Pterabyte Spawner"; + sprite = "PTERA2A8"; + width = 16; + height = 16; + } + 136 + { + title = "Pyre Fly"; + sprite = "PYREA0"; + width = 24; + height = 34; + } + 137 + { + title = "Dragonbomber"; + sprite = "DRABA1"; + width = 28; + height = 48; + } + 105 + { + title = "Jetty-Syn Bomber"; + sprite = "JETBB1"; + width = 20; + height = 50; + } + 106 + { + title = "Jetty-Syn Gunner"; + sprite = "JETGB1"; + width = 20; + height = 48; + } + 112 + { + title = "Spincushion"; + sprite = "SHRPA1"; + width = 16; + height = 24; + } + 114 + { + title = "Snailer"; + sprite = "SNLRA3A7"; + width = 24; + height = 48; + } + 129 + { + title = "Penguinator"; + sprite = "PENGA1"; + width = 24; + height = 32; + } + 130 + { + title = "Pophat"; + sprite = "POPHA1"; + width = 24; + height = 32; + } + 107 + { + title = "Crawla Commander"; + sprite = "CCOMA1"; + width = 16; + height = 32; + } + 131 + { + title = "Spinbobert"; + sprite = "SBOBB0"; + width = 32; + height = 32; + } + 132 + { + title = "Cacolantern"; + sprite = "CACOA0"; + width = 32; + height = 32; + } + 133 + { + title = "Hangster"; + sprite = "HBATC1"; + width = 24; + height = 24; + hangs = 1; + } + 127 + { + title = "Hive Elemental"; + sprite = "HIVEA0"; + width = 32; + height = 80; + } + 128 + { + title = "Bumblebore"; + sprite = "BUMBA1"; + width = 16; + height = 32; + } + 124 + { + title = "Buggle"; + sprite = "BBUZA1"; + width = 20; + height = 24; + } + 116 + { + title = "Pointy"; + sprite = "PNTYA1"; + width = 8; + height = 16; + } } - 109 + + bosses { - title = "Skim"; - sprite = "SKIMA1"; - width = 16; + color = 8; // Dark_Gray + arrow = 1; + title = "Bosses"; + + 200 + { + title = "Egg Mobile"; + sprite = "EGGMA1"; + width = 24; + height = 76; + } + 201 + { + title = "Egg Slimer"; + sprite = "EGGNA1"; + width = 24; + height = 76; + } + 202 + { + title = "Sea Egg"; + sprite = "EGGOA1"; + width = 32; + height = 116; + } + 203 + { + title = "Egg Colosseum"; + sprite = "EGGPA1"; + width = 24; + height = 76; + } + 204 + { + title = "Fang"; + sprite = "FANGA1"; + width = 24; + height = 60; + } + 206 + { + title = "Brak Eggman (Old)"; + sprite = "BRAKB1"; + width = 48; + height = 160; + } + 207 + { + title = "Metal Sonic (Race)"; + sprite = "METLI1"; + width = 16; + height = 48; + } + 208 + { + title = "Metal Sonic (Battle)"; + sprite = "METLC1"; + width = 16; + height = 48; + } + 209 + { + title = "Brak Eggman"; + sprite = "BRAK01"; + width = 48; + height = 160; + } + 290 + { + arrow = 0; + title = "Boss Escape Point"; + width = 8; + height = 16; + sprite = "internal:eggmanend"; + } + 291 + { + arrow = 0; + title = "Egg Capsule Center"; + width = 8; + height = 16; + sprite = "internal:capsule"; + } + 292 + { + arrow = 0; + title = "Boss Waypoint"; + width = 8; + height = 16; + sprite = "internal:eggmanway"; + } + 293 + { + title = "Metal Sonic Gather Point"; + sprite = "internal:metal"; + width = 8; + height = 16; + } + 294 + { + title = "Fang Waypoint"; + sprite = "internal:eggmanway"; + width = 8; + height = 16; + } + } + + rings + { + color = 14; // Yellow + title = "Rings and Weapon Panels"; + width = 24; height = 24; + sprite = "RINGA0"; + + 300 + { + title = "Ring"; + sprite = "RINGA0"; + width = 16; + } + 301 + { + title = "Bounce Ring"; + sprite = "internal:RNGBA0"; + } + 302 + { + title = "Rail Ring"; + sprite = "internal:RNGRA0"; + } + 303 + { + title = "Infinity Ring"; + sprite = "internal:RNGIA0"; + } + 304 + { + title = "Automatic Ring"; + sprite = "internal:RNGAA0"; + } + 305 + { + title = "Explosion Ring"; + sprite = "internal:RNGEA0"; + } + 306 + { + title = "Scatter Ring"; + sprite = "internal:RNGSA0"; + } + 307 + { + title = "Grenade Ring"; + sprite = "internal:RNGGA0"; + } + 308 + { + title = "CTF Team Ring (Red)"; + sprite = "internal:RRNGA0"; + width = 16; + } + 309 + { + title = "CTF Team Ring (Blue)"; + sprite = "internal:BRNGA0"; + width = 16; + } + 330 + { + title = "Bounce Ring Panel"; + sprite = "internal:PIKBA0"; + } + 331 + { + title = "Rail Ring Panel"; + sprite = "internal:PIKRA0"; + } + 332 + { + title = "Automatic Ring Panel"; + sprite = "internal:PIKAA0"; + } + 333 + { + title = "Explosion Ring Panel"; + sprite = "internal:PIKEA0"; + } + 334 + { + title = "Scatter Ring Panel"; + sprite = "internal:PIKSA0"; + } + 335 + { + title = "Grenade Ring Panel"; + sprite = "internal:PIKGA0"; + } } - 110 + + collectibles { - title = "Turret"; - sprite = "TRETA1"; + color = 10; // Light_Green + title = "Other Collectibles"; width = 16; height = 32; - } - 111 - { - title = "Pop-up Turret"; - sprite = "TURRI1"; - width = 12; - height = 64; - angletext = "Firing delay"; - } - 112 - { - title = "Sharp"; - sprite = "SHRPA1"; - width = 16; - height = 24; - } - 113 - { - title = "Jet Jaw"; - sprite = "JJAWA3A7"; - width = 12; - height = 20; - } - 114 - { - title = "Snailer"; - sprite = "SNLRA3A7"; - height = 48; - } - 115 - { - title = "Bird Aircraft Strike Hazard"; - sprite = "VLTRF1"; - width = 12; - height = 24; - } - 116 - { - title = "Pointy"; - sprite = "PNTYA1"; - width = 8; - height = 16; - } - 117 - { - title = "Robo-Hood"; - sprite = "ARCHA1"; - flags8text = "[8] Cannot jump"; - } - 118 - { - title = "CastleBot FaceStabber"; - sprite = "CBFSA1"; - width = 32; - height = 64; - } - 119 - { - title = "Egg Guard"; - sprite = "ESHIA1"; - width = 16; - height = 48; - flags8text = "[8] Double speed"; - } - 120 - { - title = "Green Snapper"; - sprite = "GSNPA1"; - height = 24; - } - 121 - { - title = "Minus"; - sprite = "MNUSA1"; - } - 122 - { - title = "Spring Shell (Green)"; - sprite = "SSHLA1"; - height = 40; - } - 125 - { - title = "Spring Shell (Yellow)"; - sprite = "SSHLI1"; - height = 40; - } - 123 - { - title = "Unidus"; - sprite = "UNIDA1"; - width = 18; - height = 36; - } -} - -bosses -{ - color = 8; // Dark_Gray - arrow = 1; - title = "Bosses"; - width = 24; - height = 52; - sprite = "EGGMA1"; - - 200 - { - title = "Boss 1 - Egg Mobile"; - sprite = "EGGMA1"; - flags4text = "[4] End level on death"; - flags8text = "[8] Alternate laser attack"; - } - 201 - { - title = "Boss 2 - Egg Slimer"; - sprite = "EGGNA1"; - height = 48; - flags4text = "[4] End level on death"; - flags8text = "[8] Speed up when hit"; - } - 202 - { - title = "Boss 3 - Sea Egg"; - sprite = "EGGOA1"; - width = 32; - height = 80; - flags4text = "[4] End level on death"; - } - 203 - { - title = "Boss 4 - Eggscalibur"; - sprite = "EGGPA1"; - flags4text = "[4] End level on death"; - } - 207 - { - title = "Boss 5A - Metal Sonic (Race)"; - sprite = "METLI1"; - width = 16; - height = 48; - } - 208 - { - title = "Boss 5B - Metal Sonic (Battle)"; - sprite = "METLC1"; - width = 16; - height = 48; - flags4text = "[4] End level on death"; - } - 209 - { - title = "Boss 6 - Brak Eggman"; - sprite = "BRAK[1"; - width = 48; - height = 160; - flags4text = "[4] End level on death"; - flags8text = "[8] Electric barrier"; - } - 206 - { - title = "Boss ? - Brak Eggman (Old)"; - sprite = "BRAKB1"; - width = 48; - height = 160; - flags4text = "[4] End level on death"; - } - 290 - { - arrow = 0; - title = "Boss Escape Point"; - width = 8; - height = 16; - sprite = "internal:eggmanend"; - } - 291 - { - arrow = 0; - title = "Egg Capsule Center"; - width = 8; - height = 16; - sprite = "internal:capsule"; - } - 292 - { - arrow = 0; - title = "Boss Waypoint"; - width = 8; - height = 16; - flags8text = "[8] Sea Egg shooting point"; - sprite = "internal:eggmanway"; - angletext = "No. (Sea Egg)"; - flagsvaluetext = "No. (Brak)"; - parametertext = "Next"; - } - 293 - { - title = "Metal Sonic Gather Point"; - sprite = "internal:metal"; - } -} - -rings -{ - color = 14; // Yellow - title = "Rings and Weapon Panels"; - width = 24; - height = 24; - flags8height = 24; - flags8text = "[8] Float"; - sprite = "RINGA0"; - - 300 - { - title = "Ring"; - sprite = "RINGA0"; - width = 16; - } - 301 - { - title = "Bounce Ring"; - sprite = "internal:RNGBA0"; - } - 302 - { - title = "Rail Ring"; - sprite = "internal:RNGRA0"; - } - 303 - { - title = "Infinity Ring"; - sprite = "internal:RNGIA0"; - } - 304 - { - title = "Automatic Ring"; - sprite = "internal:RNGAA0"; - } - 305 - { - title = "Explosion Ring"; - sprite = "internal:RNGEA0"; - } - 306 - { - title = "Scatter Ring"; - sprite = "internal:RNGSA0"; - } - 307 - { - title = "Grenade Ring"; - sprite = "internal:RNGGA0"; - } - 308 - { - title = "CTF Team Ring (Red)"; - sprite = "internal:RRNGA0"; - width = 16; - } - 309 - { - title = "CTF Team Ring (Blue)"; - sprite = "internal:BRNGA0"; - width = 16; - } - 330 - { - title = "Bounce Ring Panel"; - sprite = "internal:PIKBA0"; - } - 331 - { - title = "Rail Ring Panel"; - sprite = "internal:PIKRA0"; - } - 332 - { - title = "Automatic Ring Panel"; - sprite = "internal:PIKAA0"; - } - 333 - { - title = "Explosion Ring Panel"; - sprite = "internal:PIKEA0"; - } - 334 - { - title = "Scatter Ring Panel"; - sprite = "internal:PIKSA0"; - } - 335 - { - title = "Grenade Ring Panel"; - sprite = "internal:PIKGA0"; - } -} - -collectibles -{ - color = 10; // Light_Green - title = "Other Collectibles"; - width = 16; - height = 32; - sort = 1; - sprite = "CEMGA0"; - - 310 - { - title = "CTF Red Flag"; - sprite = "RFLGA0"; - width = 24; - height = 64; - } - 311 - { - title = "CTF Blue Flag"; - sprite = "BFLGA0"; - width = 24; - height = 64; - } - 312 - { - title = "Special Stage Token"; - sprite = "internal:token"; - width = 8; - height = 16; - flags8height = 24; - flags4text = "[4] Mario Block version"; - flags8text = "[8] Float"; - } - 313 - { - title = "Chaos Emerald 1 (Green)"; - sprite = "EMMYA0"; - } - 314 - { - title = "Chaos Emerald 2 (Purple)"; - sprite = "EMMYB0"; - } - 315 - { - title = "Chaos Emerald 3 (Blue)"; - sprite = "EMMYC0"; - } - 316 - { - title = "Chaos Emerald 4 (Cyan)"; - sprite = "EMMYD0"; - } - 317 - { - title = "Chaos Emerald 5 (Orange)"; - sprite = "EMMYE0"; - } - 318 - { - title = "Chaos Emerald 6 (Red)"; - sprite = "EMMYF0"; - } - 319 - { - title = "Chaos Emerald 7 (Gray)"; - sprite = "EMMYG0"; - } - 320 - { - title = "Emerald Hunt Location"; - sprite = "internal:hunt"; - } - 323 - { - title = "Match Chaos Emerald Spawn"; + sort = 1; sprite = "CEMGA0"; - width = 8; - height = 16; - flags8height = 24; - flags8text = "[8] Float"; - } -} -boxes -{ - color = 7; // Gray - blocking = 2; - title = "Monitors"; - width = 16; - height = 32; - flags4text = "[4] Random (Strong)"; - flags8text = "[8] Random (Weak)"; - sprite = "SRBXA0"; + 310 + { + title = "CTF Red Flag"; + sprite = "RFLGA0"; + width = 24; + height = 64; + } + 311 + { + title = "CTF Blue Flag"; + sprite = "BFLGA0"; + width = 24; + height = 64; + } + 312 + { + title = "Emerald Token"; + sprite = "TOKEA0"; + width = 16; + height = 32; + } + 313 + { + title = "Chaos Emerald 1 (Green)"; + sprite = "CEMGA0"; + } + 314 + { + title = "Chaos Emerald 2 (Purple)"; + sprite = "CEMGB0"; + } + 315 + { + title = "Chaos Emerald 3 (Blue)"; + sprite = "CEMGC0"; + } + 316 + { + title = "Chaos Emerald 4 (Cyan)"; + sprite = "CEMGD0"; + } + 317 + { + title = "Chaos Emerald 5 (Orange)"; + sprite = "CEMGE0"; + } + 318 + { + title = "Chaos Emerald 6 (Red)"; + sprite = "CEMGF0"; + } + 319 + { + title = "Chaos Emerald 7 (Gray)"; + sprite = "CEMGG0"; + } + 320 + { + title = "Emerald Hunt Location"; + sprite = "SHRDA0"; + } + 321 + { + title = "Match Chaos Emerald Spawn"; + sprite = "CEMGA0"; + } + 322 + { + title = "Emblem"; + sprite = "EMBMA0"; + width = 16; + height = 30; + } + } - 400 - { - title = "Super Ring (10 Rings)"; - sprite = "SRBXA0"; - } - 401 - { - title = "Pity Shield"; - sprite = "GRTVA0"; - } - 402 - { - title = "Attraction Shield"; - sprite = "YLTVA0"; - } - 403 - { - title = "Force Shield"; - sprite = "BLTVA0"; - } - 404 - { - title = "Armageddon Shield"; - sprite = "BKTVA0"; - } - 405 - { - title = "Whirlwind Shield"; - sprite = "WHTVA0"; - } - 406 - { - title = "Elemental Shield"; - sprite = "ELTVA0"; - } - 407 - { - title = "Super Sneakers"; - sprite = "SHTVA0"; - } - 408 - { - title = "Invincibility"; - sprite = "PINVA0"; - } - 409 - { - title = "Extra Life"; - sprite = "PRUPA0"; - flags4text = "[4] Random (Strong) / 10k points"; - flags8text = "[8] Random (Weak) / 10k points"; - } - 410 - { - title = "Eggman"; - sprite = "EGGBA0"; - flags4text = "[4] Special"; - flags8text = "[8] Ambush"; - } - 411 - { - title = "Teleporter"; - sprite = "MIXUA0"; - } - 412 - { - title = "Random"; - sprite = "QUESA0"; - flags4text = "[4] Special"; - flags8text = "[8] Ambush"; - } - 413 - { - title = "Gravity Boots"; - sprite = "GBTVA0"; - flags4text = "[4] Special"; - flags8text = "[8] Ambush"; - } - 414 - { - title = "CTF Team Ring Monitor (Red)"; - sprite = "RRBXA0"; - flags4text = "[4] Special"; - flags8text = "[8] Ambush"; - } - 415 - { - title = "CTF Team Ring Monitor (Blue)"; - sprite = "BRBXA0"; - flags4text = "[4] Special"; - flags8text = "[8] Ambush"; - } - 416 - { - title = "Recycler"; - sprite = "RECYA0"; - } - 418 - { - title = "Score (1,000 Points)"; - sprite = "PTTVA0"; - flags4text = "[4] Special"; - flags8text = "[8] Ambush"; - } - 419 - { - title = "Score (10,000 Points)"; - sprite = "PTTVF0"; - flags4text = "[4] Special"; - flags8text = "[8] Ambush"; - } -} - -miscellaneous -{ - color = 11; // Light_Cyan - title = "Miscellaneous"; - width = 16; - height = 40; - sprite = "STPTA0"; - - 500 - { - title = "Air Bubble Patch"; - sprite = "BUBLA0"; - width = 8; - height = 16; - flags8text = "[8] No distance check"; - } - 501 - { - title = "Level End Sign"; - sprite = "SIGND0"; - width = 8; - height = 32; - } - 502 - { - arrow = 1; - title = "Star Post"; - sprite = "STPTA0"; - width = 64; - height = 80; - angletext = "Angle/Order"; - } - 526 + boxes { + color = 7; // Gray blocking = 2; - title = "Cannonball"; - sprite = "CBLLA0"; + title = "Monitors"; + width = 18; + height = 40; + + 400 + { + title = "Super Ring (10 Rings)"; + sprite = "TVRIA0"; + } + 401 + { + title = "Pity Shield"; + sprite = "TVPIA0"; + } + 402 + { + title = "Attraction Shield"; + sprite = "TVATA0"; + } + 403 + { + title = "Force Shield"; + sprite = "TVFOA0"; + } + 404 + { + title = "Armageddon Shield"; + sprite = "TVARA0"; + } + 405 + { + title = "Whirlwind Shield"; + sprite = "TVWWA0"; + } + 406 + { + title = "Elemental Shield"; + sprite = "TVELA0"; + } + 407 + { + title = "Super Sneakers"; + sprite = "TVSSA0"; + } + 408 + { + title = "Invincibility"; + sprite = "TVIVA0"; + } + 409 + { + title = "Extra Life"; + sprite = "TV1UA0"; + } + 410 + { + title = "Eggman"; + sprite = "TVEGA0"; + } + 411 + { + title = "Teleporter"; + sprite = "TVMXA0"; + } + 413 + { + title = "Gravity Boots"; + sprite = "TVGVA0"; + } + 414 + { + title = "CTF Team Ring Monitor (Red)"; + sprite = "TRRIA0"; + } + 415 + { + title = "CTF Team Ring Monitor (Blue)"; + sprite = "TBRIA0"; + } + 416 + { + title = "Recycler"; + sprite = "TVRCA0"; + } + 418 + { + title = "Score (1,000 Points)"; + sprite = "TV1KA0"; + } + 419 + { + title = "Score (10,000 Points)"; + sprite = "TVTKA0"; + } + 420 + { + title = "Flame Shield"; + sprite = "TVFLA0"; + } + 421 + { + title = "Water Shield"; + sprite = "TVBBA0"; + } + 422 + { + title = "Lightning Shield"; + sprite = "TVZPA0"; + } + } + + boxes2 + { + color = 18; // Gold + blocking = 2; + title = "Monitors (Respawning)"; width = 20; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; + height = 44; + + 431 + { + title = "Pity Shield (Respawn)"; + sprite = "TVPIB0"; + } + 432 + { + title = "Attraction Shield (Respawn)"; + sprite = "TVATB0"; + } + 433 + { + title = "Force Shield (Respawn)"; + sprite = "TVFOB0"; + } + 434 + { + title = "Armageddon Shield (Respawn)"; + sprite = "TVARB0"; + } + 435 + { + title = "Whirlwind Shield (Respawn)"; + sprite = "TVWWB0"; + } + 436 + { + title = "Elemental Shield (Respawn)"; + sprite = "TVELB0"; + } + 437 + { + title = "Super Sneakers (Respawn)"; + sprite = "TVSSB0"; + } + 438 + { + title = "Invincibility (Respawn)"; + sprite = "TVIVB0"; + } + 440 + { + title = "Eggman (Respawn)"; + sprite = "TVEGB0"; + } + 443 + { + title = "Gravity Boots (Respawn)"; + sprite = "TVGVB0"; + } + 450 + { + title = "Flame Shield (Respawn)"; + sprite = "TVFLB0"; + } + 451 + { + title = "Water Shield (Respawn)"; + sprite = "TVBBB0"; + } + 452 + { + title = "Lightning Shield (Respawn)"; + sprite = "TVZPB0"; + } } - 1000 + + generic { - arrow = 1; - blocking = 2; - title = "Gargoyle"; - sprite = "GARGA1"; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; + color = 11; // Light_Cyan + title = "Generic Items & Hazards"; + + 500 + { + title = "Air Bubble Patch"; + sprite = "BUBLE0"; + width = 8; + height = 16; + } + 501 + { + title = "Signpost"; + sprite = "SIGND0"; + width = 8; + height = 32; + } + 502 + { + arrow = 1; + title = "Star Post"; + sprite = "STPTA0M0"; + width = 64; + height = 128; + } + 520 + { + title = "Bomb Sphere"; + sprite = "SPHRD0"; + width = 16; + height = 24; + } + 521 + { + title = "Spikeball"; + sprite = "SPIKA0"; + width = 12; + height = 8; + } + 522 + { + title = "Wall Spike"; + sprite = "WSPKALAR"; + width = 16; + height = 14; + arrow = 1; + } + 523 + { + title = "Spike"; + sprite = "USPKA0"; + width = 8; + height = 32; + } + 1130 + { + title = "Small Mace"; + sprite = "SMCEA0"; + width = 17; + height = 34; + } + 1131 + { + title = "Big Mace"; + sprite = "BMCEA0"; + width = 34; + height = 68; + } + 1136 + { + title = "Small Fireball"; + sprite = "SFBRA0"; + width = 17; + height = 34; + } + 1137 + { + title = "Large Fireball"; + sprite = "BFBRA0"; + width = 34; + height = 68; + } } - 1102 + + springs { - arrow = 1; - blocking = 2; - title = "Eggman Statue"; - sprite = "ESTAA1"; - width = 32; - height = 240; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - 1106 - { - arrow = 1; - title = "Chain (Swinging)"; - sprite = "internal:chain1"; - height = 32; - flags8text = "[8] Double size"; - angletext = "Tag"; - } - 1107 - { - arrow = 1; - title = "Chain (Spinning)"; - sprite = "internal:chain2"; - height = 32; - flags8text = "[8] Double size"; - angletext = "Tag"; - } - 1108 - { - arrow = 1; - title = "Chain (Hidden)"; - sprite = "internal:chain3"; - height = 32; - flags8text = "[8] Double size"; - } - 1200 - { - title = "Tumbleweed (Big)"; - sprite = "BTBLA0"; - width = 24; - height = 48; - flags8text = "[8] Moves perpetually"; - } - 1201 - { - title = "Tumbleweed (Small)"; - sprite = "STBLA0"; - width = 12; - height = 24; - flags8text = "[8] Moves perpetually"; - } - 1504 - { - title = "ATZ Target"; - sprite = "RCRYB0"; - width = 24; - height = 32; - } - 1852 - { - blocking = 2; - title = "Snowman"; - sprite = "XMS3A0"; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - 1876 - { - arrow = 1; - blocking = 2; - title = "Eggman Disco Statue"; - sprite = "ESTAB1"; + color = 12; // Light_Red + title = "Springs and Fans"; width = 20; - height = 96; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; + height = 16; + sprite = "RSPRD2"; + + 540 + { + title = "Fan"; + sprite = "FANSA0D0"; + width = 16; + height = 8; + } + 541 + { + title = "Gas Jet"; + sprite = "STEMD0"; + width = 32; + } + 542 + { + title = "Bumper"; + sprite = "BUMPA0"; + width = 32; + height = 64; + } + 543 + { + title = "Balloon"; + sprite = "BLONA0"; + width = 32; + height = 64; + } + 550 + { + title = "Yellow Spring"; + sprite = "SPRYA0"; + } + 551 + { + title = "Red Spring"; + sprite = "SPRRA0"; + } + 552 + { + title = "Blue Spring"; + sprite = "SPRBA0"; + } + 555 + { + arrow = 1; + title = "Diagonal Yellow Spring"; + sprite = "YSPRD2"; + width = 16; + } + 556 + { + arrow = 1; + title = "Diagonal Red Spring"; + sprite = "RSPRD2"; + width = 16; + } + 557 + { + arrow = 1; + title = "Diagonal Blue Spring"; + sprite = "BSPRD2"; + width = 16; + } + 558 + { + arrow = 1; + title = "Horizontal Yellow Spring"; + sprite = "SSWYD2D8"; + width = 16; + height = 32; + } + 559 + { + arrow = 1; + title = "Horizontal Red Spring"; + sprite = "SSWRD2D8"; + width = 16; + height = 32; + } + 560 + { + arrow = 1; + title = "Horizontal Blue Spring"; + sprite = "SSWBD2D8"; + width = 16; + height = 32; + } + 1134 + { + title = "Yellow Spring Ball"; + sprite = "YSPBA0"; + width = 17; + height = 34; + } + 1135 + { + title = "Red Spring Ball"; + sprite = "RSPBA0"; + width = 17; + height = 34; + } + 544 + { + arrow = 1; + title = "Yellow Boost Panel"; + sprite = "BSTYA0"; + width = 28; + height = 2; + } + 545 + { + arrow = 1; + title = "Red Boost Panel"; + sprite = "BSTRA0"; + width = 28; + height = 2; + } } -} -springs -{ - color = 12; // Light_Red - title = "Springs and Fans"; - width = 48; - height = 32; - sprite = "RSPRD2"; - - 540 + patterns { - title = "Fan"; - sprite = "FANSA0D0"; + color = 5; // Magenta + arrow = 1; + title = "Special Placement Patterns"; width = 16; - height = 16; - flags4text = "[4] Invisible"; - flags8text = "[8] No distance check"; - angletext = "Lift height"; - } - 541 - { - title = "Gas Jet"; - sprite = "STEMD0"; - width = 32; - height = 16; - } - 550 - { - title = "Yellow Spring"; - sprite = "SPVYA0"; - } - 551 - { - title = "Red Spring"; - sprite = "SPVRA0"; - } - 552 - { - title = "Blue Spring"; - sprite = "SPVBA0"; - } - 553 - { - title = "Grey Spring"; - sprite = "SPVGA0"; - } - 554 - { - arrow = 1; - title = "Diagonal Yellow Spring"; - sprite = "SPDYA2A8"; - flags8text = "[8] Rotate 22.5ยฐ CCW"; - } - 555 - { - arrow = 1; - title = "Diagonal Red Spring"; - sprite = "SPDRA2A8"; - flags8text = "[8] Rotate 22.5ยฐ CCW"; - } - 556 - { - arrow = 1; - title = "Diagonal Blue Spring"; - sprite = "SPDBA2A8"; - flags8text = "[8] Rotate 22.5ยฐ CCW"; - } - 557 - { - arrow = 1; - title = "Diagonal Grey Spring"; - sprite = "SPDGA2A8"; - flags8text = "[8] Rotate 22.5ยฐ CCW"; - } - 558 - { - arrow = 1; - title = "Horizontal Yellow Spring"; - sprite = "SPHYA2A8"; - flags8text = "[8] Rotate 22.5ยฐ CCW"; - } - 559 - { - arrow = 1; - title = "Horizontal Red Spring"; - sprite = "SPHRA2A8"; - flags8text = "[8] Rotate 22.5ยฐ CCW"; - } - 560 - { - arrow = 1; - title = "Horizontal Blue Spring"; - sprite = "SPHBA2A8"; - flags8text = "[8] Rotate 22.5ยฐ CCW"; - } - 561 - { - arrow = 1; - title = "Horizontal Grey Spring"; - sprite = "SPHGA2A8"; - flags8text = "[8] Rotate 22.5ยฐ CCW"; - } -} - -patterns -{ - color = 5; // Magenta - arrow = 1; - title = "Special Placement Patterns"; - width = 16; - height = 384; - sprite = "RINGA0"; - - 600 - { - arrow = 0; - title = "5 Vertical Rings (Yellow Spring)"; + height = 384; sprite = "RINGA0"; - } - 601 - { - arrow = 0; - title = "5 Vertical Rings (Red Spring)"; - sprite = "RINGA0"; - height = 1024; - } - 602 - { - title = "5 Diagonal Rings (Yellow Spring)"; - sprite = "RINGA0"; - height = 32; - } - 603 - { - title = "10 Diagonal Rings (Red Spring)"; - sprite = "RINGA0"; - height = 32; - } - 604 - { - title = "Circle of Rings"; - sprite = "RINGA0"; - width = 96; - height = 192; - unflippable = true; - centerHitbox = true; - } - 605 - { - title = "Circle of Rings (Big)"; - sprite = "RINGA0"; - width = 192; - unflippable = true; - centerHitbox = true; - } - 606 - { - title = "Circle of Wing Logos"; - sprite = "NWNGA0"; - width = 96; - height = 192; - unflippable = true; - centerHitbox = true; - } - 607 - { - title = "Circle of Wing Logos (Big)"; - sprite = "NWNGA0"; - width = 192; - unflippable = true; - centerHitbox = true; - } - 608 - { - title = "Circle of Rings and Wings"; - sprite = "NWNGA0"; - width = 96; - height = 192; - unflippable = true; - centerHitbox = true; - } - 609 - { - title = "Circle of Rings and Wings (Big)"; - sprite = "NWNGA0"; - width = 192; - unflippable = true; - centerHitbox = true; - } -} -invisible -{ - color = 15; // White - title = "Misc. Invisible"; - width = 8; - height = 16; - sprite = "UNKNA0"; - - 700 - { - title = "Water Ambience A (Large)"; - sprite = "internal:ambiance"; - } - - 701 - { - title = "Water Ambience B (Large)"; - sprite = "internal:ambiance"; + 600 + { + arrow = 0; + title = "5 Vertical Rings (Yellow Spring)"; + sprite = "RINGA0"; + } + 601 + { + arrow = 0; + title = "5 Vertical Rings (Red Spring)"; + sprite = "RINGA0"; + height = 1024; + } + 602 + { + title = "5 Diagonal Rings (Yellow Spring)"; + sprite = "RINGA0"; + height = 32; + } + 603 + { + title = "10 Diagonal Rings (Red Spring)"; + sprite = "RINGA0"; + height = 32; + } + 604 + { + title = "Circle of Rings"; + sprite = "RINGA0"; + width = 96; + height = 192; + } + 605 + { + title = "Circle of Rings (Big)"; + sprite = "RINGA0"; + width = 192; + } + 606 + { + title = "Circle of Blue Spheres"; + sprite = "SPHRA0"; + width = 96; + height = 192; + } + 607 + { + title = "Circle of Blue Spheres (Big)"; + sprite = "SPHRA0"; + width = 192; + } + 608 + { + title = "Circle of Rings and Spheres"; + sprite = "SPHRA0"; + width = 96; + height = 192; + } + 609 + { + title = "Circle of Rings and Spheres (Big)"; + sprite = "SPHRA0"; + width = 192; + } } - 702 + invisible { - title = "Water Ambience C (Medium)"; - sprite = "internal:ambiance"; + color = 15; // White + title = "Misc. Invisible"; + width = 0; + height = 0; + sprite = "UNKNA0"; + sort = 1; + fixedsize = true; + blocking = 0; + + 700 + { + title = "Water Ambience A (Large)"; + sprite = "internal:ambiance"; + } + + 701 + { + title = "Water Ambience B (Large)"; + sprite = "internal:ambiance"; + } + + 702 + { + title = "Water Ambience C (Medium)"; + sprite = "internal:ambiance"; + } + + 703 + { + title = "Water Ambience D (Medium)"; + sprite = "internal:ambiance"; + } + + 704 + { + title = "Water Ambience E (Small)"; + sprite = "internal:ambiance"; + } + + 705 + { + title = "Water Ambience F (Small)"; + sprite = "internal:ambiance"; + } + + 706 + { + title = "Water Ambience G (Extra Large)"; + sprite = "internal:ambiance"; + } + + 707 + { + title = "Water Ambience H (Extra Large)"; + sprite = "internal:ambiance"; + } + + 708 + { + title = "Disco Ambience"; + sprite = "internal:ambiance"; + } + + 709 + { + title = "Volcano Ambience"; + sprite = "internal:ambiance"; + } + + 710 + { + title = "Machine Ambience"; + sprite = "internal:ambiance"; + } + + 750 + { + title = "Slope Vertex"; + sprite = "internal:vertexslope"; + } + + 751 + { + arrow = 1; + title = "Teleport Destination"; + sprite = "internal:tele"; + } + + 752 + { + arrow = 1; + title = "Alternate View Point"; + sprite = "internal:view"; + } + + 753 + { + title = "Zoom Tube Waypoint"; + sprite = "internal:zoom"; + } + + 754 + { + title = "Push Point"; + sprite = "GWLGA0"; + } + 755 + { + title = "Pull Point"; + sprite = "GWLRA0"; + } + 756 + { + title = "Blast Linedef Executor"; + sprite = "TOADA0"; + width = 32; + height = 16; + } + 757 + { + title = "Fan Particle Generator"; + sprite = "PRTLA0"; + width = 8; + height = 16; + } + 758 + { + title = "Object Angle Anchor"; + sprite = "internal:view"; + } + 760 + { + title = "PolyObject Anchor"; + sprite = "internal:polyanchor"; + } + 761 + { + title = "PolyObject Spawn Point"; + sprite = "internal:polycenter"; + } + 762 + { + title = "PolyObject Spawn Point (Crush)"; + sprite = "internal:polycentercrush"; + } + 780 + { + title = "Skybox View Point"; + sprite = "internal:skyb"; + } } - 703 + greenflower { - title = "Water Ambience D (Medium)"; - sprite = "internal:ambiance"; + color = 10; // Green + title = "Greenflower"; + + 800 + { + title = "GFZ Flower"; + sprite = "FWR1A0"; + width = 16; + height = 40; + } + 801 + { + title = "Sunflower"; + sprite = "FWR2A0"; + width = 16; + height = 96; + } + 802 + { + title = "Budding Flower"; + sprite = "FWR3A0"; + width = 8; + height = 32; + } + 803 + { + title = "Blueberry Bush"; + sprite = "BUS3A0"; + width = 16; + height = 32; + } + 804 + { + title = "Berry Bush"; + sprite = "BUS1A0"; + width = 16; + height = 32; + } + 805 + { + title = "Bush"; + sprite = "BUS2A0"; + width = 16; + height = 32; + } + 806 + { + title = "GFZ Tree"; + sprite = "TRE1A0"; + width = 20; + height = 128; + } + 807 + { + title = "GFZ Berry Tree"; + sprite = "TRE1B0"; + width = 20; + height = 128; + } + 808 + { + title = "GFZ Cherry Tree"; + sprite = "TRE1C0"; + width = 20; + height = 128; + } + 809 + { + title = "Checkered Tree"; + sprite = "TRE2A0"; + width = 20; + height = 200; + } + 810 + { + title = "Checkered Tree (Sunset)"; + sprite = "TRE2B0"; + width = 20; + height = 200; + } + 811 + { + title = "Polygon Tree"; + sprite = "TRE4A0"; + width = 20; + height = 200; + } + 812 + { + title = "Bush Tree"; + sprite = "TRE5A0"; + width = 20; + height = 200; + } + 813 + { + title = "Red Bush Tree"; + sprite = "TRE5B0"; + width = 20; + height = 200; + } } - 704 + technohill { - title = "Water Ambience E (Small)"; - sprite = "internal:ambiance"; + color = 10; // Green + title = "Techno Hill"; + + 900 + { + title = "THZ Steam Flower"; + sprite = "THZPA0"; + width = 8; + height = 32; + } + 901 + { + title = "Alarm"; + sprite = "ALRMA0"; + width = 8; + height = 16; + hangs = 1; + } + 902 + { + title = "THZ Spin Flower (Red)"; + sprite = "FWR5A0"; + width = 16; + height = 64; + } + 903 + { + title = "THZ Spin Flower (Yellow)"; + sprite = "FWR6A0"; + width = 16; + height = 64; + } + 904 + { + arrow = 1; + title = "Whistlebush"; + sprite = "THZTA0"; + width = 16; + height = 64; + } } - 705 + deepsea { - title = "Water Ambience F (Small)"; - sprite = "internal:ambiance"; + color = 10; // Green + title = "Deep Sea"; + + 1000 + { + arrow = 1; + blocking = 2; + title = "Gargoyle"; + sprite = "GARGA1"; + width = 16; + height = 40; + } + 1009 + { + arrow = 1; + blocking = 2; + title = "Gargoyle (Big)"; + sprite = "GARGB1"; + width = 32; + height = 80; + } + 1001 + { + title = "Seaweed"; + sprite = "SEWEA0"; + width = 24; + height = 56; + } + 1002 + { + title = "Dripping Water"; + sprite = "DRIPD0"; + width = 8; + height = 16; + hangs = 1; + } + 1003 + { + title = "Coral (Green)"; + sprite = "CORLA0"; + width = 29; + height = 40; + } + 1004 + { + title = "Coral (Red)"; + sprite = "CORLB0"; + width = 30; + height = 53; + } + 1005 + { + title = "Coral (Orange)"; + sprite = "CORLC0"; + width = 28; + height = 41; + } + 1006 + { + title = "Blue Crystal"; + sprite = "BCRYA1"; + width = 8; + height = 16; + } + 1007 + { + title = "Kelp"; + sprite = "KELPA0"; + width = 16; + height = 292; + } + 1008 + { + title = "Stalagmite (DSZ1)"; + sprite = "DSTGA0"; + width = 8; + height = 116; + } + 1010 + { + arrow = 1; + title = "Light Beam"; + sprite = "LIBEARAL"; + width = 16; + height = 16; + } + 1011 + { + title = "Stalagmite (DSZ2)"; + sprite = "DSTGA0"; + width = 8; + height = 116; + } + 1012 + { + arrow = 1; + title = "Big Floating Mine"; + width = 28; + height = 56; + sprite = "BMNEA1"; + } + 1013 + { + title = "Animated Kelp"; + sprite = "ALGAA0"; + width = 48; + height = 120; + } + 1014 + { + title = "Large Coral (Brown)"; + sprite = "CORLD0"; + width = 56; + height = 112; + } + 1015 + { + title = "Large Coral (Beige)"; + sprite = "CORLE0"; + width = 56; + height = 112; + } } - 706 + castleeggman { - title = "Water Ambience G (Extra Large)"; - sprite = "internal:ambiance"; + color = 10; // Green + title = "Castle Eggman"; + + 1100 + { + title = "Chain (Decorative)"; + sprite = "CHANA0"; + width = 4; + height = 128; + hangs = 1; + } + 1101 + { + title = "Torch"; + sprite = "FLAMA0E0"; + width = 8; + height = 32; + } + 1102 + { + arrow = 1; + blocking = 2; + title = "Eggman Statue"; + sprite = "ESTAA1"; + width = 32; + height = 240; + } + 1103 + { + title = "CEZ Flower"; + sprite = "FWR4A0"; + width = 16; + height = 40; + } + 1104 + { + title = "Mace Spawnpoint"; + sprite = "SMCEA0"; + width = 17; + height = 34; + } + 1105 + { + title = "Chain with Maces Spawnpoint"; + sprite = "SMCEA0"; + width = 17; + height = 34; + } + 1106 + { + title = "Chained Spring Spawnpoint"; + sprite = "YSPBA0"; + width = 17; + height = 34; + } + 1107 + { + title = "Chain Spawnpoint"; + sprite = "BMCHA0"; + width = 17; + height = 34; + } + 1108 + { + arrow = 1; + title = "Hidden Chain Spawnpoint"; + sprite = "internal:chain3"; + width = 17; + height = 34; + } + 1109 + { + title = "Firebar Spawnpoint"; + sprite = "BFBRA0"; + width = 17; + height = 34; + } + 1110 + { + title = "Custom Mace Spawnpoint"; + sprite = "SMCEA0"; + width = 17; + height = 34; + } + 1111 + { + arrow = 1; + blocking = 2; + title = "Crawla Statue"; + sprite = "CSTAA1"; + width = 16; + height = 40; + } + 1112 + { + arrow = 1; + blocking = 2; + title = "Lance-a-Bot Statue"; + sprite = "CBBSA1"; + width = 32; + height = 72; + } + 1114 + { + title = "Pine Tree"; + sprite = "PINEA0"; + width = 16; + height = 628; + } + 1115 + { + title = "CEZ Shrub (Small)"; + sprite = "CEZBA0"; + width = 16; + height = 24; + } + 1116 + { + title = "CEZ Shrub (Large)"; + sprite = "CEZBB0"; + width = 32; + height = 48; + } + 1117 + { + arrow = 1; + title = "Pole Banner (Red)"; + sprite = "BANRA0"; + width = 40; + height = 224; + } + 1118 + { + arrow = 1; + title = "Pole Banner (Blue)"; + sprite = "BANRA0"; + width = 40; + height = 224; + } + 1119 + { + title = "Candle"; + sprite = "CNDLA0"; + width = 8; + height = 48; + } + 1120 + { + title = "Candle Pricket"; + sprite = "CNDLB0"; + width = 8; + height = 176; + } + 1121 + { + title = "Flame Holder"; + sprite = "FLMHA0"; + width = 24; + height = 80; + } + 1122 + { + title = "Fire Torch"; + sprite = "CTRCA0"; + width = 16; + height = 80; + } + 1123 + { + title = "Cannonball Launcher"; + sprite = "internal:cannonball"; + width = 8; + height = 16; + } + 1124 + { + blocking = 2; + title = "Cannonball"; + sprite = "CBLLA0"; + width = 20; + height = 40; + } + 1125 + { + title = "Brambles"; + sprite = "CABRALAR"; + width = 48; + height = 32; + } + 1126 + { + title = "Invisible Lockon Object"; + sprite = "LCKNC0"; + width = 16; + height = 32; + } + 1127 + { + title = "Spectator Eggrobo"; + sprite = "EGR1A1"; + width = 20; + height = 72; + } + 1128 + { + arrow = 1; + title = "Waving Flag (Red)"; + sprite = "CFLGA0"; + width = 8; + height = 208; + } + 1129 + { + arrow = 1; + title = "Waving Flag (Blue)"; + sprite = "CFLGA0"; + width = 8; + height = 208; + } } - 707 + aridcanyon { - title = "Water Ambience H (Extra Large)"; - sprite = "internal:ambiance"; + color = 10; // Green + title = "Arid Canyon"; + + 1200 + { + title = "Tumbleweed (Big)"; + sprite = "BTBLA0"; + width = 24; + height = 48; + } + 1201 + { + title = "Tumbleweed (Small)"; + sprite = "STBLA0"; + width = 12; + height = 24; + } + 1202 + { + arrow = 1; + title = "Rock Spawner"; + sprite = "ROIAA0"; + width = 8; + height = 16; + } + 1203 + { + title = "Tiny Red Flower Cactus"; + sprite = "CACTA0"; + width = 13; + height = 24; + } + 1204 + { + title = "Small Red Flower Cactus"; + sprite = "CACTB0"; + width = 15; + height = 52; + } + 1205 + { + title = "Tiny Blue Flower Cactus"; + sprite = "CACTC0"; + width = 13; + height = 24; + } + 1206 + { + title = "Small Blue Flower Cactus"; + sprite = "CACTD0"; + width = 15; + height = 52; + } + 1207 + { + title = "Prickly Pear"; + sprite = "CACTE0"; + width = 32; + height = 96; + } + 1208 + { + title = "Barrel Cactus"; + sprite = "CACTF0"; + width = 20; + height = 128; + } + 1209 + { + title = "Tall Barrel Cactus"; + sprite = "CACTG0"; + width = 24; + height = 224; + } + 1210 + { + title = "Armed Cactus"; + sprite = "CACTH0"; + width = 24; + height = 256; + } + 1211 + { + title = "Ball Cactus"; + sprite = "CACTI0"; + width = 48; + height = 96; + } + 1212 + { + title = "Caution Sign"; + sprite = "WWSGAR"; + width = 22; + height = 64; + } + 1213 + { + title = "Cacti Sign"; + sprite = "WWS2AR"; + width = 22; + height = 64; + } + 1214 + { + title = "Sharp Turn Sign"; + sprite = "WWS3ALAR"; + width = 16; + height = 192; + } + 1215 + { + title = "Mine Oil Lamp"; + sprite = "OILLA0"; + width = 22; + height = 64; + hangs = 1; + } + 1216 + { + title = "TNT Barrel"; + sprite = "BARRA1"; + width = 24; + height = 63; + } + 1217 + { + title = "TNT Proximity Shell"; + sprite = "REMTA0"; + width = 64; + height = 40; + } + 1218 + { + title = "Dust Devil"; + sprite = "TAZDCR"; + width = 80; + height = 416; + } + 1219 + { + title = "Minecart Spawner"; + sprite = "MCRTCLFR"; + width = 22; + height = 32; + } + 1220 + { + title = "Minecart Stopper"; + sprite = "MCRTIR"; + width = 32; + height = 32; + } + 1221 + { + title = "Minecart Saloon Door"; + sprite = "SALDARAL"; + width = 96; + height = 160; + } + 1222 + { + title = "Train Cameo Spawner"; + sprite = "TRAEBRBL"; + width = 28; + height = 32; + } + 1223 + { + title = "Train Dust Spawner"; + sprite = "ADSTA0"; + width = 4; + height = 4; + } + 1224 + { + title = "Train Steam Spawner"; + sprite = "STEAA0"; + width = 4; + height = 4; + } + 1229 + { + title = "Minecart Switch Point"; + sprite = "internal:zoom"; + width = 8; + height = 16; + } + 1230 + { + title = "Tiny Cactus"; + sprite = "CACTJ0"; + width = 13; + height = 28; + } + 1231 + { + title = "Small Cactus"; + sprite = "CACTK0"; + width = 15; + height = 60; + } } - 708 + redvolcano { - title = "Disco Ambience"; - sprite = "internal:ambiance"; + color = 10; // Green + title = "Red Volcano"; + + 1300 + { + arrow = 1; + title = "Flame Jet (Horizontal)"; + sprite = "internal:flameh"; + width = 16; + height = 40; + } + 1301 + { + title = "Flame Jet (Vertical)"; + sprite = "internal:flamev"; + width = 16; + height = 40; + } + 1302 + { + title = "Spinning Flame Jet (Counter-Clockwise)"; + sprite = "internal:flame2"; + width = 16; + height = 24; + } + 1303 + { + title = "Spinning Flame Jet (Clockwise)"; + sprite = "internal:flame1"; + width = 16; + height = 24; + } + 1304 + { + title = "Lavafall"; + sprite = "LFALF0"; + width = 30; + height = 32; + } + 1305 + { + title = "Rollout Rock"; + sprite = "PUMIA1A5"; + width = 30; + height = 60; + } + 1306 + { + title = "Big Fern"; + sprite = "JPLAB0"; + width = 32; + height = 48; + } + 1307 + { + title = "Jungle Palm"; + sprite = "JPLAC0"; + width = 32; + height = 48; + } + 1308 + { + title = "Torch Flower"; + sprite = "TFLOA0"; + width = 14; + height = 110; + } + 1309 + { + title = "RVZ1 Wall Vine (Long)"; + sprite = "WVINALAR"; + width = 1; + height = 288; + } + 1310 + { + title = "RVZ1 Wall Vine (Short)"; + sprite = "WVINBLBR"; + width = 1; + height = 288; + } } - 709 + botanicserenity { - title = "Volcano Ambience"; - sprite = "internal:ambiance"; - } - - 750 - { - title = "Slope Vertex"; - sprite = "internal:vertexslope"; - angletext = "Tag"; - } - - 751 - { - arrow = 1; - title = "Teleport Destination"; - sprite = "internal:tele"; - } - - 752 - { - arrow = 1; - title = "Alternate View Point"; - sprite = "internal:view"; - } - - 753 - { - title = "Zoom Tube Waypoint"; - sprite = "internal:zoom"; - angletext = "Order"; - } - - 754 - { - title = "Push Point"; - flags4text = "[4] Fades using XY"; - flags8text = "[8] Push using XYZ"; - sprite = "GWLGA0"; - angletext = "Radius"; - } - 755 - { - title = "Pull Point"; - flags4text = "[4] Fades using XY"; - flags8text = "[8] Pull using XYZ"; - sprite = "GWLRA0"; - angletext = "Radius"; - } - - 760 - { - title = "PolyObject Anchor"; - sprite = "internal:polyanchor"; - angletext = "ID"; - } - - 761 - { - title = "PolyObject Spawn Point"; - sprite = "internal:polycenter"; - angletext = "ID"; - } - - 762 - { - title = "PolyObject Spawn Point (Crush)"; - sprite = "internal:polycentercrush"; - angletext = "ID"; - } - 780 - { - title = "Skybox View Point"; - sprite = "internal:skyb"; - flags4text = "[4] In-map reference point"; - angletext = "View height"; - } - -} - -hazards -{ - color = 4; // Red - title = "Hazards"; - width = 20; - height = 40; - - 521 - { - title = "Spikeball"; - sprite = "SPIKA0"; - width = 12; - height = 24; - flags8height = 24; - flags8text = "[8] Float"; - } - 523 - { - title = "Spike"; - sprite = "USPKA0"; - width = 8; - height = 42; - flags4text = "[4] Retractable"; - flags8text = "[8] Solid"; - angletext = "Retraction interval"; - } - 524 - { - arrow = 1; - title = "Big Floating Mine"; + color = 10; // Green + title = "Botanic Serenity"; width = 16; height = 32; - sprite = "BMNEA1"; - } - 527 - { - arrow = 1; - title = "Big Floating Mine (Air)"; - width = 16; - height = 32; - sprite = "BMNEA1"; - } - 525 - { - title = "Cannonball Launcher"; - sprite = "internal:cannonball"; - } - 1101 - { - title = "Torch"; - sprite = "FLAMA0"; - width = 8; - height = 32; - } - 1105 - { - title = "Mace (Swinging)"; - sprite = "internal:mace1"; - flags4text = "[4] No sounds"; - flags8text = "[8] Double size"; - angletext = "Tag"; - } - 1104 - { - title = "Mace (Spinning)"; - sprite = "internal:mace2"; - flags4text = "[4] No sounds"; - flags8text = "[8] Double size"; - angletext = "Tag"; - } - 1202 - { - arrow = 1; - title = "Rock Spawner"; - sprite = "ROIAA0"; - angletext = "Tag"; - } - 1300 - { - arrow = 1; - title = "Flame Jet (Horizontal)"; - sprite = "internal:flameh"; - width = 16; - flags8text = "[8] Waves vertically"; - angletext = "On/Off time"; - parametertext = "Strength"; - } - 1301 - { - title = "Flame Jet (Vertical)"; - sprite = "internal:flamev"; - width = 16; - flags8text = "[8] Shoot downwards"; - angletext = "On/Off time"; - parametertext = "Strength"; - } - 1500 - { - arrow = 1; - blocking = 2; - title = "Trapgoyle"; - sprite = "GARGA1"; - width = 16; - height = 40; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - 1501 - { - arrow = 1; - blocking = 2; - title = "Trapgoyle (Up)"; - sprite = "GARGA1"; - width = 16; - height = 40; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - 1502 - { - arrow = 1; - blocking = 2; - title = "Trapgoyle (Down)"; - sprite = "GARGA1"; - width = 16; - height = 40; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - 1503 - { - arrow = 1; - blocking = 2; - title = "Trapgoyle (Long)"; - sprite = "GARGA1"; - width = 16; - height = 40; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - 3576 - { - title = "Spinning Flame Jet (Clockwise)"; - sprite = "internal:flame1"; - width = "16"; - } - 3575 - { - title = "Spinning Flame Jet (Counter-Clockwise)"; - sprite = "internal:flame2"; - width = "16"; - } -} - -decoration -{ - color = 2; // Green - title = "Decoration"; - width = 16; - height = 40; - sprite = "FWR1A0"; - - 757 - { - title = "Fan Particle Generator"; - sprite = "PRTLA0"; - width = 8; - height = 16; - angletext = "Particle speed"; - parametertext = "Interval"; - } - 800 - { - title = "GFZ Flower"; - sprite = "FWR1A0"; - } - 801 - { - title = "Sunflower"; - sprite = "FWR2A0"; - height = 96; - } - 802 - { - title = "Budding Flower"; - sprite = "FWR3A0"; - width = 8; - height = 32; - } - 804 - { - title = "Berry Bush"; - sprite = "BUS1A0"; - height = 32; - } - 805 - { - title = "Bush"; - sprite = "BUS2A0"; - height = 32; - } - 900 - { - title = "THZ Flower"; - sprite = "THZPA0"; - width = 8; - height = 32; - } - 901 - { - title = "Alarm"; - sprite = "ALRMA0"; - width = 8; - height = 16; - hangs = 1; - } - 1001 - { - title = "Seaweed"; - sprite = "SEWEA0"; - width = 24; - height = 56; - } - 1002 - { - title = "Dripping Water"; - sprite = "DRIPD0"; - width = 8; - height = 16; - hangs = 1; - angletext = "Dripping interval"; - } - 1003 - { - title = "Coral (Green)"; - sprite = "CRL1A0"; - width = 8; - height = 16; - } - 1004 - { - title = "Coral (Red)"; - sprite = "CRL2A0"; - width = 8; - height = 16; - } - 1005 - { - title = "Coral (Orange)"; - sprite = "CRL3A0"; - width = 8; - height = 16; - } - 1006 - { - title = "Blue Crystal"; - sprite = "BCRYA1"; - width = 8; - height = 16; - } - 1100 - { - title = "Chain"; - sprite = "CHANA0"; - width = 8; - height = 128; - hangs = 1; - } - 1103 - { - title = "CEZ Flower"; - sprite = "FWR4A0"; - } - 1203 - { - title = "Cactus with Brown Flower"; - sprite = "CACTA0"; - height = 32; - } - 1204 - { - title = "Cactus with Brown Flower (Tall)"; - sprite = "CACTB0"; - height = 64; - } - 1205 - { - title = "Cactus with Blue Flower"; - sprite = "CACTC0"; - height = 32; - } - 1206 - { - title = "Cactus with Blue Flower (Tall)"; - sprite = "CACTD0"; - height = 80; - } - 1850 - { - title = "Christmas Pole"; - sprite = "XMS1A0"; - } - 1851 - { - title = "Candy Cane"; - sprite = "XMS2A0"; - width = 8; - height = 32; - } - 1875 - { - title = "Disco Ball"; - sprite = "DBALA0"; - height = 54; - hangs = 1; - } - 1900 - { - title = "Brown Stalagmite (Tall)"; - sprite = "STLGA0"; - } - 1901 - { - title = "Brown Stalagmite"; - sprite = "STLGB0"; - } - 1902 - { - title = "Orange Stalagmite (Tall)"; - sprite = "STLGC0"; - } - 1903 - { - title = "Orange Stalagmite"; - sprite = "STLGD0"; - } - 1904 - { - title = "Red Stalagmite (Tall)"; - sprite = "STLGE0"; - } - 1905 - { - title = "Red Stalagmite"; - sprite = "STLGF0"; - } - 1906 - { - title = "Gray Stalagmite (Tall)"; - sprite = "STLGG0"; - } - 1907 - { - title = "Gray Stalagmite"; - sprite = "STLGH0"; - } - 1908 - { - title = "Blue Stalagmite (Tall)"; - sprite = "STLGI0"; - } - 1909 - { - title = "Blue Stalagmite"; - sprite = "STLGJ0"; - } -} - -nights -{ - color = 13; // Pink - title = "NiGHTS Items"; - width = 12; - height = 32; - sprite = "NWNGA0"; - - 1703 - { - title = "Ideya Drone"; - sprite = "NDRNA1"; - width = 16; - height = 56; - flags8text = "[8] Die upon time up"; - angletext = "Time limit"; - } - 1704 - { - arrow = 1; - title = "Bumper"; - sprite = "NBMPG3G7"; - width = 32; - height = 64; - unflippable = true; - flagsvaluetext = "Pitch"; - angletext = "Yaw"; - } - 1705 - { - arrow = 1; - title = "Hoop (Generic)"; - sprite = "HOOPA0"; - width = 80; - height = 160; - unflippable = true; - centerHitbox = true; - flagsvaluetext = "Height"; - angletext = "Pitch/Yaw"; - } - 1706 - { - title = "Wing Logo"; - sprite = "NWNGA0"; - height = 24; - unflippable = true; - } - 1707 - { - title = "Super Paraloop"; - sprite = "NPRUA0"; - flags4text = "[4] Bonus time only"; - flags8text = "[8] Spawn immediately"; - } - 1708 - { - title = "Drill Refill"; - sprite = "NPRUB0"; - flags4text = "[4] Bonus time only"; - flags8text = "[8] Spawn immediately"; - } - 1709 - { - title = "Nightopian Helper"; - sprite = "NPRUC0"; - flags4text = "[4] Bonus time only"; - flags8text = "[8] Spawn immediately"; - } - 1711 - { - title = "Extra Time"; - sprite = "NPRUD0"; - flags4text = "[4] Bonus time only"; - flags8text = "[8] Spawn immediately"; - } - 1712 - { - title = "Link Freeze"; - sprite = "NPRUE0"; - flags4text = "[4] Bonus time only"; - flags8text = "[8] Spawn immediately"; - } - 1713 - { - arrow = 1; - title = "Hoop (Customizable)"; - flags1text = "[1] Radius +16"; - flags2text = "[2] Radius +32"; - flags4text = "[4] Radius +64"; - flags8text = "[8] Radius +128"; - sprite = "HOOPA0"; - width = 80; - height = 160; - unflippable = true; - centerHitbox = true; - } -} - -nightstrk -{ - color = 13; // Pink - title = "NiGHTS Track"; - width = 8; - height = 4096; - sprite = "UNKNA0"; - - 1700 - { - title = "Axis"; - sprite = "internal:axis1"; - circle = 1; - unflippable = true; - ignoreZ = true; - flagsvaluetext = "Order"; - angletext = "Radius/Direction"; - parametertext = "Mare"; - } - 1701 - { - title = "Axis Transfer"; - sprite = "internal:axis2"; - unflippable = true; - ignoreZ = true; - flagsvaluetext = "Order"; - parametertext = "Mare"; - } - 1702 - { - title = "Axis Transfer Line"; - sprite = "internal:axis3"; - unflippable = true; - ignoreZ = true; - flagsvaluetext = "Order"; - parametertext = "Mare"; - } - 1710 - { - title = "Ideya Capture"; - sprite = "CAPSA0"; - width = 72; - height = 144; - angletext = "Rings"; - parametertext = "Mare"; - } -} - -mario -{ - color = 6; // Brown - title = "Mario Items"; - width = 16; - height = 32; - sprite = "GOOMA0"; - - 1800 - { - title = "Coin"; - sprite = "COINA0"; - height = 24; - flags8height = 24; - flags8text = "[8] Float"; - } - 1801 - { - arrow = 1; - title = "Goomba"; - sprite = "GOOMA0"; - width = 24; - } - 1802 - { - arrow = 1; - title = "Goomba (Blue)"; - sprite = "BGOMA0"; - width = 24; - } - 1803 - { - title = "Fire Flower"; - sprite = "FFWRB0"; - } - 1804 - { - title = "Koopa Shell"; - sprite = "SHLLA0"; - width = 8; - height = 16; - } - 1805 - { - title = "Puma (Jumping Fireball)"; - sprite = "PUMAA0"; - width = 8; - height = 16; - angletext = "Jump strength"; - } - 1806 - { - title = "King Bowser"; - sprite = "KOOPA0"; - height = 28; - } - 1807 - { - title = "Axe"; - sprite = "MAXEA0"; - width = 8; - height = 16; - } - 1808 - { - title = "Bush (Short)"; - sprite = "MUS1A0"; - } - 1809 - { - title = "Bush (Tall)"; - sprite = "MUS2A0"; - } - 1810 - { - title = "Toad"; - sprite = "TOADA0"; - width = 8; - } -} - -srb1 -{ - color = 3; // Cyan - arrow = 1; - title = "SRB1 Remake"; - width = 20; - height = 32; - sprite = "SRBAA1"; - - 4000 - { - title = "SRB1 Crawla"; - sprite = "SRBAA1"; - height = 40; - } - 4001 - { - title = "GuardRobo"; - sprite = "SRBBA1"; - width = 17; - height = 40; - } - 4002 - { - title = "Pyrin"; - sprite = "SRBCB1"; - width = 22; - } - 4003 - { - title = "HotRobo"; - sprite = "SRBDA0"; - height = 40; - } - 4004 - { - title = "Pogminz"; - sprite = "SRBEA1"; - } - 4005 - { - title = "Pogminz (Water)"; - sprite = "SRBEA1"; - } - 4006 - { - title = "Pog-GX2"; - sprite = "SRBFA0"; - width = 10; - height = 34; - } - 4007 - { - title = "Pyrex"; - sprite = "SRBGA1"; - width = 24; - } - 4008 - { - title = "SRB1 Turret"; - sprite = "SRBHA0"; - width = 24; - hangs = 1; - } - 4009 - { - title = "SWAT Bot"; - sprite = "SRBIA1"; - width = 21; - height = 69; - } - 4010 - { - title = "SpyBot 2000"; - sprite = "SRBJA0"; - width = 36; - height = 62; - } - 4011 - { - title = "Buzz Bomber"; - sprite = "SRBKA0"; - width = 44; - height = 45; - } - 4012 - { - arrow = 0; - title = "RBZ Spike"; - sprite = "SRBLA0"; - width = 10; - height = 53; - } - 4013 - { - arrow = 0; - blocking = 2; - title = "Dumb Metal Sonic"; - sprite = "SRBMC0"; - width = 16; - height = 40; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - 4014 - { - title = "Super SWAT Bot"; - sprite = "SRBNA1"; - width = 21; - height = 69; - } - 4015 - { - title = "Genrex"; - sprite = "SRBOA1"; - width = 17; - height = 40; - } -} - -bsz -{ - color = 2; // Green - title = "Botanic Serenity Items"; - width = 16; - height = 32; - sprite = "BSZ1A0"; - 1400 - { - title = "Tall Flower (Red)"; sprite = "BSZ1A0"; + 1400 + { + title = "Tall Flower (Red)"; + sprite = "BSZ1A0"; + } + 1401 + { + title = "Tall Flower (Purple)"; + sprite = "BSZ1B0"; + } + 1402 + { + title = "Tall Flower (Blue)"; + sprite = "BSZ1C0"; + } + 1403 + { + title = "Tall Flower (Cyan)"; + sprite = "BSZ1D0"; + } + 1404 + { + title = "Tall Flower (Yellow)"; + sprite = "BSZ1E0"; + } + 1405 + { + title = "Tall Flower (Orange)"; + sprite = "BSZ1F0"; + } + 1410 + { + title = "Medium Flower (Red)"; + sprite = "BSZ2A0"; + } + 1411 + { + title = "Medium Flower (Purple)"; + sprite = "BSZ2B0"; + } + 1412 + { + title = "Medium Flower (Blue)"; + sprite = "BSZ2C0"; + } + 1413 + { + title = "Medium Flower (Cyan)"; + sprite = "BSZ2D0"; + } + 1414 + { + title = "Medium Flower (Yellow)"; + sprite = "BSZ2E0"; + } + 1415 + { + title = "Medium Flower (Orange)"; + sprite = "BSZ2F0"; + } + 1420 + { + title = "Short Flower (Red)"; + sprite = "BSZ3A0"; + } + 1421 + { + title = "Short Flower (Purple)"; + sprite = "BSZ3B0"; + } + 1422 + { + title = "Short Flower (Blue)"; + sprite = "BSZ3C0"; + } + 1423 + { + title = "Short Flower (Cyan)"; + sprite = "BSZ3D0"; + } + 1424 + { + title = "Short Flower (Yellow)"; + sprite = "BSZ3E0"; + } + 1425 + { + title = "Short Flower (Orange)"; + sprite = "BSZ3F0"; + } + 1430 + { + title = "Tulip (Red)"; + sprite = "BST1A0"; + } + 1431 + { + title = "Tulip (Purple)"; + sprite = "BST2A0"; + } + 1432 + { + title = "Tulip (Blue)"; + sprite = "BST3A0"; + } + 1433 + { + title = "Tulip (Cyan)"; + sprite = "BST4A0"; + } + 1434 + { + title = "Tulip (Yellow)"; + sprite = "BST5A0"; + } + 1435 + { + title = "Tulip (Orange)"; + sprite = "BST6A0"; + } + 1440 + { + title = "Cluster (Red)"; + sprite = "BSZ5A0"; + } + 1441 + { + title = "Cluster (Purple)"; + sprite = "BSZ5B0"; + } + 1442 + { + title = "Cluster (Blue)"; + sprite = "BSZ5C0"; + } + 1443 + { + title = "Cluster (Cyan)"; + sprite = "BSZ5D0"; + } + 1444 + { + title = "Cluster (Yellow)"; + sprite = "BSZ5E0"; + } + 1445 + { + title = "Cluster (Orange)"; + sprite = "BSZ5F0"; + } + 1450 + { + title = "Bush (Red)"; + sprite = "BSZ6A0"; + } + 1451 + { + title = "Bush (Purple)"; + sprite = "BSZ6B0"; + } + 1452 + { + title = "Bush (Blue)"; + sprite = "BSZ6C0"; + } + 1453 + { + title = "Bush (Cyan)"; + sprite = "BSZ6D0"; + } + 1454 + { + title = "Bush (Yellow)"; + sprite = "BSZ6E0"; + } + 1455 + { + title = "Bush (Orange)"; + sprite = "BSZ6F0"; + } + 1460 + { + title = "Vine (Red)"; + sprite = "BSZ7A0"; + } + 1461 + { + title = "Vine (Purple)"; + sprite = "BSZ7B0"; + } + 1462 + { + title = "Vine (Blue)"; + sprite = "BSZ7C0"; + } + 1463 + { + title = "Vine (Cyan)"; + sprite = "BSZ7D0"; + } + 1464 + { + title = "Vine (Yellow)"; + sprite = "BSZ7E0"; + } + 1465 + { + title = "Vine (Orange)"; + sprite = "BSZ7F0"; + } + 1470 + { + title = "BSZ Shrub"; + sprite = "BSZ8A0"; + } + 1471 + { + title = "BSZ Clover"; + sprite = "BSZ8B0"; + } + 1473 + { + title = "Palm Tree (Big)"; + width = 16; + height = 160; + sprite = "BSZ8D0"; + } + 1475 + { + title = "Palm Tree (Small)"; + width = 16; + height = 80; + sprite = "BSZ8F0"; + } } - 1401 + + azuretemple { - title = "Tall Flower (Purple)"; - sprite = "BSZ1B0"; + color = 10; // Green + title = "Azure Temple"; + + 1500 + { + arrow = 1; + blocking = 2; + title = "Glaregoyle"; + sprite = "BGARA1"; + width = 16; + height = 40; + } + 1501 + { + arrow = 1; + blocking = 2; + title = "Glaregoyle (Up)"; + sprite = "BGARA1"; + width = 16; + height = 40; + } + 1502 + { + arrow = 1; + blocking = 2; + title = "Glaregoyle (Down)"; + sprite = "BGARA1"; + width = 16; + height = 40; + } + 1503 + { + arrow = 1; + blocking = 2; + title = "Glaregoyle (Long)"; + sprite = "BGARA1"; + width = 16; + height = 40; + } + 1504 + { + title = "ATZ Target"; + sprite = "RCRYB0"; + width = 24; + height = 32; + } + 1505 + { + title = "Green Flame"; + sprite = "CFLMA0E0"; + width = 8; + height = 32; + } + 1506 + { + arrow = 1; + blocking = 2; + title = "Blue Gargoyle"; + sprite = "BGARD1"; + width = 16; + height = 40; + } } - 1402 + + dreamhill { - title = "Tall Flower (Blue)"; - sprite = "BSZ1C0"; + color = 10; // Green + title = "Dream Hill"; + + 1600 + { + title = "Spring Tree"; + sprite = "TRE6A0"; + width = 16; + height = 32; + } + 1601 + { + title = "Shleep"; + sprite = "SHLPA0"; + width = 24; + height = 32; + } + 1602 + { + title = "Nightopian"; + sprite = "NTPNA1"; + width = 16; + height = 40; + } } - 1403 + + nightstrk { - title = "Tall Flower (Cyan)"; - sprite = "BSZ1D0"; + color = 13; // Pink + title = "NiGHTS Track"; + width = 8; + height = 4096; + sprite = "UNKNA0"; + + 1700 + { + title = "Axis"; + sprite = "internal:axis1"; + circle = 1; + } + 1701 + { + title = "Axis Transfer"; + sprite = "internal:axis2"; + } + 1702 + { + title = "Axis Transfer Line"; + sprite = "internal:axis3"; + } + 1710 + { + title = "Ideya Capture"; + sprite = "CAPSA0"; + width = 72; + height = 144; + } } - 1404 + + nights { - title = "Tall Flower (Yellow)"; - sprite = "BSZ1E0"; + color = 13; // Pink + title = "NiGHTS Items"; + width = 16; + height = 32; + + 1703 + { + title = "Ideya Drone"; + sprite = "NDRNA1"; + width = 16; + height = 56; + } + 1704 + { + arrow = 1; + title = "NiGHTS Bumper"; + sprite = "NBMPG3G7"; + width = 32; + height = 64; + } + 1705 + { + arrow = 1; + title = "Hoop (Generic)"; + sprite = "HOOPA0"; + width = 80; + height = 160; + } + 1706 + { + title = "Blue Sphere"; + sprite = "SPHRA0"; + width = 16; + height = 24; + } + 1707 + { + title = "Super Paraloop"; + sprite = "NPRUA0"; + } + 1708 + { + title = "Drill Refill"; + sprite = "NPRUB0"; + } + 1709 + { + title = "Nightopian Helper"; + sprite = "NPRUC0"; + } + 1711 + { + title = "Extra Time"; + sprite = "NPRUD0"; + } + 1712 + { + title = "Link Freeze"; + sprite = "NPRUE0"; + } + 1713 + { + arrow = 1; + title = "Hoop (Customizable)"; + sprite = "HOOPA0"; + width = 80; + height = 160; + } + 1714 + { + title = "Ideya Anchor Point"; + sprite = "internal:axis1"; + width = 8; + height = 16; + } } - 1405 + + mario { - title = "Tall Flower (Orange)"; - sprite = "BSZ1F0"; + color = 6; // Brown + title = "Mario"; + + 1800 + { + title = "Coin"; + sprite = "COINA0"; + width = 16; + height = 24; + } + 1801 + { + arrow = 1; + title = "Goomba"; + sprite = "GOOMA0"; + width = 24; + height = 32; + } + 1802 + { + arrow = 1; + title = "Goomba (Blue)"; + sprite = "BGOMA0"; + width = 24; + height = 32; + } + 1803 + { + title = "Fire Flower"; + sprite = "FFWRB0"; + width = 16; + height = 32; + } + 1804 + { + title = "Koopa Shell"; + sprite = "SHLLA1"; + width = 16; + height = 20; + } + 1805 + { + title = "Puma (Jumping Fireball)"; + sprite = "PUMAA0"; + width = 8; + height = 16; + } + 1806 + { + title = "King Bowser"; + sprite = "KOOPA0"; + width = 16; + height = 48; + } + 1807 + { + title = "Axe"; + sprite = "MAXEA0"; + width = 8; + height = 16; + } + 1808 + { + title = "Bush (Short)"; + sprite = "MUS1A0"; + width = 16; + height = 32; + } + 1809 + { + title = "Bush (Tall)"; + sprite = "MUS2A0"; + width = 16; + height = 32; + } + 1810 + { + title = "Toad"; + sprite = "TOADA0"; + width = 8; + height = 32; + } } - 1410 + + christmasdisco { - title = "Medium Flower (Red)"; - sprite = "BSZ2A0"; + color = 10; // Green + title = "Christmas & Disco"; + + 1850 + { + title = "Christmas Pole"; + sprite = "XMS1A0"; + width = 16; + height = 40; + } + 1851 + { + title = "Candy Cane"; + sprite = "XMS2A0"; + width = 8; + height = 32; + } + 1852 + { + blocking = 2; + title = "Snowman"; + sprite = "XMS3A0"; + width = 16; + height = 64; + } + 1853 + { + blocking = 2; + title = "Snowman (With Hat)"; + sprite = "XMS3B0"; + width = 16; + height = 80; + } + 1854 + { + title = "Lamp Post"; + sprite = "XMS4A0"; + width = 8; + height = 120; + } + 1855 + { + title = "Lamp Post (Snow)"; + sprite = "XMS4B0"; + width = 8; + height = 120; + } + 1856 + { + title = "Hanging Star"; + sprite = "XMS5A0"; + width = 4; + height = 80; + hangs = 1; + } + 1857 + { + title = "Berry Bush (Snow)"; + sprite = "BUS1B0"; + width = 16; + height = 32; + } + 1858 + { + title = "Bush (Snow)"; + sprite = "BUS2B0"; + width = 16; + height = 32; + } + 1859 + { + title = "Blueberry Bush (Snow)"; + sprite = "BUS3B0"; + width = 16; + height = 32; + } + 1875 + { + title = "Disco Ball"; + sprite = "DBALA0"; + width = 16; + height = 54; + hangs = 1; + } + 1876 + { + arrow = 1; + blocking = 2; + title = "Eggman Disco Statue"; + sprite = "ESTAB1"; + width = 20; + height = 96; + } } - 1411 + + stalagmites { - title = "Medium Flower (Purple)"; - sprite = "BSZ2B0"; + color = 10; // Green + title = "Stalagmites"; + width = 16; + height = 40; + + 1900 + { + title = "Brown Stalagmite (Tall)"; + sprite = "STLGA0"; + width = 16; + height = 40; + } + 1901 + { + title = "Brown Stalagmite"; + sprite = "STLGB0"; + width = 16; + height = 40; + } + 1902 + { + title = "Orange Stalagmite (Tall)"; + sprite = "STLGC0"; + width = 16; + height = 40; + } + 1903 + { + title = "Orange Stalagmite"; + sprite = "STLGD0"; + width = 16; + height = 40; + } + 1904 + { + title = "Red Stalagmite (Tall)"; + sprite = "STLGE0"; + width = 16; + height = 40; + } + 1905 + { + title = "Red Stalagmite"; + sprite = "STLGF0"; + width = 16; + height = 40; + } + 1906 + { + title = "Gray Stalagmite (Tall)"; + sprite = "STLGG0"; + width = 24; + height = 96; + } + 1907 + { + title = "Gray Stalagmite"; + sprite = "STLGH0"; + width = 16; + height = 40; + } + 1908 + { + title = "Blue Stalagmite (Tall)"; + sprite = "STLGI0"; + width = 16; + height = 40; + } + 1909 + { + title = "Blue Stalagmite"; + sprite = "STLGJ0"; + width = 16; + height = 40; + } } - 1412 + + hauntedheights { - title = "Medium Flower (Blue)"; - sprite = "BSZ2C0"; + color = 10; // Green + title = "Haunted Heights"; + + 2000 + { + title = "Smashing Spikeball"; + sprite = "FMCEA0"; + width = 18; + height = 28; + } + 2001 + { + title = "HHZ Grass"; + sprite = "HHZMA0"; + width = 16; + height = 40; + } + 2002 + { + title = "HHZ Tentacle 1"; + sprite = "HHZMB0"; + width = 16; + height = 40; + } + 2003 + { + title = "HHZ Tentacle 2"; + sprite = "HHZMC0"; + width = 16; + height = 40; + } + 2004 + { + title = "HHZ Stalagmite (Tall)"; + sprite = "HHZME0"; + width = 16; + height = 40; + } + 2005 + { + title = "HHZ Stalagmite (Short)"; + sprite = "HHZMF0"; + width = 16; + height = 40; + } + 2006 + { + title = "Jack-o'-lantern 1"; + sprite = "PUMKA0"; + width = 16; + height = 40; + } + 2007 + { + title = "Jack-o'-lantern 2"; + sprite = "PUMKB0"; + width = 16; + height = 40; + } + 2008 + { + title = "Jack-o'-lantern 3"; + sprite = "PUMKC0"; + width = 16; + height = 40; + } + 2009 + { + title = "Purple Mushroom"; + sprite = "SHRMD0"; + width = 16; + height = 48; + } + 2010 + { + title = "HHZ Tree"; + sprite = "HHPLC0"; + width = 12; + height = 40; + } } - 1413 + + frozenhillside { - title = "Medium Flower (Cyan)"; - sprite = "BSZ2D0"; + color = 10; // Green + title = "Frozen Hillside"; + + 2100 + { + title = "Ice Shard (Small)"; + sprite = "FHZIA0"; + width = 8; + height = 32; + } + 2101 + { + title = "Ice Shard (Large)"; + sprite = "FHZIB0"; + width = 8; + height = 32; + } + 2102 + { + title = "Crystal Tree (Aqua)"; + sprite = "TRE3A0"; + width = 20; + height = 200; + } + 2103 + { + title = "Crystal Tree (Pink)"; + sprite = "TRE3B0"; + width = 20; + height = 200; + } + 2104 + { + title = "Amy Cameo"; + sprite = "ROSYA1"; + width = 16; + height = 48; + } + 2105 + { + title = "Mistletoe"; + sprite = "XMS6A0"; + width = 52; + height = 106; + } } - 1414 + + tutorial { - title = "Medium Flower (Yellow)"; - sprite = "BSZ2E0"; + color = 10; // Green + title = "Tutorial"; + + 799 + { + title = "Tutorial Plant"; + sprite = "TUPFH0"; + width = 40; + height = 144; + } } - 1415 + + flickies { - title = "Medium Flower (Orange)"; - sprite = "BSZ2F0"; - } - 1420 - { - title = "Short Flower (Red)"; - sprite = "BSZ3A0"; - } - 1421 - { - title = "Short Flower (Purple)"; - sprite = "BSZ3B0"; - } - 1422 - { - title = "Short Flower (Blue)"; - sprite = "BSZ3C0"; - } - 1423 - { - title = "Short Flower (Cyan)"; - sprite = "BSZ3D0"; - } - 1424 - { - title = "Short Flower (Yellow)"; - sprite = "BSZ3E0"; - } - 1425 - { - title = "Short Flower (Orange)"; - sprite = "BSZ3F0"; - } - 1430 - { - title = "Tulip (Red)"; - sprite = "BSZ4A0"; - } - 1431 - { - title = "Tulip (Purple)"; - sprite = "BSZ4B0"; - } - 1432 - { - title = "Tulip (Blue)"; - sprite = "BSZ4C0"; - } - 1433 - { - title = "Tulip (Cyan)"; - sprite = "BSZ4D0"; - } - 1434 - { - title = "Tulip (Yellow)"; - sprite = "BSZ4E0"; - } - 1435 - { - title = "Tulip (Orange)"; - sprite = "BSZ4F0"; - } - 1440 - { - title = "Cluster (Red)"; - sprite = "BSZ5A0"; - } - 1441 - { - title = "Cluster (Purple)"; - sprite = "BSZ5B0"; - } - 1442 - { - title = "Cluster (Blue)"; - sprite = "BSZ5C0"; - } - 1443 - { - title = "Cluster (Cyan)"; - sprite = "BSZ5D0"; - } - 1444 - { - title = "Cluster (Yellow)"; - sprite = "BSZ5E0"; - } - 1445 - { - title = "Cluster (Orange)"; - sprite = "BSZ5F0"; - } - 1450 - { - title = "Bush (Red)"; - sprite = "BSZ6A0"; - } - 1451 - { - title = "Bush (Purple)"; - sprite = "BSZ6B0"; - } - 1452 - { - title = "Bush (Blue)"; - sprite = "BSZ6C0"; - } - 1453 - { - title = "Bush (Cyan)"; - sprite = "BSZ6D0"; - } - 1454 - { - title = "Bush (Yellow)"; - sprite = "BSZ6E0"; - } - 1455 - { - title = "Bush (Orange)"; - sprite = "BSZ6F0"; - } - 1460 - { - title = "Vine (Red)"; - sprite = "BSZ7A0"; - } - 1461 - { - title = "Vine (Purple)"; - sprite = "BSZ7B0"; - } - 1462 - { - title = "Vine (Blue)"; - sprite = "BSZ7C0"; - } - 1463 - { - title = "Vine (Cyan)"; - sprite = "BSZ7D0"; - } - 1464 - { - title = "Vine (Yellow)"; - sprite = "BSZ7E0"; - } - 1465 - { - title = "Vine (Orange)"; - sprite = "BSZ7F0"; - } - 1470 - { - title = "BSZ Shrub"; - sprite = "BSZ8A0"; - } - 1471 - { - title = "BSZ Clover"; - sprite = "BSZ8B0"; - } - 1472 - { - title = "BSZ Fish"; - sprite = "BSZ8C0"; - } - 1473 - { - title = "BSZ Sunflower"; - sprite = "BSZ8D0"; + color = 10; // Green + title = "Flickies"; + width = 8; + height = 20; + + 2200 + { + title = "Bluebird"; + sprite = "FL01A1"; + } + 2201 + { + title = "Rabbit"; + sprite = "FL02A1"; + } + 2202 + { + title = "Chicken"; + sprite = "FL03A1"; + } + 2203 + { + title = "Seal"; + sprite = "FL04A1"; + } + 2204 + { + title = "Pig"; + sprite = "FL05A1"; + } + 2205 + { + title = "Chipmunk"; + sprite = "FL06A1"; + } + 2206 + { + title = "Penguin"; + sprite = "FL07A1"; + } + 2207 + { + title = "Fish"; + sprite = "FL08A1"; + } + 2208 + { + title = "Ram"; + sprite = "FL09A1"; + } + 2209 + { + title = "Puffin"; + sprite = "FL10A1"; + } + 2210 + { + title = "Cow"; + sprite = "FL11A1"; + } + 2211 + { + title = "Rat"; + sprite = "FL12A1"; + } + 2212 + { + title = "Bear"; + sprite = "FL13A1"; + } + 2213 + { + title = "Dove"; + sprite = "FL14A1"; + } + 2214 + { + title = "Cat"; + sprite = "FL15A1"; + } + 2215 + { + title = "Canary"; + sprite = "FL16A1"; + } + 2216 + { + title = "Spider"; + sprite = "FS01A1"; + } + 2217 + { + title = "Bat"; + sprite = "FS02A0"; + } } } -derrobjs // sev: split these into multiple sections later +udmf { - color = 4; // Red - arrow = 1; - title = "SRB2Kart Stuff"; - sprite = "ITEMALAR"; - width = 8; - height = 16; + editor + { + color = 15; // White + arrow = 1; + title = ""; + error = -1; + width = 8; + height = 16; + sort = 1; - 2000 - { - title = "Random Item"; - sprite = "RNDMA0"; - width = 36; - height = 36; + 3328 = "3D Mode Start"; } - 2333 - { - title = "Capsule"; - //sprite = "internal:kartcapsule"; - width = 28; - height = 112; - blocking = 2; - flags4text = "[4] Reverse movement"; - flags8text = "[8] Back and forth"; - arg0 - { - title = "Movement sequence"; - type = 0; - } - arg1 - { - title = "Movement speed"; - type = 0; - } - } - 1488 + + starts { + color = 1; // Blue arrow = 1; - title = "Random Audience Member"; - sprite = "AUDIA2A8"; - width = 8; - height = 20; - } - 1479 - { - title = "Torch (no fullbright)"; - sprite = "FLAMA0"; - width = 8; - height = 32; - } - 1480 - { - blocking = 2; - arrow = 1; - title = "Devil Gargoyle"; - sprite = "DECOA1"; + title = "Player Starts"; width = 16; - height = 40; - } - 1481 - { - blocking = 2; - arrow = 1; - title = "Angel Gargoyle"; - sprite = "DECOB1"; - width = 16; - height = 40; - } - 1482 - { - title = "Generic Palmtree"; - sprite = "DECOC0"; - width = 16; - height = 189; - } - 1483 - { - title = "Peach's Castle Flag"; - sprite = "DECOD0"; - width = 16; - height = 40; - } - 1484 - { - title = "Sonic the Hedge (bust)"; - sprite = "DECOE0"; - width = 64; - height = 64; - } - 1485 - { - title = "Tall Bush"; - sprite = "DECOF0"; - width = 16; - height = 32; - } - 1486 - { - title = "Bush Tree"; - sprite = "DECOG0"; - width = 16; - height = 40; - } - 1487 - { - title = "Fire Hydrant"; - sprite = "DECOH0"; - width = 16; - height = 40; - } - 2400 - { - title = "Big Puma"; - sprite = "DECOI0"; - width = 24; height = 48; + sprite = "PLAYA0"; + + 1 + { + title = "Player 01 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 2 + { + title = "Player 02 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 3 + { + title = "Player 03 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 4 + { + title = "Player 04 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 5 + { + title = "Player 05 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 6 + { + title = "Player 06 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 7 + { + title = "Player 07 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 8 + { + title = "Player 08 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 9 + { + title = "Player 09 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 10 + { + title = "Player 10 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 11 + { + title = "Player 11 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 12 + { + title = "Player 12 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 13 + { + title = "Player 13 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 14 + { + title = "Player 14 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 15 + { + title = "Player 15 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 16 + { + title = "Player 16 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 17 + { + title = "Player 17 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 18 + { + title = "Player 18 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 19 + { + title = "Player 19 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 20 + { + title = "Player 20 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 21 + { + title = "Player 21 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 22 + { + title = "Player 22 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 23 + { + title = "Player 23 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 24 + { + title = "Player 24 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 25 + { + title = "Player 25 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 26 + { + title = "Player 26 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 27 + { + title = "Player 27 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 28 + { + title = "Player 28 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 29 + { + title = "Player 29 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 30 + { + title = "Player 30 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 31 + { + title = "Player 31 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 32 + { + title = "Player 32 Start"; + sprite = "PLAYA0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 33 + { + title = "Match Start"; + sprite = "NDRNA2A8"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 34 + { + title = "CTF Red Team Start"; + sprite = "SIGNG0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } + 35 + { + title = "CTF Blue Team Start"; + sprite = "SIGNE0"; + arg0 + { + title = "Spawn on ceiling?"; + type = 11; + enum = "noyes"; + } + } } - 2805 + + enemies { - title = "Autumn Bush"; - sprite = "DOODA0"; - width = 16; - height = 24; + color = 9; // Light_Blue + arrow = 1; + title = "Enemies"; + + 100 + { + title = "Crawla (Blue)"; + sprite = "POSSA1"; + width = 24; + height = 32; + } + 101 + { + title = "Crawla (Red)"; + sprite = "SPOSA1"; + width = 24; + height = 32; + } + 102 + { + title = "Stupid Dumb Unnamed RoboFish"; + sprite = "FISHA0"; + width = 8; + height = 28; + arg0 + { + title = "Jump strength"; + } + } + 103 + { + title = "Buzz (Gold)"; + sprite = "BUZZA1"; + width = 28; + height = 40; + arg0 + { + title = "Can move?"; + type = 11; + enum = "yesno"; + } + } + 104 + { + title = "Buzz (Red)"; + sprite = "RBUZA1"; + width = 28; + height = 40; + arg0 + { + title = "Can move?"; + type = 11; + enum = "yesno"; + } + } + 108 + { + title = "Deton"; + sprite = "DETNA1"; + width = 20; + height = 32; + } + 110 + { + title = "Turret"; + sprite = "TRETA1"; + width = 16; + height = 32; + arg0 + { + title = "Death trigger tag"; + type = 15; + } + } + 111 + { + title = "Pop-up Turret"; + sprite = "TURRI1"; + width = 12; + height = 64; + arg0 + { + title = "Firing delay"; + } + } + 122 + { + title = "Spring Shell (Green)"; + sprite = "SSHLA1"; + width = 24; + height = 40; + } + 125 + { + title = "Spring Shell (Yellow)"; + sprite = "SSHLI1"; + width = 24; + height = 40; + } + 109 + { + title = "Skim"; + sprite = "SKIMA1"; + width = 16; + height = 24; + } + 113 + { + title = "Jet Jaw"; + sprite = "JJAWA3A7"; + width = 12; + height = 20; + } + 126 + { + title = "Crushstacean"; + sprite = "CRABA0"; + width = 24; + height = 32; + arg0 + { + title = "Spawn direction"; + type = 11; + enum + { + 0 = "Right"; + 1 = "Left"; + } + } + } + 138 + { + title = "Banpyura"; + sprite = "CR2BA0"; + width = 24; + height = 32; + arg0 + { + title = "Spawn direction"; + type = 11; + enum + { + 0 = "Right"; + 1 = "Left"; + } + } + } + 117 + { + title = "Robo-Hood"; + sprite = "ARCHA1"; + width = 24; + height = 32; + arg0 + { + title = "Can jump?"; + type = 11; + enum = "yesno"; + } + } + 118 + { + title = "Lance-a-Bot"; + sprite = "CBFSA1"; + width = 32; + height = 72; + } + 1113 + { + title = "Suspicious Lance-a-Bot Statue"; + sprite = "CBBSA1"; + width = 32; + height = 72; + arg0 + { + title = "Push behavior"; + type = 11; + enum = "pushablebehavior"; + } + } + 119 + { + title = "Egg Guard"; + sprite = "ESHIA1"; + width = 16; + height = 48; + arg0 + { + title = "Turn direction"; + type = 11; + enum + { + 0 = "Back"; + 1 = "Right"; + 2 = "Left"; + } + } + arg1 + { + title = "Double speed?"; + type = 11; + enum = "noyes"; + } + } + 115 + { + title = "Bird Aircraft Strike Hazard"; + sprite = "VLTRF1"; + width = 12; + height = 24; + } + 120 + { + title = "Green Snapper"; + sprite = "GSNPA1"; + width = 24; + height = 24; + } + 121 + { + title = "Minus"; + sprite = "MNUSA0"; + width = 24; + height = 32; + } + 134 + { + title = "Canarivore"; + sprite = "CANAA0"; + width = 12; + height = 80; + hangs = 1; + } + 123 + { + title = "Unidus"; + sprite = "UNIDA1"; + width = 18; + height = 36; + } + 135 + { + title = "Pterabyte Spawner"; + sprite = "PTERA2A8"; + width = 16; + height = 16; + arg0 + { + title = "Number of Pterabytes"; + default = 1; + } + } + 136 + { + title = "Pyre Fly"; + sprite = "PYREA0"; + width = 24; + height = 34; + arg0 + { + title = "Start on fire?"; + type = 11; + enum = "noyes"; + } + } + 137 + { + title = "Dragonbomber"; + sprite = "DRABA1"; + width = 28; + height = 48; + } + 105 + { + title = "Jetty-Syn Bomber"; + sprite = "JETBB1"; + width = 20; + height = 50; + arg0 + { + title = "Can move?"; + type = 11; + enum = "yesno"; + } + } + 106 + { + title = "Jetty-Syn Gunner"; + sprite = "JETGB1"; + width = 20; + height = 48; + arg0 + { + title = "Can move?"; + type = 11; + enum = "yesno"; + } + } + 112 + { + title = "Spincushion"; + sprite = "SHRPA1"; + width = 16; + height = 24; + } + 114 + { + title = "Snailer"; + sprite = "SNLRA3A7"; + width = 24; + height = 48; + } + 129 + { + title = "Penguinator"; + sprite = "PENGA1"; + width = 24; + height = 32; + } + 130 + { + title = "Pophat"; + sprite = "POPHA1"; + width = 24; + height = 32; + } + 107 + { + title = "Crawla Commander"; + sprite = "CCOMA1"; + width = 16; + height = 32; + } + 131 + { + title = "Spinbobert"; + sprite = "SBOBB0"; + width = 32; + height = 32; + } + 132 + { + title = "Cacolantern"; + sprite = "CACOA0"; + width = 32; + height = 32; + arg0 + { + title = "Can move?"; + type = 11; + enum = "yesno"; + } + } + 133 + { + title = "Hangster"; + sprite = "HBATC1"; + width = 24; + height = 24; + hangs = 1; + } + 127 + { + title = "Hive Elemental"; + sprite = "HIVEA0"; + width = 32; + height = 80; + arg0 + { + title = "Number of bees"; + } + } + 128 + { + title = "Bumblebore"; + sprite = "BUMBA1"; + width = 16; + height = 32; + arg0 + { + title = "Can move?"; + type = 11; + enum = "yesno"; + } + } + 124 + { + title = "Buggle"; + sprite = "BBUZA1"; + width = 20; + height = 24; + } + 116 + { + title = "Pointy"; + sprite = "PNTYA1"; + width = 8; + height = 16; + } } - 2800 + + bosses { - title = "Autumn Flower"; - sprite = "DOODB0"; - width = 16; - height = 40; + color = 8; // Dark_Gray + arrow = 1; + title = "Bosses"; + + 200 + { + title = "Egg Mobile"; + sprite = "EGGMA1"; + width = 24; + height = 76; + arg0 + { + title = "Boss ID"; + } + arg1 + { + title = "End level on death?"; + type = 11; + enum = "noyes"; + } + arg2 + { + title = "Death trigger tag"; + type = 15; + } + arg3 + { + title = "Victory trigger tag"; + type = 15; + } + arg4 + { + title = "Pinch trigger tag"; + type = 15; + } + } + 201 + { + title = "Egg Slimer"; + sprite = "EGGNA1"; + width = 24; + height = 76; + arg0 + { + title = "Boss ID"; + } + arg1 + { + title = "End level on death?"; + type = 11; + enum = "noyes"; + } + arg2 + { + title = "Death trigger tag"; + type = 15; + } + arg3 + { + title = "Victory trigger tag"; + type = 15; + } + arg4 + { + title = "Pinch trigger tag"; + type = 15; + } + arg5 + { + title = "Speed up when hit?"; + type = 11; + enum = "yesno"; + } + } + 202 + { + title = "Sea Egg"; + sprite = "EGGOA1"; + width = 32; + height = 116; + arg0 + { + title = "Boss ID"; + } + arg1 + { + title = "End level on death?"; + type = 11; + enum = "noyes"; + } + arg2 + { + title = "Death trigger tag"; + type = 15; + } + arg3 + { + title = "Victory trigger tag"; + type = 15; + } + arg4 + { + title = "Pinch trigger tag"; + type = 15; + } + } + 203 + { + title = "Egg Colosseum"; + sprite = "EGGPA1"; + width = 24; + height = 76; + arg0 + { + title = "Boss ID"; + } + arg1 + { + title = "End level on death?"; + type = 11; + enum = "noyes"; + } + arg2 + { + title = "Death trigger tag"; + type = 15; + } + arg3 + { + title = "Victory trigger tag"; + type = 15; + } + arg4 + { + title = "Pinch trigger tag"; + type = 15; + } + arg5 + { + title = "Cage drop trigger tag"; + type = 15; + } + } + 204 + { + title = "Fang"; + sprite = "FANGA1"; + width = 24; + height = 60; + arg0 + { + title = "Boss ID"; + } + arg1 + { + title = "End level on death?"; + type = 11; + enum = "noyes"; + } + arg2 + { + title = "Death trigger tag"; + type = 15; + } + arg3 + { + title = "Victory trigger tag"; + type = 15; + } + arg4 + { + title = "Pinch trigger tag"; + type = 15; + } + arg5 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Grayscale"; + 2 = "Skip intro"; + } + } + } + 206 + { + title = "Brak Eggman (Old)"; + sprite = "BRAKB1"; + width = 48; + height = 160; + arg0 + { + title = "Boss ID"; + } + arg1 + { + title = "End level on death?"; + type = 11; + enum = "noyes"; + } + arg2 + { + title = "Death trigger tag"; + type = 15; + } + arg3 + { + title = "Victory trigger tag"; + type = 15; + } + arg4 + { + title = "Pinch trigger tag"; + type = 15; + } + arg5 + { + title = "Platform trigger tag"; + type = 15; + } + } + 207 + { + title = "Metal Sonic (Race)"; + sprite = "METLI1"; + width = 16; + height = 48; + arg0 + { + title = "Grayscale?"; + type = 11; + enum = "noyes"; + } + } + 208 + { + title = "Metal Sonic (Battle)"; + sprite = "METLC1"; + width = 16; + height = 48; + arg0 + { + title = "Boss ID"; + } + arg1 + { + title = "End level on death?"; + type = 11; + enum = "noyes"; + } + arg2 + { + title = "Death trigger tag"; + type = 15; + } + arg3 + { + title = "Victory trigger tag"; + type = 15; + } + arg4 + { + title = "Pinch trigger tag"; + type = 15; + } + arg5 + { + title = "Grayscale?"; + type = 11; + enum = "noyes"; + } + } + 209 + { + title = "Brak Eggman"; + sprite = "BRAK01"; + width = 48; + height = 160; + arg0 + { + title = "Boss ID"; + } + arg1 + { + title = "End level on death?"; + type = 11; + enum = "noyes"; + } + arg2 + { + title = "Death trigger tag"; + type = 15; + } + arg3 + { + title = "Victory trigger tag"; + type = 15; + } + arg4 + { + title = "Pinch trigger tag"; + type = 15; + } + arg5 + { + title = "Attack trigger tag"; + type = 15; + } + arg6 + { + title = "Flags"; + type = 12; + enum + { + 1 = "No origin-fling death"; + 2 = "Electric barrier"; + } + } + } + 290 + { + arrow = 0; + title = "Boss Escape Point"; + width = 8; + height = 16; + sprite = "internal:eggmanend"; + } + 291 + { + arrow = 0; + title = "Egg Capsule Center"; + width = 8; + height = 16; + sprite = "internal:capsule"; + } + 292 + { + arrow = 0; + title = "Boss Waypoint"; + width = 8; + height = 16; + sprite = "internal:eggmanway"; + arg0 + { + title = "Sea Egg sequence"; + } + arg1 + { + title = "Brak Eggman sequence"; + } + } + 293 + { + title = "Metal Sonic Gather Point"; + sprite = "internal:metal"; + width = 8; + height = 16; + } + 294 + { + title = "Fang Waypoint"; + sprite = "internal:eggmanway"; + width = 8; + height = 16; + arg0 + { + title = "Center waypoint?"; + type = 11; + enum = "noyes"; + } + } } - 2801 + + rings { - title = "Autumn Sunflower"; - sprite = "DOODD0"; - width = 16; - height = 96; - } - 2802 - { - title = "Autumn Budding Flower"; - sprite = "DOODF0"; - width = 8; - height = 32; - } - 2809 - { - title = "Decorative MKSC Item"; - sprite = "DOODJ0"; - width = 16; - height = 32; - } - 2807 - { - title = "Decorative DKR Item"; - sprite = "DOODL0"; - width = 91; - height = 166; - } - 2808 - { - title = "Big Ring"; - sprite = "BRNGA0"; - width = 26; - height = 62; - } - 2301 - { - title = "SMK DP Bush 1"; - sprite = "SNESA0"; - width = 14; - height = 15; - } - 2302 - { - title = "SMK DP Bush 2"; - sprite = "SNESB0"; - width = 13; - height = 13; - } - 2303 - { - title = "SMK DP Bush 3"; - sprite = "SNESC0"; - width = 7; - height = 7; - } - /*379 - { - title = "MKSC Boo"; - sprite = "GBASA0"; - width = 16; - height = 56; - }*/ - 2015 - { - title = "Buzz Bomber"; - sprite = "BUZBA2A8"; + color = 14; // Yellow + title = "Rings and Weapon Panels"; width = 24; height = 24; - } - 2500 - { - title = "Chomper"; - sprite = "CHOMA2A8"; - width = 24; - height = 48; - } - 2016 - { - title = "SCZ Palmtree"; - sprite = "SACOA0"; - width = 16; - height = 96; - } - 3000 - { - title = "SCZ Blue Flower"; - sprite = "SACOB0"; - width = 16; - height = 40; - } - 3001 - { - title = "SCZ Blue Tulips"; - sprite = "SACOC0"; - width = 16; - height = 40; - } - 3002 - { - title = "SCZ Yellow Flower"; - sprite = "SACOD0"; - width = 16; - height = 40; - } - 3003 - { - title = "SCZ Yellow Tulips"; - sprite = "SACOE0"; - width = 16; - height = 40; - } - 4022 // Dupe - { - title = "SCZ Wall Plant"; - sprite = "SACOF0"; - width = 16; - height = 40; - } - 4024 - { - title = "SCZ Plant"; - sprite = "SACOG0"; - width = 16; - height = 40; - } - 4025 - { - title = "SCZ Bush"; - sprite = "SACOH0"; - width = 16; - height = 40; - } - 4026 - { - title = "CAZ Skull"; - sprite = "CRABA1"; - width = 16; - height = 40; - } - 4027 - { - title = "CAZ Phantom Tree"; - sprite = "CRABB0"; - width = 32; - height = 150; - } - 4028 - { - title = "CAZ Flying Gargoyle"; - sprite = "CRABI1"; - width = 20; - height = 170; - } - 4029 - { - title = "CAZ Lamppost"; - sprite = "CRABK0"; - width = 32; - height = 150; - } - 4030 - { - title = "CAZ Dead Tree"; - sprite = "CRABL0"; - width = 32; - height = 150; - } - 715 - { - title = "Sonic the Hedge"; - sprite = "SBUSA0"; - width = 192; - height = 922; - } - 1969 - { - title = "MZ Torch"; - sprite = "MARBA0"; - width = 12; - height = 45; - } - 1970 - { - title = "MZ Burner"; - sprite = "MARBJ0"; - width = 24; - height = 96; - } - 4050 - { - title = "CD SS1 UFO"; - sprite = "FUFOA0"; - width = 70; - height = 70; - } - 1988 - { - title = "RRZ Lamp"; - sprite = "RUSTA0"; - width = 12; - height = 45; - } - 1989 - { - title = "RRZ Chain"; - sprite = "RUSTB0"; - width = 12; - height = 45; - } - 462 - { - title = "SD2 BP Balloon"; - sprite = "BLONA0"; - width = 32; - height = 64; - angletext = "Color"; - } - 2018 - { - title = "PRZ Smoke Generator"; - sprite = "SMOKA0"; - width = 24; - height = 64; - flags4text = "[4] Spawn VVZ smoke"; - } - 1600 - { - title = "VVZ Smoke"; - sprite = "VAPEA0"; - width = 16; - height = 64; - } - 716 - { - title = "HTZ Pinetree"; - sprite = "HTZAA0"; - width = 5; - height = 204; - } - 717 - { - title = "HTZ Bush"; - sprite = "HTZBA0"; - width = 24; - height = 38; - } - 718 - { - title = "MKSC SG Vine 1"; - sprite = "SGVAA0"; - width = 32; - height = 256; - } - 719 - { - title = "MKSC SG Vine 2"; - sprite = "SGVBA0"; - width = 17; - height = 48; - } - 720 - { - title = "MKSC SG Vine 3"; - sprite = "SGVCA0"; - width = 17; - height = 48; - } - 711 - { - title = "MKDS PG Tree"; - sprite = "PGTRA0"; - width = 30; - height = 504; - } - 712 - { - title = "MKDS PG Flower 1"; - sprite = "PGF1A0"; - width = 17; - height = 48; - } - 713 - { - title = "MKDS PG Flower 2"; - sprite = "PGF2A0"; - width = 17; - height = 48; - } - 714 - { - title = "MKDS PG Flower 3"; - sprite = "PGF3A0"; - width = 17; - height = 48; - } - 715 - { - title = "MKDS PG Bush"; - sprite = "PGBHA0"; - width = 384; - height = 922; - } - 1960 - { - title = "SM SS3 Pillar"; - sprite = "DPLRA0"; - width = 58; - height = 256; - } - 3124 - { - title = "MC Spotlight"; - sprite = "SPTLA0"; - width = 8; - height = 16; - } - 3120 - { - title = "MC Random Shadow"; - sprite = "ENM1B2B8"; - width = 16; - height = 32; - } - 3121 - { - title = "MC Roaming Shadow"; - sprite = "ENM1C2C8"; - width = 16; - height = 32; - } - 3122 - { - title = "MC Sign"; - sprite = "MARRA0"; - width = 64; - height = 128; - flags1text = "[1] Flip Arrow"; - flags4text = "[4] Boost Warning"; - } - 3199 - { - title = "Mementos Reaper Waypoint"; - sprite = "ENM1B5"; - width = 64; - height = 128; - flags1text = "[1] Flip Arrow"; - flags4text = "[4] Boost Warning"; - } - 3202 - { - title = "Mementos Reaper"; - sprite = "REAPA0"; - width = 64; - height = 128; - } - 3201 - { - title = "Mementos Teleporter"; - sprite = "GARUA0"; - width = 512; - height = 16; - } - 1601 - { - title = "MCZ Jack in the Box"; - sprite = "JITBA0"; - width = 16; - height = 128; - } - 2499 - { - title = "3CD Moon"; - sprite = "CDMOA0"; - width = 30; - height = 60; - } - 2498 - { - title = "3CD Bush"; - sprite = "CDBUA0"; - width = 16; - height = 16; - } - 2496 - { - title = "3CD Tree 1"; - sprite = "CDBUB0"; - width = 20; - height = 20; - } - 2497 - { - title = "3CD Tree 2"; - sprite = "CDBUC0"; - width = 20; - height = 20; - } - 3204 - { - title = "DSZ Pinetree"; - sprite = "PINEC0"; - width = 32; - height = 192; - } - 2311 - { - title = "EZZ Propeller"; - sprite = "PPLRA0"; - width = 32; - height = 48; - } - 3742 - { - title = "DPZ Palmtree"; - sprite = "DPPTA0"; - width = 16; - height = 560; - } - 1950 - { - title = "AAZ Palmtree"; - sprite = "AATRC0"; - width = 160; - height = 256; - angletext = "Leaves"; - parametertext = "Height"; - } - 2005 - { - title = "BBZ Frogger"; - sprite = "FROGA2A8"; - width = 28; - height = 72; - } - 2006 - { - title = "BBZ Robra"; - sprite = "CBRAA2A8"; - width = 32; - height = 72; - } - 2007 - { - blocking = 2; - title = "BBZ Blue Robra"; - sprite = "BBRAA2A8"; - width = 32; - height = 72; - } - 2679 - { - title = "EGZ Fog Generator"; - sprite = "EGFGA0"; - } - 3970 - { - blocking = 2; - title = "SMK Pipe"; - sprite = "SMKPA1A5"; - width = 20; - height = 52; - flags8text = "[8] Orange"; - } - 3971 - { - title = "SMK DP Monty Mole"; - sprite = "MTYMA0"; - width = 28; - height = 32; - } - 3972 - { - blocking = 2; - title = "SMK Thwomp"; - sprite = "THWPA0"; - width = 22; - height = 52; - flags8text = "[8] Rainbow"; - } - 3745 - { - title = "SMK VL Snowball"; - sprite = "SNOBA0"; - width = 16; - height = 32; - } - 3203 - { - blocking = 2; - title = "SMK VL Ice Block"; - sprite = "ICEBARAL"; - width = 32; - height = 32; - } - 749 - { - title = "Blue Torch"; - sprite = "CNDLA0"; - width = 8; - height = 32; - } - 748 - { - title = "Green Torch"; - sprite = "CNDLE0"; - width = 8; - height = 32; - } - 744 - { - blocking = 2; - title = "CK RR Chest"; - sprite = "CHESA0"; - width = 48; - height = 64; - } - 743 - { - blocking = 2; - title = "CK RR Chimera Statue"; - sprite = "CHIMA0"; - width = 64; - height = 128; - } - 742 - { - blocking = 2; - title = "CK RR Dragon Statue"; - sprite = "DRGNA0"; - width = 64; - height = 128; - } - 741 - { - blocking = 2; - title = "CK RR Lizard Man Statue"; - sprite = "LZMNA0"; - width = 64; - height = 128; - } - 740 - { - blocking = 2; - title = "CK RR Pegasus Statue"; - sprite = "PGSSA0"; - width = 64; - height = 128; - } - 739 - { - title = "Small Purple Torch"; - sprite = "ZTCHA0"; - width = 8; - height = 32; - } - 747 - { - blocking = 2; - title = "KKR GD Thing"; - sprite = "DOCHA0"; - width = 16; - height = 64; - } - 746 - { - blocking = 2; - title = "KKR GD Duck"; - sprite = "DUCKA0"; - width = 16; - height = 64; - } - 745 - { - blocking = 2; - title = "KKR GD Tree"; - sprite = "GTREA0"; - width = 32; - height = 128; - } - 738 - { - title = "THH Monokuma"; - sprite = "MKMAA2"; - width = 16; - height = 64; - } - 737 - { - title = "Small Red Torch"; - sprite = "RTCHA0"; - width = 8; - height = 32; - } - 736 - { - title = "PC Bowling Pin"; - sprite = "BOWLA0"; - width = 16; - height = 64; - } - 735 - { - title = "PC Merry-Go-Round Ambience"; - sprite = "internal:ambiance"; - } - 734 - { - title = "Twinkle Cart Ambience"; - sprite = "internal:ambiance"; - } - 733 - { - title = "PC Exploding Barrel"; - sprite = "BRRLA0"; - width = 32; - height = 64; - } - 732 - { - blocking = 2; - title = "PC Merry-Go-Round Horse"; - sprite = "HRSEA0"; - width = 32; - height = 128; - } - 731 - { - blocking = 2; - title = "Chao Fruit (Blue)"; - sprite = "BFRTA0"; - width = 16; - height = 16; - } - 730 - { - blocking = 2; - title = "Chao Fruit (Orange)"; - sprite = "OFRTA0"; - width = 16; - height = 16; - } - 729 - { - blocking = 2; - title = "Chao Fruit (Red)"; - sprite = "RFRTA0"; - width = 16; - height = 16; - } - 728 - { - blocking = 2; - title = "Chao Fruit (Pink)"; - sprite = "OFRTA0"; - width = 16; - height = 16; - } - 727 - { - title = "RBA Spikeball 1"; - sprite = "ASPKA0"; - width = 64; - height = 32; - } - 726 - { - title = "RBA Spikeball 2"; - sprite = "ASPKA0"; - width = 64; - height = 32; - } - 725 - { - title = "RBA Spikeball 3"; - sprite = "ASPKA0"; - width = 64; - height = 32; - } - 724 - { - title = "RBA Boost Prompt"; - sprite = "HBSTA0"; - width = 64; - height = 64; - } - 724 - { - title = "RBA Boost OFF"; - sprite = "HBSFA0"; - width = 64; - height = 64; - } - 724 - { - title = "RBA Boost ON"; - sprite = "HBSOA0"; - width = 64; - height = 64; - } - 2200 - { - title = "AS Toad"; - sprite = "TOAHA0"; - width = 16; - height = 64; - } - 2201 - { - blocking = 2; - title = "FTZ Lizard Man Statue"; - sprite = "WBLZA0"; - width = 32; - height = 92; - } - 2202 - { - blocking = 2; - title = "FTZ Lion Man Statue"; - sprite = "WBLNA0"; - width = 32; - height = 92; - } -} -waypoints -{ - color = 4; // Red - arrow = 1; - title = "Waypoints"; - sprite = "KBLNC0"; - width = 16; - height = 32; - - 2001 - { - title = "Waypoint (height = next waypoint ID)"; - sprite = "EMBMP0"; - angletext = "ID"; - flags1text = "[1] Disable"; - flags4text = "[4] Shortcut"; - flags8text = "[8] No respawn"; + sprite = "RINGA0"; arg0 { - title = "Next Waypoint ID"; - type = 14; + title = "Float?"; + type = 11; + enum = "yesno"; } - arg1 + + 300 { - title = "Radius"; - default = 384; - renderstyle = "Circle"; + title = "Ring"; + sprite = "RINGA0"; + width = 16; } - arg2 + 301 { - title = "Finish Line?"; - type = 0; + title = "Bounce Ring"; + sprite = "internal:RNGBA0"; + } + 302 + { + title = "Rail Ring"; + sprite = "internal:RNGRA0"; + } + 303 + { + title = "Infinity Ring"; + sprite = "internal:RNGIA0"; + } + 304 + { + title = "Automatic Ring"; + sprite = "internal:RNGAA0"; + } + 305 + { + title = "Explosion Ring"; + sprite = "internal:RNGEA0"; + } + 306 + { + title = "Scatter Ring"; + sprite = "internal:RNGSA0"; + } + 307 + { + title = "Grenade Ring"; + sprite = "internal:RNGGA0"; + } + 308 + { + title = "CTF Team Ring (Red)"; + sprite = "internal:RRNGA0"; + width = 16; + } + 309 + { + title = "CTF Team Ring (Blue)"; + sprite = "internal:BRNGA0"; + width = 16; + } + 330 + { + title = "Bounce Ring Panel"; + sprite = "internal:PIKBA0"; + } + 331 + { + title = "Rail Ring Panel"; + sprite = "internal:PIKRA0"; + } + 332 + { + title = "Automatic Ring Panel"; + sprite = "internal:PIKAA0"; + } + 333 + { + title = "Explosion Ring Panel"; + sprite = "internal:PIKEA0"; + } + 334 + { + title = "Scatter Ring Panel"; + sprite = "internal:PIKSA0"; + } + 335 + { + title = "Grenade Ring Panel"; + sprite = "internal:PIKGA0"; } } - 2004 + + collectibles { - title = "Bot Hint"; - sprite = "EMBMA0"; - flags8text = "[8] Avoid this area"; + color = 10; // Light_Green + title = "Other Collectibles"; + width = 16; + height = 32; + sort = 1; + sprite = "CEMGA0"; + + 310 + { + title = "CTF Red Flag"; + sprite = "RFLGA0"; + width = 24; + height = 64; + } + 311 + { + title = "CTF Blue Flag"; + sprite = "BFLGA0"; + width = 24; + height = 64; + } + 312 + { + title = "Emerald Token"; + sprite = "TOKEA0"; + width = 16; + height = 32; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } + } + 313 + { + title = "Chaos Emerald 1 (Green)"; + sprite = "CEMGA0"; + } + 314 + { + title = "Chaos Emerald 2 (Purple)"; + sprite = "CEMGB0"; + } + 315 + { + title = "Chaos Emerald 3 (Blue)"; + sprite = "CEMGC0"; + } + 316 + { + title = "Chaos Emerald 4 (Cyan)"; + sprite = "CEMGD0"; + } + 317 + { + title = "Chaos Emerald 5 (Orange)"; + sprite = "CEMGE0"; + } + 318 + { + title = "Chaos Emerald 6 (Red)"; + sprite = "CEMGF0"; + } + 319 + { + title = "Chaos Emerald 7 (Gray)"; + sprite = "CEMGG0"; + } + 320 + { + title = "Emerald Hunt Location"; + sprite = "SHRDA0"; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } + } + 321 + { + title = "Match Chaos Emerald Spawn"; + sprite = "CEMGA0"; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } + } + 322 + { + title = "Emblem"; + sprite = "EMBMA0"; + width = 16; + height = 30; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } + } + } + + boxes + { + color = 7; // Gray + blocking = 2; + title = "Monitors"; + width = 18; + height = 40; + arg0 + { + title = "Death trigger tag"; + type = 15; + } + + 400 + { + title = "Super Ring (10 Rings)"; + sprite = "TVRIA0"; + arg1 + { + title = "Respawn behavior"; + type = 11; + enum = "monitorrespawn"; + } + } + 401 + { + title = "Pity Shield"; + sprite = "TVPIA0"; + arg1 + { + title = "Respawn behavior"; + type = 11; + enum = "monitorrespawn"; + } + } + 402 + { + title = "Attraction Shield"; + sprite = "TVATA0"; + arg1 + { + title = "Respawn behavior"; + type = 11; + enum = "monitorrespawn"; + } + } + 403 + { + title = "Force Shield"; + sprite = "TVFOA0"; + arg1 + { + title = "Respawn behavior"; + type = 11; + enum = "monitorrespawn"; + } + } + 404 + { + title = "Armageddon Shield"; + sprite = "TVARA0"; + arg1 + { + title = "Respawn behavior"; + type = 11; + enum = "monitorrespawn"; + } + } + 405 + { + title = "Whirlwind Shield"; + sprite = "TVWWA0"; + arg1 + { + title = "Respawn behavior"; + type = 11; + enum = "monitorrespawn"; + } + } + 406 + { + title = "Elemental Shield"; + sprite = "TVELA0"; + arg1 + { + title = "Respawn behavior"; + type = 11; + enum = "monitorrespawn"; + } + } + 407 + { + title = "Super Sneakers"; + sprite = "TVSSA0"; + arg1 + { + title = "Respawn behavior"; + type = 11; + enum = "monitorrespawn"; + } + } + 408 + { + title = "Invincibility"; + sprite = "TVIVA0"; + arg1 + { + title = "Respawn behavior"; + type = 11; + enum = "monitorrespawn"; + } + } + 409 + { + title = "Extra Life"; + sprite = "TV1UA0"; + arg1 + { + title = "Respawn behavior"; + type = 11; + enum = "monitorrespawn"; + } + arg2 + { + title = "Points"; + type = 11; + enum + { + 0 = "1,000"; + 1 = "10,000"; + } + } + } + 410 + { + title = "Eggman"; + sprite = "TVEGA0"; + } + 411 + { + title = "Teleporter"; + sprite = "TVMXA0"; + arg1 + { + title = "Respawn behavior"; + type = 11; + enum = "monitorrespawn"; + } + } + 413 + { + title = "Gravity Boots"; + sprite = "TVGVA0"; + } + 414 + { + title = "CTF Team Ring Monitor (Red)"; + sprite = "TRRIA0"; + } + 415 + { + title = "CTF Team Ring Monitor (Blue)"; + sprite = "TBRIA0"; + } + 416 + { + title = "Recycler"; + sprite = "TVRCA0"; + arg1 + { + title = "Respawn behavior"; + type = 11; + enum = "monitorrespawn"; + } + } + 418 + { + title = "Score (1,000 Points)"; + sprite = "TV1KA0"; + } + 419 + { + title = "Score (10,000 Points)"; + sprite = "TVTKA0"; + } + 420 + { + title = "Flame Shield"; + sprite = "TVFLA0"; + arg1 + { + title = "Respawn behavior"; + type = 11; + enum = "monitorrespawn"; + } + } + 421 + { + title = "Water Shield"; + sprite = "TVBBA0"; + arg1 + { + title = "Respawn behavior"; + type = 11; + enum = "monitorrespawn"; + } + } + 422 + { + title = "Lightning Shield"; + sprite = "TVZPA0"; + arg1 + { + title = "Respawn behavior"; + type = 11; + enum = "monitorrespawn"; + } + } + } + + boxes2 + { + color = 18; // Gold + blocking = 2; + title = "Monitors (Respawning)"; + width = 20; + height = 44; + arg0 + { + title = "Death trigger tag"; + type = 15; + } + + 431 + { + title = "Pity Shield (Respawn)"; + sprite = "TVPIB0"; + } + 432 + { + title = "Attraction Shield (Respawn)"; + sprite = "TVATB0"; + } + 433 + { + title = "Force Shield (Respawn)"; + sprite = "TVFOB0"; + } + 434 + { + title = "Armageddon Shield (Respawn)"; + sprite = "TVARB0"; + } + 435 + { + title = "Whirlwind Shield (Respawn)"; + sprite = "TVWWB0"; + } + 436 + { + title = "Elemental Shield (Respawn)"; + sprite = "TVELB0"; + } + 437 + { + title = "Super Sneakers (Respawn)"; + sprite = "TVSSB0"; + } + 438 + { + title = "Invincibility (Respawn)"; + sprite = "TVIVB0"; + } + 440 + { + title = "Eggman (Respawn)"; + sprite = "TVEGB0"; + } + 443 + { + title = "Gravity Boots (Respawn)"; + sprite = "TVGVB0"; + } + 450 + { + title = "Flame Shield (Respawn)"; + sprite = "TVFLB0"; + } + 451 + { + title = "Water Shield (Respawn)"; + sprite = "TVBBB0"; + } + 452 + { + title = "Lightning Shield (Respawn)"; + sprite = "TVZPB0"; + } + } + + generic + { + color = 11; // Light_Cyan + title = "Generic Items & Hazards"; + + 500 + { + title = "Air Bubble Patch"; + sprite = "BUBLE0"; + width = 8; + height = 16; + arg0 + { + title = "Distance check?"; + type = 11; + enum = "yesno"; + } + } + 501 + { + title = "Signpost"; + sprite = "SIGND0"; + width = 8; + height = 32; + } + 502 + { + arrow = 1; + title = "Star Post"; + sprite = "STPTA0M0"; + width = 64; + height = 128; + arg0 + { + title = "Order"; + } + arg1 + { + title = "Respawn at center?"; + type = 11; + enum = "noyes"; + } + } + 520 + { + title = "Bomb Sphere"; + sprite = "SPHRD0"; + width = 16; + height = 24; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } + } + 521 + { + title = "Spikeball"; + sprite = "SPIKA0"; + width = 12; + height = 8; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } + } + 522 + { + title = "Wall Spike"; + sprite = "WSPKALAR"; + width = 16; + height = 14; + arrow = 1; + arg0 + { + title = "Retraction interval"; + } + arg1 + { + title = "Start interval"; + } + arg2 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Start retracted"; + 2 = "Intangible"; + } + } + } + 523 + { + title = "Spike"; + sprite = "USPKA0"; + width = 8; + height = 32; + arg0 + { + title = "Retraction interval"; + } + arg1 + { + title = "Start interval"; + } + arg2 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Start retracted"; + 2 = "Intangible"; + } + } + } + 1130 + { + title = "Small Mace"; + sprite = "SMCEA0"; + width = 17; + height = 34; + } + 1131 + { + title = "Big Mace"; + sprite = "BMCEA0"; + width = 34; + height = 68; + } + 1136 + { + title = "Small Fireball"; + sprite = "SFBRA0"; + width = 17; + height = 34; + } + 1137 + { + title = "Large Fireball"; + sprite = "BFBRA0"; + width = 34; + height = 68; + } + } + + springs + { + color = 12; // Light_Red + title = "Springs and Fans"; + width = 20; + height = 16; + sprite = "RSPRD2"; + + 540 + { + title = "Fan"; + sprite = "FANSA0D0"; + width = 16; + height = 8; + arg0 + { + title = "Lift height"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Invisible"; + 2 = "No distance check"; + } + } + } + 541 + { + title = "Gas Jet"; + sprite = "STEMD0"; + width = 32; + arg0 + { + title = "Play sound?"; + type = 11; + enum = "yesno"; + } + } + 542 + { + title = "Bumper"; + sprite = "BUMPA0"; + width = 32; + height = 64; + } + 543 + { + title = "Balloon"; + sprite = "BLONA0"; + width = 32; + height = 64; + arg0 + { + title = "Respawn?"; + type = 11; + enum = "noyes"; + } + stringarg0 + { + title = "Color"; + } + } + 550 + { + title = "Yellow Spring"; + sprite = "SPRYA0"; + } + 551 + { + title = "Red Spring"; + sprite = "SPRRA0"; + } + 552 + { + title = "Blue Spring"; + sprite = "SPRBA0"; + } + 555 + { + arrow = 1; + title = "Diagonal Yellow Spring"; + sprite = "YSPRD2"; + width = 16; + arg0 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Ignore gravity"; + 2 = "Rotate 22.5ยฐ CCW"; + } + } + } + 556 + { + arrow = 1; + title = "Diagonal Red Spring"; + sprite = "RSPRD2"; + width = 16; + arg0 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Ignore gravity"; + 2 = "Rotate 22.5ยฐ CCW"; + } + } + } + 557 + { + arrow = 1; + title = "Diagonal Blue Spring"; + sprite = "BSPRD2"; + width = 16; + arg0 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Ignore gravity"; + 2 = "Rotate 22.5ยฐ CCW"; + } + } + } + 558 + { + arrow = 1; + title = "Horizontal Yellow Spring"; + sprite = "SSWYD2D8"; + width = 16; + height = 32; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } + } + 559 + { + arrow = 1; + title = "Horizontal Red Spring"; + sprite = "SSWRD2D8"; + width = 16; + height = 32; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } + } + 560 + { + arrow = 1; + title = "Horizontal Blue Spring"; + sprite = "SSWBD2D8"; + width = 16; + height = 32; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } + } + 1134 + { + title = "Yellow Spring Ball"; + sprite = "YSPBA0"; + width = 17; + height = 34; + } + 1135 + { + title = "Red Spring Ball"; + sprite = "RSPBA0"; + width = 17; + height = 34; + } + 544 + { + arrow = 1; + title = "Yellow Boost Panel"; + sprite = "BSTYA0"; + width = 28; + height = 2; + arg0 + { + title = "Force spin?"; + type = 11; + enum = "noyes"; + } + } + 545 + { + arrow = 1; + title = "Red Boost Panel"; + sprite = "BSTRA0"; + width = 28; + height = 2; + arg0 + { + title = "Force spin?"; + type = 11; + enum = "noyes"; + } + } + } + + patterns + { + color = 5; // Magenta + arrow = 1; + title = "Special Placement Patterns"; + width = 16; + height = 384; + sprite = "RINGA0"; + + 600 + { + arrow = 0; + title = "5 Vertical Rings (Yellow Spring)"; + sprite = "RINGA0"; + } + 601 + { + arrow = 0; + title = "5 Vertical Rings (Red Spring)"; + sprite = "RINGA0"; + height = 1024; + } + 602 + { + title = "5 Diagonal Rings (Yellow Spring)"; + sprite = "RINGA0"; + height = 32; + } + 603 + { + title = "10 Diagonal Rings (Red Spring)"; + sprite = "RINGA0"; + height = 32; + } + 604 + { + title = "Circle of Rings"; + sprite = "RINGA0"; + width = 96; + height = 192; + } + 605 + { + title = "Circle of Rings (Big)"; + sprite = "RINGA0"; + width = 192; + } + 606 + { + title = "Circle of Blue Spheres"; + sprite = "SPHRA0"; + width = 96; + height = 192; + } + 607 + { + title = "Circle of Blue Spheres (Big)"; + sprite = "SPHRA0"; + width = 192; + } + 608 + { + title = "Circle of Rings and Spheres"; + sprite = "SPHRA0"; + width = 96; + height = 192; + } + 609 + { + title = "Circle of Rings and Spheres (Big)"; + sprite = "SPHRA0"; + width = 192; + } + 610 + { + title = "Row of Items"; + sprite = "RINGA0"; + arg0 + { + title = "Number of items"; + } + arg1 + { + title = "Horizontal spacing"; + } + arg2 + { + title = "Vertical spacing"; + } + stringarg0 + { + title = "Object types"; + } + } + 611 + { + title = "Circle of Items"; + sprite = "RINGA0"; + width = 96; + height = 192; + arg0 + { + title = "Number of items"; + } + arg1 + { + title = "Radius"; + } + stringarg0 + { + title = "Object types"; + } + } + } + + invisible + { + color = 15; // White + title = "Misc. Invisible"; + width = 0; + height = 0; + sprite = "UNKNA0"; + sort = 1; + fixedsize = true; + blocking = 0; + + 700 + { + title = "Ambient Sound Effect"; + sprite = "internal:ambiance"; + arg0 + { + title = "Repeat speed"; + } + stringarg0 + { + title = "Sound"; + } + } + + 750 + { + title = "Slope Vertex"; + sprite = "internal:vertexslope"; + arg0 + { + title = "Absolute height?"; + type = 11; + enum = "noyes"; + } + } + + 751 + { + arrow = 1; + title = "Teleport Destination"; + sprite = "internal:tele"; + } + + 752 + { + arrow = 1; + title = "Alternate View Point"; + sprite = "internal:view"; + } + + 753 + { + title = "Zoom Tube Waypoint"; + sprite = "internal:zoom"; + arg0 + { + title = "Sequence"; + } + arg1 + { + title = "Order"; + } + } + + 754 + { + title = "Push/Pull Point"; + sprite = "GWLGA0"; + arg0 + { + title = "Radius"; + } + arg1 + { + title = "Strength"; + } + arg2 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Fade using XY"; + 2 = "Push using XYZ"; + 4 = "Non-exclusive"; + } + } + } + 756 + { + title = "Blast Linedef Executor"; + sprite = "TOADA0"; + width = 32; + height = 16; + arg0 + { + title = "Linedef tag"; + type = 15; + } + } + 757 + { + title = "Fan Particle Generator"; + sprite = "PRTLA0"; + width = 8; + height = 16; + arg0 + { + title = "Particles"; + } + arg1 + { + title = "Radius"; + } + arg2 + { + title = "Rising speed"; + } + arg3 + { + title = "Rotation speed"; + type = 8; + } + arg4 + { + title = "Spawn interval"; + } + arg5 + { + title = "Rising distance"; + } + arg6 + { + title = "Heights control linedef"; + type = 15; + } + } + 758 + { + title = "Object Angle Anchor"; + sprite = "internal:view"; + } + 760 + { + title = "PolyObject Anchor"; + sprite = "internal:polyanchor"; + } + 761 + { + title = "PolyObject Spawn Point"; + sprite = "internal:polycenter"; + } + 762 + { + title = "PolyObject Spawn Point (Crush)"; + sprite = "internal:polycentercrush"; + } + 780 + { + title = "Skybox View Point"; + sprite = "internal:skyb"; + arg0 + { + title = "Type"; + type = 11; + enum + { + 0 = "Viewpoint"; + 1 = "Centerpoint"; + } + } + } + } + + greenflower + { + color = 10; // Green + title = "Greenflower"; + + 800 + { + title = "GFZ Flower"; + sprite = "FWR1A0"; + width = 16; + height = 40; + } + 801 + { + title = "Sunflower"; + sprite = "FWR2A0"; + width = 16; + height = 96; + } + 802 + { + title = "Budding Flower"; + sprite = "FWR3A0"; + width = 8; + height = 32; + } + 803 + { + title = "Blueberry Bush"; + sprite = "BUS3A0"; + width = 16; + height = 32; + } + 804 + { + title = "Berry Bush"; + sprite = "BUS1A0"; + width = 16; + height = 32; + } + 805 + { + title = "Bush"; + sprite = "BUS2A0"; + width = 16; + height = 32; + } + 806 + { + title = "GFZ Tree"; + sprite = "TRE1A0"; + width = 20; + height = 128; + } + 807 + { + title = "GFZ Berry Tree"; + sprite = "TRE1B0"; + width = 20; + height = 128; + } + 808 + { + title = "GFZ Cherry Tree"; + sprite = "TRE1C0"; + width = 20; + height = 128; + } + 809 + { + title = "Checkered Tree"; + sprite = "TRE2A0"; + width = 20; + height = 200; + } + 810 + { + title = "Checkered Tree (Sunset)"; + sprite = "TRE2B0"; + width = 20; + height = 200; + } + 811 + { + title = "Polygon Tree"; + sprite = "TRE4A0"; + width = 20; + height = 200; + } + 812 + { + title = "Bush Tree"; + sprite = "TRE5A0"; + width = 20; + height = 200; + } + 813 + { + title = "Red Bush Tree"; + sprite = "TRE5B0"; + width = 20; + height = 200; + } + } + + technohill + { + color = 10; // Green + title = "Techno Hill"; + + 900 + { + title = "THZ Steam Flower"; + sprite = "THZPA0"; + width = 8; + height = 32; + } + 901 + { + title = "Alarm"; + sprite = "ALRMA0"; + width = 8; + height = 16; + hangs = 1; + } + 902 + { + title = "THZ Spin Flower (Red)"; + sprite = "FWR5A0"; + width = 16; + height = 64; + } + 903 + { + title = "THZ Spin Flower (Yellow)"; + sprite = "FWR6A0"; + width = 16; + height = 64; + } + 904 + { + arrow = 1; + title = "Whistlebush"; + sprite = "THZTA0"; + width = 16; + height = 64; + } + } + + deepsea + { + color = 10; // Green + title = "Deep Sea"; + + 1000 + { + arrow = 1; + blocking = 2; + title = "Gargoyle"; + sprite = "GARGA1"; + width = 16; + height = 40; + arg0 + { + title = "Push behavior"; + type = 11; + enum = "pushablebehavior"; + } + } + 1009 + { + arrow = 1; + blocking = 2; + title = "Gargoyle (Big)"; + sprite = "GARGB1"; + width = 32; + height = 80; + arg0 + { + title = "Push behavior"; + type = 11; + enum = "pushablebehavior"; + } + } + 1001 + { + title = "Seaweed"; + sprite = "SEWEA0"; + width = 24; + height = 56; + } + 1002 + { + title = "Dripping Water"; + sprite = "DRIPD0"; + width = 8; + height = 16; + hangs = 1; + arg0 + { + title = "Dripping delay"; + } + } + 1003 + { + title = "Coral (Green)"; + sprite = "CORLA0"; + width = 29; + height = 40; + } + 1004 + { + title = "Coral (Red)"; + sprite = "CORLB0"; + width = 30; + height = 53; + } + 1005 + { + title = "Coral (Orange)"; + sprite = "CORLC0"; + width = 28; + height = 41; + } + 1006 + { + title = "Blue Crystal"; + sprite = "BCRYA1"; + width = 8; + height = 16; + } + 1007 + { + title = "Kelp"; + sprite = "KELPA0"; + width = 16; + height = 292; + arg0 + { + title = "Double size?"; + type = 11; + enum = "noyes"; + } + } + 1008 + { + title = "Stalagmite (DSZ1)"; + sprite = "DSTGA0"; + width = 8; + height = 116; + arg0 + { + title = "Double size?"; + type = 11; + enum = "noyes"; + } + } + 1010 + { + arrow = 1; + title = "Light Beam"; + sprite = "LIBEARAL"; + width = 16; + height = 16; + } + 1011 + { + title = "Stalagmite (DSZ2)"; + sprite = "DSTGA0"; + width = 8; + height = 116; + arg0 + { + title = "Double size?"; + type = 11; + enum = "noyes"; + } + } + 1012 + { + arrow = 1; + title = "Big Floating Mine"; + width = 28; + height = 56; + sprite = "BMNEA1"; + } + 1013 + { + title = "Animated Kelp"; + sprite = "ALGAA0"; + width = 48; + height = 120; + } + 1014 + { + title = "Large Coral (Brown)"; + sprite = "CORLD0"; + width = 56; + height = 112; + } + 1015 + { + title = "Large Coral (Beige)"; + sprite = "CORLE0"; + width = 56; + height = 112; + } + } + + castleeggman + { + color = 10; // Green + title = "Castle Eggman"; + + 1100 + { + title = "Chain (Decorative)"; + sprite = "CHANA0"; + width = 4; + height = 128; + hangs = 1; + } + 1101 + { + title = "Torch"; + sprite = "FLAMA0E0"; + width = 8; + height = 32; + arg0 + { + title = "Corona?"; + type = 11; + enum = "noyes"; + } + } + 1102 + { + arrow = 1; + blocking = 2; + title = "Eggman Statue"; + sprite = "ESTAA1"; + width = 32; + height = 240; + arg0 + { + title = "Push behavior"; + type = 11; + enum = "pushablebehavior"; + } + arg1 + { + title = "Solid gold?"; + type = 11; + enum = "noyes"; + } + } + 1103 + { + title = "CEZ Flower"; + sprite = "FWR4A0"; + width = 16; + height = 40; + } + 1104 + { + title = "Mace Spawnpoint"; + sprite = "SMCEA0"; + width = 17; + height = 34; + arg0 + { + title = "Number of links"; + } + arg1 + { + title = "Number of spokes"; + } + arg2 + { + title = "Width"; + } + arg3 + { + title = "Speed"; + } + arg4 + { + title = "Phase"; + type = 8; + } + arg5 + { + title = "Pinch"; + type = 8; + } + arg6 + { + title = "Omitted spokes"; + } + arg7 + { + title = "Omitted links"; + } + arg8 + { + title = "Flags"; + type = 12; + enum = "maceflags"; + } + } + 1105 + { + title = "Chain with Maces Spawnpoint"; + sprite = "SMCEA0"; + width = 17; + height = 34; + arg0 + { + title = "Number of links"; + } + arg1 + { + title = "Number of spokes"; + } + arg2 + { + title = "Width"; + } + arg3 + { + title = "Speed"; + } + arg4 + { + title = "Phase"; + type = 8; + } + arg5 + { + title = "Pinch"; + type = 8; + } + arg6 + { + title = "Omitted spokes"; + } + arg7 + { + title = "Omitted links"; + } + arg8 + { + title = "Flags"; + type = 12; + enum = "maceflags"; + } + } + 1106 + { + title = "Chained Spring Spawnpoint"; + sprite = "YSPBA0"; + width = 17; + height = 34; + arg0 + { + title = "Number of links"; + } + arg1 + { + title = "Number of spokes"; + } + arg2 + { + title = "Width"; + } + arg3 + { + title = "Speed"; + } + arg4 + { + title = "Phase"; + type = 8; + } + arg5 + { + title = "Pinch"; + type = 8; + } + arg6 + { + title = "Omitted spokes"; + } + arg7 + { + title = "Omitted links"; + } + arg8 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Red spring"; + 2 = "No sounds"; + 4 = "Player-turnable chain"; + 8 = "Swing instead of spin"; + 16 = "Make chain from end item"; + 32 = "Spawn link at origin"; + 64 = "Clip inside ground"; + 128 = "No distance check"; + } + } + } + 1107 + { + title = "Chain Spawnpoint"; + sprite = "BMCHA0"; + width = 17; + height = 34; + arg0 + { + title = "Number of links"; + } + arg1 + { + title = "Number of spokes"; + } + arg2 + { + title = "Width"; + } + arg3 + { + title = "Speed"; + } + arg4 + { + title = "Phase"; + type = 8; + } + arg5 + { + title = "Pinch"; + type = 8; + } + arg6 + { + title = "Omitted spokes"; + } + arg7 + { + title = "Omitted links"; + } + arg8 + { + title = "Flags"; + type = 12; + enum = "maceflags"; + + } + } + 1108 + { + arrow = 1; + title = "Hidden Chain Spawnpoint"; + sprite = "internal:chain3"; + width = 17; + height = 34; + } + 1109 + { + title = "Firebar Spawnpoint"; + sprite = "BFBRA0"; + width = 17; + height = 34; + arg0 + { + title = "Number of links"; + } + arg1 + { + title = "Number of spokes"; + } + arg2 + { + title = "Width"; + } + arg3 + { + title = "Speed"; + } + arg4 + { + title = "Phase"; + type = 8; + } + arg5 + { + title = "Pinch"; + type = 8; + } + arg6 + { + title = "Omitted spokes"; + } + arg7 + { + title = "Omitted links"; + } + arg8 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Double size"; + 2 = "No sounds"; + 4 = "Player-turnable chain"; + 8 = "Swing instead of spin"; + 16 = "Omit chain links"; + 32 = "Spawn link at origin"; + 64 = "Clip inside ground"; + 128 = "No distance check"; + } + } + } + 1110 + { + title = "Custom Mace Spawnpoint"; + sprite = "SMCEA0"; + width = 17; + height = 34; + arg0 + { + title = "Number of links"; + } + arg1 + { + title = "Number of spokes"; + } + arg2 + { + title = "Width"; + } + arg3 + { + title = "Speed"; + } + arg4 + { + title = "Phase"; + type = 8; + } + arg5 + { + title = "Pinch"; + type = 8; + } + arg6 + { + title = "Omitted spokes"; + } + arg7 + { + title = "Omitted links"; + } + arg8 + { + title = "Flags"; + type = 12; + enum = "maceflags"; + } + stringarg0 + { + title = "Mace object type"; + type = 2; + } + stringarg1 + { + title = "Link object type"; + type = 2; + } + } + 1111 + { + arrow = 1; + blocking = 2; + title = "Crawla Statue"; + sprite = "CSTAA1"; + width = 16; + height = 40; + arg0 + { + title = "Push behavior"; + type = 11; + enum = "pushablebehavior"; + } + } + 1112 + { + arrow = 1; + blocking = 2; + title = "Lance-a-Bot Statue"; + sprite = "CBBSA1"; + width = 32; + height = 72; + arg0 + { + title = "Push behavior"; + type = 11; + enum = "pushablebehavior"; + } + } + 1114 + { + title = "Pine Tree"; + sprite = "PINEA0"; + width = 16; + height = 628; + } + 1115 + { + title = "CEZ Shrub (Small)"; + sprite = "CEZBA0"; + width = 16; + height = 24; + } + 1116 + { + title = "CEZ Shrub (Large)"; + sprite = "CEZBB0"; + width = 32; + height = 48; + } + 1117 + { + arrow = 1; + title = "Pole Banner (Red)"; + sprite = "BANRA0"; + width = 40; + height = 224; + } + 1118 + { + arrow = 1; + title = "Pole Banner (Blue)"; + sprite = "BANRA0"; + width = 40; + height = 224; + } + 1119 + { + title = "Candle"; + sprite = "CNDLA0"; + width = 8; + height = 48; + arg0 + { + title = "Corona?"; + type = 11; + enum = "noyes"; + } + } + 1120 + { + title = "Candle Pricket"; + sprite = "CNDLB0"; + width = 8; + height = 176; + arg0 + { + title = "Corona?"; + type = 11; + enum = "noyes"; + } + } + 1121 + { + title = "Flame Holder"; + sprite = "FLMHA0"; + width = 24; + height = 80; + arg0 + { + title = "Flags"; + type = 12; + enum + { + 1 = "No flame"; + 2 = "Add corona"; + } + } + } + 1122 + { + title = "Fire Torch"; + sprite = "CTRCA0"; + width = 16; + height = 80; + } + 1123 + { + title = "Cannonball Launcher"; + sprite = "internal:cannonball"; + width = 8; + height = 16; + } + 1124 + { + blocking = 2; + title = "Cannonball"; + sprite = "CBLLA0"; + width = 20; + height = 40; + arg0 + { + title = "Push behavior"; + type = 11; + enum = "pushablebehavior"; + } + } + 1125 + { + title = "Brambles"; + sprite = "CABRALAR"; + width = 48; + height = 32; + } + 1126 + { + title = "Invisible Lockon Object"; + sprite = "LCKNC0"; + width = 16; + height = 32; + } + 1127 + { + title = "Spectator Eggrobo"; + sprite = "EGR1A1"; + width = 20; + height = 72; + arg0 + { + title = "Movement"; + type = 11; + enum + { + 0 = "None"; + 1 = "Right"; + 2 = "Left"; + } + } + } + 1128 + { + arrow = 1; + title = "Waving Flag (Red)"; + sprite = "CFLGA0"; + width = 8; + height = 208; + } + 1129 + { + arrow = 1; + title = "Waving Flag (Blue)"; + sprite = "CFLGA0"; + width = 8; + height = 208; + } + } + + aridcanyon + { + color = 10; // Green + title = "Arid Canyon"; + + 1200 + { + title = "Tumbleweed (Big)"; + sprite = "BTBLA0"; + width = 24; + height = 48; + arg0 + { + title = "Move perpetually?"; + type = 11; + enum = "noyes"; + } + } + 1201 + { + title = "Tumbleweed (Small)"; + sprite = "STBLA0"; + width = 12; + height = 24; + arg0 + { + title = "Move perpetually?"; + type = 11; + enum = "noyes"; + } + } + 1202 + { + arrow = 1; + title = "Rock Spawner"; + sprite = "ROIAA0"; + width = 8; + height = 16; + arg0 + { + title = "Speed"; + } + arg1 + { + title = "Spawn interval"; + } + arg2 + { + title = "Randomize speed?"; + type = 11; + enum = "noyes"; + } + stringarg0 + { + title = "Object type"; + type = 2; + } + } + 1203 + { + title = "Tiny Red Flower Cactus"; + sprite = "CACTA0"; + width = 13; + height = 24; + } + 1204 + { + title = "Small Red Flower Cactus"; + sprite = "CACTB0"; + width = 15; + height = 52; + } + 1205 + { + title = "Tiny Blue Flower Cactus"; + sprite = "CACTC0"; + width = 13; + height = 24; + } + 1206 + { + title = "Small Blue Flower Cactus"; + sprite = "CACTD0"; + width = 15; + height = 52; + } + 1207 + { + title = "Prickly Pear"; + sprite = "CACTE0"; + width = 32; + height = 96; + } + 1208 + { + title = "Barrel Cactus"; + sprite = "CACTF0"; + width = 20; + height = 128; + } + 1209 + { + title = "Tall Barrel Cactus"; + sprite = "CACTG0"; + width = 24; + height = 224; + } + 1210 + { + title = "Armed Cactus"; + sprite = "CACTH0"; + width = 24; + height = 256; + } + 1211 + { + title = "Ball Cactus"; + sprite = "CACTI0"; + width = 48; + height = 96; + } + 1212 + { + title = "Caution Sign"; + sprite = "WWSGAR"; + width = 22; + height = 64; + } + 1213 + { + title = "Cacti Sign"; + sprite = "WWS2AR"; + width = 22; + height = 64; + } + 1214 + { + title = "Sharp Turn Sign"; + sprite = "WWS3ALAR"; + width = 16; + height = 192; + } + 1215 + { + title = "Mine Oil Lamp"; + sprite = "OILLA0"; + width = 22; + height = 64; + hangs = 1; + } + 1216 + { + title = "TNT Barrel"; + sprite = "BARRA1"; + width = 24; + height = 63; + arg0 + { + title = "Push behavior"; + type = 11; + enum = "pushablebehavior"; + } + } + 1217 + { + title = "TNT Proximity Shell"; + sprite = "REMTA0"; + width = 64; + height = 40; + } + 1218 + { + title = "Dust Devil"; + sprite = "TAZDCR"; + width = 80; + height = 416; + } + 1219 + { + title = "Minecart Spawner"; + sprite = "MCRTCLFR"; + width = 22; + height = 32; + } + 1220 + { + title = "Minecart Stopper"; + sprite = "MCRTIR"; + width = 32; + height = 32; + } + 1221 + { + title = "Minecart Saloon Door"; + sprite = "SALDARAL"; + width = 96; + height = 160; + arg0 + { + title = "Allow non-minecart players?"; + type = 11; + enum = "noyes"; + } + } + 1222 + { + title = "Train Cameo Spawner"; + sprite = "TRAEBRBL"; + width = 28; + height = 32; + } + 1223 + { + title = "Train Dust Spawner"; + sprite = "ADSTA0"; + width = 4; + height = 4; + } + 1224 + { + title = "Train Steam Spawner"; + sprite = "STEAA0"; + width = 4; + height = 4; + } + 1229 + { + title = "Minecart Switch Point"; + sprite = "internal:zoom"; + width = 8; + height = 16; + arg0 + { + title = "Type"; + type = 11; + enum + { + 0 = "Disable"; + 1 = "Enable"; + } + } + } + 1230 + { + title = "Tiny Cactus"; + sprite = "CACTJ0"; + width = 13; + height = 28; + } + 1231 + { + title = "Small Cactus"; + sprite = "CACTK0"; + width = 15; + height = 60; + } + } + + redvolcano + { + color = 10; // Green + title = "Red Volcano"; + + 1300 + { + arrow = 1; + title = "Flame Jet (Horizontal)"; + sprite = "internal:flameh"; + width = 16; + height = 40; + arg0 + { + title = "On time"; + } + arg1 + { + title = "Off time"; + } + arg2 + { + title = "Strength"; + } + arg3 + { + title = "Waving direction"; + type = 11; + enum + { + 0 = "Horizontal"; + 1 = "Vertical"; + } + } + } + 1301 + { + title = "Flame Jet (Vertical)"; + sprite = "internal:flamev"; + width = 16; + height = 40; + arg0 + { + title = "On time"; + } + arg1 + { + title = "Off time"; + } + arg2 + { + title = "Strength"; + } + arg3 + { + title = "Shooting direction"; + type = 11; + enum + { + 0 = "Upwards"; + 1 = "Downwards"; + } + } + } + 1302 + { + title = "Spinning Flame Jet (Counter-Clockwise)"; + sprite = "internal:flame2"; + width = 16; + height = 24; + } + 1303 + { + title = "Spinning Flame Jet (Clockwise)"; + sprite = "internal:flame1"; + width = 16; + height = 24; + } + 1304 + { + title = "Lavafall"; + sprite = "LFALF0"; + width = 30; + height = 32; + arg0 + { + title = "Initial delay"; + } + arg1 + { + title = "Double size?"; + type = 11; + enum = "noyes"; + } + } + 1305 + { + title = "Rollout Rock"; + sprite = "PUMIA1A5"; + width = 30; + height = 60; + arg0 + { + title = "Buoyant?"; + type = 11; + enum = "yesno"; + } + } + 1306 + { + title = "Big Fern"; + sprite = "JPLAB0"; + width = 32; + height = 48; + } + 1307 + { + title = "Jungle Palm"; + sprite = "JPLAC0"; + width = 32; + height = 48; + } + 1308 + { + title = "Torch Flower"; + sprite = "TFLOA0"; + width = 14; + height = 110; + } + 1309 + { + title = "RVZ1 Wall Vine (Long)"; + sprite = "WVINALAR"; + width = 1; + height = 288; + } + 1310 + { + title = "RVZ1 Wall Vine (Short)"; + sprite = "WVINBLBR"; + width = 1; + height = 288; + } + } + + botanicserenity + { + color = 10; // Green + title = "Botanic Serenity"; + width = 16; + height = 32; + sprite = "BSZ1A0"; + 1400 + { + title = "Tall Flower (Red)"; + sprite = "BSZ1A0"; + } + 1401 + { + title = "Tall Flower (Purple)"; + sprite = "BSZ1B0"; + } + 1402 + { + title = "Tall Flower (Blue)"; + sprite = "BSZ1C0"; + } + 1403 + { + title = "Tall Flower (Cyan)"; + sprite = "BSZ1D0"; + } + 1404 + { + title = "Tall Flower (Yellow)"; + sprite = "BSZ1E0"; + } + 1405 + { + title = "Tall Flower (Orange)"; + sprite = "BSZ1F0"; + } + 1410 + { + title = "Medium Flower (Red)"; + sprite = "BSZ2A0"; + } + 1411 + { + title = "Medium Flower (Purple)"; + sprite = "BSZ2B0"; + } + 1412 + { + title = "Medium Flower (Blue)"; + sprite = "BSZ2C0"; + } + 1413 + { + title = "Medium Flower (Cyan)"; + sprite = "BSZ2D0"; + } + 1414 + { + title = "Medium Flower (Yellow)"; + sprite = "BSZ2E0"; + } + 1415 + { + title = "Medium Flower (Orange)"; + sprite = "BSZ2F0"; + } + 1420 + { + title = "Short Flower (Red)"; + sprite = "BSZ3A0"; + } + 1421 + { + title = "Short Flower (Purple)"; + sprite = "BSZ3B0"; + } + 1422 + { + title = "Short Flower (Blue)"; + sprite = "BSZ3C0"; + } + 1423 + { + title = "Short Flower (Cyan)"; + sprite = "BSZ3D0"; + } + 1424 + { + title = "Short Flower (Yellow)"; + sprite = "BSZ3E0"; + } + 1425 + { + title = "Short Flower (Orange)"; + sprite = "BSZ3F0"; + } + 1430 + { + title = "Tulip (Red)"; + sprite = "BST1A0"; + } + 1431 + { + title = "Tulip (Purple)"; + sprite = "BST2A0"; + } + 1432 + { + title = "Tulip (Blue)"; + sprite = "BST3A0"; + } + 1433 + { + title = "Tulip (Cyan)"; + sprite = "BST4A0"; + } + 1434 + { + title = "Tulip (Yellow)"; + sprite = "BST5A0"; + } + 1435 + { + title = "Tulip (Orange)"; + sprite = "BST6A0"; + } + 1440 + { + title = "Cluster (Red)"; + sprite = "BSZ5A0"; + } + 1441 + { + title = "Cluster (Purple)"; + sprite = "BSZ5B0"; + } + 1442 + { + title = "Cluster (Blue)"; + sprite = "BSZ5C0"; + } + 1443 + { + title = "Cluster (Cyan)"; + sprite = "BSZ5D0"; + } + 1444 + { + title = "Cluster (Yellow)"; + sprite = "BSZ5E0"; + } + 1445 + { + title = "Cluster (Orange)"; + sprite = "BSZ5F0"; + } + 1450 + { + title = "Bush (Red)"; + sprite = "BSZ6A0"; + } + 1451 + { + title = "Bush (Purple)"; + sprite = "BSZ6B0"; + } + 1452 + { + title = "Bush (Blue)"; + sprite = "BSZ6C0"; + } + 1453 + { + title = "Bush (Cyan)"; + sprite = "BSZ6D0"; + } + 1454 + { + title = "Bush (Yellow)"; + sprite = "BSZ6E0"; + } + 1455 + { + title = "Bush (Orange)"; + sprite = "BSZ6F0"; + } + 1460 + { + title = "Vine (Red)"; + sprite = "BSZ7A0"; + } + 1461 + { + title = "Vine (Purple)"; + sprite = "BSZ7B0"; + } + 1462 + { + title = "Vine (Blue)"; + sprite = "BSZ7C0"; + } + 1463 + { + title = "Vine (Cyan)"; + sprite = "BSZ7D0"; + } + 1464 + { + title = "Vine (Yellow)"; + sprite = "BSZ7E0"; + } + 1465 + { + title = "Vine (Orange)"; + sprite = "BSZ7F0"; + } + 1470 + { + title = "BSZ Shrub"; + sprite = "BSZ8A0"; + } + 1471 + { + title = "BSZ Clover"; + sprite = "BSZ8B0"; + } + 1473 + { + title = "Palm Tree (Big)"; + width = 16; + height = 160; + sprite = "BSZ8D0"; + } + 1475 + { + title = "Palm Tree (Small)"; + width = 16; + height = 80; + sprite = "BSZ8F0"; + } + } + + azuretemple + { + color = 10; // Green + title = "Azure Temple"; + + 1500 + { + arrow = 1; + blocking = 2; + title = "Glaregoyle"; + sprite = "BGARA1"; + width = 16; + height = 40; + arg0 + { + title = "Push behavior"; + type = 11; + enum = "pushablebehavior"; + } + arg1 + { + title = "Starting delay"; + } + } + 1501 + { + arrow = 1; + blocking = 2; + title = "Glaregoyle (Up)"; + sprite = "BGARA1"; + width = 16; + height = 40; + arg0 + { + title = "Push behavior"; + type = 11; + enum = "pushablebehavior"; + } + arg1 + { + title = "Starting delay"; + } + } + 1502 + { + arrow = 1; + blocking = 2; + title = "Glaregoyle (Down)"; + sprite = "BGARA1"; + width = 16; + height = 40; + arg0 + { + title = "Push behavior"; + type = 11; + enum = "pushablebehavior"; + } + arg1 + { + title = "Starting delay"; + } + } + 1503 + { + arrow = 1; + blocking = 2; + title = "Glaregoyle (Long)"; + sprite = "BGARA1"; + width = 16; + height = 40; + arg0 + { + title = "Push behavior"; + type = 11; + enum = "pushablebehavior"; + } + arg1 + { + title = "Starting delay"; + } + } + 1504 + { + title = "ATZ Target"; + sprite = "RCRYB0"; + width = 24; + height = 32; + } + 1505 + { + title = "Green Flame"; + sprite = "CFLMA0E0"; + width = 8; + height = 32; + } + 1506 + { + arrow = 1; + blocking = 2; + title = "Blue Gargoyle"; + sprite = "BGARD1"; + width = 16; + height = 40; + arg0 + { + title = "Push behavior"; + type = 11; + enum = "pushablebehavior"; + } + } + } + + dreamhill + { + color = 10; // Green + title = "Dream Hill"; + + 1600 + { + title = "Spring Tree"; + sprite = "TRE6A0"; + width = 16; + height = 32; + } + 1601 + { + title = "Shleep"; + sprite = "SHLPA0"; + width = 24; + height = 32; + } + 1602 + { + title = "Nightopian"; + sprite = "NTPNA1"; + width = 16; + height = 40; + arg0 + { + title = "Can move?"; + type = 11; + enum = "yesno"; + } + } + } + + nightstrk + { + color = 13; // Pink + title = "NiGHTS Track"; + width = 8; + height = 4096; + sprite = "UNKNA0"; + + 1700 + { + title = "Axis"; + sprite = "internal:axis1"; + circle = 1; + arg0 + { + title = "Mare"; + } + arg1 + { + title = "Order"; + } + arg2 + { + title = "Radius"; + } + arg3 + { + title = "Direction"; + type = 11; + enum + { + 0 = "Clockwise"; + 1 = "Counterclockwise"; + } + } + } + 1701 + { + title = "Axis Transfer"; + sprite = "internal:axis2"; + arg0 + { + title = "Mare"; + } + arg1 + { + title = "Order"; + } + } + 1702 + { + title = "Axis Transfer Line"; + sprite = "internal:axis3"; + arg0 + { + title = "Mare"; + } + arg1 + { + title = "Order"; + } + } + 1710 + { + title = "Ideya Capture"; + sprite = "CAPSA0"; + width = 72; + height = 144; + arg0 + { + title = "Mare"; + } + arg1 + { + title = "Required spheres"; + } + } + } + + nights + { + color = 13; // Pink + title = "NiGHTS Items"; + width = 16; + height = 32; + + 1703 + { + title = "Ideya Drone"; + sprite = "NDRNA1"; + width = 16; + height = 56; + arg0 + { + title = "Time limit"; + } + arg1 + { + title = "Height"; + } + arg2 + { + title = "Radius"; + } + arg3 + { + title = "Alignment"; + type = 11; + enum + { + 0 = "Bottom with offset"; + 1 = "Bottom"; + 2 = "Middle"; + 3 = "Top"; + } + } + arg4 + { + title = "Die upon time up?"; + type = 11; + enum = "noyes"; + } + } + 1704 + { + arrow = 1; + title = "NiGHTS Bumper"; + sprite = "NBMPG3G7"; + width = 32; + height = 64; + } + 1706 + { + title = "Blue Sphere"; + sprite = "SPHRA0"; + width = 16; + height = 24; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } + } + 1707 + { + title = "Super Paraloop"; + sprite = "NPRUA0"; + arg0 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Bonus time only"; + 2 = "Spawn immediately"; + } + } + } + 1708 + { + title = "Drill Refill"; + sprite = "NPRUB0"; + arg0 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Bonus time only"; + 2 = "Spawn immediately"; + } + } + } + 1709 + { + title = "Nightopian Helper"; + sprite = "NPRUC0"; + arg0 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Bonus time only"; + 2 = "Spawn immediately"; + } + } + } + 1711 + { + title = "Extra Time"; + sprite = "NPRUD0"; + arg0 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Bonus time only"; + 2 = "Spawn immediately"; + } + } + } + 1712 + { + title = "Link Freeze"; + sprite = "NPRUE0"; + arg0 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Bonus time only"; + 2 = "Spawn immediately"; + } + } + } + 1713 + { + arrow = 1; + title = "Hoop"; + sprite = "HOOPA0"; + width = 80; + height = 160; + arg0 + { + title = "Radius"; + } + } + 1714 + { + title = "Ideya Anchor Point"; + sprite = "internal:axis1"; + width = 8; + height = 16; + arg0 + { + title = "Mare"; + } + } + } + + mario + { + color = 6; // Brown + title = "Mario"; + + 1800 + { + title = "Coin"; + sprite = "COINA0"; + width = 16; + height = 24; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } + } + 1801 + { + arrow = 1; + title = "Goomba"; + sprite = "GOOMA0"; + width = 24; + height = 32; + } + 1802 + { + arrow = 1; + title = "Goomba (Blue)"; + sprite = "BGOMA0"; + width = 24; + height = 32; + } + 1803 + { + title = "Fire Flower"; + sprite = "FFWRB0"; + width = 16; + height = 32; + } + 1804 + { + title = "Koopa Shell"; + sprite = "SHLLA1"; + width = 16; + height = 20; + } + 1805 + { + title = "Puma (Jumping Fireball)"; + sprite = "PUMAA0"; + width = 8; + height = 16; + arg0 + { + title = "Jump strength"; + } + } + 1806 + { + title = "King Bowser"; + sprite = "KOOPA0"; + width = 16; + height = 48; + arg0 + { + title = "Death trigger tag"; + type = 15; + } + } + 1807 + { + title = "Axe"; + sprite = "MAXEA0"; + width = 8; + height = 16; + arg0 + { + title = "Death trigger tag"; + type = 15; + } + } + 1808 + { + title = "Bush (Short)"; + sprite = "MUS1A0"; + width = 16; + height = 32; + } + 1809 + { + title = "Bush (Tall)"; + sprite = "MUS2A0"; + width = 16; + height = 32; + } + 1810 + { + title = "Toad"; + sprite = "TOADA0"; + width = 8; + height = 32; + } + } + + christmasdisco + { + color = 10; // Green + title = "Christmas & Disco"; + + 1850 + { + title = "Christmas Pole"; + sprite = "XMS1A0"; + width = 16; + height = 40; + } + 1851 + { + title = "Candy Cane"; + sprite = "XMS2A0"; + width = 8; + height = 32; + } + 1852 + { + blocking = 2; + title = "Snowman"; + sprite = "XMS3A0"; + width = 16; + height = 64; + arg0 + { + title = "Push behavior"; + type = 11; + enum = "pushablebehavior"; + } + } + 1853 + { + blocking = 2; + title = "Snowman (With Hat)"; + sprite = "XMS3B0"; + width = 16; + height = 80; + arg0 + { + title = "Push behavior"; + type = 11; + enum = "pushablebehavior"; + } + } + 1854 + { + title = "Lamp Post"; + sprite = "XMS4A0"; + width = 8; + height = 120; + } + 1855 + { + title = "Lamp Post (Snow)"; + sprite = "XMS4B0"; + width = 8; + height = 120; + } + 1856 + { + title = "Hanging Star"; + sprite = "XMS5A0"; + width = 4; + height = 80; + hangs = 1; + } + 1857 + { + title = "Berry Bush (Snow)"; + sprite = "BUS1B0"; + width = 16; + height = 32; + } + 1858 + { + title = "Bush (Snow)"; + sprite = "BUS2B0"; + width = 16; + height = 32; + } + 1859 + { + title = "Blueberry Bush (Snow)"; + sprite = "BUS3B0"; + width = 16; + height = 32; + } + 1875 + { + title = "Disco Ball"; + sprite = "DBALA0"; + width = 16; + height = 54; + hangs = 1; + } + 1876 + { + arrow = 1; + blocking = 2; + title = "Eggman Disco Statue"; + sprite = "ESTAB1"; + width = 20; + height = 96; + arg0 + { + title = "Push behavior"; + type = 11; + enum = "pushablebehavior"; + } + } + } + + stalagmites + { + color = 10; // Green + title = "Stalagmites"; + width = 16; + height = 40; + + 1900 + { + title = "Brown Stalagmite (Tall)"; + sprite = "STLGA0"; + width = 16; + height = 40; + } + 1901 + { + title = "Brown Stalagmite"; + sprite = "STLGB0"; + width = 16; + height = 40; + } + 1902 + { + title = "Orange Stalagmite (Tall)"; + sprite = "STLGC0"; + width = 16; + height = 40; + } + 1903 + { + title = "Orange Stalagmite"; + sprite = "STLGD0"; + width = 16; + height = 40; + } + 1904 + { + title = "Red Stalagmite (Tall)"; + sprite = "STLGE0"; + width = 16; + height = 40; + } + 1905 + { + title = "Red Stalagmite"; + sprite = "STLGF0"; + width = 16; + height = 40; + } + 1906 + { + title = "Gray Stalagmite (Tall)"; + sprite = "STLGG0"; + width = 24; + height = 96; + } + 1907 + { + title = "Gray Stalagmite"; + sprite = "STLGH0"; + width = 16; + height = 40; + } + 1908 + { + title = "Blue Stalagmite (Tall)"; + sprite = "STLGI0"; + width = 16; + height = 40; + } + 1909 + { + title = "Blue Stalagmite"; + sprite = "STLGJ0"; + width = 16; + height = 40; + } + } + + hauntedheights + { + color = 10; // Green + title = "Haunted Heights"; + + 2000 + { + title = "Smashing Spikeball"; + sprite = "FMCEA0"; + width = 18; + height = 28; + arg0 + { + title = "Initial delay"; + } + } + 2001 + { + title = "HHZ Grass"; + sprite = "HHZMA0"; + width = 16; + height = 40; + } + 2002 + { + title = "HHZ Tentacle 1"; + sprite = "HHZMB0"; + width = 16; + height = 40; + } + 2003 + { + title = "HHZ Tentacle 2"; + sprite = "HHZMC0"; + width = 16; + height = 40; + } + 2004 + { + title = "HHZ Stalagmite (Tall)"; + sprite = "HHZME0"; + width = 16; + height = 40; + } + 2005 + { + title = "HHZ Stalagmite (Short)"; + sprite = "HHZMF0"; + width = 16; + height = 40; + } + 2006 + { + title = "Jack-o'-lantern 1"; + sprite = "PUMKA0"; + width = 16; + height = 40; + arg0 + { + title = "Flicker"; + type = 11; + enum = "yesno"; + } + } + 2007 + { + title = "Jack-o'-lantern 2"; + sprite = "PUMKB0"; + width = 16; + height = 40; + arg0 + { + title = "Flicker"; + type = 11; + enum = "yesno"; + } + } + 2008 + { + title = "Jack-o'-lantern 3"; + sprite = "PUMKC0"; + width = 16; + height = 40; + arg0 + { + title = "Flicker"; + type = 11; + enum = "yesno"; + } + } + 2009 + { + title = "Purple Mushroom"; + sprite = "SHRMD0"; + width = 16; + height = 48; + } + 2010 + { + title = "HHZ Tree"; + sprite = "HHPLC0"; + width = 12; + height = 40; + } + } + + frozenhillside + { + color = 10; // Green + title = "Frozen Hillside"; + + 2100 + { + title = "Ice Shard (Small)"; + sprite = "FHZIA0"; + width = 8; + height = 32; + } + 2101 + { + title = "Ice Shard (Large)"; + sprite = "FHZIB0"; + width = 8; + height = 32; + } + 2102 + { + title = "Crystal Tree (Aqua)"; + sprite = "TRE3A0"; + width = 20; + height = 200; + } + 2103 + { + title = "Crystal Tree (Pink)"; + sprite = "TRE3B0"; + width = 20; + height = 200; + } + 2104 + { + title = "Amy Cameo"; + sprite = "ROSYA1"; + width = 16; + height = 48; + arg0 + { + title = "Grayscale?"; + type = 11; + enum = "noyes"; + } + } + 2105 + { + title = "Mistletoe"; + sprite = "XMS6A0"; + width = 52; + height = 106; + } + } + + tutorial + { + color = 10; // Green + title = "Tutorial"; + + 799 + { + title = "Tutorial Plant"; + sprite = "TUPFH0"; + width = 40; + height = 144; + arg0 + { + title = "Start frame"; + } + } + } + + flickies + { + color = 10; // Green + title = "Flickies"; + width = 8; + height = 20; arg0 { title = "Radius"; - default = 32; - renderstyle = "Circle"; } arg1 { - title = "Turn strength"; - default = 2; - type = 0; + title = "Flags"; + type = 12; + enum + { + 1 = "Move aimlessly"; + 2 = "No movement"; + 4 = "Hop"; + } + } + + 2200 + { + title = "Bluebird"; + sprite = "FL01A1"; + } + 2201 + { + title = "Rabbit"; + sprite = "FL02A1"; + } + 2202 + { + title = "Chicken"; + sprite = "FL03A1"; + } + 2203 + { + title = "Seal"; + sprite = "FL04A1"; + } + 2204 + { + title = "Pig"; + sprite = "FL05A1"; + } + 2205 + { + title = "Chipmunk"; + sprite = "FL06A1"; + } + 2206 + { + title = "Penguin"; + sprite = "FL07A1"; + } + 2207 + { + title = "Fish"; + sprite = "FL08A1"; + arg2 + { + title = "Color"; + type = 11; + enum + { + 0 = "Random"; + 1 = "Red"; + 2 = "Cyan"; + 3 = "Blue"; + 4 = "Vapor"; + 5 = "Purple"; + 6 = "Bubblegum"; + 7 = "Neon"; + 8 = "Black"; + 9 = "Beige"; + 10 = "Lavender"; + 11 = "Ruby"; + 12 = "Salmon"; + 13 = "Sunset"; + 14 = "Orange"; + 15 = "Yellow"; + } + } + } + 2208 + { + title = "Ram"; + sprite = "FL09A1"; + } + 2209 + { + title = "Puffin"; + sprite = "FL10A1"; + } + 2210 + { + title = "Cow"; + sprite = "FL11A1"; + } + 2211 + { + title = "Rat"; + sprite = "FL12A1"; + } + 2212 + { + title = "Bear"; + sprite = "FL13A1"; + } + 2213 + { + title = "Dove"; + sprite = "FL14A1"; + } + 2214 + { + title = "Cat"; + sprite = "FL15A1"; + } + 2215 + { + title = "Canary"; + sprite = "FL16A1"; + } + 2216 + { + title = "Spider"; + sprite = "FS01A1"; + } + 2217 + { + title = "Bat"; + sprite = "FS02A0"; + } + } + + waypoints + { + color = 4; // Red + arrow = 1; + title = "Waypoints"; + sprite = "KBLNC0"; + width = 16; + height = 32; + + 2001 + { + title = "Waypoint (height = next waypoint ID)"; + sprite = "EMBMP0"; + angletext = "ID"; + flags1text = "[1] Disable"; + flags4text = "[4] Shortcut"; + flags8text = "[8] No respawn"; + arg0 + { + title = "Next Waypoint ID"; + type = 14; + } + arg1 + { + title = "Radius"; + default = 384; + renderstyle = "Circle"; + } + arg2 + { + title = "Finish Line?"; + type = 0; + } } } } diff --git a/extras/conf/udb/Kart2_UDMF.cfg b/extras/conf/udb/Kart2_UDMF.cfg index 3ea02325b..fe4fcb113 100644 --- a/extras/conf/udb/Kart2_UDMF.cfg +++ b/extras/conf/udb/Kart2_UDMF.cfg @@ -25,12 +25,6 @@ scriptlumpnames include("Includes\\Kart2_misc.cfg", "scriptlumpnames"); } -// THING TYPES -thingtypes -{ - include("Includes\\Kart2_things.cfg"); -} - //Default things filters thingsfilters { diff --git a/src/d_netcmd.c b/src/d_netcmd.c index ff5c9dd57..293dda851 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1076,7 +1076,7 @@ void D_RegisterClientCommands(void) // ingame object placing COM_AddCommand("objectplace", Command_ObjectPlace_f); - COM_AddCommand("writethings", Command_Writethings_f); + //COM_AddCommand("writethings", Command_Writethings_f); CV_RegisterVar(&cv_speed); CV_RegisterVar(&cv_opflags); CV_RegisterVar(&cv_ophoopflags); diff --git a/src/deh_lua.c b/src/deh_lua.c index 9c407dbda..56bfdf4ea 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -339,14 +339,85 @@ static inline int lib_getenum(lua_State *L) } else if (fastncmp("ML_", word, 3)) { p = word+3; - for (i = 0; i < 16; i++) - if (ML_LIST[i] && fastcmp(p, ML_LIST[i])) { + for (i = 0; ML_LIST[i]; i++) + if (fastcmp(p, ML_LIST[i])) { lua_pushinteger(L, ((lua_Integer)1<mo->angle = FixedAngle(mthing->angle << FRACBITS); f = gh->mo->floorz; c = gh->mo->ceilingz - mobjinfo[MT_PLAYER].height; - if (!!(mthing->options & MTF_AMBUSH) ^ !!(mthing->options & MTF_OBJECTFLIP)) + if (!!(mthing->args[0]) ^ !!(mthing->options & MTF_OBJECTFLIP)) { z = c - offset; if (z < f) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index f9c60f94e..e1fd97cd1 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1098,7 +1098,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // PEGGING if (gl_linedef->flags & ML_DONTPEGTOP) texturevpegtop = 0; - else if (gl_linedef->flags & ML_EFFECT1) + else if (gl_linedef->flags & ML_SKEWTD) texturevpegtop = worldhigh + textureheight[gl_sidedef->toptexture] - worldtop; else texturevpegtop = gl_backsector->ceilingheight + textureheight[gl_sidedef->toptexture] - gl_frontsector->ceilingheight; @@ -1114,7 +1114,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; // Adjust t value for sloped walls - if (!(gl_linedef->flags & ML_EFFECT1)) + if (!(gl_linedef->flags & ML_SKEWTD)) { // Unskewed wallVerts[3].t -= (worldtop - gl_frontsector->ceilingheight) * grTex->scaleY; @@ -1171,7 +1171,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // PEGGING if (!(gl_linedef->flags & ML_DONTPEGBOTTOM)) texturevpegbottom = 0; - else if (gl_linedef->flags & ML_EFFECT1) + else if (gl_linedef->flags & ML_SKEWTD) texturevpegbottom = worldbottom - worldlow; else texturevpegbottom = gl_frontsector->floorheight - gl_backsector->floorheight; @@ -1187,7 +1187,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; // Adjust t value for sloped walls - if (!(gl_linedef->flags & ML_EFFECT1)) + if (!(gl_linedef->flags & ML_SKEWTD)) { // Unskewed wallVerts[0].t -= (worldbottom - gl_frontsector->floorheight) * grTex->scaleY; @@ -1251,7 +1251,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if (gl_sidedef->repeatcnt) repeats = 1 + gl_sidedef->repeatcnt; - else if (gl_linedef->flags & ML_EFFECT5) + else if (gl_linedef->flags & ML_WRAPMIDTEX) { fixed_t high, low; @@ -1293,9 +1293,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom popenbottom = max(worldbottom, worldlow); } - if (gl_linedef->flags & ML_EFFECT2) + if (gl_linedef->flags & ML_NOSKEW) { - if (!!(gl_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gl_linedef->flags & ML_EFFECT3)) + if (gl_linedef->flags & ML_MIDPEG) { polybottom = max(front->floorheight, back->floorheight) + gl_sidedef->rowoffset; polytop = polybottom + textureheight[gl_midtexture]*repeats; @@ -1306,7 +1306,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom polybottom = polytop - textureheight[gl_midtexture]*repeats; } } - else if (!!(gl_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gl_linedef->flags & ML_EFFECT3)) + else if (gl_linedef->flags & ML_MIDPEG) { polybottom = popenbottom + gl_sidedef->rowoffset; polytop = polybottom + textureheight[gl_midtexture]*repeats; @@ -1336,7 +1336,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom { // PEGGING - if (!!(gl_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gl_linedef->flags & ML_EFFECT3)) + if (gl_linedef->flags & ML_MIDPEG) texturevpeg = textureheight[gl_sidedef->midtexture]*repeats - h + polybottom; else texturevpeg = polytop - h; @@ -1359,9 +1359,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom { fixed_t midtextureslant; - if (gl_linedef->flags & ML_EFFECT2) + if (gl_linedef->flags & ML_NOSKEW) midtextureslant = 0; - else if (!!(gl_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gl_linedef->flags & ML_EFFECT3)) + else if (gl_linedef->flags & ML_MIDPEG) midtextureslant = worldlow < worldbottom ? worldbottomslope-worldbottom : worldlowslope-worldlow; @@ -1386,7 +1386,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom { // PEGGING - if (!!(gl_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gl_linedef->flags & ML_EFFECT3)) + if (gl_linedef->flags & ML_MIDPEG) texturevpeg = textureheight[gl_sidedef->midtexture]*repeats - h + polybottom; else texturevpeg = polytop - h; @@ -1400,44 +1400,17 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // set alpha for transparent walls // ooops ! this do not work at all because render order we should render it in backtofront order - switch (gl_linedef->special) + if (gl_linedef->blendmode && gl_linedef->blendmode != AST_FOG) { - // Translucent - case 102: - case 121: - case 123: - case 124: - case 125: - case 141: - case 142: - case 144: - case 145: - case 174: - case 175: - case 192: - case 195: - case 221: - case 253: - case 256: - if (gl_linedef->blendmode && gl_linedef->blendmode != AST_FOG) - blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), &Surf); - else - blendmode = PF_Translucent; - break; - default: - if (gl_linedef->blendmode && gl_linedef->blendmode != AST_FOG) - { - if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT) - blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), &Surf); - else - blendmode = HWR_GetBlendModeFlag(gl_linedef->blendmode); - } - else if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT) - blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gl_linedef->alpha), &Surf); - else - blendmode = PF_Masked; - break; + if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT) + blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), &Surf); + else + blendmode = HWR_GetBlendModeFlag(gl_linedef->blendmode); } + else if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT) + blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gl_linedef->alpha), &Surf); + else + blendmode = PF_Masked; if (gl_curline->polyseg && gl_curline->polyseg->translucency > 0) { @@ -1505,7 +1478,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom { fixed_t texturevpeg; // PEGGING - if ((gl_linedef->flags & (ML_DONTPEGBOTTOM|ML_EFFECT2)) == (ML_DONTPEGBOTTOM|ML_EFFECT2)) + if ((gl_linedef->flags & (ML_DONTPEGBOTTOM|ML_NOSKEW)) == (ML_DONTPEGBOTTOM|ML_NOSKEW)) texturevpeg = gl_frontsector->floorheight + textureheight[gl_sidedef->midtexture] - gl_frontsector->ceilingheight + gl_sidedef->rowoffset; else if (gl_linedef->flags & ML_DONTPEGBOTTOM) texturevpeg = worldbottom + textureheight[gl_sidedef->midtexture] - worldtop + gl_sidedef->rowoffset; @@ -1521,7 +1494,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; // Texture correction for slopes - if (gl_linedef->flags & ML_EFFECT2) { + if (gl_linedef->flags & ML_NOSKEW) { wallVerts[3].t += (gl_frontsector->ceilingheight - worldtop) * grTex->scaleY; wallVerts[2].t += (gl_frontsector->ceilingheight - worldtopslope) * grTex->scaleY; wallVerts[0].t += (gl_frontsector->floorheight - worldbottom) * grTex->scaleY; @@ -1676,13 +1649,13 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom { texturevpeg = sides[newline->sidenum[0]].rowoffset; attachtobottom = !!(newline->flags & ML_DONTPEGBOTTOM); - slopeskew = !!(newline->flags & ML_DONTPEGTOP); + slopeskew = !!(newline->flags & ML_SKEWTD); } else { texturevpeg = sides[rover->master->sidenum[0]].rowoffset; attachtobottom = !!(gl_linedef->flags & ML_DONTPEGBOTTOM); - slopeskew = !!(rover->master->flags & ML_DONTPEGTOP); + slopeskew = !!(rover->master->flags & ML_SKEWTD); } grTex = HWR_GetTexture(texnum); @@ -3033,13 +3006,13 @@ static void HWR_Subsector(size_t num) } light = R_GetPlaneLight(gl_frontsector, locFloorHeight, false); - if (gl_frontsector->floorlightsec == -1) - floorlightlevel = *gl_frontsector->lightlist[light].lightlevel; + if (gl_frontsector->floorlightsec == -1 && !gl_frontsector->floorlightabsolute) + floorlightlevel = max(0, min(255, *gl_frontsector->lightlist[light].lightlevel + gl_frontsector->floorlightlevel)); floorcolormap = *gl_frontsector->lightlist[light].extra_colormap; light = R_GetPlaneLight(gl_frontsector, locCeilingHeight, false); - if (gl_frontsector->ceilinglightsec == -1) - ceilinglightlevel = *gl_frontsector->lightlist[light].lightlevel; + if (gl_frontsector->ceilinglightsec == -1 && !gl_frontsector->ceilinglightabsolute) + ceilinglightlevel = max(0, min(255, *gl_frontsector->lightlist[light].lightlevel + gl_frontsector->ceilinglightlevel)); ceilingcolormap = *gl_frontsector->lightlist[light].extra_colormap; } @@ -3570,7 +3543,7 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v return false; cullplane = FIXED_TO_FLOAT(cullheight->frontsector->floorheight); - if (cullheight->flags & ML_NOCLIMB) // Group culling + if (cullheight->args[1]) // Group culling { if (!viewcullheight) return false; diff --git a/src/info.c b/src/info.c index ee71d9972..b1f4bc1be 100644 --- a/src/info.c +++ b/src/info.c @@ -1002,7 +1002,7 @@ state_t states[NUMSTATES] = {SPR_TRET, FF_FULLBRIGHT|2, 7, {A_Pain}, 0, 0, S_TURRETSHOCK7}, // S_TURRETSHOCK6 {SPR_TRET, FF_FULLBRIGHT|3, 7, {NULL}, 0, 0, S_TURRETSHOCK8}, // S_TURRETSHOCK7 {SPR_TRET, FF_FULLBRIGHT|4, 7, {NULL}, 0, 0, S_TURRETSHOCK9}, // S_TURRETSHOCK8 - {SPR_TRET, FF_FULLBRIGHT|4, 7, {A_LinedefExecute}, LE_TURRET, 0, S_XPLD1}, // S_TURRETSHOCK9 + {SPR_TRET, FF_FULLBRIGHT|4, 7, {A_LinedefExecuteFromArg}, 0, 0, S_XPLD1}, // S_TURRETSHOCK9 {SPR_TURR, 0, 1, {A_Look}, 1, 0, S_TURRETPOPDOWN8}, // S_TURRETLOOK {SPR_TURR, 0, 0, {A_FaceTarget}, 0, 0, S_TURRETPOPUP1}, // S_TURRETSEE @@ -1555,7 +1555,7 @@ state_t states[NUMSTATES] = {SPR_FANG, 18, 16, {A_FaceTarget}, 3, 0, S_FANG_PINCHLOBSHOT1}, // S_FANG_PINCHLOBSHOT0 {SPR_FANG, 19, 2, {A_FaceTarget}, 3, 0, S_FANG_PINCHLOBSHOT2}, // S_FANG_PINCHLOBSHOT1 {SPR_FANG, 20, 30, {A_Boss5MakeItRain}, MT_FBOMB, -16, S_FANG_PINCHLOBSHOT3}, // S_FANG_PINCHLOBSHOT2 - {SPR_FANG, 20, 18, {A_LinedefExecute}, LE_BOSS4DROP, 0, S_FANG_PINCHLOBSHOT4}, // S_FANG_PINCHLOBSHOT3 + {SPR_FANG, 20, 18, {A_LinedefExecuteFromArg}, 4, 0, S_FANG_PINCHLOBSHOT4}, // S_FANG_PINCHLOBSHOT3 {SPR_FANG, 0, 0, {A_Boss5Calm}, 0, 0, S_FANG_PATHINGSTART1}, // S_FANG_PINCHLOBSHOT4 {SPR_FANG, 21, 0, {A_DoNPCPain}, 0, 0, S_FANG_DIE2}, // S_FANG_DIE1 @@ -18929,13 +18929,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - // ambient water 1a (large) - { // MT_AWATERA + // ambient sound effect + { // MT_AMBIENT 700, // doomednum S_INVISIBLE, // spawnstate - 35, // spawnhealth + 1000, // spawnhealth S_NULL, // seestate - sfx_amwtr1, // seesound + sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate @@ -18957,283 +18957,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - // ambient water 1b (large) - { // MT_AWATERB - 701, // doomednum - S_INVISIBLE, // spawnstate - 35, // spawnhealth - S_NULL, // seestate - sfx_amwtr2, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 16*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags - S_NULL // raisestate - }, - - // ambient water 2a (medium) - { // MT_AWATERC - 702, // doomednum - S_INVISIBLE, // spawnstate - 35, // spawnhealth - S_NULL, // seestate - sfx_amwtr3, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 16*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags - S_NULL // raisestate - }, - - // ambient water 2b (medium) - { // MT_AWATERD - 703, // doomednum - S_INVISIBLE, // spawnstate - 35, // spawnhealth - S_NULL, // seestate - sfx_amwtr4, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 16*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags - S_NULL // raisestate - }, - - // ambient water 3a (small) - { // MT_AWATERE - 704, // doomednum - S_INVISIBLE, // spawnstate - 35, // spawnhealth - S_NULL, // seestate - sfx_amwtr5, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 16*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags - S_NULL // raisestate - }, - - // ambient water 3b (small) - { // MT_AWATERF - 705, // doomednum - S_INVISIBLE, // spawnstate - 35, // spawnhealth - S_NULL, // seestate - sfx_amwtr6, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 16*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags - S_NULL // raisestate - }, - - // ambient water 4a (extra large) - { // MT_AWATERG - 706, // doomednum - S_INVISIBLE, // spawnstate - 35, // spawnhealth - S_NULL, // seestate - sfx_amwtr7, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_SPLASH1, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 16*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags - S_NULL // raisestate - }, - - // ambient water 4b (extra large) - { // MT_AWATERH - 707, // doomednum - S_INVISIBLE, // spawnstate - 35, // spawnhealth - S_NULL, // seestate - sfx_amwtr8, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 16*FRACUNIT, // height - 0, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags - S_NULL // raisestate - }, - - { // MT_RANDOMAMBIENT - 708, // doomednum - S_INVISIBLE, // spawnstate - 512, // spawnhealth: repeat speed - S_NULL, // seestate - sfx_ambint, // seesound - 0, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 255, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 8*FRACUNIT, // radius - 16*FRACUNIT, // height - 0, // display offset - 1000, // mass - 0, // damage - sfx_None, // activesound - MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_AMBIENT, // flags - S_NULL // raisestate - }, - - { // MT_RANDOMAMBIENT2 - 709, // doomednum - S_INVISIBLE, // spawnstate - 220, // spawnhealth: repeat speed - S_NULL, // seestate - sfx_ambin2, // seesound - 0, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 255, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 8*FRACUNIT, // radius - 16*FRACUNIT, // height - 0, // display offset - 1000, // mass - 0, // damage - sfx_None, // activesound - MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_AMBIENT, // flags - S_NULL // raisestate - }, - - { // MT_MACHINEAMBIENCE - 710, // doomednum - S_INVISIBLE, // spawnstate - 24, // spawnhealth: repeat speed - S_NULL, // seestate - sfx_ambmac, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 200, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 1*FRACUNIT, // speed - 16*FRACUNIT, // radius - 16*FRACUNIT, // height - 0, // display offset - 100, // mass - 20, // damage - sfx_None, // activesound - MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_AMBIENT, // flags - S_NULL // raisestate - }, - { // MT_CORK -1, // doomednum S_CORK, // spawnstate @@ -21586,34 +21309,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - // for use with wind and current effects - { // MT_PULL - 755, // doomednum - S_INVISIBLE, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 8, // radius - 8, // height - 0, // display offset - 10, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOGRAVITY, // flags - S_NULL // raisestate - }, - { // MT_GHOST -1, // doomednum S_THOK, // spawnstate diff --git a/src/info.h b/src/info.h index 975122946..176705a41 100644 --- a/src/info.h +++ b/src/info.h @@ -134,6 +134,7 @@ enum actionnum A_BOSS3PATH, A_BOSS3SHOCKTHINK, A_LINEDEFEXECUTE, + A_LINEDEFEXECUTEFROMARG, A_PLAYSEESOUND, A_PLAYATTACKSOUND, A_PLAYACTIVESOUND, @@ -396,6 +397,7 @@ void A_Boss3TakeDamage(); void A_Boss3Path(); void A_Boss3ShockThink(); void A_LinedefExecute(); +void A_LinedefExecuteFromArg(); void A_PlaySeeSound(); void A_PlayAttackSound(); void A_PlayActiveSound(); @@ -6171,17 +6173,7 @@ typedef enum mobj_type MT_FINISHFLAG, // Finish flag // Ambient Sounds - MT_AWATERA, // Ambient Water Sound 1 - MT_AWATERB, // Ambient Water Sound 2 - MT_AWATERC, // Ambient Water Sound 3 - MT_AWATERD, // Ambient Water Sound 4 - MT_AWATERE, // Ambient Water Sound 5 - MT_AWATERF, // Ambient Water Sound 6 - MT_AWATERG, // Ambient Water Sound 7 - MT_AWATERH, // Ambient Water Sound 8 - MT_RANDOMAMBIENT, - MT_RANDOMAMBIENT2, - MT_MACHINEAMBIENCE, + MT_AMBIENT, MT_CORK, MT_LHRT, @@ -6285,7 +6277,6 @@ typedef enum mobj_type MT_CRUMBLEOBJ, // Sound generator for crumbling platform MT_TUBEWAYPOINT, MT_PUSH, - MT_PULL, MT_GHOST, MT_OVERLAY, MT_ANGLEMAN, diff --git a/src/k_bot.c b/src/k_bot.c index 1b5a183b0..1c2ab4b80 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -1318,7 +1318,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) return; } - if (botController != NULL && (botController->flags & ML_EFFECT2)) + if (botController != NULL && (botController->flags & ML_NOSKEW)) // FIXME: UDMF-ify { // Disable bot controls entirely. return; @@ -1326,7 +1326,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) destangle = player->mo->angle; - if (botController != NULL && (botController->flags & ML_EFFECT1)) + if (botController != NULL && (botController->flags & ML_SKEWTD)) // FIXME: UDMF-ify { const fixed_t dist = DEFAULT_WAYPOINT_RADIUS * player->mo->scale; diff --git a/src/k_botsearch.c b/src/k_botsearch.c index 48c5745fd..52fbc19e0 100644 --- a/src/k_botsearch.c +++ b/src/k_botsearch.c @@ -144,22 +144,14 @@ UINT8 K_EggboxStealth(fixed_t x, fixed_t y) --------------------------------------------------*/ static boolean K_BotHatesThisSectorsSpecial(player_t *player, sector_t *sec) { - switch (GETSECSPECIAL(sec->special, 1)) + if (sec->damagetype != SD_NONE) { - case 1: // Damage - case 5: // Spikes - case 6: case 7: // Death Pit - case 8: // Instant Kill - return true; - //case 2: case 3: // Offroad (let's let them lawnmower) - case 4: // Offroad (Strong) - if (!K_BotCanTakeCut(player)) - { - return true; - } - break; - default: - break; + return true; + } + + if (sec->offroad > FRACUNIT) // Only care about strong offroad. + { + return !K_BotCanTakeCut(player); } return false; @@ -177,7 +169,7 @@ boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t sector_t *bestsector = NULL; ffloor_t *rover; - // TODO: Properly support SF_FLIPSPECIAL_FLOOR / SF_FLIPSPECIAL_CEILING. + // TODO: Properly support MSF_FLIPSPECIAL_FLOOR / MSF_FLIPSPECIAL_CEILING. // An earlier attempt at it caused lots of false positives and other weird // quirks with intangible FOFs. diff --git a/src/k_brightmap.c b/src/k_brightmap.c index a70d7a955..d5ed88e2a 100644 --- a/src/k_brightmap.c +++ b/src/k_brightmap.c @@ -86,31 +86,29 @@ static brightmapStorage_t *K_GetBrightmapStorageByTextureName(const char *checkN } /*-------------------------------------------------- - static boolean K_BRIGHTLumpParser(UINT8 *data, size_t size) + static boolean K_BRIGHTLumpParser(size_t size) Parses inputted lump data as a BRIGHT lump. Input Arguments:- - data - Pointer to lump data. size - The length of the lump data. Return:- false if any errors occured, otherwise true. --------------------------------------------------*/ -static boolean K_BRIGHTLumpParser(UINT8 *data, size_t size) +static boolean K_BRIGHTLumpParser(size_t size) { - char *tkn = M_GetToken((char *)data); + const char *tkn = M_TokenizerRead(0); size_t pos = 0; - while (tkn && (pos = M_GetTokenPos()) < size) + while (tkn && (pos = M_TokenizerGetEndPos()) < size) { boolean valid = true; if (stricmp(tkn, "texture") == 0) { - Z_Free(tkn); - tkn = M_GetToken(NULL); - pos = M_GetTokenPos(); + tkn = M_TokenizerRead(0); + pos = M_TokenizerGetEndPos(); if (tkn && pos < size) { @@ -123,9 +121,8 @@ static boolean K_BRIGHTLumpParser(UINT8 *data, size_t size) bms->textureHash = quickncasehash(tkn, 8); } - Z_Free(tkn); - tkn = M_GetToken(NULL); - pos = M_GetTokenPos(); + tkn = M_TokenizerRead(0); + pos = M_TokenizerGetEndPos(); if (tkn && pos < size) { @@ -151,17 +148,14 @@ static boolean K_BRIGHTLumpParser(UINT8 *data, size_t size) valid = false; } - Z_Free(tkn); - if (valid == false) { return false; } - tkn = M_GetToken(NULL); + tkn = M_TokenizerRead(0); } - Z_Free(tkn); return true; } @@ -198,7 +192,10 @@ void K_InitBrightmapsPwad(INT32 wadNum) size = W_LumpLengthPwad(wadNum, lumpNum); CONS_Printf(M_GetText("Loading BRIGHT from %s\n"), name); - K_BRIGHTLumpParser(data, size); + + M_TokenizerOpen((char *)data); + K_BRIGHTLumpParser(size); + M_TokenizerClose(); free(name); Z_Free(data); diff --git a/src/k_kart.c b/src/k_kart.c index 398b3f235..ecd04957c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1842,10 +1842,9 @@ boolean K_KartSolidBounce(mobj_t *bounceMobj, mobj_t *solidMobj) \return boolean */ -static UINT8 K_CheckOffroadCollide(mobj_t *mo) +static fixed_t K_CheckOffroadCollide(mobj_t *mo) { // Check for sectors in touching_sectorlist - UINT8 i; // special type iter msecnode_t *node; // touching_sectorlist iter sector_t *s; // main sector shortcut sector_t *s2; // FOF sector shortcut @@ -1874,13 +1873,11 @@ static UINT8 K_CheckOffroadCollide(mobj_t *mo) cel = P_MobjCeilingZ(mo, s, s, mo->x, mo->y, NULL, true, true); // get Z coords of both floors and ceilings for this sector (this accounts for slopes properly.) // NOTE: we don't use P_GetZAt with our x/y directly because the mobj won't have the same height because of its hitbox on the slope. Complex garbage but tldr it doesn't work. - if ( ((s->flags & SF_FLIPSPECIAL_FLOOR) && mo->z == flr) // floor check - || ((mo->eflags & MFE_VERTICALFLIP && (s->flags & SF_FLIPSPECIAL_CEILING) && (mo->z + mo->height) == cel)) ) // ceiling check. - - for (i = 2; i < 5; i++) // check for sector special - - if (GETSECSPECIAL(s->special, 1) == i) - return i-1; // return offroad type + if ( ((s->flags & MSF_FLIPSPECIAL_FLOOR) && mo->z == flr) // floor check + || ((mo->eflags & MFE_VERTICALFLIP && (s->flags & MSF_FLIPSPECIAL_CEILING) && (mo->z + mo->height) == cel)) ) // ceiling check. + { + return s->offroad; + } // 2: If we're here, we haven't found anything. So let's try looking for FOFs in the sectors using the same logic. for (rover = s->ffloors; rover; rover = rover->next) @@ -1895,18 +1892,15 @@ static UINT8 K_CheckOffroadCollide(mobj_t *mo) // we will do essentially the same checks as above instead of bothering with top/bottom height of the FOF. // Reminder that an FOF's floor is its bottom, silly! - if ( ((s2->flags & SF_FLIPSPECIAL_FLOOR) && mo->z == cel) // "floor" check - || ((s2->flags & SF_FLIPSPECIAL_CEILING) && (mo->z + mo->height) == flr) ) // "ceiling" check. - - for (i = 2; i < 5; i++) // check for sector special - - if (GETSECSPECIAL(s2->special, 1) == i) - return i-1; // return offroad type - + if ( ((s2->flags & MSF_FLIPSPECIAL_FLOOR) && mo->z == cel) // "floor" check + || ((s2->flags & MSF_FLIPSPECIAL_CEILING) && (mo->z + mo->height) == flr) ) // "ceiling" check. + { + return s2->offroad; + } } } - return 0; // couldn't find any offroad + return 0; // couldn't find any offroad } /** \brief Updates the Player's offroad value once per frame @@ -1920,13 +1914,14 @@ static void K_UpdateOffroad(player_t *player) terrain_t *terrain = player->mo->terrain; fixed_t offroadstrength = 0; + // TODO: Make this use actual special touch code. if (terrain != NULL && terrain->offroad > 0) { offroadstrength = (terrain->offroad << FRACBITS); } else { - offroadstrength = (K_CheckOffroadCollide(player->mo) << FRACBITS); + offroadstrength = K_CheckOffroadCollide(player->mo); } // If you are in offroad, a timer starts. diff --git a/src/k_race.c b/src/k_race.c index 1354b9d56..2e7f477e9 100644 --- a/src/k_race.c +++ b/src/k_race.c @@ -112,6 +112,8 @@ static void K_CreateFinishLineFromPoints(fixed_t x1, fixed_t y1, fixed_t x2, fix finishBeamLine->dx = x2 - x1; finishBeamLine->dy = y2 - y1; + finishBeamLine->angle = R_PointToAngle2(0, 0, finishBeamLine->dx, finishBeamLine->dy); + finishBeamLine->flags = 0; } @@ -241,7 +243,7 @@ static void K_DrawFinishLineBeamForLine(fixed_t offset, angle_t aiming, line_t * fixed_t linex = line->v1->x; fixed_t liney = line->v1->y; - angle_t lineangle = R_PointToAngle2(0, 0, line->dx, line->dy) + ANGLE_90; + angle_t lineangle = line->angle + ANGLE_90; UINT8 i; diff --git a/src/k_terrain.c b/src/k_terrain.c index cd420e37a..6204db63f 100644 --- a/src/k_terrain.c +++ b/src/k_terrain.c @@ -1087,7 +1087,7 @@ void K_UpdateTerrainOverlay(mobj_t *mo) } /*-------------------------------------------------- - static void K_FlagBoolean(UINT32 *inputFlags, UINT32 newFlag, char *val) + static void K_FlagBoolean(UINT32 *inputFlags, UINT32 newFlag, const char *val) Sets a flag to true or false depending on the string input. @@ -1100,7 +1100,7 @@ void K_UpdateTerrainOverlay(mobj_t *mo) Return:- None --------------------------------------------------*/ -static void K_FlagBoolean(UINT32 *inputFlags, UINT32 newFlag, char *val) +static void K_FlagBoolean(UINT32 *inputFlags, UINT32 newFlag, const char *val) { if (stricmp(val, "true") == 0) { @@ -1158,7 +1158,7 @@ static void K_NewSplashDefs(void) } /*-------------------------------------------------- - static void K_ParseSplashParameter(size_t i, char *param, char *val) + static void K_ParseSplashParameter(size_t i, const char *param, const char *val) Parser function for Splash blocks. @@ -1170,7 +1170,7 @@ static void K_NewSplashDefs(void) Return:- None --------------------------------------------------*/ -static void K_ParseSplashParameter(size_t i, char *param, char *val) +static void K_ParseSplashParameter(size_t i, const char *param, const char *val) { t_splash_t *splash = &splashDefs[i]; @@ -1260,7 +1260,7 @@ static void K_NewFootstepDefs(void) } /*-------------------------------------------------- - static void K_ParseFootstepParameter(size_t i, char *param, char *val) + static void K_ParseFootstepParameter(size_t i, const char *param, const char *val) Parser function for Footstep blocks. @@ -1272,7 +1272,7 @@ static void K_NewFootstepDefs(void) Return:- None --------------------------------------------------*/ -static void K_ParseFootstepParameter(size_t i, char *param, char *val) +static void K_ParseFootstepParameter(size_t i, const char *param, const char *val) { t_footstep_t *footstep = &footstepDefs[i]; @@ -1367,7 +1367,7 @@ static void K_NewOverlayDefs(void) } /*-------------------------------------------------- - static void K_ParseOverlayParameter(size_t i, char *param, char *val) + static void K_ParseOverlayParameter(size_t i, const char *param, const char *val) Parser function for Overlay blocks. @@ -1379,7 +1379,7 @@ static void K_NewOverlayDefs(void) Return:- None --------------------------------------------------*/ -static void K_ParseOverlayParameter(size_t i, char *param, char *val) +static void K_ParseOverlayParameter(size_t i, const char *param, const char *val) { t_overlay_t *overlay = &overlayDefs[i]; @@ -1449,7 +1449,7 @@ static void K_NewTerrainDefs(void) } /*-------------------------------------------------- - static void K_ParseTerrainParameter(size_t i, char *param, char *val) + static void K_ParseTerrainParameter(size_t i, const char *param, const char *val) Parser function for Terrain blocks. @@ -1461,7 +1461,7 @@ static void K_NewTerrainDefs(void) Return:- None --------------------------------------------------*/ -static void K_ParseTerrainParameter(size_t i, char *param, char *val) +static void K_ParseTerrainParameter(size_t i, const char *param, const char *val) { terrain_t *terrain = &terrainDefs[i]; @@ -1536,7 +1536,7 @@ static void K_NewTerrainFloorDefs(void) } /*-------------------------------------------------- - static boolean K_DoTERRAINLumpParse(size_t num, void (*parser)(UINT32, char *, char *)) + static boolean K_DoTERRAINLumpParse(size_t num, void (*parser)(size_t, const char *, const char *)) Runs another parser function for the TERRAIN lump, handling the nitty-gritty parts of the @@ -1549,61 +1549,53 @@ static void K_NewTerrainFloorDefs(void) Return:- false if any errors occured, otherwise true. --------------------------------------------------*/ -static boolean K_DoTERRAINLumpParse(size_t num, void (*parser)(size_t, char *, char *)) +static boolean K_DoTERRAINLumpParse(size_t num, void (*parser)(size_t, const char *, const char *)) { - char *param, *val; + const char *param, *val; - param = M_GetToken(NULL); + param = M_TokenizerRead(0); if (!fastcmp(param, "{")) { - Z_Free(param); CONS_Alert(CONS_WARNING, "Invalid TERRAIN data capsule!\n"); return false; } - Z_Free(param); - while (true) { - param = M_GetToken(NULL); + param = M_TokenizerRead(0); if (fastcmp(param, "}")) { - Z_Free(param); break; } - val = M_GetToken(NULL); + val = M_TokenizerRead(0); parser(num, param, val); - - Z_Free(param); - Z_Free(val); } return true; } /*-------------------------------------------------- - static boolean K_TERRAINLumpParser(UINT8 *data, size_t size) + static boolean K_TERRAINLumpParser(size_t size) Parses inputted lump data as a TERRAIN lump. Input Arguments:- - data - Pointer to lump data. size - The length of the lump data. Return:- false if any errors occured, otherwise true. --------------------------------------------------*/ -static boolean K_TERRAINLumpParser(UINT8 *data, size_t size) +static boolean K_TERRAINLumpParser(size_t size) { - char *tkn = M_GetToken((char *)data); + const char *tkn = M_TokenizerRead(0); UINT32 tknHash = 0; size_t pos = 0; size_t i; - while (tkn && (pos = M_GetTokenPos()) < size) + while (tkn && (pos = M_TokenizerGetEndPos()) < size) { boolean valid = true; @@ -1616,9 +1608,8 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size) // Check for valid fields. else if (stricmp(tkn, "splash") == 0) { - Z_Free(tkn); - tkn = M_GetToken(NULL); - pos = M_GetTokenPos(); + tkn = M_TokenizerRead(0); + pos = M_TokenizerGetEndPos(); if (tkn && pos < size) { @@ -1657,9 +1648,8 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size) } else if (stricmp(tkn, "footstep") == 0) { - Z_Free(tkn); - tkn = M_GetToken(NULL); - pos = M_GetTokenPos(); + tkn = M_TokenizerRead(0); + pos = M_TokenizerGetEndPos(); if (tkn && pos < size) { @@ -1698,9 +1688,8 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size) } else if (stricmp(tkn, "overlay") == 0) { - Z_Free(tkn); - tkn = M_GetToken(NULL); - pos = M_GetTokenPos(); + tkn = M_TokenizerRead(0); + pos = M_TokenizerGetEndPos(); if (tkn && pos < size) { @@ -1739,9 +1728,8 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size) } else if (stricmp(tkn, "terrain") == 0) { - Z_Free(tkn); - tkn = M_GetToken(NULL); - pos = M_GetTokenPos(); + tkn = M_TokenizerRead(0); + pos = M_TokenizerGetEndPos(); if (tkn && pos < size) { @@ -1780,9 +1768,8 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size) } else if (stricmp(tkn, "floor") == 0 || stricmp(tkn, "texture") == 0) { - Z_Free(tkn); - tkn = M_GetToken(NULL); - pos = M_GetTokenPos(); + tkn = M_TokenizerRead(0); + pos = M_TokenizerGetEndPos(); if (tkn && pos < size) { @@ -1790,9 +1777,8 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size) { // "optional" is ZDoom syntax // We don't use it, but we can ignore it. - Z_Free(tkn); - tkn = M_GetToken(NULL); - pos = M_GetTokenPos(); + tkn = M_TokenizerRead(0); + pos = M_TokenizerGetEndPos(); } if (tkn && pos < size) @@ -1820,9 +1806,8 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size) f->textureHash = tknHash; } - Z_Free(tkn); - tkn = M_GetToken(NULL); - pos = M_GetTokenPos(); + tkn = M_TokenizerRead(0); + pos = M_TokenizerGetEndPos(); if (tkn && pos < size) { @@ -1859,9 +1844,8 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size) } else if (stricmp(tkn, "defaultTerrain") == 0) { - Z_Free(tkn); - tkn = M_GetToken(NULL); - pos = M_GetTokenPos(); + tkn = M_TokenizerRead(0); + pos = M_TokenizerGetEndPos(); if (tkn && pos < size) { @@ -1898,9 +1882,8 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size) } else if (stricmp(tkn, "defaultOffroadFootstep") == 0) { - Z_Free(tkn); - tkn = M_GetToken(NULL); - pos = M_GetTokenPos(); + tkn = M_TokenizerRead(0); + pos = M_TokenizerGetEndPos(); if (tkn && pos < size) { @@ -1941,17 +1924,14 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size) valid = false; } - Z_Free(tkn); - if (valid == false) { return false; } - tkn = M_GetToken(NULL); + tkn = M_TokenizerRead(0); } - Z_Free(tkn); return true; } @@ -1997,7 +1977,10 @@ void K_InitTerrain(UINT16 wadNum) size = W_LumpLengthPwad(wadNum, lumpNum); CONS_Printf(M_GetText("Loading TERRAIN from %s\n"), name); - K_TERRAINLumpParser(data, size); + + M_TokenizerOpen((char *)data); + K_TERRAINLumpParser(size); + M_TokenizerClose(); free(name); } diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 045ff3020..27c44b35c 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1817,15 +1817,51 @@ static int lib_pExplodeMissile(lua_State *L) static int lib_pMobjTouchingSectorSpecial(lua_State *L) { - mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + mobj_t *mo = *((mobj_t**)luaL_checkudata(L, 1, META_MOBJ)); INT32 section = (INT32)luaL_checkinteger(L, 2); INT32 number = (INT32)luaL_checkinteger(L, 3); - boolean touchground = lua_optboolean(L, 4); //HUDSAFE INLEVEL if (!mo) return LUA_ErrInvalid(L, "mobj_t"); - LUA_PushUserdata(L, P_MobjTouchingSectorSpecial(mo, section, number, touchground), META_SECTOR); + LUA_PushUserdata(L, P_MobjTouchingSectorSpecial(mo, section, number), META_SECTOR); + return 1; +} + +static int lib_pMobjTouchingSectorSpecialFlag(lua_State *L) +{ + mobj_t *mo = *((mobj_t**)luaL_checkudata(L, 1, META_MOBJ)); + sectorspecialflags_t flag = (INT32)luaL_checkinteger(L, 2); + //HUDSAFE + INLEVEL + if (!mo) + return LUA_ErrInvalid(L, "mobj_t"); + LUA_PushUserdata(L, P_MobjTouchingSectorSpecialFlag(mo, flag), META_SECTOR); + return 1; +} + +static int lib_pPlayerTouchingSectorSpecial(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + INT32 section = (INT32)luaL_checkinteger(L, 2); + INT32 number = (INT32)luaL_checkinteger(L, 3); + //HUDSAFE + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + LUA_PushUserdata(L, P_PlayerTouchingSectorSpecial(player, section, number), META_SECTOR); + return 1; +} + +static int lib_pPlayerTouchingSectorSpecialFlag(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + sectorspecialflags_t flag = (INT32)luaL_checkinteger(L, 2); + //HUDSAFE + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + LUA_PushUserdata(L, P_PlayerTouchingSectorSpecialFlag(player, flag), META_SECTOR); return 1; } @@ -1960,34 +1996,13 @@ static int lib_pFadeLight(lua_State *L) INT32 speed = (INT32)luaL_checkinteger(L, 3); boolean ticbased = lua_optboolean(L, 4); boolean force = lua_optboolean(L, 5); + boolean relative = lua_optboolean(L, 6); NOHUD INLEVEL - P_FadeLight(tag, destvalue, speed, ticbased, force); + P_FadeLight(tag, destvalue, speed, ticbased, force, relative); return 0; } -static int lib_pThingOnSpecial3DFloor(lua_State *L) -{ - mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - NOHUD - INLEVEL - if (!mo) - return LUA_ErrInvalid(L, "mobj_t"); - LUA_PushUserdata(L, P_ThingOnSpecial3DFloor(mo), META_SECTOR); - return 1; -} - -static int lib_pIsFlagAtBase(lua_State *L) -{ - mobjtype_t flag = luaL_checkinteger(L, 1); - NOHUD - INLEVEL - if (flag >= NUMMOBJTYPES) - return luaL_error(L, "mobj type %d out of range (0 - %d)", flag, NUMMOBJTYPES-1); - lua_pushboolean(L, P_IsFlagAtBase(flag)); - return 1; -} - static int lib_pSetupLevelSky(lua_State *L) { const char *skytexname = luaL_checkstring(L, 1); @@ -3982,6 +3997,9 @@ static luaL_Reg lib[] = { {"P_SetMobjStateNF",lib_pSetMobjStateNF}, {"P_ExplodeMissile",lib_pExplodeMissile}, {"P_MobjTouchingSectorSpecial",lib_pMobjTouchingSectorSpecial}, + {"P_MobjTouchingSectorSpecialFlag",lib_pMobjTouchingSectorSpecialFlag}, + {"P_PlayerTouchingSectorSpecial",lib_pPlayerTouchingSectorSpecial}, + {"P_PlayerTouchingSectorSpecialFlag",lib_pPlayerTouchingSectorSpecialFlag}, {"P_FindLowestFloorSurrounding",lib_pFindLowestFloorSurrounding}, {"P_FindHighestFloorSurrounding",lib_pFindHighestFloorSurrounding}, {"P_FindNextHighestFloor",lib_pFindNextHighestFloor}, @@ -3993,8 +4011,6 @@ static luaL_Reg lib[] = { {"P_LinedefExecute",lib_pLinedefExecute}, {"P_SpawnLightningFlash",lib_pSpawnLightningFlash}, {"P_FadeLight",lib_pFadeLight}, - {"P_ThingOnSpecial3DFloor",lib_pThingOnSpecial3DFloor}, - {"P_IsFlagAtBase",lib_pIsFlagAtBase}, {"P_SetupLevelSky",lib_pSetupLevelSky}, {"P_SetSkyboxMobj",lib_pSetSkyboxMobj}, {"P_StartQuake",lib_pStartQuake}, diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 16e26069f..925483ea3 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -35,6 +35,10 @@ enum sector_e { sector_floorpic, sector_ceilingpic, sector_lightlevel, + sector_floorlightlevel, + sector_floorlightabsolute, + sector_ceilinglightlevel, + sector_ceilinglightabsolute, sector_special, sector_tag, sector_taglist, @@ -44,7 +48,14 @@ enum sector_e { sector_lines, sector_ffloors, sector_fslope, - sector_cslope + sector_cslope, + sector_flags, + sector_specialflags, + sector_damagetype, + sector_triggertag, + sector_triggerer, + sector_friction, + sector_gravity, }; static const char *const sector_opt[] = { @@ -54,6 +65,10 @@ static const char *const sector_opt[] = { "floorpic", "ceilingpic", "lightlevel", + "floorlightlevel", + "floorlightabsolute", + "ceilinglightlevel", + "ceilinglightabsolute", "special", "tag", "taglist", @@ -64,6 +79,13 @@ static const char *const sector_opt[] = { "ffloors", "f_slope", "c_slope", + "flags", + "specialflags", + "damagetype", + "triggertag", + "triggerer", + "friction", + "gravity", NULL}; enum subsector_e { @@ -88,6 +110,7 @@ enum line_e { line_v2, line_dx, line_dy, + line_angle, line_flags, line_special, line_tag, @@ -113,6 +136,7 @@ static const char *const line_opt[] = { "v2", "dx", "dy", + "angle", "flags", "special", "tag", @@ -197,6 +221,12 @@ enum ffloor_e { ffloor_prev, ffloor_alpha, ffloor_blend, + ffloor_bustflags, + ffloor_busttype, + ffloor_busttag, + ffloor_sinkspeed, + ffloor_friction, + ffloor_bouncestrength, }; static const char *const ffloor_opt[] = { @@ -216,6 +246,12 @@ static const char *const ffloor_opt[] = { "prev", "alpha", "blend", + "bustflags", + "busttype", + "busttag", + "sinkspeed", + "friction", + "bouncestrength", NULL}; #ifdef HAVE_LUA_SEGS @@ -581,6 +617,18 @@ static int sector_get(lua_State *L) case sector_lightlevel: lua_pushinteger(L, sector->lightlevel); return 1; + case sector_floorlightlevel: + lua_pushinteger(L, sector->floorlightlevel); + return 1; + case sector_floorlightabsolute: + lua_pushboolean(L, sector->floorlightabsolute); + return 1; + case sector_ceilinglightlevel: + lua_pushinteger(L, sector->ceilinglightlevel); + return 1; + case sector_ceilinglightabsolute: + lua_pushboolean(L, sector->ceilinglightabsolute); + return 1; case sector_special: lua_pushinteger(L, sector->special); return 1; @@ -619,6 +667,27 @@ static int sector_get(lua_State *L) case sector_cslope: // c_slope LUA_PushUserdata(L, sector->c_slope, META_SLOPE); return 1; + case sector_flags: // flags + lua_pushinteger(L, sector->flags); + return 1; + case sector_specialflags: // specialflags + lua_pushinteger(L, sector->specialflags); + return 1; + case sector_damagetype: // damagetype + lua_pushinteger(L, (UINT8)sector->damagetype); + return 1; + case sector_triggertag: // triggertag + lua_pushinteger(L, (INT16)sector->triggertag); + return 1; + case sector_triggerer: // triggerer + lua_pushinteger(L, (UINT8)sector->triggerer); + return 1; + case sector_friction: // friction + lua_pushfixed(L, sector->friction); + return 1; + case sector_gravity: // gravity + lua_pushfixed(L, sector->gravity); + return 1; } return 0; } @@ -646,6 +715,7 @@ static int sector_set(lua_State *L) case sector_ffloors: // ffloors case sector_fslope: // f_slope case sector_cslope: // c_slope + case sector_friction: // friction default: return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]); case sector_floorheight: { // floorheight @@ -685,6 +755,18 @@ static int sector_set(lua_State *L) case sector_lightlevel: sector->lightlevel = (INT16)luaL_checkinteger(L, 3); break; + case sector_floorlightlevel: + sector->floorlightlevel = (INT16)luaL_checkinteger(L, 3); + break; + case sector_floorlightabsolute: + sector->floorlightabsolute = luaL_checkboolean(L, 3); + break; + case sector_ceilinglightlevel: + sector->ceilinglightlevel = (INT16)luaL_checkinteger(L, 3); + break; + case sector_ceilinglightabsolute: + sector->ceilinglightabsolute = luaL_checkboolean(L, 3); + break; case sector_special: sector->special = (INT16)luaL_checkinteger(L, 3); break; @@ -693,6 +775,25 @@ static int sector_set(lua_State *L) break; case sector_taglist: return LUA_ErrSetDirectly(L, "sector_t", "taglist"); + case sector_flags: + sector->flags = luaL_checkinteger(L, 3); + CheckForReverseGravity |= (sector->flags & MSF_GRAVITYFLIP); + break; + case sector_specialflags: + sector->specialflags = luaL_checkinteger(L, 3); + break; + case sector_damagetype: + sector->damagetype = (UINT8)luaL_checkinteger(L, 3); + break; + case sector_triggertag: + sector->triggertag = (INT16)luaL_checkinteger(L, 3); + break; + case sector_triggerer: + sector->triggerer = (UINT8)luaL_checkinteger(L, 3); + break; + case sector_gravity: + sector->gravity = luaL_checkfixed(L, 3); + break; } return 0; } @@ -823,6 +924,9 @@ static int line_get(lua_State *L) case line_dy: lua_pushfixed(L, line->dy); return 1; + case line_angle: + lua_pushangle(L, line->angle); + return 1; case line_flags: lua_pushinteger(L, line->flags); return 1; @@ -1812,6 +1916,24 @@ static int ffloor_get(lua_State *L) case ffloor_blend: lua_pushinteger(L, ffloor->blend); return 1; + case ffloor_bustflags: + lua_pushinteger(L, ffloor->bustflags); + return 1; + case ffloor_busttype: + lua_pushinteger(L, ffloor->busttype); + return 1; + case ffloor_busttag: + lua_pushinteger(L, ffloor->busttag); + return 1; + case ffloor_sinkspeed: + lua_pushfixed(L, ffloor->sinkspeed); + return 1; + case ffloor_friction: + lua_pushfixed(L, ffloor->friction); + return 1; + case ffloor_bouncestrength: + lua_pushfixed(L, ffloor->bouncestrength); + return 1; } return 0; } diff --git a/src/lua_polyobjlib.c b/src/lua_polyobjlib.c index 2a5bcfbf1..0ee0055ae 100644 --- a/src/lua_polyobjlib.c +++ b/src/lua_polyobjlib.c @@ -244,13 +244,14 @@ static int lib_polyobj_rotate(lua_State *L) { polyobj_t *po = *((polyobj_t **)luaL_checkudata(L, 1, META_POLYOBJ)); angle_t delta = luaL_checkangle(L, 2); - UINT8 turnthings = (UINT8)luaL_optinteger(L, 3, 0); // don't turn anything by default? (could change this if not desired) - boolean checkmobjs = lua_opttrueboolean(L, 4); + boolean turnplayers = lua_opttrueboolean(L, 3); + boolean turnothers = lua_opttrueboolean(L, 4); + boolean checkmobjs = lua_opttrueboolean(L, 5); NOHUD INLEVEL if (!po) return LUA_ErrInvalid(L, "polyobj_t"); - lua_pushboolean(L, Polyobj_rotate(po, delta, turnthings, checkmobjs)); + lua_pushboolean(L, Polyobj_rotate(po, delta, turnplayers, turnothers, checkmobjs)); return 1; } diff --git a/src/m_cheat.c b/src/m_cheat.c index aafdf5b87..9614c9b60 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -382,7 +382,7 @@ void Command_Teleport_f(void) // Flagging a player's ambush will make them start on the ceiling // Objectflip inverts - if (!!(mt->options & MTF_AMBUSH) ^ !!(mt->options & MTF_OBJECTFLIP)) + if (!!(mt->args[0]) ^ !!(mt->options & MTF_OBJECTFLIP)) intz = ss->sector->ceilingheight - p->mo->height - offset; else intz = ss->sector->floorheight + offset; @@ -807,7 +807,7 @@ static void OP_CycleThings(INT32 amt) } while (mobjinfo[op_currentthing].doomednum == -1 || op_currentthing == MT_NIGHTSDRONE - || mobjinfo[op_currentthing].flags & (MF_AMBIENT|MF_NOSECTOR) + || mobjinfo[op_currentthing].flags & MF_NOSECTOR || (states[mobjinfo[op_currentthing].spawnstate].sprite == SPR_NULL && states[mobjinfo[op_currentthing].seestate].sprite == SPR_NULL) ); @@ -1050,9 +1050,9 @@ void OP_ObjectplaceMovement(player_t *player) return; mt = OP_CreateNewMapThing(player, (UINT16)spawnthing, ceiling); - if (mt->type >= 600 && mt->type <= 609) // Placement patterns + if (mt->type >= 600 && mt->type <= 611) // Placement patterns P_SpawnItemPattern(mt); - else if (mt->type == 1705 || mt->type == 1713) // NiGHTS Hoops + else if (mt->type == 1713) // NiGHTS Hoops P_SpawnHoop(mt); else P_SpawnMapThing(mt); @@ -1064,13 +1064,13 @@ void OP_ObjectplaceMovement(player_t *player) // // Objectplace related commands. // -void Command_Writethings_f(void) +/*void Command_Writethings_f(void) { REQUIRE_INLEVEL; REQUIRE_OBJECTPLACE; P_WriteThings(); -} +}*/ void Command_ObjectPlace_f(void) { diff --git a/src/m_cheat.h b/src/m_cheat.h index b5e018afc..499f60dd8 100644 --- a/src/m_cheat.h +++ b/src/m_cheat.h @@ -44,7 +44,7 @@ void cht_Init(void); // ObjectPlace // void Command_ObjectPlace_f(void); -void Command_Writethings_f(void); +//void Command_Writethings_f(void); extern consvar_t cv_opflags, cv_ophoopflags, cv_mapthingnum, cv_speed; //extern consvar_t cv_snapto, cv_grid; diff --git a/src/m_misc.c b/src/m_misc.c index eeb287751..3826b40d8 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -2074,18 +2074,168 @@ void M_UnGetToken(void) endPos = oldendPos; } -/** Returns the current token's position. - */ -UINT32 M_GetTokenPos(void) +#define NUMTOKENS 2 +static const char *tokenizerInput = NULL; +static UINT32 tokenCapacity[NUMTOKENS] = {0}; +static char *tokenizerToken[NUMTOKENS] = {NULL}; +static UINT32 tokenizerStartPos = 0; +static UINT32 tokenizerEndPos = 0; +static UINT32 tokenizerInputLength = 0; +static UINT8 tokenizerInComment = 0; // 0 = not in comment, 1 = // Single-line, 2 = /* Multi-line */ + +void M_TokenizerOpen(const char *inputString) { - return endPos; + size_t i; + + tokenizerInput = inputString; + for (i = 0; i < NUMTOKENS; i++) + { + tokenCapacity[i] = 1024; + tokenizerToken[i] = (char*)Z_Malloc(tokenCapacity[i] * sizeof(char), PU_STATIC, NULL); + } + tokenizerInputLength = strlen(tokenizerInput); } -/** Sets the current token's position. - */ -void M_SetTokenPos(UINT32 newPos) +void M_TokenizerClose(void) { - endPos = newPos; + size_t i; + + tokenizerInput = NULL; + for (i = 0; i < NUMTOKENS; i++) + Z_Free(tokenizerToken[i]); + tokenizerStartPos = 0; + tokenizerEndPos = 0; + tokenizerInComment = 0; +} + +static void M_DetectComment(UINT32 *pos) +{ + if (tokenizerInComment) + return; + + if (*pos >= tokenizerInputLength - 1) + return; + + if (tokenizerInput[*pos] != '/') + return; + + //Single-line comment start + if (tokenizerInput[*pos + 1] == '/') + tokenizerInComment = 1; + //Multi-line comment start + else if (tokenizerInput[*pos + 1] == '*') + tokenizerInComment = 2; +} + +static void M_ReadTokenString(UINT32 i) +{ + UINT32 tokenLength = tokenizerEndPos - tokenizerStartPos; + if (tokenLength + 1 > tokenCapacity[i]) + { + tokenCapacity[i] = tokenLength + 1; + // Assign the memory. Don't forget an extra byte for the end of the string! + tokenizerToken[i] = (char *)Z_Malloc(tokenCapacity[i] * sizeof(char), PU_STATIC, NULL); + } + // Copy the string. + M_Memcpy(tokenizerToken[i], tokenizerInput + tokenizerStartPos, (size_t)tokenLength); + // Make the final character NUL. + tokenizerToken[i][tokenLength] = '\0'; +} + +const char *M_TokenizerRead(UINT32 i) +{ + if (!tokenizerInput) + return NULL; + + tokenizerStartPos = tokenizerEndPos; + + // Try to detect comments now, in case we're pointing right at one + M_DetectComment(&tokenizerStartPos); + + // Find the first non-whitespace char, or else the end of the string trying + while ((tokenizerInput[tokenizerStartPos] == ' ' + || tokenizerInput[tokenizerStartPos] == '\t' + || tokenizerInput[tokenizerStartPos] == '\r' + || tokenizerInput[tokenizerStartPos] == '\n' + || tokenizerInput[tokenizerStartPos] == '\0' + || tokenizerInput[tokenizerStartPos] == '=' || tokenizerInput[tokenizerStartPos] == ';' // UDMF TEXTMAP. + || tokenizerInComment != 0) + && tokenizerStartPos < tokenizerInputLength) + { + // Try to detect comment endings now + if (tokenizerInComment == 1 && tokenizerInput[tokenizerStartPos] == '\n') + tokenizerInComment = 0; // End of line for a single-line comment + else if (tokenizerInComment == 2 + && tokenizerStartPos < tokenizerInputLength - 1 + && tokenizerInput[tokenizerStartPos] == '*' + && tokenizerInput[tokenizerStartPos+1] == '/') + { + // End of multi-line comment + tokenizerInComment = 0; + tokenizerStartPos++; // Make damn well sure we're out of the comment ending at the end of it all + } + + tokenizerStartPos++; + M_DetectComment(&tokenizerStartPos); + } + + // If the end of the string is reached, no token is to be read + if (tokenizerStartPos == tokenizerInputLength) { + tokenizerEndPos = tokenizerInputLength; + return NULL; + } + // Else, if it's one of these three symbols, capture only this one character + else if (tokenizerInput[tokenizerStartPos] == ',' + || tokenizerInput[tokenizerStartPos] == '{' + || tokenizerInput[tokenizerStartPos] == '}') + { + tokenizerEndPos = tokenizerStartPos + 1; + tokenizerToken[i][0] = tokenizerInput[tokenizerStartPos]; + tokenizerToken[i][1] = '\0'; + return tokenizerToken[i]; + } + // Return entire string within quotes, except without the quotes. + else if (tokenizerInput[tokenizerStartPos] == '"') + { + tokenizerEndPos = ++tokenizerStartPos; + while (tokenizerInput[tokenizerEndPos] != '"' && tokenizerEndPos < tokenizerInputLength) + tokenizerEndPos++; + + M_ReadTokenString(i); + tokenizerEndPos++; + return tokenizerToken[i]; + } + + // Now find the end of the token. This includes several additional characters that are okay to capture as one character, but not trailing at the end of another token. + tokenizerEndPos = tokenizerStartPos + 1; + while ((tokenizerInput[tokenizerEndPos] != ' ' + && tokenizerInput[tokenizerEndPos] != '\t' + && tokenizerInput[tokenizerEndPos] != '\r' + && tokenizerInput[tokenizerEndPos] != '\n' + && tokenizerInput[tokenizerEndPos] != ',' + && tokenizerInput[tokenizerEndPos] != '{' + && tokenizerInput[tokenizerEndPos] != '}' + && tokenizerInput[tokenizerEndPos] != '=' && tokenizerInput[tokenizerEndPos] != ';' // UDMF TEXTMAP. + && tokenizerInComment == 0) + && tokenizerEndPos < tokenizerInputLength) + { + tokenizerEndPos++; + // Try to detect comment starts now; if it's in a comment, we don't want it in this token + M_DetectComment(&tokenizerEndPos); + } + + M_ReadTokenString(i); + return tokenizerToken[i]; +} + +UINT32 M_TokenizerGetEndPos(void) +{ + return tokenizerEndPos; +} + +void M_TokenizerSetEndPos(UINT32 newPos) +{ + tokenizerEndPos = newPos; } /** Count bits in a number. diff --git a/src/objects/jawz.c b/src/objects/jawz.c index b5bc71058..cc241ba87 100644 --- a/src/objects/jawz.c +++ b/src/objects/jawz.c @@ -219,10 +219,12 @@ void Obj_JawzThink(mobj_t *th) JawzChase(th, grounded); K_DriftDustHandling(th); - if (P_MobjTouchingSectorSpecial(th, 3, 1, true)) + /* todo: UDMFify + if (P_MobjTouchingSectorSpecialFlag(th, ?)) { K_DoPogoSpring(th, 0, 1); } + */ if (jawz_selfdelay(th) > 0) { diff --git a/src/objects/orbinaut.c b/src/objects/orbinaut.c index ac209ec16..4f5d5ede6 100644 --- a/src/objects/orbinaut.c +++ b/src/objects/orbinaut.c @@ -124,10 +124,12 @@ void Obj_OrbinautThink(mobj_t *th) P_Thrust(th, th->angle, thrustamount); } - if (P_MobjTouchingSectorSpecial(th, 3, 1, true)) + /* todo: UDMFify + if (P_MobjTouchingSectorSpecialFlag(th, SS)) { K_DoPogoSpring(th, 0, 1); } + */ if (orbinaut_selfdelay(th) > 0) { diff --git a/src/p_ceilng.c b/src/p_ceilng.c index 062ebbda6..bec47a1ba 100644 --- a/src/p_ceilng.c +++ b/src/p_ceilng.c @@ -35,7 +35,6 @@ INT32 ceilmovesound = sfx_None; void T_MoveCeiling(ceiling_t *ceiling) { result_e res; - boolean dontupdate = false; if (ceiling->delaytimer) { @@ -43,259 +42,81 @@ void T_MoveCeiling(ceiling_t *ceiling) return; } - switch (ceiling->direction) + res = T_MovePlane(ceiling->sector, ceiling->speed, (ceiling->direction == 1) ? ceiling->topheight : ceiling->bottomheight, false, true, ceiling->direction); + + if (ceiling->type == bounceCeiling) { - case 0: // IN STASIS - break; - case 1: // UP - res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false, true, ceiling->direction); - - if (ceiling->type == bounceCeiling) - { - const fixed_t origspeed = FixedDiv(ceiling->origspeed,(ELEVATORSPEED/2)); - const fixed_t fs = abs(ceiling->sector->ceilingheight - lines[ceiling->texture].frontsector->ceilingheight); - const fixed_t bs = abs(ceiling->sector->ceilingheight - lines[ceiling->texture].backsector->ceilingheight); - if (fs < bs) - ceiling->speed = FixedDiv(fs,25*FRACUNIT) + FRACUNIT/4; - else - ceiling->speed = FixedDiv(bs,25*FRACUNIT) + FRACUNIT/4; - - ceiling->speed = FixedMul(ceiling->speed,origspeed); - } - - if (res == pastdest) - { - switch (ceiling->type) - { - case instantMoveCeilingByFrontSector: - if (ceiling->texture > -1) - ceiling->sector->ceilingpic = ceiling->texture; - ceiling->sector->ceilingdata = NULL; - ceiling->sector->ceilspeed = 0; - P_RemoveThinker(&ceiling->thinker); - dontupdate = true; - break; - case moveCeilingByFrontSector: - if (ceiling->texture < -1) // chained linedef executing - P_LinedefExecute((INT16)(ceiling->texture + INT16_MAX + 2), NULL, NULL); - if (ceiling->texture > -1) // flat changing - ceiling->sector->ceilingpic = ceiling->texture; - /* FALLTHRU */ - case raiseToHighest: -// case raiseCeilingByLine: - case moveCeilingByFrontTexture: - ceiling->sector->ceilingdata = NULL; - ceiling->sector->ceilspeed = 0; - P_RemoveThinker(&ceiling->thinker); - dontupdate = true; - break; - - case fastCrushAndRaise: - case crushAndRaise: - ceiling->direction = -1; - break; - - case bounceCeiling: - { - fixed_t dest = ceiling->topheight; - - if (dest == lines[ceiling->texture].frontsector->ceilingheight) - dest = lines[ceiling->texture].backsector->ceilingheight; - else - dest = lines[ceiling->texture].frontsector->ceilingheight; - - if (dest < ceiling->sector->ceilingheight) // must move down - { - ceiling->direction = -1; - ceiling->bottomheight = dest; - } - else // must move up - { - ceiling->direction = 1; - ceiling->topheight = dest; - } - - ceiling->delaytimer = ceiling->delay; - - // That's it. Do not set dontupdate, do not remove the thinker. - break; - } - - case bounceCeilingCrush: - { - fixed_t dest = ceiling->topheight; - - if (dest == lines[ceiling->texture].frontsector->ceilingheight) - { - dest = lines[ceiling->texture].backsector->ceilingheight; - ceiling->speed = ceiling->origspeed = FixedDiv(abs(lines[ceiling->texture].dy),4*FRACUNIT); // return trip, use dy - } - else - { - dest = lines[ceiling->texture].frontsector->ceilingheight; - ceiling->speed = ceiling->origspeed = FixedDiv(abs(lines[ceiling->texture].dx),4*FRACUNIT); // going frontways, use dx - } - - if (dest < ceiling->sector->ceilingheight) // must move down - { - ceiling->direction = -1; - ceiling->bottomheight = dest; - } - else // must move up - { - ceiling->direction = 1; - ceiling->topheight = dest; - } - - ceiling->delaytimer = ceiling->delay; - - // That's it. Do not set dontupdate, do not remove the thinker. - break; - } - - default: - break; - } - } - break; - - case -1: // DOWN - res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, true, ceiling->direction); - - if (ceiling->type == bounceCeiling) - { - const fixed_t origspeed = FixedDiv(ceiling->origspeed,(ELEVATORSPEED/2)); - const fixed_t fs = abs(ceiling->sector->ceilingheight - lines[ceiling->texture].frontsector->ceilingheight); - const fixed_t bs = abs(ceiling->sector->ceilingheight - lines[ceiling->texture].backsector->ceilingheight); - if (fs < bs) - ceiling->speed = FixedDiv(fs,25*FRACUNIT) + FRACUNIT/4; - else - ceiling->speed = FixedDiv(bs,25*FRACUNIT) + FRACUNIT/4; - ceiling->speed = FixedMul(ceiling->speed,origspeed); - } - - if (res == pastdest) - { - switch (ceiling->type) - { - // make platform stop at bottom of all crusher strokes - // except generalized ones, reset speed, start back up - case crushAndRaise: - ceiling->speed = CEILSPEED; - /* FALLTHRU */ - case fastCrushAndRaise: - ceiling->direction = 1; - break; - - case instantMoveCeilingByFrontSector: - if (ceiling->texture > -1) - ceiling->sector->ceilingpic = ceiling->texture; - ceiling->sector->ceilingdata = NULL; - ceiling->sector->ceilspeed = 0; - P_RemoveThinker(&ceiling->thinker); - dontupdate = true; - break; - - case moveCeilingByFrontSector: - if (ceiling->texture < -1) // chained linedef executing - P_LinedefExecute((INT16)(ceiling->texture + INT16_MAX + 2), NULL, NULL); - if (ceiling->texture > -1) // flat changing - ceiling->sector->ceilingpic = ceiling->texture; - // don't break - /* FALLTHRU */ - - // in all other cases, just remove the active ceiling - case lowerAndCrush: - case lowerToLowest: - case raiseToLowest: -// case lowerCeilingByLine: - case moveCeilingByFrontTexture: - ceiling->sector->ceilingdata = NULL; - ceiling->sector->ceilspeed = 0; - P_RemoveThinker(&ceiling->thinker); - dontupdate = true; - break; - case bounceCeiling: - { - fixed_t dest = ceiling->bottomheight; - - if (dest == lines[ceiling->texture].frontsector->ceilingheight) - dest = lines[ceiling->texture].backsector->ceilingheight; - else - dest = lines[ceiling->texture].frontsector->ceilingheight; - - if (dest < ceiling->sector->ceilingheight) // must move down - { - ceiling->direction = -1; - ceiling->bottomheight = dest; - } - else // must move up - { - ceiling->direction = 1; - ceiling->topheight = dest; - } - - ceiling->delaytimer = ceiling->delay; - - // That's it. Do not set dontupdate, do not remove the thinker. - break; - } - - case bounceCeilingCrush: - { - fixed_t dest = ceiling->bottomheight; - - if (dest == lines[ceiling->texture].frontsector->ceilingheight) - { - dest = lines[ceiling->texture].backsector->ceilingheight; - ceiling->speed = ceiling->origspeed = FixedDiv(abs(lines[ceiling->texture].dy),4*FRACUNIT); // return trip, use dy - } - else - { - dest = lines[ceiling->texture].frontsector->ceilingheight; - ceiling->speed = ceiling->origspeed = FixedDiv(abs(lines[ceiling->texture].dx),4*FRACUNIT); // going frontways, use dx - } - - if (dest < ceiling->sector->ceilingheight) // must move down - { - ceiling->direction = -1; - ceiling->bottomheight = dest; - } - else // must move up - { - ceiling->direction = 1; - ceiling->topheight = dest; - } - - ceiling->delaytimer = ceiling->delay; - - // That's it. Do not set dontupdate, do not remove the thinker. - break; - } - - default: - break; - } - } - else if (res == crushed) - { - switch (ceiling->type) - { - case crushAndRaise: - case lowerAndCrush: - ceiling->speed = FixedDiv(CEILSPEED,8*FRACUNIT); - break; - - default: - break; - } - } - break; + const fixed_t origspeed = FixedDiv(ceiling->origspeed, (ELEVATORSPEED/2)); + const fixed_t fs = abs(ceiling->sector->ceilingheight - lines[ceiling->sourceline].frontsector->ceilingheight); + const fixed_t bs = abs(ceiling->sector->ceilingheight - lines[ceiling->sourceline].backsector->ceilingheight); + if (fs < bs) + ceiling->speed = FixedDiv(fs, 25*FRACUNIT) + FRACUNIT/4; + else + ceiling->speed = FixedDiv(bs, 25*FRACUNIT) + FRACUNIT/4; + ceiling->speed = FixedMul(ceiling->speed, origspeed); } - if (!dontupdate) - ceiling->sector->ceilspeed = ceiling->speed*ceiling->direction; - else - ceiling->sector->ceilspeed = 0; + + if (res == pastdest) + { + switch (ceiling->type) + { + case instantMoveCeilingByFrontSector: + if (ceiling->texture > -1) // flat changing + ceiling->sector->ceilingpic = ceiling->texture; + ceiling->sector->ceilingdata = NULL; + ceiling->sector->ceilspeed = 0; + P_RemoveThinker(&ceiling->thinker); + return; + case moveCeilingByFrontSector: + if (ceiling->tag) // chained linedef executing + P_LinedefExecute(ceiling->tag, NULL, NULL); + if (ceiling->texture > -1) // flat changing + ceiling->sector->ceilingpic = ceiling->texture; + /* FALLTHRU */ + case raiseToHighest: + case moveCeilingByDistance: + ceiling->sector->ceilingdata = NULL; + ceiling->sector->ceilspeed = 0; + P_RemoveThinker(&ceiling->thinker); + return; + case bounceCeiling: + case bounceCeilingCrush: + { + fixed_t dest = (ceiling->direction == 1) ? ceiling->topheight : ceiling->bottomheight; + + if (dest == lines[ceiling->sourceline].frontsector->ceilingheight) + { + dest = lines[ceiling->sourceline].backsector->ceilingheight; + ceiling->origspeed = lines[ceiling->sourceline].args[3] << (FRACBITS - 2); // return trip, use args[3] + } + else + { + dest = lines[ceiling->sourceline].frontsector->ceilingheight; + ceiling->origspeed = lines[ceiling->sourceline].args[2] << (FRACBITS - 2); // going frontways, use args[2] + } + + if (ceiling->type == bounceCeilingCrush) + ceiling->speed = ceiling->origspeed; + + if (dest < ceiling->sector->ceilingheight) // must move down + { + ceiling->direction = -1; + ceiling->bottomheight = dest; + } + else // must move up + { + ceiling->direction = 1; + ceiling->topheight = dest; + } + + ceiling->delaytimer = ceiling->delay; + break; + } + default: + break; + } + } + ceiling->sector->ceilspeed = ceiling->speed*ceiling->direction; } /** Moves a ceiling crusher. @@ -323,11 +144,7 @@ void T_CrushCeiling(ceiling_t *ceiling) if (res == pastdest) { ceiling->direction = -1; - - if (lines[ceiling->sourceline].flags & ML_EFFECT4) - ceiling->speed = ceiling->oldspeed; - else - ceiling->speed = ceiling->oldspeed*2; + ceiling->speed = lines[ceiling->sourceline].args[2] << (FRACBITS - 2); if (ceiling->type == crushCeilOnce || ceiling->type == crushBothOnce) @@ -368,12 +185,8 @@ void T_CrushCeiling(ceiling_t *ceiling) ceiling->sector->soundorg.z = ceiling->sector->floorheight; S_StartSound(mp,sfx_pstop); - if (lines[ceiling->sourceline].flags & ML_EFFECT4) - ceiling->speed = ceiling->oldspeed; - else - ceiling->speed = ceiling->oldspeed/2; - ceiling->direction = 1; + ceiling->speed = lines[ceiling->sourceline].args[3] << (FRACBITS - 2); } break; } @@ -386,18 +199,18 @@ void T_CrushCeiling(ceiling_t *ceiling) /** Starts a ceiling mover. * + * \param tag Tag. * \param line The source line. * \param type The type of ceiling movement. * \return 1 if at least one ceiling mover was started, 0 otherwise. * \sa EV_DoCrush, EV_DoFloor, EV_DoElevator, T_MoveCeiling */ -INT32 EV_DoCeiling(line_t *line, ceiling_e type) +INT32 EV_DoCeiling(mtag_t tag, line_t *line, ceiling_e type) { INT32 rtn = 0, firstone = 1; INT32 secnum = -1; sector_t *sec; ceiling_t *ceiling; - mtag_t tag = Tag_FGet(&line->tags); TAG_ITER_SECTORS(tag, secnum) { @@ -418,44 +231,12 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type) switch (type) { - case fastCrushAndRaise: - ceiling->crush = true; - ceiling->topheight = sec->ceilingheight; - ceiling->bottomheight = sec->floorheight + (8*FRACUNIT); - ceiling->direction = -1; - ceiling->speed = CEILSPEED * 2; - break; - - case crushAndRaise: - ceiling->crush = true; - ceiling->topheight = sec->ceilingheight; - /* FALLTHRU */ - case lowerAndCrush: - ceiling->bottomheight = sec->floorheight; - ceiling->bottomheight += 4*FRACUNIT; - ceiling->direction = -1; - ceiling->speed = line->dx; - break; - case raiseToHighest: ceiling->topheight = P_FindHighestCeilingSurrounding(sec); ceiling->direction = 1; ceiling->speed = CEILSPEED; break; - //SoM: 3/6/2000: Added Boom types - case lowerToLowest: - ceiling->bottomheight = P_FindLowestCeilingSurrounding(sec); - ceiling->direction = -1; - ceiling->speed = CEILSPEED; - break; - - case raiseToLowest: // Graue 09-07-2004 - ceiling->topheight = P_FindLowestCeilingSurrounding(sec) - 4*FRACUNIT; - ceiling->direction = 1; - ceiling->speed = line->dx; // hack - break; - case lowerToLowestFast: ceiling->bottomheight = P_FindLowestCeilingSurrounding(sec); ceiling->direction = -1; @@ -470,8 +251,7 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type) // Linedef executor excellence case moveCeilingByFrontSector: - ceiling->speed = P_AproxDistance(line->dx, line->dy); - ceiling->speed = FixedDiv(ceiling->speed,8*FRACUNIT); + ceiling->speed = line->args[2] << (FRACBITS - 3); if (line->frontsector->ceilingheight >= sec->ceilingheight) // Move up { ceiling->direction = 1; @@ -484,21 +264,13 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type) } // chained linedef executing ability - if (line->flags & ML_BLOCKPLAYERS) - { - // only set it on ONE of the moving sectors (the smallest numbered) - // and front side x offset must be positive - if (firstone && sides[line->sidenum[0]].textureoffset > 0) - ceiling->texture = (sides[line->sidenum[0]].textureoffset>>FRACBITS) - 32769; - else - ceiling->texture = -1; - } + // only set it on ONE of the moving sectors (the smallest numbered) + // only set it if there isn't also a floor mover + if (line->args[3] && line->args[1] == 1) + ceiling->tag = firstone ? (INT16)line->args[3] : 0; // flat changing ability - else if (line->flags & ML_NOCLIMB) - ceiling->texture = line->frontsector->ceilingpic; - else - ceiling->texture = -1; + ceiling->texture = line->args[4] ? line->frontsector->ceilingpic : -1; break; // More linedef executor junk @@ -515,67 +287,30 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type) ceiling->direction = -1; ceiling->bottomheight = line->frontsector->ceilingheight; } - if (line->flags & ML_NOCLIMB) - ceiling->texture = -1; - else - ceiling->texture = line->frontsector->ceilingpic; + + // If flag is set, change ceiling texture after moving + ceiling->texture = line->args[2] ? line->frontsector->ceilingpic : -1; break; - case moveCeilingByFrontTexture: - if (line->flags & ML_NOCLIMB) + case moveCeilingByDistance: + if (line->args[4]) ceiling->speed = INT32_MAX/2; // as above, "instant" is one tic else - ceiling->speed = FixedDiv(sides[line->sidenum[0]].textureoffset,8*FRACUNIT); // texture x offset - if (sides[line->sidenum[0]].rowoffset > 0) + ceiling->speed = line->args[3] << (FRACBITS - 3); + if (line->args[2] > 0) { ceiling->direction = 1; // up - ceiling->topheight = sec->ceilingheight + sides[line->sidenum[0]].rowoffset; // texture y offset + ceiling->topheight = sec->ceilingheight + (line->args[2] << FRACBITS); } else { ceiling->direction = -1; // down - ceiling->bottomheight = sec->ceilingheight + sides[line->sidenum[0]].rowoffset; // texture y offset + ceiling->bottomheight = sec->ceilingheight + (line->args[2] << FRACBITS); } break; -/* - case lowerCeilingByLine: - ceiling->speed = FixedDiv(abs(line->dx),8*FRACUNIT); - ceiling->direction = -1; // Move down - ceiling->bottomheight = sec->ceilingheight - abs(line->dy); - break; - - case raiseCeilingByLine: - ceiling->speed = FixedDiv(abs(line->dx),8*FRACUNIT); - ceiling->direction = 1; // Move up - ceiling->topheight = sec->ceilingheight + abs(line->dy); - break; -*/ - case bounceCeiling: - ceiling->speed = P_AproxDistance(line->dx, line->dy); // same speed as elevateContinuous - ceiling->speed = FixedDiv(ceiling->speed,4*FRACUNIT); - ceiling->origspeed = ceiling->speed; - if (line->frontsector->ceilingheight >= sec->ceilingheight) // Move up - { - ceiling->direction = 1; - ceiling->topheight = line->frontsector->ceilingheight; - } - else // Move down - { - ceiling->direction = -1; - ceiling->bottomheight = line->frontsector->ceilingheight; - } - - // Any delay? - ceiling->delay = sides[line->sidenum[0]].textureoffset >> FRACBITS; - ceiling->delaytimer = sides[line->sidenum[0]].rowoffset >> FRACBITS; // Initial delay - - ceiling->texture = (fixed_t)(line - lines); // hack: use texture to store sourceline number - break; - case bounceCeilingCrush: - ceiling->speed = abs(line->dx); // same speed as elevateContinuous - ceiling->speed = FixedDiv(ceiling->speed,4*FRACUNIT); + ceiling->speed = line->args[2] << (FRACBITS - 2); // same speed as elevateContinuous ceiling->origspeed = ceiling->speed; if (line->frontsector->ceilingheight >= sec->ceilingheight) // Move up { @@ -589,10 +324,8 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type) } // Any delay? - ceiling->delay = sides[line->sidenum[0]].textureoffset >> FRACBITS; - ceiling->delaytimer = sides[line->sidenum[0]].rowoffset >> FRACBITS; // Initial delay - - ceiling->texture = (fixed_t)(line - lines); // hack: use texture to store sourceline number + ceiling->delay = line->args[5]; + ceiling->delaytimer = line->args[4]; // Initial delay break; default: @@ -600,7 +333,6 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type) } - ceiling->tag = tag; ceiling->type = type; firstone = 0; @@ -612,19 +344,19 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type) /** Starts a ceiling crusher. * + * \param tag Tag. * \param line The source line. * \param type The type of ceiling, either ::crushAndRaise or * ::fastCrushAndRaise. * \return 1 if at least one crusher was started, 0 otherwise. * \sa EV_DoCeiling, EV_DoFloor, EV_DoElevator, T_CrushCeiling */ -INT32 EV_DoCrush(line_t *line, ceiling_e type) +INT32 EV_DoCrush(mtag_t tag, line_t *line, ceiling_e type) { INT32 rtn = 0; INT32 secnum = -1; sector_t *sec; ceiling_t *ceiling; - mtag_t tag = Tag_FGet(&line->tags); TAG_ITER_SECTORS(tag, secnum) { @@ -642,46 +374,33 @@ INT32 EV_DoCrush(line_t *line, ceiling_e type) ceiling->sector = sec; ceiling->crush = true; ceiling->sourceline = (INT32)(line-lines); - - if (line->flags & ML_EFFECT4) - ceiling->oldspeed = FixedDiv(abs(line->dx),4*FRACUNIT); - else - ceiling->oldspeed = (R_PointToDist2(line->v2->x, line->v2->y, line->v1->x, line->v1->y)/16); + ceiling->speed = ceiling->origspeed = line->args[2] << (FRACBITS - 2); switch(type) { - case fastCrushAndRaise: // Up and then down + case raiseAndCrush: // Up and then down ceiling->topheight = P_FindHighestCeilingSurrounding(sec); ceiling->direction = 1; - ceiling->speed = ceiling->oldspeed; + // Retain stupid behavior for backwards compatibility + if (!udmf && !(line->flags & ML_MIDSOLID)) + ceiling->speed /= 2; + else + ceiling->speed = line->args[3] << (FRACBITS - 2); ceiling->bottomheight = sec->floorheight + FRACUNIT; break; case crushBothOnce: ceiling->topheight = sec->ceilingheight; ceiling->bottomheight = sec->floorheight + (sec->ceilingheight-sec->floorheight)/2; ceiling->direction = -1; - - if (line->flags & ML_EFFECT4) - ceiling->speed = ceiling->oldspeed; - else - ceiling->speed = ceiling->oldspeed*2; - break; case crushCeilOnce: default: // Down and then up. ceiling->topheight = sec->ceilingheight; ceiling->direction = -1; - - if (line->flags & ML_EFFECT4) - ceiling->speed = ceiling->oldspeed; - else - ceiling->speed = ceiling->oldspeed*2; - ceiling->bottomheight = sec->floorheight + FRACUNIT; break; } - ceiling->tag = tag; ceiling->type = type; // interpolation diff --git a/src/p_enemy.c b/src/p_enemy.c index 827e42c8e..3859d9335 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -12,6 +12,7 @@ /// \brief Enemy thinking, AI /// Action Pointer Functions that are associated with states/frames +#include "dehacked.h" #include "doomdef.h" #include "g_game.h" #include "p_local.h" @@ -162,6 +163,7 @@ void A_Boss3TakeDamage(mobj_t *actor); void A_Boss3Path(mobj_t *actor); void A_Boss3ShockThink(mobj_t *actor); void A_LinedefExecute(mobj_t *actor); +void A_LinedefExecuteFromArg(mobj_t *actor); void A_PlaySeeSound(mobj_t *actor); void A_PlayAttackSound(mobj_t *actor); void A_PlayActiveSound(mobj_t *actor); @@ -3385,6 +3387,116 @@ void A_Explode(mobj_t *actor) P_RadiusAttack(actor, actor->target, actor->info->damage, locvar1, true); } +static mobj_t *P_FindBossFlyPoint(mobj_t *mo, INT32 tag) +{ + INT32 i; + mobj_t *closest = NULL; + + TAG_ITER_THINGS(tag, i) + { + mobj_t *mo2 = mapthings[i].mobj; + + if (!mo2) + continue; + + if (mo2->type != MT_BOSSFLYPOINT) + continue; + + // If this one's further than the last one, don't go for it. + if (closest && + P_AproxDistance(P_AproxDistance(mo->x - mo2->x, mo->y - mo2->y), mo->z - mo2->z) > + P_AproxDistance(P_AproxDistance(mo->x - closest->x, mo->y - closest->y), mo->z - closest->z)) + continue; + + closest = mo2; + } + + return closest; +} + +static void P_DoBossVictory(mobj_t *mo) +{ + thinker_t *th; + mobj_t *mo2; + INT32 i; + + // scan the remaining thinkers to see if all bosses are dead + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo2 = (mobj_t *)th; + + if (mo2 == mo) + continue; + + if ((mo2->flags & MF_BOSS) && mo2->health > 0) + return; + } + + // victory! + if (mo->spawnpoint) + P_LinedefExecute(mo->spawnpoint->args[3], mo, NULL); + + if (stoppedclock && modeattacking) // if you're just time attacking, skip making the capsule appear since you don't need to step on it anyways. + return; + + if (mo->flags2 & MF2_BOSSNOTRAP) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + P_DoPlayerExit(&players[i]); + } + } + else + { + if (!udmf) + { + // Bring the egg trap up to the surface + // Incredibly shitty code ahead + EV_DoElevator(LE_CAPSULE0, NULL, elevateHighest); + EV_DoElevator(LE_CAPSULE1, NULL, elevateUp); + EV_DoElevator(LE_CAPSULE2, NULL, elevateHighest); + } + } +} + +static void P_DoBossDefaultDeath(mobj_t *mo) +{ + INT32 bossid = (mo->spawnpoint ? mo->spawnpoint->args[0] : 0); + + // Stop exploding and prepare to run. + P_SetMobjState(mo, mo->info->xdeathstate); + if (P_MobjWasRemoved(mo)) + return; + + P_SetTarget(&mo->target, P_FindBossFlyPoint(mo, bossid)); + + mo->flags |= MF_NOGRAVITY|MF_NOCLIP; + mo->flags |= MF_NOCLIPHEIGHT; + + mo->movedir = 0; + mo->extravalue1 = 35; + mo->flags2 |= MF2_BOSSFLEE; + mo->momz = P_MobjFlip(mo)*2*mo->scale; + + if (mo->target) + { + angle_t diff = R_PointToAngle2(mo->x, mo->y, mo->target->x, mo->target->y) - mo->angle; + if (diff) + { + if (diff > ANGLE_180) + diff = InvAngle(InvAngle(diff)/mo->extravalue1); + else + diff /= mo->extravalue1; + mo->movedir = diff; + } + } +} + // Function: A_BossDeath // // Description: Possibly trigger special effects when boss dies. @@ -3394,18 +3506,13 @@ void A_Explode(mobj_t *actor) // void A_BossDeath(mobj_t *mo) { - thinker_t *th; - mobj_t *mo2; - line_t junk; INT32 i; if (LUA_CallAction(A_BOSSDEATH, mo)) return; - if (mo->spawnpoint && mo->spawnpoint->extrainfo) - P_LinedefExecute(LE_BOSSDEAD+(mo->spawnpoint->extrainfo*LE_PARAMWIDTH), mo, NULL); - else - P_LinedefExecute(LE_BOSSDEAD, mo, NULL); + if (mo->spawnpoint) + P_LinedefExecute(mo->spawnpoint->args[2], mo, NULL); mo->health = 0; // Boss is dead (but not necessarily fleeing...) @@ -3421,241 +3528,19 @@ void A_BossDeath(mobj_t *mo) if (i == MAXPLAYERS) return; // no one left alive, so do not end game - // scan the remaining thinkers to see - // if all bosses are dead - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; + P_DoBossVictory(mo); - mo2 = (mobj_t *)th; - if (mo2 != mo && (mo2->flags & MF_BOSS) && mo2->health > 0) - goto bossjustdie; // other boss not dead - just go straight to dying! - } - - // victory! - P_LinedefExecute(LE_ALLBOSSESDEAD, mo, NULL); - if (stoppedclock && modeattacking) // if you're just time attacking, skip making the capsule appear since you don't need to step on it anyways. - goto bossjustdie; - if (mo->flags2 & MF2_BOSSNOTRAP) - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - P_DoPlayerExit(&players[i]); - } - } - else - { - // Initialize my junk - junk.tags.tags = NULL; - junk.tags.count = 0; - - // Bring the egg trap up to the surface - // Incredibly shitty code ahead - Tag_FSet(&junk.tags, LE_CAPSULE0); - EV_DoElevator(&junk, elevateHighest, false); - Tag_FSet(&junk.tags, LE_CAPSULE1); - EV_DoElevator(&junk, elevateUp, false); - Tag_FSet(&junk.tags, LE_CAPSULE2); - EV_DoElevator(&junk, elevateHighest, false); - } - -bossjustdie: if (LUA_HookMobj(mo, MOBJ_HOOK(BossDeath))) return; else if (P_MobjWasRemoved(mo)) return; - // Spawn your junk - switch (mo->type) - { - default: - break; - case MT_EGGMOBILE: // twin laser pods - { - mo2 = P_SpawnMobjFromMobj(mo, - P_ReturnThrustX(mo, mo->angle - ANGLE_90, 32<angle - ANGLE_90, 32<angle = mo->angle; - P_InstaThrust(mo2, mo2->angle - ANGLE_90, 4*mo2->scale); - P_SetObjectMomZ(mo2, 4*FRACUNIT, false); - P_SetMobjState(mo2, S_BOSSEGLZ1); - - mo2 = P_SpawnMobjFromMobj(mo, - P_ReturnThrustX(mo, mo->angle + ANGLE_90, 32<angle + ANGLE_90, 32<angle = mo->angle; - P_InstaThrust(mo2, mo2->angle + ANGLE_90, 4*mo2->scale); - P_SetObjectMomZ(mo2, 4*FRACUNIT, false); - P_SetMobjState(mo2, S_BOSSEGLZ2); - } - break; - case MT_EGGMOBILE2: // twin tanks + spigot - { - mo2 = P_SpawnMobjFromMobj(mo, - P_ReturnThrustX(mo, mo->angle - ANGLE_90, 32<angle - ANGLE_90, 32<angle = mo->angle; - P_InstaThrust(mo2, mo2->angle - ANGLE_90, 4*mo2->scale); - P_SetObjectMomZ(mo2, 4*FRACUNIT, false); - P_SetMobjState(mo2, S_BOSSTANK1); - - mo2 = P_SpawnMobjFromMobj(mo, - P_ReturnThrustX(mo, mo->angle + ANGLE_90, 32<angle + ANGLE_90, 32<angle = mo->angle; - P_InstaThrust(mo2, mo2->angle + ANGLE_90, 4*mo2->scale); - P_SetObjectMomZ(mo2, 4*FRACUNIT, false); - P_SetMobjState(mo2, S_BOSSTANK2); - - mo2 = P_SpawnMobjFromMobj(mo, 0, 0, - mobjinfo[MT_EGGMOBILE2].height + (32<angle = mo->angle; - P_SetObjectMomZ(mo2, 4*FRACUNIT, false); - mo2->momz += mo->momz; - P_SetMobjState(mo2, S_BOSSSPIGOT); - } - break; - case MT_EGGMOBILE3: - { - mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_BOSSJUNK); - mo2->angle = mo->angle; - P_SetMobjState(mo2, S_BOSSSEBH1); - } - break; - } - // now do another switch case for escaping switch (mo->type) { - case MT_KOOPA: - { - // Initialize my junk - junk.tags.tags = NULL; - junk.tags.count = 0; - - Tag_FSet(&junk.tags, LE_KOOPA); - EV_DoCeiling(&junk, raiseToHighest); - return; - } - case MT_FANG: - { - if (mo->flags2 & MF2_SLIDEPUSH) - { - P_RemoveMobj(mo); - return; - } - if (mo->tracer) - { - var1 = var2 = 0; - A_Boss5Jump(mo); - mo->momx = ((16 - 1)*mo->momx)/16; - mo->momy = ((16 - 1)*mo->momy)/16; - { - const fixed_t time = FixedHypot(mo->tracer->x - mo->x, mo->tracer->y - mo->y)/FixedHypot(mo->momx, mo->momy); - const fixed_t speed = 64*FRACUNIT; - mobj_t *pole = P_SpawnMobj( - mo->tracer->x - P_ReturnThrustX(mo->tracer, mo->tracer->angle, speed*time), - mo->tracer->y - P_ReturnThrustY(mo->tracer, mo->tracer->angle, speed*time), - mo->tracer->floorz + (256+1)*FRACUNIT, - MT_FSGNB); - P_SetTarget(&pole->tracer, P_SpawnMobj( - pole->x, pole->y, - pole->z - 256*FRACUNIT, - MT_FSGNB)); - P_SetTarget(&pole->tracer->tracer, P_SpawnMobj( - pole->x + P_ReturnThrustX(pole, mo->tracer->angle, FRACUNIT), - pole->y + P_ReturnThrustY(pole, mo->tracer->angle, FRACUNIT), - pole->z + 256*FRACUNIT, - MT_FSGNA)); - pole->tracer->flags |= MF_NOCLIPTHING; - P_SetScale(pole, (pole->destscale = 2*FRACUNIT)); - P_SetScale(pole->tracer, (pole->tracer->destscale = 2*FRACUNIT)); - pole->angle = mo->tracer->angle; - pole->tracer->angle = mo->tracer->angle; - pole->tracer->tracer->angle = pole->angle - ANGLE_90; - pole->momx = P_ReturnThrustX(pole, pole->angle, speed); - pole->momy = P_ReturnThrustY(pole, pole->angle, speed); - pole->tracer->momx = pole->momx; - pole->tracer->momy = pole->momy; - pole->tracer->tracer->momx = pole->momx; - pole->tracer->tracer->momy = pole->momy; - } - } - else - { - P_SetObjectMomZ(mo, 10*FRACUNIT, false); - mo->flags |= MF_NOGRAVITY; - } - mo->flags |= MF_NOCLIP|MF_NOCLIPHEIGHT; - return; - } default: //eggmobiles - { - UINT8 extrainfo = (mo->spawnpoint ? mo->spawnpoint->extrainfo : 0); - - // Stop exploding and prepare to run. - P_SetMobjState(mo, mo->info->xdeathstate); - if (P_MobjWasRemoved(mo)) - return; - - P_SetTarget(&mo->target, NULL); - - // Flee! Flee! Find a point to escape to! If none, just shoot upward! - // scan the thinkers to find the runaway point - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_BOSSFLYPOINT) - continue; - - if (mo2->spawnpoint && mo2->spawnpoint->extrainfo != extrainfo) - continue; - - // If this one's further then the last one, don't go for it. - if (mo->target && - P_AproxDistance(P_AproxDistance(mo->x - mo2->x, mo->y - mo2->y), mo->z - mo2->z) > - P_AproxDistance(P_AproxDistance(mo->x - mo->target->x, mo->y - mo->target->y), mo->z - mo->target->z)) - continue; - - // Otherwise... Do! - P_SetTarget(&mo->target, mo2); - } - - mo->flags |= MF_NOGRAVITY|MF_NOCLIP; - mo->flags |= MF_NOCLIPHEIGHT; - - mo->movedir = 0; - mo->extravalue1 = 35; - mo->flags2 |= MF2_BOSSFLEE; - mo->momz = P_MobjFlip(mo)*2*mo->scale; - - if (mo->target) - { - angle_t diff = R_PointToAngle2(mo->x, mo->y, mo->target->x, mo->target->y) - mo->angle; - if (diff) - { - if (diff > ANGLE_180) - diff = InvAngle(InvAngle(diff)/mo->extravalue1); - else - diff /= mo->extravalue1; - mo->movedir = diff; - } - } - + P_DoBossDefaultDeath(mo); break; - } } } @@ -4192,12 +4077,16 @@ void A_FishJump(mobj_t *actor) fixed_t jumpval; if (locvar1) - jumpval = var1; + jumpval = locvar1; else - jumpval = FixedMul(AngleFixed(actor->angle)/4, actor->scale); + { + if (actor->spawnpoint && actor->spawnpoint->args[0]) + jumpval = actor->spawnpoint->args[0]; + else + jumpval = 44; + } - if (!jumpval) jumpval = FixedMul(44*(FRACUNIT/4), actor->scale); - actor->momz = jumpval; + actor->momz = FixedMul(jumpval << (FRACBITS - 2), actor->scale); P_SetMobjStateNF(actor, actor->info->seestate); } @@ -5196,48 +5085,34 @@ void A_RockSpawn(mobj_t *actor) { mobj_t *mo; mobjtype_t type; - INT32 i = Tag_FindLineSpecial(12, (INT16)actor->threshold); - line_t *line; fixed_t dist; - fixed_t randomoomph; if (LUA_CallAction(A_ROCKSPAWN, actor)) return; - if (i == -1) + if (!actor->spawnpoint) + return; + + type = actor->spawnpoint->stringargs[0] ? get_number(actor->spawnpoint->stringargs[0]) : MT_ROCKCRUMBLE1; + + if (type < MT_NULL || type >= NUMMOBJTYPES) { - CONS_Debug(DBG_GAMELOGIC, "A_RockSpawn: Unable to find parameter line 12 (tag %d)!\n", actor->threshold); + CONS_Debug(DBG_GAMELOGIC, "A_RockSpawn: Invalid mobj type %s!\n", actor->spawnpoint->stringargs[0]); return; } - line = &lines[i]; - - if (!(sides[line->sidenum[0]].textureoffset >> FRACBITS)) - { - CONS_Debug(DBG_GAMELOGIC, "A_RockSpawn: No X-offset detected! (tag %d)!\n", actor->threshold); - return; - } - - dist = P_AproxDistance(line->dx, line->dy)/16; - - if (dist < 1) - dist = 1; - - type = MT_ROCKCRUMBLE1 + (sides[line->sidenum[0]].rowoffset >> FRACBITS); - - if (line->flags & ML_NOCLIMB) - randomoomph = P_RandomByte(PR_DECORATION) * (FRACUNIT/32); - else - randomoomph = 0; + dist = max(actor->spawnpoint->args[0] << (FRACBITS - 4), 1); + if (actor->spawnpoint->args[2]) + dist += P_RandomByte(PR_UNDEFINED) * (FRACUNIT/32); // random oomph mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_FALLINGROCK); P_SetMobjState(mo, mobjinfo[type].spawnstate); - mo->angle = R_PointToAngle2(line->v2->x, line->v2->y, line->v1->x, line->v1->y); + mo->angle = FixedAngle(actor->spawnpoint->angle << FRACBITS); - P_InstaThrust(mo, mo->angle, dist + randomoomph); - mo->momz = dist + randomoomph; + P_InstaThrust(mo, mo->angle, dist); + mo->momz = dist; - var1 = sides[line->sidenum[0]].textureoffset >> FRACBITS; + var1 = actor->spawnpoint->args[1]; A_SetTics(actor); } @@ -5899,10 +5774,8 @@ void A_Boss1Chase(mobj_t *actor) } else { - if (actor->spawnpoint && actor->spawnpoint->extrainfo) - P_LinedefExecute(LE_PINCHPHASE+(actor->spawnpoint->extrainfo*LE_PARAMWIDTH), actor, NULL); - else - P_LinedefExecute(LE_PINCHPHASE, actor, NULL); + if (actor->spawnpoint) + P_LinedefExecute(actor->spawnpoint->args[4], actor, NULL); P_SetMobjState(actor, actor->info->raisestate); } @@ -6026,7 +5899,7 @@ void A_Boss2Chase(mobj_t *actor) } else { - // Only speed up if you have the 'Deaf' flag. + // Only speed up if you have the ambush flag. if (actor->flags2 & MF2_AMBUSH) speedvar = actor->health; else @@ -6599,12 +6472,21 @@ void A_GuardChase(mobj_t *actor) false) && speed > 0) // can't be the same check as previous so that P_TryMove gets to happen. { - if (actor->spawnpoint && ((actor->spawnpoint->options & (MTF_EXTRA|MTF_OBJECTSPECIAL)) == MTF_OBJECTSPECIAL)) - actor->angle += ANGLE_90; - else if (actor->spawnpoint && ((actor->spawnpoint->options & (MTF_EXTRA|MTF_OBJECTSPECIAL)) == MTF_EXTRA)) - actor->angle -= ANGLE_90; - else - actor->angle += ANGLE_180; + INT32 direction = actor->spawnpoint ? actor->spawnpoint->args[0] : TMGD_BACK; + + switch (direction) + { + case TMGD_BACK: + default: + actor->angle += ANGLE_180; + break; + case TMGD_RIGHT: + actor->angle -= ANGLE_90; + break; + case TMGD_LEFT: + actor->angle += ANGLE_90; + break; + } } if (actor->extravalue1 < actor->info->speed) @@ -6804,10 +6686,6 @@ void A_Boss3TakeDamage(mobj_t *actor) actor->movecount = var1; actor->movefactor = -512*FRACUNIT; - - /*if (actor->target && actor->target->spawnpoint) - actor->threshold = actor->target->spawnpoint->extrainfo;*/ - } // Function: A_Boss3Path @@ -6847,27 +6725,21 @@ void A_Boss3Path(mobj_t *actor) if (!(actor->flags2 & MF2_STRONGBOX)) { - thinker_t *th; mobj_t *mo2; + INT32 i; P_SetTarget(&actor->target, NULL); - // scan the thinkers - // to find a point that matches - // the number - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + // Find waypoint + TAG_ITER_THINGS(actor->cusval, i) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; + mo2 = mapthings[i].mobj; - mo2 = (mobj_t *)th; + if (!mo2) + continue; if (mo2->type != MT_BOSS3WAYPOINT) continue; - if (!mo2->spawnpoint) - continue; - if (mo2->spawnpoint->angle != actor->threshold) - continue; - if (mo2->spawnpoint->extrainfo != actor->cusval) + if (mapthings[i].args[0] != actor->threshold) continue; P_SetTarget(&actor->target, mo2); @@ -7013,8 +6885,6 @@ void A_LinedefExecute(mobj_t *actor) if (locvar2) tagnum += locvar2*(AngleFixed(actor->angle)>>FRACBITS); - else if (actor->spawnpoint && actor->spawnpoint->extrainfo) - tagnum += (actor->spawnpoint->extrainfo*LE_PARAMWIDTH); CONS_Debug(DBG_GAMELOGIC, "A_LinedefExecute: Running mobjtype %d's sector with tag %d\n", actor->type, tagnum); @@ -7022,6 +6892,38 @@ void A_LinedefExecute(mobj_t *actor) P_LinedefExecute((INT16)tagnum, actor, actor->subsector->sector); } +// Function: A_LinedefExecuteFromArg +// +// Description: Object's location is used to set the calling sector. The tag used is the spawnpoint mapthing's args[var1]. +// +// var1 = mapthing arg to take tag from +// var2 = unused +// +void A_LinedefExecuteFromArg(mobj_t *actor) +{ + INT32 tagnum; + INT32 locvar1 = var1; + + if (LUA_CallAction(A_LINEDEFEXECUTEFROMARG, actor)) + return; + + if (!actor->spawnpoint) + return; + + if (locvar1 < 0 || locvar1 > NUMMAPTHINGARGS) + { + CONS_Debug(DBG_GAMELOGIC, "A_LinedefExecuteFromArg: Invalid mapthing arg %d\n", locvar1); + return; + } + + tagnum = actor->spawnpoint->args[locvar1]; + + CONS_Debug(DBG_GAMELOGIC, "A_LinedefExecuteFromArg: Running mobjtype %d's sector with tag %d\n", actor->type, tagnum); + + // tag 32768 displayed in map editors is actually tag -32768, tag 32769 is -32767, 65535 is -1 etc. + P_LinedefExecute((INT16)tagnum, actor, actor->subsector->sector); +} + // Function: A_PlaySeeSound // // Description: Plays the object's seesound. @@ -10151,10 +10053,7 @@ void A_BrakLobShot(mobj_t *actor) return; // Don't even bother if we've got nothing to aim at. // Look up actor's current gravity situation - if (actor->subsector->sector->gravity) - g = FixedMul(gravity,(FixedDiv(*actor->subsector->sector->gravity>>FRACBITS, 1000))); - else - g = gravity; + g = FixedMul(gravity, P_GetSectorGravityFactor(actor->subsector->sector)); // Look up distance between actor and its target x = P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y); @@ -10266,10 +10165,7 @@ void A_NapalmScatter(mobj_t *actor) airtime = 16<subsector->sector->gravity) - g = FixedMul(gravity,(FixedDiv(*actor->subsector->sector->gravity>>FRACBITS, 1000))); - else - g = gravity; + g = FixedMul(gravity, P_GetSectorGravityFactor(actor->subsector->sector)); // vy = (g*(airtime-1))/2 vy = FixedMul(g,(airtime-(1<>1; @@ -10394,7 +10290,7 @@ void A_FlickySpawn(mobj_t *actor) } // Internal Flicky color setting -void P_InternalFlickySetColor(mobj_t *actor, UINT8 extrainfo) +void P_InternalFlickySetColor(mobj_t *actor, UINT8 color) { UINT8 flickycolors[] = { SKINCOLOR_RED, @@ -10414,11 +10310,11 @@ void P_InternalFlickySetColor(mobj_t *actor, UINT8 extrainfo) SKINCOLOR_YELLOW, }; - if (extrainfo == 0) + if (color == 0) // until we can customize flicky colors by level header, just stick to SRB2's defaults actor->color = flickycolors[P_RandomKey(PR_UNDEFINED, 2)]; //flickycolors[P_RandomKey(sizeof(flickycolors))]; else - actor->color = flickycolors[min(extrainfo-1, 14)]; // sizeof(flickycolors)-1 + actor->color = flickycolors[min(color-1, 14)]; // sizeof(flickycolors)-1 } // Function: A_FlickyCenter @@ -10428,17 +10324,17 @@ void P_InternalFlickySetColor(mobj_t *actor, UINT8 extrainfo) // var1: // Lower 16 bits = if 0, spawns random flicky based on level header. Else, spawns the designated thing type. // Bits 17-20 = Flicky color, up to 15. Applies to fish. -// Bit 21 = Flag MF_SLIDEME (see below) -// Bit 22 = Flag MF_GRENADEBOUNCE (see below) -// Bit 23 = Flag MF_NOCLIPTHING (see below) +// Bit 21 = Flag TMFF_AIMLESS (see below) +// Bit 22 = Flag TMFF_STATIONARY (see below) +// Bit 23 = Flag TMFF_HOP (see below) // // If actor is placed from a spawnpoint (map Thing), the Thing's properties take precedence. // -// var2 = maximum default distance away from spawn the flickies are allowed to travel. If angle != 0, then that's the radius. +// var2 = maximum default distance away from spawn the flickies are allowed to travel. If args[0] != 0, then that's the radius. // -// If MTF_EXTRA (MF_SLIDEME): is flagged, Flickies move aimlessly. Else, orbit around the target. -// If MTF_OBJECTSPECIAL (MF_GRENADEBOUNCE): Flickies stand in-place without gravity (unless they hop, then gravity is applied.) -// If MTF_AMBUSH (MF_NOCLIPTHING): is flagged, Flickies hop. +// If TMFF_AIMLESS (MF_SLIDEME): is flagged, Flickies move aimlessly. Else, orbit around the target. +// If TMFF_STATIONARY (MF_GRENADEBOUNCE): Flickies stand in-place without gravity (unless they hop, then gravity is applied.) +// If TMFF_HOP (MF_NOCLIPTHING): is flagged, Flickies hop. // void A_FlickyCenter(mobj_t *actor) { @@ -10460,14 +10356,15 @@ void A_FlickyCenter(mobj_t *actor) if (actor->spawnpoint) { actor->flags &= ~(MF_SLIDEME|MF_GRENADEBOUNCE|MF_NOCLIPTHING); - actor->flags |= ( - ((actor->spawnpoint->options & MTF_EXTRA) ? MF_SLIDEME : 0) - | ((actor->spawnpoint->options & MTF_OBJECTSPECIAL) ? MF_GRENADEBOUNCE : 0) - | ((actor->spawnpoint->options & MTF_AMBUSH) ? MF_NOCLIPTHING : 0) - ); - actor->extravalue1 = actor->spawnpoint->angle ? abs(actor->spawnpoint->angle) * FRACUNIT - : locvar2 ? abs(locvar2) : 384 * FRACUNIT; - actor->extravalue2 = actor->spawnpoint->extrainfo; + if (actor->spawnpoint->args[1] & TMFF_AIMLESS) + actor->flags |= MF_SLIDEME; + if (actor->spawnpoint->args[1] & TMFF_STATIONARY) + actor->flags |= MF_GRENADEBOUNCE; + if (actor->spawnpoint->args[1] & TMFF_HOP) + actor->flags |= MF_NOCLIPTHING; + actor->extravalue1 = actor->spawnpoint->args[0] ? abs(actor->spawnpoint->args[0])*FRACUNIT + : locvar2 ? abs(locvar2) : 384*FRACUNIT; + actor->extravalue2 = actor->spawnpoint->args[2]; actor->friction = actor->spawnpoint->x*FRACUNIT; actor->movefactor = actor->spawnpoint->y*FRACUNIT; actor->watertop = actor->spawnpoint->z*FRACUNIT; @@ -10475,11 +10372,12 @@ void A_FlickyCenter(mobj_t *actor) else { actor->flags &= ~(MF_SLIDEME|MF_GRENADEBOUNCE|MF_NOCLIPTHING); - actor->flags |= ( - ((flickyflags & 1) ? MF_SLIDEME : 0) - | ((flickyflags & 2) ? MF_GRENADEBOUNCE : 0) - | ((flickyflags & 4) ? MF_NOCLIPTHING : 0) - ); + if (flickyflags & TMFF_AIMLESS) + actor->flags |= MF_SLIDEME; + if (flickyflags & TMFF_STATIONARY) + actor->flags |= MF_GRENADEBOUNCE; + if (flickyflags & TMFF_HOP) + actor->flags |= MF_NOCLIPTHING; actor->extravalue1 = abs(locvar2); actor->extravalue2 = flickycolor; actor->friction = actor->x; @@ -10980,8 +10878,12 @@ void A_Boss5Jump(mobj_t *actor) if (!actor->tracer) return; // Don't even bother if we've got nothing to aim at. + // Scale with map g = FixedMul(gravity, mapobjectscale); + // Look up actor's current gravity situation + g = FixedMul(gravity, P_GetSectorGravityFactor(actor->subsector->sector)); + // Look up distance between actor and its tracer x = FixedHypot(actor->tracer->x - actor->x, actor->tracer->y - actor->y); // Look up height difference between actor and its tracer @@ -11405,67 +11307,43 @@ void A_Boss5FindWaypoint(mobj_t *actor) { INT32 locvar1 = var1; boolean avoidcenter; - UINT32 i; - UINT8 extrainfo = (actor->spawnpoint ? actor->spawnpoint->extrainfo : 0); + INT32 i; + INT32 bossid = (actor->spawnpoint ? actor->spawnpoint->args[0] : 0); if (LUA_CallAction(A_BOSS5FINDWAYPOINT, actor)) return; avoidcenter = !actor->tracer || (actor->health == actor->info->damage+1); - if (locvar1 == 2) // look for the boss waypoint + if (locvar1 == 2) // look for the boss flypoint { - thinker_t *th; - mobj_t *mo2; - P_SetTarget(&actor->tracer, NULL); - // Flee! Flee! Find a point to escape to! If none, just shoot upward! - // scan the thinkers to find the runaway point - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; + P_SetTarget(&actor->tracer, P_FindBossFlyPoint(actor, bossid)); - mo2 = (mobj_t *)th; - - if (mo2->type != MT_BOSSFLYPOINT) - continue; - - if (mo2->spawnpoint && mo2->spawnpoint->extrainfo != extrainfo) - continue; - - // If this one's further then the last one, don't go for it. - if (actor->tracer && - P_AproxDistance(P_AproxDistance(actor->x - mo2->x, actor->y - mo2->y), actor->z - mo2->z) > - P_AproxDistance(P_AproxDistance(actor->x - actor->tracer->x, actor->y - actor->tracer->y), actor->z - actor->tracer->z)) - continue; - - // Otherwise... Do! - P_SetTarget(&actor->tracer, mo2); - } if (!actor->tracer) return; // no boss flypoints found } else if (locvar1 == 1) // always go to ambush-marked waypoint { + boolean found = false; + if (avoidcenter) goto nowaypoints; // if we can't go the center, why on earth are we doing this? - for (i = 0; i < nummapthings; i++) + TAG_ITER_THINGS(bossid, i) { if (!mapthings[i].mobj) continue; if (mapthings[i].mobj->type != MT_FANGWAYPOINT) continue; - if (mapthings[i].extrainfo != extrainfo) - continue; - if (!(mapthings[i].options & MTF_AMBUSH)) + if (!(mapthings[i].args[0])) continue; P_SetTarget(&actor->tracer, mapthings[i].mobj); + found = true; break; } - if (i == nummapthings) + if (!found) goto nowaypoints; } else // locvar1 == 0 @@ -11478,7 +11356,7 @@ void A_Boss5FindWaypoint(mobj_t *actor) actor->z += hackoffset; // first, count how many waypoints we have - for (i = 0; i < nummapthings; i++) + TAG_ITER_THINGS(bossid, i) { if (!mapthings[i].mobj) continue; @@ -11486,9 +11364,7 @@ void A_Boss5FindWaypoint(mobj_t *actor) continue; if (actor->tracer == mapthings[i].mobj) // this was your tracer last time continue; - if (mapthings[i].extrainfo != extrainfo) - continue; - if (mapthings[i].options & MTF_AMBUSH) + if (mapthings[i].args[0]) { if (avoidcenter) continue; @@ -11535,7 +11411,7 @@ void A_Boss5FindWaypoint(mobj_t *actor) numfangwaypoints = 0; // now find them again and add them to the table! - for (i = 0; i < nummapthings; i++) + TAG_ITER_THINGS(bossid, i) { if (!mapthings[i].mobj) continue; @@ -11543,9 +11419,7 @@ void A_Boss5FindWaypoint(mobj_t *actor) continue; if (actor->tracer == mapthings[i].mobj) // this was your tracer last time continue; - if (mapthings[i].extrainfo != extrainfo) - continue; - if (mapthings[i].options & MTF_AMBUSH) + if (mapthings[i].args[0]) { if (avoidcenter) continue; @@ -12833,7 +12707,7 @@ void A_SpawnPterabytes(mobj_t *actor) return; if (actor->spawnpoint) - amount = actor->spawnpoint->extrainfo + 1; + amount = min(1, actor->spawnpoint->args[0]); interval = FixedAngle(FRACUNIT*360/amount); diff --git a/src/p_floor.c b/src/p_floor.c index 581e83740..be62c5786 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -11,6 +11,7 @@ /// \file p_floor.c /// \brief Floor animation, elevators +#include "dehacked.h" #include "doomdef.h" #include "doomstat.h" #include "m_random.h" @@ -163,7 +164,7 @@ result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crus void T_MoveFloor(floormove_t *movefloor) { result_e res = 0; - boolean dontupdate = false; + boolean remove = false; if (movefloor->delaytimer) { @@ -179,8 +180,8 @@ void T_MoveFloor(floormove_t *movefloor) if (movefloor->type == bounceFloor) { const fixed_t origspeed = FixedDiv(movefloor->origspeed,(ELEVATORSPEED/2)); - const fixed_t fs = abs(movefloor->sector->floorheight - lines[movefloor->texture].frontsector->floorheight); - const fixed_t bs = abs(movefloor->sector->floorheight - lines[movefloor->texture].backsector->floorheight); + const fixed_t fs = abs(movefloor->sector->floorheight - lines[movefloor->sourceline].frontsector->floorheight); + const fixed_t bs = abs(movefloor->sector->floorheight - lines[movefloor->sourceline].backsector->floorheight); if (fs < bs) movefloor->speed = FixedDiv(fs,25*FRACUNIT) + FRACUNIT/4; else @@ -191,113 +192,62 @@ void T_MoveFloor(floormove_t *movefloor) if (res == pastdest) { - if (movefloor->direction == 1) + switch (movefloor->type) { - switch (movefloor->type) - { - case moveFloorByFrontSector: - if (movefloor->texture < -1) // chained linedef executing - P_LinedefExecute((INT16)(movefloor->texture + INT16_MAX + 2), NULL, NULL); - /* FALLTHRU */ - case instantMoveFloorByFrontSector: - if (movefloor->texture > -1) // flat changing - movefloor->sector->floorpic = movefloor->texture; - break; - case bounceFloor: // Graue 03-12-2004 - if (movefloor->floordestheight == lines[movefloor->texture].frontsector->floorheight) - movefloor->floordestheight = lines[movefloor->texture].backsector->floorheight; - else - movefloor->floordestheight = lines[movefloor->texture].frontsector->floorheight; - movefloor->direction = (movefloor->floordestheight < movefloor->sector->floorheight) ? -1 : 1; - movefloor->sector->floorspeed = movefloor->speed * movefloor->direction; - movefloor->delaytimer = movefloor->delay; - P_RecalcPrecipInSector(movefloor->sector); - return; // not break, why did this work? Graue 04-03-2004 - case bounceFloorCrush: // Graue 03-27-2004 - if (movefloor->floordestheight == lines[movefloor->texture].frontsector->floorheight) - { - movefloor->floordestheight = lines[movefloor->texture].backsector->floorheight; - movefloor->speed = movefloor->origspeed = FixedDiv(abs(lines[movefloor->texture].dy),4*FRACUNIT); // return trip, use dy - } - else - { - movefloor->floordestheight = lines[movefloor->texture].frontsector->floorheight; - movefloor->speed = movefloor->origspeed = FixedDiv(abs(lines[movefloor->texture].dx),4*FRACUNIT); // forward again, use dx - } - movefloor->direction = (movefloor->floordestheight < movefloor->sector->floorheight) ? -1 : 1; - movefloor->sector->floorspeed = movefloor->speed * movefloor->direction; - movefloor->delaytimer = movefloor->delay; - P_RecalcPrecipInSector(movefloor->sector); - return; // not break, why did this work? Graue 04-03-2004 - case crushFloorOnce: - movefloor->floordestheight = lines[movefloor->texture].frontsector->floorheight; + case moveFloorByFrontSector: + if (movefloor->tag) // chained linedef executing + P_LinedefExecute(movefloor->tag, NULL, NULL); + /* FALLTHRU */ + case instantMoveFloorByFrontSector: + if (movefloor->texture > -1) // flat changing + movefloor->sector->floorpic = movefloor->texture; + remove = true; + break; + case bounceFloor: // Graue 03-12-2004 + case bounceFloorCrush: // Graue 03-27-2004 + if (movefloor->floordestheight == lines[movefloor->sourceline].frontsector->floorheight) + { + movefloor->floordestheight = lines[movefloor->sourceline].backsector->floorheight; + movefloor->origspeed = lines[movefloor->sourceline].args[3] << (FRACBITS - 2); // return trip, use args[3] + } + else + { + movefloor->floordestheight = lines[movefloor->sourceline].frontsector->floorheight; + movefloor->origspeed = lines[movefloor->sourceline].args[2] << (FRACBITS - 2); // forward again, use args[2] + } + if (movefloor->type == bounceFloorCrush) + movefloor->speed = movefloor->origspeed; + movefloor->direction = (movefloor->floordestheight < movefloor->sector->floorheight) ? -1 : 1; + movefloor->delaytimer = movefloor->delay; + remove = false; + break; + case crushFloorOnce: + if (movefloor->direction == 1) + { + movefloor->floordestheight = lines[movefloor->sourceline].frontsector->floorheight; movefloor->direction = -1; + movefloor->speed = lines[movefloor->sourceline].args[3] << (FRACBITS - 2); movefloor->sector->soundorg.z = movefloor->sector->floorheight; - S_StartSound(&movefloor->sector->soundorg,sfx_pstop); - P_RecalcPrecipInSector(movefloor->sector); - return; - default: - break; - } - } - else if (movefloor->direction == -1) - { - switch (movefloor->type) - { - case moveFloorByFrontSector: - if (movefloor->texture < -1) // chained linedef executing - P_LinedefExecute((INT16)(movefloor->texture + INT16_MAX + 2), NULL, NULL); - /* FALLTHRU */ - case instantMoveFloorByFrontSector: - if (movefloor->texture > -1) // flat changing - movefloor->sector->floorpic = movefloor->texture; - break; - case bounceFloor: // Graue 03-12-2004 - if (movefloor->floordestheight == lines[movefloor->texture].frontsector->floorheight) - movefloor->floordestheight = lines[movefloor->texture].backsector->floorheight; - else - movefloor->floordestheight = lines[movefloor->texture].frontsector->floorheight; - movefloor->direction = (movefloor->floordestheight < movefloor->sector->floorheight) ? -1 : 1; - movefloor->sector->floorspeed = movefloor->speed * movefloor->direction; - movefloor->delaytimer = movefloor->delay; - P_RecalcPrecipInSector(movefloor->sector); - return; // not break, why did this work? Graue 04-03-2004 - case bounceFloorCrush: // Graue 03-27-2004 - if (movefloor->floordestheight == lines[movefloor->texture].frontsector->floorheight) - { - movefloor->floordestheight = lines[movefloor->texture].backsector->floorheight; - movefloor->speed = movefloor->origspeed = FixedDiv(abs(lines[movefloor->texture].dy),4*FRACUNIT); // return trip, use dy - } - else - { - movefloor->floordestheight = lines[movefloor->texture].frontsector->floorheight; - movefloor->speed = movefloor->origspeed = FixedDiv(abs(lines[movefloor->texture].dx),4*FRACUNIT); // forward again, use dx - } - movefloor->direction = (movefloor->floordestheight < movefloor->sector->floorheight) ? -1 : 1; - movefloor->sector->floorspeed = movefloor->speed * movefloor->direction; - movefloor->delaytimer = movefloor->delay; - P_RecalcPrecipInSector(movefloor->sector); - return; // not break, why did this work? Graue 04-03-2004 - case crushFloorOnce: - movefloor->sector->floordata = NULL; // Clear up the thinker so others can use it - P_RemoveThinker(&movefloor->thinker); - movefloor->sector->floorspeed = 0; - P_RecalcPrecipInSector(movefloor->sector); - return; - default: - break; - } + S_StartSound(&movefloor->sector->soundorg, sfx_pstop); + remove = false; + } + else + remove = true; + break; + default: + remove = true; + break; } + } + if (remove) + { movefloor->sector->floordata = NULL; // Clear up the thinker so others can use it movefloor->sector->floorspeed = 0; P_RemoveThinker(&movefloor->thinker); - dontupdate = true; } - if (!dontupdate) - movefloor->sector->floorspeed = movefloor->speed*movefloor->direction; else - movefloor->sector->floorspeed = 0; + movefloor->sector->floorspeed = movefloor->speed*movefloor->direction; P_RecalcPrecipInSector(movefloor->sector); } @@ -637,7 +587,6 @@ void T_BounceCheese(bouncecheese_t *bouncer) sector_t *actionsector; boolean remove; INT32 i; - mtag_t tag = Tag_FGet(&bouncer->sourceline->tags); if (bouncer->sector->crumblestate == CRUMBLE_RESTORE || bouncer->sector->crumblestate == CRUMBLE_WAIT || bouncer->sector->crumblestate == CRUMBLE_ACTIVATED) // Oops! Crumbler says to remove yourself! @@ -652,7 +601,7 @@ void T_BounceCheese(bouncecheese_t *bouncer) } // You can use multiple target sectors, but at your own risk!!! - TAG_ITER_SECTORS(tag, i) + TAG_ITER_SECTORS(bouncer->sourceline->args[0], i) { actionsector = §ors[i]; actionsector->moved = true; @@ -776,7 +725,7 @@ void T_StartCrumble(crumble_t *crumble) ffloor_t *rover; sector_t *sector; INT32 i; - mtag_t tag = Tag_FGet(&crumble->sourceline->tags); + mtag_t tag = crumble->sourceline->args[0]; // Once done, the no-return thinker just sits there, // constantly 'returning'... kind of an oxymoron, isn't it? @@ -1099,23 +1048,6 @@ void T_MarioBlockChecker(mariocheck_t *block) } } -static boolean P_IsPlayerValid(size_t playernum) -{ - if (!playeringame[playernum]) - return false; - - if (!players[playernum].mo) - return false; - - if (players[playernum].mo->health <= 0) - return false; - - if (players[playernum].spectator) - return false; - - return true; -} - // This is the Thwomp's 'brain'. It looks around for players nearby, and if // it finds any, **SMASH**!!! Muahahhaa.... void T_ThwompSector(thwomp_t *thwomp) @@ -1131,7 +1063,7 @@ void T_ThwompSector(thwomp_t *thwomp) // I could of used rowoffset, but the FOF actually // modifies the textures's Y offset. It doesn't with // textureoffset, so Effect 4 can be ignored as usual. - if (thwomp->sourceline->flags & ML_EFFECT1 + if ((thwomp->sourceline->flags & ML_SKEWTD) // FIXME: UDMF-ify && leveltime < (unsigned)(sides[thwomp->sourceline->sidenum[0]].textureoffset>>FRACBITS)) thwomp->direction = 0; @@ -1282,7 +1214,7 @@ void T_NoEnemiesSector(noenemies_t *nobaddies) sector_t *sec = NULL; INT32 secnum = -1; boolean FOFsector = false; - mtag_t tag = Tag_FGet(&nobaddies->sourceline->tags); + mtag_t tag = nobaddies->sourceline->args[0]; TAG_ITER_SECTORS(tag, secnum) { @@ -1294,14 +1226,13 @@ void T_NoEnemiesSector(noenemies_t *nobaddies) for (i = 0; i < sec->linecount; i++) { INT32 targetsecnum = -1; - mtag_t tag2 = Tag_FGet(&sec->lines[i]->tags); if (sec->lines[i]->special < 100 || sec->lines[i]->special >= 300) continue; FOFsector = true; - TAG_ITER_SECTORS(tag2, targetsecnum) + TAG_ITER_SECTORS(sec->lines[i]->args[0], targetsecnum) { if (T_SectorHasEnemies(§ors[targetsecnum])) return; @@ -1319,190 +1250,68 @@ void T_NoEnemiesSector(noenemies_t *nobaddies) P_RemoveThinker(&nobaddies->thinker); } -static boolean P_IsMobjTouchingSector(mobj_t *mo, sector_t *sec) +static boolean P_CheckAllTrigger(eachtime_t *eachtime) { - msecnode_t *node; + size_t i; - if (mo->subsector->sector == sec) - return true; - - if (!(sec->flags & SF_TRIGGERSPECIAL_TOUCH)) - return false; - - for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) + for (i = 0; i < MAXPLAYERS; i++) { - if (node->m_sector == sec) - return true; + if (P_CanPlayerTrigger(i) && !eachtime->playersInArea[i]) + return false; } - return false; + return true; } -// -// T_EachTimeThinker -// -// Runs a linedef exec whenever a player enters an area. -// Keeps track of players currently in the area and notices any changes. -// -// \sa P_AddEachTimeThinker -// void T_EachTimeThinker(eachtime_t *eachtime) { - size_t i, j; - sector_t *sec = NULL; - sector_t *targetsec = NULL; - INT32 secnum = -1; + size_t i; boolean oldPlayersInArea[MAXPLAYERS]; - boolean oldPlayersOnArea[MAXPLAYERS]; - boolean *oldPlayersArea; - boolean *playersArea; - boolean FOFsector = false; - boolean floortouch = false; - fixed_t bottomheight, topheight; - ffloor_t *rover; - mtag_t tag = Tag_FGet(&eachtime->sourceline->tags); + sector_t *caller[MAXPLAYERS]; + boolean allPlayersChecked = false; + boolean allPlayersTrigger = false; for (i = 0; i < MAXPLAYERS; i++) { oldPlayersInArea[i] = eachtime->playersInArea[i]; - oldPlayersOnArea[i] = eachtime->playersOnArea[i]; - eachtime->playersInArea[i] = false; - eachtime->playersOnArea[i] = false; - } - - TAG_ITER_SECTORS(tag, secnum) - { - sec = §ors[secnum]; - - FOFsector = false; - - if (GETSECSPECIAL(sec->special, 2) == 3 || GETSECSPECIAL(sec->special, 2) == 5) - floortouch = true; - else if (GETSECSPECIAL(sec->special, 2) >= 1 && GETSECSPECIAL(sec->special, 2) <= 8) - floortouch = false; - else - continue; - - // Check the lines of this sector, to see if it is a FOF control sector. - for (i = 0; i < sec->linecount; i++) - { - INT32 targetsecnum = -1; - mtag_t tag2 = Tag_FGet(&sec->lines[i]->tags); - - if (sec->lines[i]->special < 100 || sec->lines[i]->special >= 300) - continue; - - FOFsector = true; - - TAG_ITER_SECTORS(tag2, targetsecnum) - { - targetsec = §ors[targetsecnum]; - - // Find the FOF corresponding to the control linedef - for (rover = targetsec->ffloors; rover; rover = rover->next) - { - if (rover->master == sec->lines[i]) - break; - } - - if (!rover) // This should be impossible, but don't complain if it is the case somehow - continue; - - if (!(rover->flags & FF_EXISTS)) // If the FOF does not "exist", we pretend that nobody's there - continue; - - for (j = 0; j < MAXPLAYERS; j++) - { - if (!P_IsPlayerValid(j)) - continue; - - if (!P_IsMobjTouchingSector(players[j].mo, targetsec)) - continue; - - topheight = P_GetSpecialTopZ(players[j].mo, sec, targetsec); - bottomheight = P_GetSpecialBottomZ(players[j].mo, sec, targetsec); - - if (players[j].mo->z > topheight) - continue; - - if (players[j].mo->z + players[j].mo->height < bottomheight) - continue; - - if (floortouch && P_IsObjectOnGroundIn(players[j].mo, targetsec)) - eachtime->playersOnArea[j] = true; - else - eachtime->playersInArea[j] = true; - } - } - } - - if (!FOFsector) - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (!P_IsPlayerValid(i)) - continue; - - if (!P_IsMobjTouchingSector(players[i].mo, sec)) - continue; - - if (!(players[i].mo->subsector->sector == sec - || P_MobjTouchingSectorSpecial(players[i].mo, 2, (GETSECSPECIAL(sec->special, 2)), false) == sec)) - continue; - - if (floortouch && P_IsObjectOnRealGround(players[i].mo, sec)) - eachtime->playersOnArea[i] = true; - else - eachtime->playersInArea[i] = true; - } - } - } - - // Check if a new player entered. - // If not, check if a player hit the floor. - // If either condition is true, execute. - if (floortouch) - { - playersArea = eachtime->playersOnArea; - oldPlayersArea = oldPlayersOnArea; - } - else - { - playersArea = eachtime->playersInArea; - oldPlayersArea = oldPlayersInArea; + caller[i] = P_CanPlayerTrigger(i) ? P_FindPlayerTrigger(&players[i], eachtime->sourceline) : NULL; + eachtime->playersInArea[i] = caller[i] != NULL; } // Easy check... nothing has changed - if (!memcmp(playersArea, oldPlayersArea, sizeof(boolean)*MAXPLAYERS)) + if (!memcmp(eachtime->playersInArea, oldPlayersInArea, sizeof(boolean)*MAXPLAYERS)) return; - // If sector has an "all players" trigger type, all players need to be in area - if (GETSECSPECIAL(sec->special, 2) == 2 || GETSECSPECIAL(sec->special, 2) == 3) - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (P_IsPlayerValid(i) && !playersArea[i]) - return; - } - } - // Trigger for every player who has entered (and exited, if triggerOnExit) for (i = 0; i < MAXPLAYERS; i++) { - if (playersArea[i] == oldPlayersArea[i]) + if (eachtime->playersInArea[i] == oldPlayersInArea[i]) continue; // If player has just left, check if still valid - if (!playersArea[i] && (!eachtime->triggerOnExit || !P_IsPlayerValid(i))) + if (!eachtime->playersInArea[i] && (!eachtime->triggerOnExit || !P_CanPlayerTrigger(i))) continue; - CONS_Debug(DBG_GAMELOGIC, "Trying to activate each time executor with tag %d\n", tag); + // If sector has an "all players" trigger type, all players need to be in area + if (caller[i] && caller[i]->triggerer == TO_ALLPLAYERS) + { + if (!allPlayersChecked) + { + allPlayersChecked = true; + allPlayersTrigger = P_CheckAllTrigger(eachtime); + } + + if (!allPlayersTrigger) + continue; + } + + CONS_Debug(DBG_GAMELOGIC, "Trying to activate each time executor with tag %d\n", Tag_FGet(&eachtime->sourceline->tags)); // 03/08/14 -Monster Iestyn // No more stupid hacks involving changing eachtime->sourceline's tag or special or whatever! // This should now run ONLY the stuff for eachtime->sourceline itself, instead of all trigger linedefs sharing the same tag. // Makes much more sense doing it this way, honestly. - P_RunTriggerLinedef(eachtime->sourceline, players[i].mo, sec); + P_RunTriggerLinedef(eachtime->sourceline, players[i].mo, caller[i]); if (!eachtime->sourceline->special) // this happens only for "Trigger on X calls" linedefs P_RemoveThinker(&eachtime->thinker); @@ -1747,13 +1556,12 @@ void T_PlaneDisplace(planedisplace_t *pd) // (egg capsule button), P_PlayerInSpecialSector (buttons), // and P_SpawnSpecials (continuous floor movers and instant lower). // -void EV_DoFloor(line_t *line, floor_e floortype) +void EV_DoFloor(mtag_t tag, line_t *line, floor_e floortype) { INT32 firstone = 1; INT32 secnum = -1; sector_t *sec; floormove_t *dofloor; - mtag_t tag = Tag_FGet(&line->tags); TAG_ITER_SECTORS(tag, secnum) { @@ -1774,34 +1582,25 @@ void EV_DoFloor(line_t *line, floor_e floortype) dofloor->type = floortype; dofloor->crush = false; // default: types that crush will change this dofloor->sector = sec; + dofloor->sourceline = (INT32)(line - lines); switch (floortype) { - // Lowers a floor to the lowest surrounding floor. - case lowerFloorToLowest: - dofloor->direction = -1; // down - dofloor->speed = FLOORSPEED*2; // 2 fracunits per tic - dofloor->floordestheight = P_FindLowestFloorSurrounding(sec); - break; - - // Used for part of the Egg Capsule, when an FOF with type 666 is - // contacted by the player. + // Used to open the top of an Egg Capsule. case raiseFloorToNearestFast: dofloor->direction = -1; // down dofloor->speed = FLOORSPEED*4; // 4 fracunits per tic dofloor->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight); break; - // Used for sectors tagged to 50 linedefs (effectively - // changing the base height for placing things in that sector). + // Instantly lower floor to surrounding sectors. + // Used as a hack in the binary map format to allow thing heights above 4096. case instantLower: dofloor->direction = -1; // down dofloor->speed = INT32_MAX/2; // "instant" means "takes one tic" dofloor->floordestheight = P_FindLowestFloorSurrounding(sec); break; - // Linedef executor command, linetype 101. - // Front sector floor = destination height. case instantMoveFloorByFrontSector: dofloor->speed = INT32_MAX/2; // as above, "instant" is one tic dofloor->floordestheight = line->frontsector->floorheight; @@ -1811,22 +1610,12 @@ void EV_DoFloor(line_t *line, floor_e floortype) else dofloor->direction = -1; // down - // New for 1.09: now you can use the no climb flag to - // DISABLE the flat changing. This makes it work - // totally opposite the way linetype 106 does. Yet - // another reason I'll be glad to break backwards - // compatibility for the final. - if (line->flags & ML_NOCLIMB) - dofloor->texture = -1; // don't mess with the floorpic - else - dofloor->texture = line->frontsector->floorpic; + // If flag is set, change floor texture after moving + dofloor->texture = line->args[2] ? line->frontsector->floorpic : -1; break; - // Linedef executor command, linetype 106. - // Line length = speed, front sector floor = destination height. case moveFloorByFrontSector: - dofloor->speed = P_AproxDistance(line->dx, line->dy); - dofloor->speed = FixedDiv(dofloor->speed,8*FRACUNIT); + dofloor->speed = line->args[2] << (FRACBITS - 3); dofloor->floordestheight = line->frontsector->floorheight; if (dofloor->floordestheight >= sec->floorheight) @@ -1835,85 +1624,31 @@ void EV_DoFloor(line_t *line, floor_e floortype) dofloor->direction = -1; // down // chained linedef executing ability - if (line->flags & ML_BLOCKPLAYERS) - { - // Only set it on one of the moving sectors (the - // smallest numbered) and only if the front side - // x offset is positive, indicating a valid tag. - if (firstone && sides[line->sidenum[0]].textureoffset > 0) - dofloor->texture = (sides[line->sidenum[0]].textureoffset>>FRACBITS) - 32769; - else - dofloor->texture = -1; - } + // Only set it on one of the moving sectors (the smallest numbered) + if (line->args[3]) + dofloor->tag = firstone ? (INT16)line->args[3] : -1; // flat changing ability - else if (line->flags & ML_NOCLIMB) - dofloor->texture = line->frontsector->floorpic; - else - dofloor->texture = -1; // nothing special to do after movement completes - + dofloor->texture = line->args[4] ? line->frontsector->floorpic : -1; break; - case moveFloorByFrontTexture: - if (line->flags & ML_NOCLIMB) + case moveFloorByDistance: + if (line->args[4]) dofloor->speed = INT32_MAX/2; // as above, "instant" is one tic else - dofloor->speed = FixedDiv(sides[line->sidenum[0]].textureoffset,8*FRACUNIT); // texture x offset - dofloor->floordestheight = sec->floorheight + sides[line->sidenum[0]].rowoffset; // texture y offset + dofloor->speed = line->args[3] << (FRACBITS - 3); + dofloor->floordestheight = sec->floorheight + (line->args[2] << FRACBITS); if (dofloor->floordestheight > sec->floorheight) dofloor->direction = 1; // up else dofloor->direction = -1; // down break; -/* - // Linedef executor command, linetype 108. - // dx = speed, dy = amount to lower. - case lowerFloorByLine: - dofloor->direction = -1; // down - dofloor->speed = FixedDiv(abs(line->dx),8*FRACUNIT); - dofloor->floordestheight = sec->floorheight - abs(line->dy); - if (dofloor->floordestheight > sec->floorheight) // wrapped around - I_Error("Can't lower sector %d\n", secnum); - break; - - // Linedef executor command, linetype 109. - // dx = speed, dy = amount to raise. - case raiseFloorByLine: - dofloor->direction = 1; // up - dofloor->speed = FixedDiv(abs(line->dx),8*FRACUNIT); - dofloor->floordestheight = sec->floorheight + abs(line->dy); - if (dofloor->floordestheight < sec->floorheight) // wrapped around - I_Error("Can't raise sector %d\n", secnum); - break; -*/ - - // Linetypes 2/3. - // Move floor up and down indefinitely like the old elevators. + // Move floor up and down indefinitely. + // bounceFloor has slowdown at the top and bottom of movement. case bounceFloor: - dofloor->speed = P_AproxDistance(line->dx, line->dy); // same speed as elevateContinuous - dofloor->speed = FixedDiv(dofloor->speed,4*FRACUNIT); - dofloor->origspeed = dofloor->speed; // it gets slowed down at the top and bottom - dofloor->floordestheight = line->frontsector->floorheight; - - if (dofloor->floordestheight >= sec->floorheight) - dofloor->direction = 1; // up - else - dofloor->direction = -1; // down - - // Any delay? - dofloor->delay = sides[line->sidenum[0]].textureoffset >> FRACBITS; - dofloor->delaytimer = sides[line->sidenum[0]].rowoffset >> FRACBITS; // Initial delay - - dofloor->texture = (fixed_t)(line - lines); // hack: store source line number - break; - - // Linetypes 6/7. - // Like 2/3, but no slowdown at the top and bottom of movement, - // and the speed is line->dx the first way, line->dy for the - // return trip. Good for crushers. case bounceFloorCrush: - dofloor->speed = FixedDiv(abs(line->dx),4*FRACUNIT); + dofloor->speed = line->args[2] << (FRACBITS - 2); // same speed as elevateContinuous dofloor->origspeed = dofloor->speed; dofloor->floordestheight = line->frontsector->floorheight; @@ -1923,27 +1658,18 @@ void EV_DoFloor(line_t *line, floor_e floortype) dofloor->direction = -1; // down // Any delay? - dofloor->delay = sides[line->sidenum[0]].textureoffset >> FRACBITS; - dofloor->delaytimer = sides[line->sidenum[0]].rowoffset >> FRACBITS; // Initial delay - - dofloor->texture = (fixed_t)(line - lines); // hack: store source line number + dofloor->delay = line->args[5]; + dofloor->delaytimer = line->args[4]; // Initial delay break; case crushFloorOnce: - dofloor->speed = FixedDiv(abs(line->dx),4*FRACUNIT); - dofloor->origspeed = dofloor->speed; + dofloor->speed = dofloor->origspeed = line->args[2] << (FRACBITS - 2); dofloor->floordestheight = line->frontsector->ceilingheight; if (dofloor->floordestheight >= sec->floorheight) dofloor->direction = 1; // up else dofloor->direction = -1; // down - - // Any delay? - dofloor->delay = sides[line->sidenum[0]].textureoffset >> FRACBITS; - dofloor->delaytimer = sides[line->sidenum[0]].rowoffset >> FRACBITS; - - dofloor->texture = (fixed_t)(line - lines); // hack: store source line number break; default: @@ -1967,14 +1693,13 @@ void EV_DoFloor(line_t *line, floor_e floortype) // // jff 2/22/98 new type to move floor and ceiling in parallel // -void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed) +void EV_DoElevator(mtag_t tag, line_t *line, elevator_e elevtype) { INT32 secnum = -1; sector_t *sec; elevator_t *elevator; - mtag_t tag = Tag_FGet(&line->tags); - // act on all sectors with the same tag as the triggering linedef + // act on all sectors with the given tag TAG_ITER_SECTORS(tag, secnum) { sec = §ors[secnum]; @@ -1992,6 +1717,7 @@ void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed) elevator->type = elevtype; elevator->sourceline = line; elevator->distance = 1; // Always crush unless otherwise + elevator->sector = sec; // set up the fields according to the type of elevator action switch (elevtype) @@ -1999,92 +1725,58 @@ void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed) // elevator down to next floor case elevateDown: elevator->direction = -1; - elevator->sector = sec; elevator->speed = ELEVATORSPEED/2; // half speed elevator->floordestheight = P_FindNextLowestFloor(sec, sec->floorheight); - elevator->ceilingdestheight = elevator->floordestheight - + sec->ceilingheight - sec->floorheight; break; // elevator up to next floor case elevateUp: elevator->direction = 1; - elevator->sector = sec; elevator->speed = ELEVATORSPEED/4; // quarter speed elevator->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight); - elevator->ceilingdestheight = elevator->floordestheight - + sec->ceilingheight - sec->floorheight; break; // elevator up to highest floor case elevateHighest: elevator->direction = 1; - elevator->sector = sec; elevator->speed = ELEVATORSPEED/4; // quarter speed elevator->floordestheight = P_FindHighestFloorSurrounding(sec); - elevator->ceilingdestheight = elevator->floordestheight - + sec->ceilingheight - sec->floorheight; - break; - - // elevator to floor height of activating switch's front sector - case elevateCurrent: - elevator->sector = sec; - elevator->speed = ELEVATORSPEED; - elevator->floordestheight = line->frontsector->floorheight; - elevator->ceilingdestheight = elevator->floordestheight - + sec->ceilingheight - sec->floorheight; - elevator->direction = elevator->floordestheight > sec->floorheight? 1 : -1; break; case elevateContinuous: - if (customspeed) - { - elevator->origspeed = P_AproxDistance(line->dx, line->dy); - elevator->origspeed = FixedDiv(elevator->origspeed,4*FRACUNIT); - elevator->speed = elevator->origspeed; - } - else - { - elevator->speed = ELEVATORSPEED/2; - elevator->origspeed = elevator->speed; - } + elevator->origspeed = line->args[1] << (FRACBITS - 2); + elevator->speed = elevator->origspeed; - elevator->sector = sec; - elevator->low = !(line->flags & ML_NOCLIMB); // go down first unless noclimb is on + elevator->low = !line->args[4]; // go down first unless args[4] is set if (elevator->low) { elevator->direction = 1; elevator->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight); - elevator->ceilingdestheight = elevator->floordestheight - + sec->ceilingheight - sec->floorheight; } else { elevator->direction = -1; elevator->floordestheight = P_FindNextLowestFloor(sec,sec->floorheight); - elevator->ceilingdestheight = elevator->floordestheight - + sec->ceilingheight - sec->floorheight; } elevator->floorwasheight = elevator->sector->floorheight; elevator->ceilingwasheight = elevator->sector->ceilingheight; - elevator->delay = sides[line->sidenum[0]].textureoffset >> FRACBITS; - elevator->delaytimer = sides[line->sidenum[0]].rowoffset >> FRACBITS; // Initial delay + elevator->delay = line->args[3]; + elevator->delaytimer = line->args[2]; // Initial delay break; case bridgeFall: elevator->direction = -1; - elevator->sector = sec; elevator->speed = ELEVATORSPEED*4; // quadruple speed elevator->floordestheight = P_FindNextLowestFloor(sec, sec->floorheight); - elevator->ceilingdestheight = elevator->floordestheight - + sec->ceilingheight - sec->floorheight; break; default: break; } + elevator->ceilingdestheight = elevator->floordestheight + sec->ceilingheight - sec->floorheight; + // interpolation R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, false); R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, true); @@ -2097,7 +1789,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) fixed_t leftx, rightx, topy, bottomy, topz, bottomz, widthfactor, heightfactor, a, b, c, spacing; mobjtype_t type; tic_t lifetime; - INT16 flags; + boolean fromcenter; sector_t *controlsec = rover->master->frontsector; mtag_t tag = Tag_FGet(&controlsec->tags); @@ -2127,25 +1819,20 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) spacing = (32<>FRACBITS != -1) - lifetime = (sides[lines[tagline].sidenum[0]].rowoffset>>FRACBITS); - else - lifetime = 0; - } - flags = lines[tagline].flags; + if (lines[tagline].stringargs[0]) + type = get_number(lines[tagline].stringargs[0]); + if (lines[tagline].args[0]) + spacing = lines[tagline].args[0] << FRACBITS; + if (lines[tagline].args[1]) + lifetime = (lines[tagline].args[1] != -1) ? lines[tagline].args[1] : 0; + fromcenter = !!lines[tagline].args[2]; } } @@ -2180,7 +1867,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) topz = *rover->topheight-(spacing>>1); bottomz = *rover->bottomheight; - if (flags & ML_EFFECT1) + if (fromcenter) { widthfactor = (rightx + topy - leftx - bottomy)>>3; heightfactor = (topz - *rover->bottomheight)>>2; @@ -2204,7 +1891,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) spawned = P_SpawnMobj(a, b, c, type); spawned->angle += P_RandomKey(PR_TERRAIN, 36)*ANG10; // irrelevant for default objects but might make sense for some custom ones - if (flags & ML_EFFECT1) + if (fromcenter) { P_InstaThrust(spawned, R_PointToAngle2(sec->soundorg.x, sec->soundorg.y, a, b), FixedDiv(P_AproxDistance(a - sec->soundorg.x, b - sec->soundorg.y), widthfactor)); P_SetObjectMomZ(spawned, FixedDiv((c - bottomz), heightfactor), false); @@ -2284,7 +1971,7 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating, crumble_t *crumble; sector_t *foundsec; INT32 i; - mtag_t tag = Tag_FGet(&rover->master->tags); + mtag_t tag = rover->master->args[0]; // If floor is already activated, skip it if (sec->floordata) @@ -2380,7 +2067,7 @@ void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher) block->direction = 1; block->floorstartheight = block->sector->floorheight; block->ceilingstartheight = block->sector->ceilingheight; - block->tag = (INT16)Tag_FGet(§or->tags); + block->tag = (INT16)rover->master->args[0]; // interpolation R_CreateInterpolator_SectorPlane(&block->thinker, roversec, false); diff --git a/src/p_inter.c b/src/p_inter.c index b7e26d63a..6eee8e322 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -516,7 +516,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; case MT_STARPOST: - P_TouchStarPost(special, player, special->spawnpoint && (special->spawnpoint->options & MTF_OBJECTSPECIAL)); + P_TouchStarPost(special, player, special->spawnpoint && special->spawnpoint->args[1]); return; case MT_BIGTUMBLEWEED: diff --git a/src/p_lights.c b/src/p_lights.c index 2fa4e6822..2bd25ffd2 100644 --- a/src/p_lights.c +++ b/src/p_lights.c @@ -30,7 +30,7 @@ void P_RemoveLighting(sector_t *sector) // The thinker is the first member in all the lighting action structs, // so just let the thinker get freed, and that will free the whole // structure. - P_RemoveThinker(&((elevator_t *)sector->lightingdata)->thinker); + P_RemoveThinker(&((thinkerdata_t *)sector->lightingdata)->thinker); sector->lightingdata = NULL; } } @@ -54,43 +54,36 @@ void T_FireFlicker(fireflicker_t *flick) amount = (INT16)((UINT8)(P_RandomByte(PR_UNDEFINED) & 3) * 16); if (flick->sector->lightlevel - amount < flick->minlight) - flick->sector->lightlevel = (INT16)flick->minlight; + flick->sector->lightlevel = flick->minlight; else - flick->sector->lightlevel = (INT16)((INT16)flick->maxlight - amount); + flick->sector->lightlevel = flick->maxlight - amount; flick->count = flick->resetcount; } /** Spawns an adjustable fire flicker effect in a sector. * - * \param minsector Sector whose light level is used as the darkest. - * \param maxsector Sector whose light level is used as the brightest, - * and also the target sector for the effect. + * \param sector Target sector for the effect. + * \param lighta One of the two light levels to move between. + * \param lightb The other light level. * \param length Four times the number of tics between flickers. * \sa T_FireFlicker */ -fireflicker_t *P_SpawnAdjustableFireFlicker(sector_t *minsector, sector_t *maxsector, INT32 length) +fireflicker_t *P_SpawnAdjustableFireFlicker(sector_t *sector, INT16 lighta, INT16 lightb, INT32 length) { fireflicker_t *flick; - P_RemoveLighting(maxsector); // out with the old, in with the new + P_RemoveLighting(sector); // out with the old, in with the new flick = Z_Calloc(sizeof (*flick), PU_LEVSPEC, NULL); P_AddThinker(THINK_MAIN, &flick->thinker); flick->thinker.function.acp1 = (actionf_p1)T_FireFlicker; - flick->sector = maxsector; - flick->maxlight = maxsector->lightlevel; - flick->minlight = minsector->lightlevel; - if (flick->minlight > flick->maxlight) - { - // You mixed them up, you dummy. - INT32 oops = flick->minlight; - flick->minlight = flick->maxlight; - flick->maxlight = oops; - } + flick->sector = sector; + flick->maxlight = max(lighta, lightb); + flick->minlight = min(lighta, lightb); flick->count = flick->resetcount = length/4; - maxsector->lightingdata = flick; + sector->lightingdata = flick; // input bounds checking and stuff if (!flick->resetcount) @@ -103,6 +96,9 @@ fireflicker_t *P_SpawnAdjustableFireFlicker(sector_t *minsector, sector_t *maxse flick->maxlight++; } + // Make sure the starting light level is in range. + sector->lightlevel = max(flick->minlight, min(flick->maxlight, sector->lightlevel)); + return flick; } @@ -148,7 +144,7 @@ void P_SpawnLightningFlash(sector_t *sector) minlight = ((lightflash_t *)sector->lightingdata)->minlight; } - P_RemoveThinker(&((elevator_t *)sector->lightingdata)->thinker); + P_RemoveThinker(&((thinkerdata_t *)sector->lightingdata)->thinker); } sector->lightingdata = NULL; @@ -182,21 +178,21 @@ void T_StrobeFlash(strobe_t *flash) if (flash->sector->lightlevel == flash->minlight) { - flash->sector->lightlevel = (INT16)flash->maxlight; + flash->sector->lightlevel = flash->maxlight; flash->count = flash->brighttime; } else { - flash->sector->lightlevel = (INT16)flash->minlight; + flash->sector->lightlevel = flash->minlight; flash->count = flash->darktime; } } /** Spawns an adjustable strobe light effect in a sector. * - * \param minsector Sector whose light level is used as the darkest. - * \param maxsector Sector whose light level is used as the brightest, - * and also the target sector for the effect. + * \param sector Target sector for the effect. + * \param lighta One of the two light levels to move between. + * \param lightb The other light level. * \param darktime Time in tics for the light to be dark. * \param brighttime Time in tics for the light to be bright. * \param inSync If true, the effect will be kept in sync @@ -207,29 +203,21 @@ void T_StrobeFlash(strobe_t *flash) * the strobe flash is random. * \sa T_StrobeFlash */ -strobe_t *P_SpawnAdjustableStrobeFlash(sector_t *minsector, sector_t *maxsector, INT32 darktime, INT32 brighttime, boolean inSync) +strobe_t *P_SpawnAdjustableStrobeFlash(sector_t *sector, INT16 lighta, INT16 lightb, INT32 darktime, INT32 brighttime, boolean inSync) { strobe_t *flash; - P_RemoveLighting(maxsector); // out with the old, in with the new + P_RemoveLighting(sector); // out with the old, in with the new flash = Z_Calloc(sizeof (*flash), PU_LEVSPEC, NULL); P_AddThinker(THINK_MAIN, &flash->thinker); - flash->sector = maxsector; + flash->sector = sector; flash->darktime = darktime; flash->brighttime = brighttime; flash->thinker.function.acp1 = (actionf_p1)T_StrobeFlash; - flash->maxlight = maxsector->lightlevel; - flash->minlight = minsector->lightlevel; - - if (flash->minlight > flash->maxlight) - { - // You mixed them up, you dummy. - INT32 oops = flash->minlight; - flash->minlight = flash->maxlight; - flash->maxlight = oops; - } + flash->maxlight = max(lighta, lightb); + flash->minlight = min(lighta, lightb); if (flash->minlight == flash->maxlight) flash->minlight = 0; @@ -239,7 +227,10 @@ strobe_t *P_SpawnAdjustableStrobeFlash(sector_t *minsector, sector_t *maxsector, else flash->count = 1; - maxsector->lightingdata = flash; + // Make sure the starting light level is in range. + sector->lightlevel = max(flash->minlight, min(flash->maxlight, sector->lightlevel)); + + sector->lightingdata = flash; return flash; } @@ -254,20 +245,20 @@ void T_Glow(glow_t *g) { case -1: // DOWN - g->sector->lightlevel = (INT16)(g->sector->lightlevel - (INT16)g->speed); + g->sector->lightlevel -= g->speed; if (g->sector->lightlevel <= g->minlight) { - g->sector->lightlevel = (INT16)(g->sector->lightlevel + (INT16)g->speed); + g->sector->lightlevel += g->speed; g->direction = 1; } break; case 1: // UP - g->sector->lightlevel = (INT16)(g->sector->lightlevel + (INT16)g->speed); + g->sector->lightlevel += g->speed; if (g->sector->lightlevel >= g->maxlight) { - g->sector->lightlevel = (INT16)(g->sector->lightlevel - (INT16)g->speed); + g->sector->lightlevel -= g->speed; g->direction = -1; } break; @@ -276,34 +267,27 @@ void T_Glow(glow_t *g) /** Spawns an adjustable glowing light effect in a sector. * - * \param minsector Sector whose light level is used as the darkest. - * \param maxsector Sector whose light level is used as the brightest, - * and also the target sector for the effect. + * \param sector Target sector for the effect. + * \param lighta One of the two light levels to move between. + * \param lightb The other light level. * \param length The speed of the effect. * \sa T_Glow */ -glow_t *P_SpawnAdjustableGlowingLight(sector_t *minsector, sector_t *maxsector, INT32 length) +glow_t *P_SpawnAdjustableGlowingLight(sector_t *sector, INT16 lighta, INT16 lightb, INT32 length) { glow_t *g; - P_RemoveLighting(maxsector); // out with the old, in with the new + P_RemoveLighting(sector); // out with the old, in with the new g = Z_Calloc(sizeof (*g), PU_LEVSPEC, NULL); P_AddThinker(THINK_MAIN, &g->thinker); - g->sector = maxsector; - g->minlight = minsector->lightlevel; - g->maxlight = maxsector->lightlevel; - if (g->minlight > g->maxlight) - { - // You mixed them up, you dummy. - INT32 oops = g->minlight; - g->minlight = g->maxlight; - g->maxlight = oops; - } + g->sector = sector; + g->minlight = min(lighta, lightb); + g->maxlight = max(lighta, lightb); g->thinker.function.acp1 = (actionf_p1)T_Glow; g->direction = 1; - g->speed = length/4; + g->speed = (INT16)(length/4); if (g->speed > (g->maxlight - g->minlight)/2) // don't make it ridiculous speed g->speed = (g->maxlight - g->minlight)/2; @@ -317,7 +301,10 @@ glow_t *P_SpawnAdjustableGlowingLight(sector_t *minsector, sector_t *maxsector, g->speed = (g->maxlight - g->minlight)/2; } - maxsector->lightingdata = g; + // Make sure the starting light level is in range. + sector->lightlevel = max(g->minlight, min(g->maxlight, sector->lightlevel)); + + sector->lightingdata = g; return g; } @@ -371,9 +358,10 @@ void P_FadeLightBySector(sector_t *sector, INT32 destvalue, INT32 speed, boolean } } -void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed, boolean ticbased, boolean force) +void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed, boolean ticbased, boolean force, boolean relative) { INT32 i; + INT32 realdestvalue; // search all sectors for ones with tag TAG_ITER_SECTORS(tag, i) @@ -386,7 +374,9 @@ void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed, boolean ticbased, bool CONS_Debug(DBG_GAMELOGIC, "Line type 420 Executor: Fade light thinker already exists, timer: %d\n", ((lightlevel_t*)sectors[i].lightingdata)->timer); continue; } - P_FadeLightBySector(§ors[i], destvalue, speed, ticbased); + + realdestvalue = relative ? max(0, min(255, sectors[i].lightlevel + destvalue)) : destvalue; + P_FadeLightBySector(§ors[i], realdestvalue, speed, ticbased); } } diff --git a/src/p_local.h b/src/p_local.h index 18ff574fb..f5d613e97 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -371,7 +371,7 @@ void P_NewChaseDir(mobj_t *actor); boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed_t dist); mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz, boolean lookforplayers, SINT8 moveforward); -void P_InternalFlickySetColor(mobj_t *actor, UINT8 extrainfo); +void P_InternalFlickySetColor(mobj_t *actor, UINT8 color); #define P_IsFlickyCenter(type) (type > MT_FLICKY_01 && type < MT_SEED && (type - MT_FLICKY_01) % 2 ? 1 : 0) void P_InternalFlickyBubble(mobj_t *actor); void P_InternalFlickyFly(mobj_t *actor, fixed_t flyspeed, fixed_t targetdist, fixed_t chasez); @@ -414,7 +414,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y); boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam); boolean P_CheckMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff); fixed_t P_BaseStepUp(void); -fixed_t P_GetThingStepUp(mobj_t *thing); +fixed_t P_GetThingStepUp(mobj_t *thing, fixed_t destX, fixed_t destY); boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff); boolean P_Move(mobj_t *actor, fixed_t speed); boolean P_SetOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z); diff --git a/src/p_map.c b/src/p_map.c index 297f0cbe7..879a6650e 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -481,7 +481,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) switch (spring->type) { case MT_FAN: // fan - if (zdist > (spring->health << FRACBITS)) // max z distance determined by health (set by map thing angle) + if (zdist > (spring->health << FRACBITS)) // max z distance determined by health (set by map thing args[0]) break; if (flipval*object->momz >= FixedMul(speed, spring->scale)) // if object's already moving faster than your best, don't bother break; @@ -2143,7 +2143,7 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) mapcampointer = thiscam; - if (GETSECSPECIAL(newsubsec->sector->special, 4) == 12) + if (newsubsec->sector->flags & MSF_NOCLIPCAMERA) { // Camera noclip on entire sector. tmfloorz = tmdropoffz = thiscam->z; tmceilingz = tmdrpoffceilz = thiscam->z + thiscam->height; @@ -2183,7 +2183,7 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) for (rover = newsubsec->sector->ffloors; rover; rover = rover->next) { fixed_t topheight, bottomheight; - if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12) + if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA)) continue; topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, x, y, NULL); @@ -2255,7 +2255,7 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) // We're inside it! Yess... polysec = po->lines[0]->backsector; - if (GETSECSPECIAL(polysec->special, 4) == 12) + if (polysec->flags & MSF_NOCLIPCAMERA) { // Camera noclip polyobj. plink = (polymaplink_t *)(plink->link.next); continue; @@ -2509,7 +2509,7 @@ fixed_t P_BaseStepUp(void) return FixedMul(MAXSTEPMOVE, mapobjectscale); } -fixed_t P_GetThingStepUp(mobj_t *thing) +fixed_t P_GetThingStepUp(mobj_t *thing, fixed_t destX, fixed_t destY) { const fixed_t maxstepmove = P_BaseStepUp(); fixed_t maxstep = maxstepmove; @@ -2520,12 +2520,14 @@ fixed_t P_GetThingStepUp(mobj_t *thing) maxstep += maxstepmove; } - if (P_MobjTouchingSectorSpecial(thing, 1, 13, false)) + if (P_MobjTouchingSectorSpecialFlag(thing, SSF_DOUBLESTEPUP) + || (R_PointInSubsector(destX, destY)->sector->specialflags & SSF_DOUBLESTEPUP)) { // If using type Section1:13, double the maxstep. maxstep <<= 1; } - else if (P_MobjTouchingSectorSpecial(thing, 1, 12, false)) + else if (P_MobjTouchingSectorSpecialFlag(thing, SSF_NOSTEPUP) + || (R_PointInSubsector(destX, destY)->sector->specialflags & SSF_NOSTEPUP)) { // If using type Section1:12, no maxstep. For short walls, like Egg Zeppelin maxstep = 0; @@ -2599,7 +2601,7 @@ increment_move if (!(thing->flags & MF_NOCLIP)) { //All things are affected by their scale. - fixed_t maxstep = P_GetThingStepUp(thing); + fixed_t maxstep = P_GetThingStepUp(thing, x, y); if (tmceilingz - tmfloorz < thing->height) { @@ -2651,7 +2653,8 @@ increment_move } } else if (thing->momz * P_MobjFlip(thing) <= 0 // Step down requires moving down. - && !(P_MobjTouchingSectorSpecial(thing, 1, 14, false))) + && !(P_MobjTouchingSectorSpecialFlag(thing, SSF_NOSTEPDOWN) + || (R_PointInSubsector(x, y)->sector->specialflags & SSF_NOSTEPDOWN))) { // If the floor difference is MAXSTEPMOVE or less, and the sector isn't Section1:14, ALWAYS // step down! Formerly required a Section1:13 sector for the full MAXSTEPMOVE, but no more. @@ -3150,7 +3153,7 @@ static void P_HitCameraSlideLine(line_t *ld, camera_t *thiscam) } side = P_PointOnLineSide(thiscam->x, thiscam->y, ld); - lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy); + lineangle = ld->angle; if (side == 1) lineangle += ANGLE_180; @@ -3196,7 +3199,7 @@ static void P_HitSlideLine(line_t *ld) side = P_PointOnLineSide(slidemo->x, slidemo->y, ld); - lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy); + lineangle = ld->angle; if (side == 1) lineangle += ANGLE_180; @@ -3230,7 +3233,7 @@ static void P_PlayerHitBounceLine(line_t *ld) fixed_t x, y; side = P_PointOnLineSide(slidemo->x, slidemo->y, ld); - lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy)-ANGLE_90; + lineangle = ld->angle - ANGLE_90; if (side == 1) lineangle += ANGLE_180; @@ -3279,7 +3282,7 @@ static void P_HitBounceLine(line_t *ld) return; } - lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy); + lineangle = ld->angle; if (lineangle >= ANGLE_180) lineangle -= ANGLE_180; @@ -3366,7 +3369,7 @@ static boolean PTR_LineIsBlocking(line_t *li) if (opentop - slidemo->z < slidemo->height) return true; // mobj is too high - if (openbottom - slidemo->z > P_GetThingStepUp(slidemo)) + if (openbottom - slidemo->z > P_GetThingStepUp(slidemo, slidemo->x, slidemo->y)) return true; // too big a step up return false; @@ -3387,7 +3390,7 @@ static boolean PTR_SlideTraverse(intercept_t *in) // see if it is closer than best so far if (li->polyobj && slidemo->player) { - if ((li->polyobj->lines[0]->backsector->flags & SF_TRIGGERSPECIAL_TOUCH) && !(li->polyobj->flags & POF_NOSPECIALS)) + if ((li->polyobj->lines[0]->backsector->flags & MSF_TRIGGERSPECIAL_TOUCH) && !(li->polyobj->flags & POF_NOSPECIALS)) P_ProcessSpecialSector(slidemo->player, slidemo->subsector->sector, li->polyobj->lines[0]->backsector); } @@ -3514,10 +3517,7 @@ static void P_CheckLavaWall(mobj_t *mo, sector_t *sec) if (!(rover->flags & FF_SWIMMABLE)) continue; - if (GETSECSPECIAL(rover->master->frontsector->special, 1) != 3) - continue; - - if (rover->master->flags & ML_BLOCKPLAYERS) + if (rover->master->frontsector->damagetype != SD_LAVA) continue; topheight = P_GetFFloorTopZAt(rover, mo->x, mo->y); diff --git a/src/p_maputl.c b/src/p_maputl.c index 74fe2331d..d05e2fad3 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -437,7 +437,7 @@ void P_CameraLineOpening(line_t *linedef) for (rover = front->ffloors; rover; rover = rover->next) { fixed_t topheight, bottomheight; - if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12) + if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA)) continue; topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tmx, tmy, linedef); @@ -461,7 +461,7 @@ void P_CameraLineOpening(line_t *linedef) for (rover = back->ffloors; rover; rover = rover->next) { fixed_t topheight, bottomheight; - if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12) + if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA)) continue; topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tmx, tmy, linedef); @@ -527,27 +527,39 @@ P_GetMidtextureTopBottom #if 0 // don't remove this code unless solid midtextures // on non-solid polyobjects should NEVER happen in the future - if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) { - if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat + if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) + { + if ((linedef->flags & ML_WRAPMIDTEX) && !side->repeatcnt) // "infinite" repeat + { texbottom = back->floorheight + side->rowoffset; textop = back->ceilingheight + side->rowoffset; - } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { + } + else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_MIDPEG)) + { texbottom = back->floorheight + side->rowoffset; textop = texbottom + texheight*(side->repeatcnt+1); - } else { + } + else + { textop = back->ceilingheight + side->rowoffset; texbottom = textop - texheight*(side->repeatcnt+1); } - } else + } + else #endif { - if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat + if ((linedef->flags & ML_WRAPMIDTEX) && !side->repeatcnt) // "infinite" repeat + { texbottom += side->rowoffset; textop += side->rowoffset; - } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { + } + else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_MIDPEG)) + { texbottom += side->rowoffset; textop = texbottom + texheight*(side->repeatcnt+1); - } else { + } + else + { textop += side->rowoffset; texbottom = textop - texheight*(side->repeatcnt+1); } @@ -562,6 +574,16 @@ P_GetMidtextureTopBottom return true; } +static boolean P_MidtextureIsSolid(line_t *linedef, mobj_t *mobj) +{ + if (P_IsLineTripWire(linedef) == true) + { + return (mobj->player && !K_TripwirePass(mobj->player)); + } + + return (linedef->flags & ML_MIDSOLID); +} + void P_LineOpening(line_t *linedef, mobj_t *mobj) { enum { FRONT, BACK }; @@ -670,9 +692,9 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) if (mobj) { // Check for collision with front side's midtexture if Effect 4 is set - if ((linedef->flags & ML_EFFECT4 || (mobj->player && P_IsLineTripWire(linedef) && !K_TripwirePass(mobj->player))) - && !linedef->polyobj // don't do anything for polyobjects! ...for now - ) { + if (P_MidtextureIsSolid(linedef, mobj) == true + && !linedef->polyobj) // don't do anything for polyobjects! ...for now + { fixed_t textop, texbottom; fixed_t texmid, delta1, delta2; @@ -683,7 +705,9 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) delta1 = abs(mobj->z - texmid); delta2 = abs(thingtop - texmid); - if (delta1 > delta2) { // Below + if (delta1 > delta2) + { + // Below if (opentop > texbottom) { topedge[lo] -= ( opentop - texbottom ); @@ -692,7 +716,10 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) openceilingstep = ( thingtop - topedge[lo] ); openceilingdrop = ( topedge[hi] - topedge[lo] ); } - } else { // Above + } + else + { + // Above if (openbottom < textop) { botedge[hi] += ( textop - openbottom ); @@ -704,6 +731,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) } } } + if (linedef->polyobj) { // Treat polyobj's backsector like a 3D Floor diff --git a/src/p_mobj.c b/src/p_mobj.c index 6df9b921c..71ba3c581 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11,6 +11,7 @@ /// \file p_mobj.c /// \brief Moving object handling. Spawn functions +#include "dehacked.h" #include "doomdef.h" #include "g_game.h" #include "g_input.h" @@ -1057,6 +1058,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) if (mo->subsector->sector->ffloors) // Check for 3D floor gravity too. { ffloor_t *rover; + fixed_t gravfactor; for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next) { @@ -1066,13 +1068,14 @@ fixed_t P_GetMobjGravity(mobj_t *mo) if ((rover->flags & (FF_SWIMMABLE|FF_GOOWATER)) == (FF_SWIMMABLE|FF_GOOWATER)) goopgravity = true; - if (!(rover->master->frontsector->gravity)) + gravfactor = P_GetSectorGravityFactor(mo->subsector->sector); + + if (gravfactor == FRACUNIT) continue; - gravityadd = -FixedMul(gravity, - (FixedDiv(*rover->master->frontsector->gravity>>FRACBITS, 1000))); + gravityadd = -FixedMul(gravity, gravfactor); - if (rover->master->frontsector->verticalflip && gravityadd > 0) + if ((rover->master->frontsector->flags & MSF_GRAVITYFLIP) && gravityadd > 0) mo->eflags |= MFE_VERTICALFLIP; no3dfloorgrav = false; @@ -1082,13 +1085,9 @@ fixed_t P_GetMobjGravity(mobj_t *mo) if (no3dfloorgrav) { - if (mo->subsector->sector->gravity) - gravityadd = -FixedMul(gravity, - (FixedDiv(*mo->subsector->sector->gravity>>FRACBITS, 1000))); - else - gravityadd = -gravity; + gravityadd = -FixedMul(gravity, P_GetSectorGravityFactor(mo->subsector->sector)); - if (mo->subsector->sector->verticalflip && gravityadd > 0) + if ((mo->subsector->sector->flags & MSF_GRAVITYFLIP) && gravityadd > 0) mo->eflags |= MFE_VERTICALFLIP; } @@ -1415,8 +1414,7 @@ static void P_PushableCheckBustables(mobj_t *mo) if (!(rover->flags & FF_BUSTUP)) continue; - // Needs ML_EFFECT4 flag for pushables to break it - if (!(rover->master->flags & ML_EFFECT4)) + if (!(rover->bustflags & FB_PUSHABLES)) continue; if (rover->master->frontsector->crumblestate != CRUMBLE_NONE) @@ -1426,7 +1424,7 @@ static void P_PushableCheckBustables(mobj_t *mo) bottomheight = P_GetFOFBottomZ(mo, node->m_sector, rover, mo->x, mo->y, NULL); // Height checks - if (rover->flags & FF_SHATTERBOTTOM) + if (rover->bustflags & FB_ONLYBOTTOM) { if (mo->z + mo->momz + mo->height < bottomheight) continue; @@ -1434,36 +1432,42 @@ static void P_PushableCheckBustables(mobj_t *mo) if (mo->z + mo->height > bottomheight) continue; } - else if (rover->flags & FF_SPINBUST) - { - if (mo->z + mo->momz > topheight) - continue; - - if (mo->z + mo->height < bottomheight) - continue; - } - else if (rover->flags & FF_SHATTER) - { - if (mo->z + mo->momz > topheight) - continue; - - if (mo->z + mo->momz + mo->height < bottomheight) - continue; - } else { - if (mo->z >= topheight) - continue; + switch (rover->busttype) + { + case BT_TOUCH: + if (mo->z + mo->momz > topheight) + continue; - if (mo->z + mo->height < bottomheight) - continue; + if (mo->z + mo->momz + mo->height < bottomheight) + continue; + + break; + case BT_SPINBUST: + if (mo->z + mo->momz > topheight) + continue; + + if (mo->z + mo->height < bottomheight) + continue; + + break; + default: + if (mo->z >= topheight) + continue; + + if (mo->z + mo->height < bottomheight) + continue; + + break; + } } EV_CrumbleChain(NULL, rover); // node->m_sector // Run a linedef executor?? - if (rover->master->flags & ML_EFFECT5) - P_LinedefExecute((INT16)(P_AproxDistance(rover->master->dx, rover->master->dy)>>FRACBITS), mo, node->m_sector); + if (rover->bustflags & FB_EXECUTOR) + P_LinedefExecute(rover->busttag, mo, node->m_sector); goto bustupdone; } @@ -2094,16 +2098,22 @@ boolean P_CheckDeathPitCollide(mobj_t *mo) I_Assert(!P_MobjWasRemoved(mo)); if (mo->player && mo->player->pflags & PF_GODMODE) + { return false; + } - if (((mo->z <= mo->subsector->sector->floorheight - && ((mo->subsector->sector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->subsector->sector->flags & SF_FLIPSPECIAL_FLOOR)) - || (mo->z + mo->height >= mo->subsector->sector->ceilingheight - && ((mo->subsector->sector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (mo->eflags & MFE_VERTICALFLIP)) && (mo->subsector->sector->flags & SF_FLIPSPECIAL_CEILING))) - && (GETSECSPECIAL(mo->subsector->sector->special, 1) == 6 - || GETSECSPECIAL(mo->subsector->sector->special, 1) == 7 - || GETSECSPECIAL(mo->subsector->sector->special, 1) == 8)) - return true; + if (mo->subsector->sector->damagetype == SD_DEATHPIT) + { + const boolean flipped = (mo->eflags & MFE_VERTICALFLIP); + const sectorflags_t flags = mo->subsector->sector->flags; + + return ( + (mo->z <= mo->subsector->sector->floorheight + && ((flags & MSF_TRIGGERSPECIAL_HEADBUMP) || !flipped) && (flags & MSF_FLIPSPECIAL_FLOOR)) + || (mo->z + mo->height >= mo->subsector->sector->ceilingheight + && ((flags & MSF_TRIGGERSPECIAL_HEADBUMP) || flipped) && (flags & MSF_FLIPSPECIAL_CEILING)) + ); + } return false; } @@ -2115,8 +2125,7 @@ boolean P_CheckSolidLava(mobj_t *mobj, ffloor_t *rover) return false; } - if (rover->flags & FF_SWIMMABLE && GETSECSPECIAL(rover->master->frontsector->special, 1) == 3 - && !(rover->master->flags & ML_BLOCKPLAYERS)) + if ((rover->flags & FF_SWIMMABLE) && (rover->master->frontsector->damagetype == SD_LAVA)) { return true; } @@ -2522,7 +2531,7 @@ boolean P_ZMovement(mobj_t *mo) { if (mo->flags2 & MF2_AMBUSH) { - // If deafed, give the tumbleweed another random kick if it runs out of steam. + // Give the tumbleweed another random kick if it runs out of steam. mom.z += P_MobjFlip(mo)*FixedMul(6*FRACUNIT, mo->scale); if (P_RandomChance(PR_DECORATION, FRACUNIT/2)) @@ -2691,7 +2700,7 @@ static void P_CheckMarioBlocks(mobj_t *mo) if (*rover->bottomheight != mo->ceilingz) continue; - if (rover->flags & FF_SHATTERBOTTOM) // Brick block! + if (rover->flags & FF_GOOWATER) // Brick block! EV_CrumbleChain(node->m_sector, rover); else // Question block! EV_MarioBlock(rover, node->m_sector, mo); @@ -3181,7 +3190,7 @@ boolean P_CanRunOnWater(mobj_t *mobj, ffloor_t *rover) return false; } - maxStep = P_GetThingStepUp(mobj); + maxStep = P_GetThingStepUp(mobj, mobj->x, mobj->y); surfDiff = flip ? (surfaceheight - mobjbottom) : (mobjbottom - surfaceheight); if (surfDiff <= maxStep && surfDiff >= 0) @@ -3286,7 +3295,7 @@ void P_MobjCheckWater(mobj_t *mobj) if (mobj->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)) { - if (GETSECSPECIAL(rover->master->frontsector->special, 1) == 3) + if (rover->master->frontsector->damagetype == SD_LAVA) mobj->eflags |= MFE_TOUCHLAVA; if (rover->flags & FF_GOOWATER && !(mobj->flags & MF_NOGRAVITY)) @@ -3591,19 +3600,16 @@ static boolean P_CameraCheckHeat(camera_t *thiscam) { sector_t *sector; fixed_t halfheight = thiscam->z + (thiscam->height >> 1); - size_t i; // see if we are in water sector = thiscam->subsector->sector; - for (i = 0; i < sector->tags.count; i++) - if (Tag_FindLineSpecial(13, sector->tags.tags[i]) != -1) - return true; + if (sector->flags & MSF_HEATWAVE) + return true; if (sector->ffloors) { ffloor_t *rover; - size_t j; for (rover = sector->ffloors; rover; rover = rover->next) { @@ -3615,8 +3621,7 @@ static boolean P_CameraCheckHeat(camera_t *thiscam) if (halfheight <= P_GetFFloorBottomZAt(rover, thiscam->x, thiscam->y)) continue; - for (j = 0; j < rover->master->frontsector->tags.count; j++) - if (Tag_FindLineSpecial(13, rover->master->frontsector->tags.tags[j]) != -1) + if (rover->master->frontsector->flags & MSF_HEATWAVE) return true; } } @@ -5225,7 +5230,6 @@ void P_RunKartItems(void) P_SetTarget(&kitemcap, NULL); } - void P_RunOverlays(void) { // run overlays @@ -9243,16 +9247,9 @@ static boolean P_FuseThink(mobj_t *mobj) { // gargoyle and snowman handled in P_PushableThinker, not here case MT_SPIKE: - P_SetMobjState(mobj, mobj->state->nextstate); - mobj->fuse = mobj->info->speed; - if (mobj->spawnpoint) - mobj->fuse += mobj->spawnpoint->angle; - break; case MT_WALLSPIKE: P_SetMobjState(mobj, mobj->state->nextstate); - mobj->fuse = mobj->info->speed; - if (mobj->spawnpoint) - mobj->fuse += (mobj->spawnpoint->angle / 360); + mobj->fuse = mobj->spawnpoint ? mobj->spawnpoint->args[0] : mobj->info->speed; break; case MT_LAVAFALL: if (mobj->state - states == S_LAVAFALL_DORMANT) @@ -9388,7 +9385,7 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->flags & MF_NOTHINK) return; - if ((mobj->flags & MF_BOSS) && mobj->spawnpoint && (bossdisabled & (1<spawnpoint->extrainfo))) + if ((mobj->flags & MF_BOSS) && mobj->spawnpoint && (bossdisabled & (1<spawnpoint->args[0]))) return; // Don't run any thinker code while in hitlag @@ -9414,16 +9411,8 @@ void P_MobjThinker(mobj_t *mobj) tmfloorthing = tmhitthing = NULL; - // Sector special (2,8) allows ANY mobj to trigger a linedef exec - if (mobj->subsector && GETSECSPECIAL(mobj->subsector->sector->special, 2) == 8) - { - sector_t *sec2 = P_ThingOnSpecial3DFloor(mobj); - if (sec2 && GETSECSPECIAL(sec2->special, 2) == 1) - { - mtag_t tag = Tag_FGet(&sec2->tags); - P_LinedefExecute(tag, mobj, sec2); - } - } + // Sector flag MSF_TRIGGERLINE_MOBJ allows ANY mobj to trigger a linedef exec + P_CheckMobjTrigger(mobj, false); if (mobj->scale != mobj->destscale) P_MobjScaleThink(mobj); // Slowly scale up/down to reach your destscale. @@ -9510,7 +9499,7 @@ void P_MobjThinker(mobj_t *mobj) // Destroy items sector special if (P_CanDeleteKartItem(mobj->type)) { - if (mobj->health > 0 && P_MobjTouchingSectorSpecial(mobj, 4, 7, true)) + if (mobj->health > 0 && P_MobjTouchingSectorSpecialFlag(mobj, SSF_DELETEITEMS)) { if (mobj->type == MT_SSMINE || mobj->type == MT_BUBBLESHIELDTRAP @@ -9544,10 +9533,12 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->flags2 & MF2_DEBRIS) K_MineExplodeThink(mobj); - if (mobj->flags & MF_AMBIENT) + if (mobj->type == MT_AMBIENT) { - if (!(leveltime % mobj->health) && mobj->info->seesound) - S_StartSound(mobj, mobj->info->seesound); + if (leveltime % mobj->health) + return; + if (mobj->threshold) + S_StartSound(mobj, mobj->threshold); return; } @@ -9705,28 +9696,10 @@ boolean P_RailThinker(mobj_t *mobj) // Unquick, unoptimized function for pushables void P_PushableThinker(mobj_t *mobj) { - sector_t *sec; - I_Assert(mobj != NULL); I_Assert(!P_MobjWasRemoved(mobj)); - sec = mobj->subsector->sector; - - if (GETSECSPECIAL(sec->special, 2) == 1 && mobj->z == sec->floorheight) - { - mtag_t tag = Tag_FGet(&sec->tags); - P_LinedefExecute(tag, mobj, sec); - } - -// else if (GETSECSPECIAL(sec->special, 2) == 8) - { - sector_t *sec2 = P_ThingOnSpecial3DFloor(mobj); - if (sec2 && GETSECSPECIAL(sec2->special, 2) == 1) - { - mtag_t tag = Tag_FGet(&sec2->tags); - P_LinedefExecute(tag, mobj, sec2); - } - } + P_CheckMobjTrigger(mobj, true); // it has to be pushable RIGHT NOW for this part to happen if (mobj->flags & MF_PUSHABLE && !(mobj->momx || mobj->momy)) @@ -10636,9 +10609,9 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype } else { - INT32 special = GETSECSPECIAL(mobj->subsector->sector->special, 1); - boolean sFlag = (mobj->precipflags & PCF_FLIP) ? (mobj->subsector->sector->flags & SF_FLIPSPECIAL_CEILING) : (mobj->subsector->sector->flags & SF_FLIPSPECIAL_FLOOR); - boolean pitFloor = ((special == 6 || special == 7) && sFlag); + INT32 dmg = mobj->subsector->sector->damagetype; + boolean sFlag = (mobj->precipflags & PCF_FLIP) ? (mobj->subsector->sector->flags & MSF_FLIPSPECIAL_CEILING) : (mobj->subsector->sector->flags & MSF_FLIPSPECIAL_FLOOR); + boolean pitFloor = ((dmg == SD_DEATHPIT) && sFlag); boolean skyFloor = (mobj->precipflags & PCF_FLIP) ? (mobj->subsector->sector->ceilingpic == skyflatnum) : (mobj->subsector->sector->floorpic == skyflatnum); if (pitFloor || skyFloor) @@ -10917,7 +10890,7 @@ static void P_SpawnPrecipitationAt(fixed_t basex, fixed_t basey) condition = (precipsector->sector->ceilingpic == skyflatnum); } - if (precipsector->sector->flags & SF_INVERTPRECIP) + if (precipsector->sector->flags & MSF_INVERTPRECIP) { condition = !condition; } @@ -11508,9 +11481,9 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) if (p->respawn.state != RESPAWNST_NONE || p->spectator) offset += K_RespawnOffset(p, (mthing->options & MTF_OBJECTFLIP)); - // Flagging a player's ambush will make them start on the ceiling + // Setting the spawnpoint's args[0] will make the player start on the ceiling // Objectflip inverts - if (!!(mthing->options & MTF_AMBUSH) ^ !!(mthing->options & MTF_OBJECTFLIP)) + if (!!(mthing->args[0]) ^ !!(mthing->options & MTF_OBJECTFLIP)) z = ceilingspawn - offset; else z = floor + offset; @@ -11521,7 +11494,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) mobj->flags2 |= MF2_OBJECTFLIP; } - if (mthing->options & MTF_AMBUSH) + if (mthing->args[0]) P_SetPlayerMobjState(mobj, S_KART_SPINOUT); } else @@ -11645,19 +11618,19 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt // Objects with a non-zero default height. // (None yet) - // Horizontal springs, may float additional units with MTF_AMBUSH. + // Horizontal springs, float additional units unless args[0] is set. case MT_YELLOWHORIZ: case MT_REDHORIZ: case MT_BLUEHORIZ: - offset += mthing->options & MTF_AMBUSH ? 16*FRACUNIT : 0; + offset += mthing->args[0] ? 0 : 16*FRACUNIT; break; - // Ring-like items, may float additional units with MTF_AMBUSH. + // Ring-like items, float additional units unless args[0] is set. case MT_SPIKEBALL: case MT_EMBLEM: case MT_RING: case MT_BLUESPHERE: - offset += mthing->options & MTF_AMBUSH ? 24*FRACUNIT : 0; + offset += mthing->args[0] ? 0 : 24*FRACUNIT; break; // This object does not have an offset @@ -11719,14 +11692,15 @@ static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing) return true; } else if (metalrecording && mthing->type == mobjinfo[MT_METALSONIC_RACE].doomednum) - { // If recording, you ARE Metal Sonic. Do not spawn it, do not save normal spawnpoints. + { + // If recording, you ARE Metal Sonic. Do not spawn it, do not save normal spawnpoints. playerstarts[0] = mthing; return true; } else if (mthing->type == 750 // Slope vertex point (formerly chaos spawn) || (mthing->type == 777 || mthing->type == 778) // Slope anchors - || (mthing->type >= 600 && mthing->type <= 609) // Special placement patterns - || mthing->type == 1705 || mthing->type == 1713) // Hoops + || (mthing->type >= 600 && mthing->type <= 611) // Special placement patterns + || mthing->type == 1713) // Hoops { return true; // These are handled elsewhere. } @@ -11806,7 +11780,7 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj) while (emblem) { - if (emblem->type == ET_GLOBAL && emblem->tag == mthing->angle) + if (emblem->type == ET_GLOBAL && emblem->tag == Tag_FGet(&mthing->tags)) break; emblem = M_GetLevelEmblems(-1); @@ -11814,7 +11788,7 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj) if (!emblem) { - CONS_Debug(DBG_GAMELOGIC, "No map emblem for map %d with tag %d found!\n", gamemap, mthing->angle); + CONS_Debug(DBG_GAMELOGIC, "No map emblem for map %d with tag %d found!\n", gamemap, Tag_FGet(&mthing->tags)); return false; } @@ -11858,59 +11832,20 @@ static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) mobjflag_t mflagsapply; mobjflag2_t mflags2apply; mobjeflag_t meflagsapply; - INT32 line; const size_t mthingi = (size_t)(mthing - mapthings); - // Find the corresponding linedef special, using angle as tag - line = Tag_FindLineSpecial(9, mthing->angle); - - if (line == -1) - { - CONS_Debug(DBG_GAMELOGIC, "Mace chain (mapthing #%s) needs to be tagged to a #9 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle); - return false; - } - /* - mapthing - - MTF_AMBUSH : - MT_SPRINGBALLPOINT - upgrade from yellow to red spring - anything else - bigger mace/chain theory - MTF_OBJECTSPECIAL - force silent - MTF_GRAVFLIP - flips objects, doesn't affect chain arrangements - Parameter value : number of "spokes" - - linedef - - ML_NOCLIMB : - MT_CHAINPOINT/MT_CHAINMACEPOINT with ML_EFFECT1 applied - Direction not controllable - anything else - no functionality - ML_EFFECT1 : Swings instead of spins - ML_EFFECT2 : Linktype is replaced with macetype for all spokes not ending in chains (inverted for MT_FIREBARPOINT) - ML_EFFECT3 : Spawn a bonus linktype at the hinge point - ML_EFFECT4 : Don't clip inside the ground - ML_EFFECT5 : Don't stop thinking when too far away - */ - mlength = abs(lines[line].dx >> FRACBITS); - mspeed = abs(lines[line].dy >> (FRACBITS - 4)); - mphase = (sides[lines[line].sidenum[0]].textureoffset >> FRACBITS) % 360; - if ((mminlength = -sides[lines[line].sidenum[0]].rowoffset >> FRACBITS) < 0) - mminlength = 0; - else if (mminlength > mlength - 1) - mminlength = mlength - 1; - mpitch = (lines[line].frontsector->floorheight >> FRACBITS) % 360; - myaw = (lines[line].frontsector->ceilingheight >> FRACBITS) % 360; - - mnumspokes = mthing->extrainfo + 1; + mlength = abs(mthing->args[0]); + mnumspokes = mthing->args[1] + 1; mspokeangle = FixedAngle((360*FRACUNIT)/mnumspokes) >> ANGLETOFINESHIFT; - - if (lines[line].backsector) - { - mpinch = (lines[line].backsector->floorheight >> FRACBITS) % 360; - mroll = (lines[line].backsector->ceilingheight >> FRACBITS) % 360; - mnumnospokes = (sides[lines[line].sidenum[1]].textureoffset >> FRACBITS); - if ((mwidth = sides[lines[line].sidenum[1]].rowoffset >> FRACBITS) < 0) - mwidth = 0; - } - else - mpinch = mroll = mnumnospokes = mwidth = 0; + mwidth = max(0, mthing->args[2]); + mspeed = abs(mthing->args[3] << 4); + mphase = mthing->args[4] % 360; + mpinch = mthing->args[5] % 360; + mnumnospokes = mthing->args[6]; + mminlength = max(0, min(mlength - 1, mthing->args[7])); + mpitch = mthing->pitch % 360; + myaw = mthing->angle % 360; + mroll = mthing->roll % 360; CONS_Debug(DBG_GAMELOGIC, "Mace/Chain (mapthing #%s):\n" "Length is %d (minus %d)\n" @@ -11941,26 +11876,23 @@ static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) switch (mobj->type) { case MT_SPRINGBALLPOINT: - macetype = ((mthing->options & MTF_AMBUSH) + macetype = ((mthing->args[8] & TMM_DOUBLESIZE) ? MT_REDSPRINGBALL : MT_YELLOWSPRINGBALL); chainlink = MT_SMALLMACECHAIN; break; case MT_FIREBARPOINT: - macetype = ((mthing->options & MTF_AMBUSH) + macetype = ((mthing->args[8] & TMM_DOUBLESIZE) ? MT_BIGFIREBAR : MT_SMALLFIREBAR); chainlink = MT_NULL; break; case MT_CUSTOMMACEPOINT: - macetype = (mobjtype_t)sides[lines[line].sidenum[0]].toptexture; - if (lines[line].backsector) - chainlink = (mobjtype_t)sides[lines[line].sidenum[1]].toptexture; - else - chainlink = MT_NULL; + macetype = mthing->stringargs[0] ? get_number(mthing->stringargs[0]) : MT_NULL; + chainlink = mthing->stringargs[1] ? get_number(mthing->stringargs[1]) : MT_NULL; break; case MT_CHAINPOINT: - if (mthing->options & MTF_AMBUSH) + if (mthing->args[8] & TMM_DOUBLESIZE) { macetype = MT_BIGGRABCHAIN; chainlink = MT_BIGMACECHAIN; @@ -11973,7 +11905,7 @@ static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) mchainlike = true; break; default: - if (mthing->options & MTF_AMBUSH) + if (mthing->args[8] & TMM_DOUBLESIZE) { macetype = MT_BIGMACE; chainlink = MT_BIGMACECHAIN; @@ -12000,11 +11932,11 @@ static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) firsttype = macetype; // Adjustable direction - if (lines[line].flags & ML_NOCLIMB) + if (mthing->args[8] & TMM_ALLOWYAWCONTROL) mobj->flags |= MF_SLIDEME; // Swinging - if (lines[line].flags & ML_EFFECT1) + if (mthing->args[8] & TMM_SWING) { mobj->flags2 |= MF2_STRONGBOX; mmin = ((mnumnospokes > 1) ? 1 : 0); @@ -12013,11 +11945,11 @@ static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) mmin = mnumspokes; // If over distance away, don't move UNLESS this flag is applied - if (lines[line].flags & ML_EFFECT5) + if (mthing->args[8] & TMM_ALWAYSTHINK) mobj->flags2 |= MF2_BOSSNOTRAP; // Make the links the same type as the end - repeated below - if ((mobj->type != MT_CHAINPOINT) && (((lines[line].flags & ML_EFFECT2) == ML_EFFECT2) != (mobj->type == MT_FIREBARPOINT))) // exclusive or + if ((mobj->type != MT_CHAINPOINT) && (((mthing->args[8] & TMM_MACELINKS) == TMM_MACELINKS) != (mobj->type == MT_FIREBARPOINT))) // exclusive or { linktype = macetype; radiusfactor = 2; // Double the radius. @@ -12029,7 +11961,7 @@ static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) mchainlike = (firsttype == chainlink); widthfactor = (mchainlike ? 1 : 2); - mflagsapply = ((lines[line].flags & ML_EFFECT4) ? 0 : (MF_NOCLIP | MF_NOCLIPHEIGHT)); + mflagsapply = (mthing->args[8] & TMM_CLIP) ? 0 : (MF_NOCLIP|MF_NOCLIPHEIGHT); mflags2apply = ((mthing->options & MTF_OBJECTFLIP) ? MF2_OBJECTFLIP : 0); meflagsapply = ((mthing->options & MTF_OBJECTFLIP) ? MFE_VERTICALFLIP : 0); @@ -12055,14 +11987,14 @@ static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) hprev = spawnee;\ } - mdosound = (mspeed && !(mthing->options & MTF_OBJECTSPECIAL)); - mdocenter = (macetype && (lines[line].flags & ML_EFFECT3)); + mdosound = (mspeed && !(mthing->args[8] & TMM_SILENT)); + mdocenter = (macetype && (mthing->args[8] & TMM_CENTERLINK)); // The actual spawning of spokes while (mnumspokes-- > 0) { // Offsets - if (lines[line].flags & ML_EFFECT1) // Swinging + if (mthing->args[8] & TMM_SWING) // Swinging mroll = (mroll - mspokeangle) & FINEMASK; else // Spinning mphase = (mphase - mspokeangle) & FINEMASK; @@ -12073,7 +12005,7 @@ static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) continue; linktype = chainlink; - firsttype = ((mthing->options & MTF_AMBUSH) ? MT_BIGGRABCHAIN : MT_SMALLGRABCHAIN); + firsttype = ((mthing->args[8] & TMM_DOUBLESIZE) ? MT_BIGGRABCHAIN : MT_SMALLGRABCHAIN); mmaxlength = 1 + (mlength - 1) * radiusfactor; radiusfactor = widthfactor = 1; } @@ -12082,7 +12014,7 @@ static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) if (mobj->type == MT_CHAINMACEPOINT) { // Make the links the same type as the end - repeated above - if (lines[line].flags & ML_EFFECT2) + if (mthing->args[8] & TMM_MACELINKS) { linktype = macetype; radiusfactor = 2; @@ -12165,50 +12097,43 @@ static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) static boolean P_SetupParticleGen(mapthing_t *mthing, mobj_t *mobj) { - fixed_t radius, speed; + fixed_t radius, speed, zdist; INT32 type, numdivisions, anglespeed, ticcount; angle_t angledivision; INT32 line; const size_t mthingi = (size_t)(mthing - mapthings); - // Find the corresponding linedef special, using angle as tag - line = Tag_FindLineSpecial(15, mthing->angle); + // Find the corresponding linedef special, using args[6] as tag + line = mthing->args[6] ? Tag_FindLineSpecial(15, mthing->args[6]) : -1; - if (line == -1) - { - CONS_Debug(DBG_GAMELOGIC, "Particle generator (mapthing #%s) needs to be tagged to a #15 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle); - return false; - } + type = mthing->stringargs[0] ? get_number(mthing->stringargs[0]) : MT_PARTICLE; - if (sides[lines[line].sidenum[0]].toptexture) - type = sides[lines[line].sidenum[0]].toptexture; // Set as object type in p_setup.c... - else - type = (INT32)MT_PARTICLE; - - if (!lines[line].backsector - || (ticcount = (sides[lines[line].sidenum[1]].textureoffset >> FRACBITS)) < 1) + ticcount = mthing->args[4]; + if (ticcount < 1) ticcount = 3; - numdivisions = mthing->z; + numdivisions = mthing->args[0]; if (numdivisions) { - radius = R_PointToDist2(lines[line].v1->x, lines[line].v1->y, lines[line].v2->x, lines[line].v2->y); - anglespeed = (sides[lines[line].sidenum[0]].rowoffset >> FRACBITS) % 360; + radius = mthing->args[1] << FRACBITS; + anglespeed = (mthing->args[3]) % 360; angledivision = 360/numdivisions; } else { - numdivisions = 1; // Simple trick to make A_ParticleSpawn simpler. + numdivisions = 1; // Simple trick to make P_ParticleGenSceneryThink simpler. radius = 0; anglespeed = 0; angledivision = 0; } - speed = abs(sides[lines[line].sidenum[0]].textureoffset); + speed = abs(mthing->args[2]) << FRACBITS; if (mthing->options & MTF_OBJECTFLIP) speed *= -1; + zdist = abs(mthing->args[5]) << FRACBITS; + CONS_Debug(DBG_GAMELOGIC, "Particle Generator (mapthing #%s):\n" "Radius is %d\n" "Speed is %d\n" @@ -12216,9 +12141,14 @@ static boolean P_SetupParticleGen(mapthing_t *mthing, mobj_t *mobj) "Numdivisions is %d\n" "Angledivision is %d\n" "Type is %d\n" - "Tic seperation is %d\n", + "Tic separation is %d\n", sizeu1(mthingi), radius, speed, anglespeed, numdivisions, angledivision, type, ticcount); + if (line == -1) + CONS_Debug(DBG_GAMELOGIC, "Spawn Z is %d\nZ dist is %d\n", mobj->z, zdist); + else + CONS_Debug(DBG_GAMELOGIC, "Heights are taken from control sector\n"); + mobj->angle = 0; mobj->movefactor = speed; mobj->lastlook = numdivisions; @@ -12227,6 +12157,7 @@ static boolean P_SetupParticleGen(mapthing_t *mthing, mobj_t *mobj) mobj->friction = radius; mobj->threshold = type; mobj->reactiontime = ticcount; + mobj->extravalue1 = zdist; mobj->cvmem = line; mobj->watertop = mobj->waterbottom = 0; return true; @@ -12285,6 +12216,37 @@ static void P_SnapToFinishLine(mobj_t *mobj) } } +static mobj_t *P_MakeSoftwareCorona(mobj_t *mo, INT32 height) +{ + mobj_t *corona = P_SpawnMobjFromMobj(mo, 0, 0, height<sprite = SPR_FLAM; + corona->frame = (FF_FULLBRIGHT|FF_TRANS90|12); + corona->tics = -1; + return corona; +} + +static boolean P_MapAlreadyHasStarPost(mobj_t *mobj) +{ + thinker_t *th; + mobj_t *mo2; + + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo2 = (mobj_t *)th; + + if (mo2 == mobj) + continue; + + if (mo2->type == MT_STARPOST && mo2->health == mobj->health) + return true; + } + + return false; +} + static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) { boolean override = LUA_HookMapThingSpawn(mobj, mthing); @@ -12312,21 +12274,21 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean break; } - if (mthing->options & MTF_OBJECTSPECIAL) + if (mthing->args[0]) skyboxcenterpnts[tag] = mobj; else skyboxviewpnts[tag] = mobj; break; } case MT_EGGSTATUE: - if (mthing->options & MTF_EXTRA) + if (mthing->args[1]) { mobj->color = SKINCOLOR_GOLD; mobj->colorized = true; } break; case MT_FAN: - if (mthing->options & MTF_OBJECTSPECIAL) + if (mthing->args[1] & TMF_INVISIBLE) { P_UnsetThingPosition(mobj); if (sector_list) @@ -12337,39 +12299,36 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean mobj->flags |= MF_NOSECTOR; // this flag basically turns it invisible P_SetThingPosition(mobj); } - if (mthing->angle) - mobj->health = mthing->angle; + if (mthing->args[1] & TMF_NODISTANCECHECK) + mobj->flags2 |= MF2_AMBUSH; + if (mthing->args[0]) + mobj->health = mthing->args[0]; else mobj->health = FixedMul(mobj->subsector->sector->ceilingheight - mobj->subsector->sector->floorheight, 3*(FRACUNIT/4)) >> FRACBITS; break; case MT_BALLOON: - if (mthing->angle > 0) - mobj->color = ((mthing->angle - 1) % (numskincolors - 1)) + 1; + if (mthing->stringargs[0]) + mobj->color = get_number(mthing->stringargs[0]); + if (mthing->args[0]) + mobj->flags2 |= MF2_AMBUSH; break; -#define makesoftwarecorona(mo, h) \ - corona = P_SpawnMobjFromMobj(mo, 0, 0, h<sprite = SPR_FLAM;\ - corona->frame = (FF_FULLBRIGHT|FF_TRANS90|12);\ - corona->tics = -1 case MT_FLAME: - if (mthing->options & MTF_EXTRA) + if (mthing->args[0]) { - mobj_t *corona; - makesoftwarecorona(mobj, 20); + mobj_t *corona = P_MakeSoftwareCorona(mobj, 20); P_SetScale(corona, (corona->destscale = mobj->scale*3)); P_SetTarget(&mobj->tracer, corona); } break; case MT_FLAMEHOLDER: - if (!(mthing->options & MTF_OBJECTSPECIAL)) // Spawn the fire + if (!(mthing->args[0] & TMFH_NOFLAME)) // Spawn the fire { mobj_t *flame = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_FLAME); P_SetTarget(&flame->target, mobj); flame->flags2 |= MF2_BOSSNOTRAP; - if (mthing->options & MTF_EXTRA) + if (mthing->args[0] & TMFH_CORONA) { - mobj_t *corona; - makesoftwarecorona(flame, 20); + mobj_t *corona = P_MakeSoftwareCorona(flame, 20); P_SetScale(corona, (corona->destscale = flame->scale*3)); P_SetTarget(&flame->tracer, corona); } @@ -12377,17 +12336,13 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean break; case MT_CANDLE: case MT_CANDLEPRICKET: - if (mthing->options & MTF_EXTRA) - { - mobj_t *corona; - makesoftwarecorona(mobj, ((mobj->type == MT_CANDLE) ? 42 : 176)); - } + if (mthing->args[0]) + P_MakeSoftwareCorona(mobj, ((mobj->type == MT_CANDLE) ? 42 : 176)); break; -#undef makesoftwarecorona case MT_JACKO1: case MT_JACKO2: case MT_JACKO3: - if (!(mthing->options & MTF_EXTRA)) // take the torch out of the crafting recipe + if (!(mthing->args[0])) // take the torch out of the crafting recipe { mobj_t *overlay = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_OVERLAY); P_SetTarget(&overlay->target, mobj); @@ -12395,17 +12350,15 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean } break; case MT_WATERDRIP: - mobj->tics = 3*TICRATE + mthing->angle; + mobj->tics = 3*TICRATE + mthing->args[0]; break; case MT_FLAMEJET: case MT_VERTICALFLAMEJET: - mobj->threshold = (mthing->angle >> 10) & 7; - mobj->movecount = (mthing->angle >> 13); - - mobj->threshold *= (TICRATE/2); - mobj->movecount *= (TICRATE/2); - - mobj->movedir = mthing->extrainfo; + mobj->movecount = mthing->args[0]; + mobj->threshold = mthing->args[1]; + mobj->movedir = mthing->args[2]; + if (mthing->args[3]) + mobj->flags2 |= MF2_AMBUSH; break; case MT_MACEPOINT: case MT_CHAINMACEPOINT: @@ -12426,8 +12379,8 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean break; case MT_TUBEWAYPOINT: { - UINT8 sequence = mthing->angle >> 8; - UINT8 id = mthing->angle & 255; + UINT8 sequence = mthing->args[0]; + UINT8 id = mthing->args[1]; mobj->health = id; mobj->threshold = sequence; P_AddTubeWaypoint(sequence, id, mobj); @@ -12436,7 +12389,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean case MT_DSZSTALAGMITE: case MT_DSZ2STALAGMITE: case MT_KELP: - if (mthing->options & MTF_OBJECTSPECIAL) { // make mobj twice as big as normal + if (mthing->args[0]) { // make mobj twice as big as normal P_SetScale(mobj, 2*mobj->scale); // not 2*FRACUNIT in case of something like the old ERZ3 mode mobj->destscale = mobj->scale; } @@ -12476,8 +12429,8 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean } break; case MT_SMASHINGSPIKEBALL: - if (mthing->angle > 0) - mobj->tics += mthing->angle; + if (mthing->args[0] > 0) + mobj->tics += mthing->args[0]; break; case MT_BIGFERN: { @@ -12500,72 +12453,38 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean return false; break; case MT_AXIS: - // Inverted if uppermost bit is set - if (mthing->angle & 16384) + // Inverted if args[3] is set + if (mthing->args[3]) mobj->flags2 |= MF2_AMBUSH; - if (mthing->angle > 0) - mobj->radius = (mthing->angle & 16383) << FRACBITS; + mobj->radius = abs(mthing->args[2]) << FRACBITS; // FALLTHRU case MT_AXISTRANSFER: case MT_AXISTRANSFERLINE: // Mare it belongs to - mobj->threshold = min(mthing->extrainfo, 7); + mobj->threshold = min(mthing->args[0], 7); // # in the mare - mobj->health = mthing->options; + mobj->health = mthing->args[1]; mobj->flags2 |= MF2_AXIS; break; case MT_STARPOST: - { - thinker_t* th; - mobj_t* mo2; - boolean foundanother = false; - - if (mthing->extrainfo) - // Allow thing Parameter to define star post num too! - // For starposts above param 15 (the 16th), add 360 to the angle like before and start parameter from 1 (NOT 0)! - // So the 16th starpost is angle=0 param=15, the 17th would be angle=360 param=1. - // This seems more intuitive for mappers to use until UDMF is ready, since most SP maps won't have over 16 consecutive star posts. - mobj->health = mthing->extrainfo + (mthing->angle/360)*15 + 1; - else - // Old behavior if Parameter is 0; add 360 to the angle for each consecutive star post. - mobj->health = (mthing->angle/360) + 1; - - // See if other starposts exist in this level that have the same value. - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t*)th; - - if (mo2 == mobj) - continue; - - if (mo2->type == MT_STARPOST && mo2->health == mobj->health) - { - foundanother = true; - break; - } - } - - if (!foundanother) + mobj->health = mthing->args[0] + 1; + if (!P_MapAlreadyHasStarPost(mobj)) numstarposts++; break; - } case MT_SPIKE: // Pop up spikes! - if (mthing->options & MTF_OBJECTSPECIAL) + if (mthing->args[0]) { mobj->flags &= ~MF_SCENERY; - mobj->fuse = (16 - mthing->extrainfo)*(mthing->angle + mobj->info->speed)/16; - if (mthing->options & MTF_EXTRA) - P_SetMobjState(mobj, mobj->info->meleestate); + mobj->fuse = mthing->args[1]; } - // Use per-thing collision for spikes if the deaf flag isn't checked. - if (!(mthing->options & MTF_AMBUSH) && !metalrecording) + if (mthing->args[2] & TMSF_RETRACTED) + P_SetMobjState(mobj, mobj->info->meleestate); + // Use per-thing collision for spikes unless the intangible flag is checked. + if (!(mthing->args[2] & TMSF_INTANGIBLE) && !metalrecording) { P_UnsetThingPosition(mobj); mobj->flags &= ~(MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT); @@ -12575,22 +12494,21 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean break; case MT_WALLSPIKE: // Pop up spikes! - if (mthing->options & MTF_OBJECTSPECIAL) + if (mthing->args[0]) { mobj->flags &= ~MF_SCENERY; - mobj->fuse = (16 - mthing->extrainfo)*((mthing->angle/360) + mobj->info->speed)/16; - if (mthing->options & MTF_EXTRA) - P_SetMobjState(mobj, mobj->info->meleestate); + mobj->fuse = mthing->args[1]; } - // Use per-thing collision for spikes if the deaf flag isn't checked. - if (!(mthing->options & MTF_AMBUSH) && !metalrecording) + if (mthing->args[2] & TMSF_RETRACTED) + P_SetMobjState(mobj, mobj->info->meleestate); + // Use per-thing collision for spikes unless the intangible flag is checked. + if (!(mthing->args[2] & TMSF_INTANGIBLE) && !metalrecording) { P_UnsetThingPosition(mobj); mobj->flags &= ~(MF_NOBLOCKMAP | MF_NOCLIPHEIGHT); mobj->flags |= MF_SOLID; P_SetThingPosition(mobj); } - // spawn base { const angle_t mobjangle = FixedAngle(mthing->angle << FRACBITS); // the mobj's own angle hasn't been set quite yet so... @@ -12608,12 +12526,13 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean break; case MT_BIGTUMBLEWEED: case MT_LITTLETUMBLEWEED: - if (mthing->options & MTF_AMBUSH) + if (mthing->args[0]) { fixed_t offset = FixedMul(16*FRACUNIT, mobj->scale); mobj->momx += P_RandomChance(PR_DECORATION, FRACUNIT/2) ? offset : -offset; mobj->momy += P_RandomChance(PR_DECORATION, FRACUNIT/2) ? offset : -offset; mobj->momz += offset; + mobj->flags2 |= MF2_AMBUSH; } break; case MT_REDFLAG: @@ -12967,63 +12886,13 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean if (mobj->flags & MF_BOSS) { - if (mthing->options & MTF_OBJECTSPECIAL) // No egg trap for this boss + if (mthing->args[1]) // No egg trap for this boss mobj->flags2 |= MF2_BOSSNOTRAP; } return true; } -static void P_SetAmbush(mobj_t *mobj) -{ - if (mobj->flags & MF_SPRING) - { - // gravity toggle - mobj->flags ^= MF_NOGRAVITY; - } - - if (mobj->flags & MF_PUSHABLE) - { - mobj->flags &= ~MF_PUSHABLE; - } - - if ((mobj->flags & MF_MONITOR) && mobj->info->speed != 0) - { - // flag for strong/weak random boxes - // any monitor with nonzero speed is allowed to respawn like this - mobj->flags2 |= MF2_AMBUSH; - } - - else if (mobj->type != MT_AXIS && - mobj->type != MT_AXISTRANSFER && - mobj->type != MT_AXISTRANSFERLINE && - mobj->type != MT_NIGHTSBUMPER && - mobj->type != MT_STARPOST) - mobj->flags2 |= MF2_AMBUSH; - - if (mobj->type == MT_DUELBOMB) - { - Obj_DuelBombReverse(mobj); - } -} - -static void P_SetObjectSpecial(mobj_t *mobj) -{ - if ((mobj->flags & MF_MONITOR) && mobj->info->speed != 0) - { - // flag for strong/weak random boxes - // any monitor with nonzero speed is allowed to respawn like this - mobj->flags2 |= MF2_STRONGBOX; - } - - // Pushables bounce and slide coolly with object special flag set - if (mobj->flags & MF_PUSHABLE) - { - mobj->flags2 |= MF2_SLIDEPUSH; - mobj->flags &= ~MF_SLIDEME; - } -} - static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, fixed_t z, mobjtype_t i) { fixed_t relativise = FixedDiv(mthing->scale, mapobjectscale); @@ -13060,23 +12929,6 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, mthing->mobj = mobj; - // ignore MTF_ flags and return early - if (i == MT_NIGHTSBUMPER) - return mobj; - - if ((mthing->options & MTF_AMBUSH) - && (mthing->options & MTF_OBJECTSPECIAL) - && (mobj->flags & MF_PUSHABLE)) - mobj->flags2 |= MF2_CLASSICPUSH; - else - { - if (mthing->options & MTF_AMBUSH) - P_SetAmbush(mobj); - - if (mthing->options & MTF_OBJECTSPECIAL) - P_SetObjectSpecial(mobj); - } - // Generic reverse gravity for individual objects flag. if (mthing->options & MTF_OBJECTFLIP) { @@ -13084,16 +12936,6 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, mobj->flags2 |= MF2_OBJECTFLIP; } - // Extra functionality - if (mthing->options & MTF_EXTRA) - { - if (mobj->flags & MF_MONITOR && (mthing->angle & 16384)) - { - // Store line exec tag to run upon popping - mobj->lastlook = (mthing->angle & 16383); - } - } - return mobj; } @@ -13138,13 +12980,18 @@ mobj_t *P_SpawnMapThing(mapthing_t *mthing) return P_SpawnMobjFromMapThing(mthing, x, y, z, i); } -static void P_SpawnHoopInternal(mapthing_t *mthing, INT32 hoopsize, fixed_t sizefactor) +void P_SpawnHoop(mapthing_t *mthing) { + if (metalrecording) + return; + mobj_t *mobj = NULL; mobj_t *nextmobj = NULL; mobj_t *hoopcenter; TMatrix *pitchmatrix, *yawmatrix; - fixed_t radius = hoopsize*sizefactor; + fixed_t radius = mthing->args[0] << FRACBITS; + fixed_t sizefactor = 4*FRACUNIT; + fixed_t hoopsize = radius/sizefactor; INT32 i; angle_t fa; TVector v, *res; @@ -13161,10 +13008,9 @@ static void P_SpawnHoopInternal(mapthing_t *mthing, INT32 hoopsize, fixed_t size hoopcenter->y = y; P_SetThingPosition(hoopcenter); - // Scale 0-255 to 0-359 =( - hoopcenter->movedir = ((mthing->angle & 255)*360)/256; // Pitch + hoopcenter->movedir = mthing->pitch; pitchmatrix = RotateXMatrix(FixedAngle(hoopcenter->movedir << FRACBITS)); - hoopcenter->movecount = (((UINT16)mthing->angle >> 8)*360)/256; // Yaw + hoopcenter->movecount = mthing->angle; yawmatrix = RotateZMatrix(FixedAngle(hoopcenter->movecount << FRACBITS)); // For the hoop when it flies away @@ -13241,20 +13087,7 @@ static void P_SpawnHoopInternal(mapthing_t *mthing, INT32 hoopsize, fixed_t size } while (hoopsize >= 8); } -void P_SpawnHoop(mapthing_t *mthing) -{ - if (metalrecording) - return; - - if (mthing->type == 1705) // Generic hoop - P_SpawnHoopInternal(mthing, 24, 4*FRACUNIT); - else // Customizable hoop - // For each flag add 16 fracunits to the size - // Default (0 flags) is 32 fracunits - P_SpawnHoopInternal(mthing, 8 + (4*(mthing->options & 0xF)), 4*FRACUNIT); -} - -static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t* itemtypes, UINT8 numitemtypes, INT32 numitems, fixed_t horizontalspacing, fixed_t verticalspacing, INT16 fixedangle) +static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 numitemtypes, INT32 numitems, fixed_t horizontalspacing, fixed_t verticalspacing, INT16 fixedangle) { mapthing_t dummything; mobj_t *mobj = NULL; @@ -13303,7 +13136,7 @@ static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t* itemtypes, UINT8 numi } } -static void P_SpawnSingularItemRow(mapthing_t* mthing, mobjtype_t itemtype, INT32 numitems, fixed_t horizontalspacing, fixed_t verticalspacing, INT16 fixedangle) +static void P_SpawnSingularItemRow(mapthing_t *mthing, mobjtype_t itemtype, INT32 numitems, fixed_t horizontalspacing, fixed_t verticalspacing, INT16 fixedangle) { mobjtype_t itemtypes[1] = { itemtype }; P_SpawnItemRow(mthing, itemtypes, 1, numitems, horizontalspacing, verticalspacing, fixedangle); @@ -13365,6 +13198,35 @@ static void P_SpawnItemCircle(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 n } } +static void P_ParseItemTypes(char *itemstring, mobjtype_t *itemtypes, UINT8 *numitemtypes) +{ + char *tok; + + *numitemtypes = 0; + if (itemstring) + { + char *stringcopy = Z_Malloc(strlen(itemstring) + 1, PU_LEVEL, NULL); + M_Memcpy(stringcopy, itemstring, strlen(itemstring)); + stringcopy[strlen(itemstring)] = '\0'; + + tok = strtok(stringcopy, " "); + while (tok && *numitemtypes < 128) + { + itemtypes[*numitemtypes] = get_number(tok); + tok = strtok(NULL, " "); + (*numitemtypes)++; + } + + Z_Free(stringcopy); + } + else + { + //If no types are supplied, default to ring + itemtypes[0] = MT_RING; + *numitemtypes = 1; + } +} + void P_SpawnItemPattern(mapthing_t *mthing) { switch (mthing->type) @@ -13391,6 +13253,27 @@ void P_SpawnItemPattern(mapthing_t *mthing) P_SpawnItemCircle(mthing, itemtypes, 1, numitems, size); return; } + case 610: // Generic item row + { + mobjtype_t itemtypes[128]; //If you want to have a row with more than 128 different object types, you're crazy. + UINT8 numitemtypes; + if (!udmf) + return; + P_ParseItemTypes(mthing->stringargs[0], itemtypes, &numitemtypes); + P_SpawnItemRow(mthing, itemtypes, numitemtypes, mthing->args[0], mthing->args[1] << FRACBITS, mthing->args[2] << FRACBITS, mthing->angle); + return; + } + case 611: // Generic item circle + { + mobjtype_t itemtypes[128]; //If you want to have a circle with more than 128 different object types, you're crazy. + UINT8 numitemtypes; + if (!udmf) + return; + CONS_Printf("Itemstring: %s\n", mthing->stringargs[0]); + P_ParseItemTypes(mthing->stringargs[0], itemtypes, &numitemtypes); + P_SpawnItemCircle(mthing, itemtypes, numitemtypes, mthing->args[0], mthing->args[1] << FRACBITS); + return; + } default: return; } diff --git a/src/p_mobj.h b/src/p_mobj.h index 19cd1c77a..923fc7f80 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -118,7 +118,7 @@ typedef enum // Don't apply gravity (every tic); object will float, keeping current height // or changing it actively. MF_NOGRAVITY = 1<<9, - // This object is an ambient sound. + // This object is an ambient sound. Obsolete, but keep this around for backwards compatibility. MF_AMBIENT = 1<<10, // Slide this object when it hits a wall. MF_SLIDEME = 1<<11, diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 590ca66b1..cd946e5ee 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -786,7 +786,7 @@ static void Polyobj_pushThing(polyobj_t *po, line_t *line, mobj_t *mo) vertex_t closest; // calculate angle of line and subtract 90 degrees to get normal - lineangle = R_PointToAngle2(0, 0, line->dx, line->dy) - ANGLE_90; + lineangle = line->angle - ANGLE_90; lineangle >>= ANGLETOFINESHIFT; momx = FixedMul(po->thrust, FINECOSINE(lineangle)); momy = FixedMul(po->thrust, FINESINE(lineangle)); @@ -961,7 +961,7 @@ static INT32 Polyobj_clipThings(polyobj_t *po, line_t *line) else Polyobj_pushThing(po, line, mo); - if (mo->player && (po->lines[0]->backsector->flags & SF_TRIGGERSPECIAL_TOUCH) && !(po->flags & POF_NOSPECIALS)) + if (mo->player && (po->lines[0]->backsector->flags & MSF_TRIGGERSPECIAL_TOUCH) && !(po->flags & POF_NOSPECIALS)) P_ProcessSpecialSector(mo->player, mo->subsector->sector, po->lines[0]->backsector); hitflags |= 1; @@ -1058,6 +1058,8 @@ static void Polyobj_rotateLine(line_t *ld) ld->dx = v2->x - v1->x; ld->dy = v2->y - v1->y; + ld->angle = R_PointToAngle2(0, 0, ld->dx, ld->dy); + // determine slopetype ld->slopetype = !ld->dx ? ST_VERTICAL : !ld->dy ? ST_HORIZONTAL : ((ld->dy > 0) == (ld->dx > 0)) ? ST_POSITIVE : ST_NEGATIVE; @@ -1087,7 +1089,7 @@ static void Polyobj_rotateLine(line_t *ld) } // Causes objects resting on top of the rotating polyobject to 'ride' with its movement. -static void Polyobj_rotateThings(polyobj_t *po, vector2_t origin, angle_t delta, UINT8 turnthings) +static void Polyobj_rotateThings(polyobj_t *po, vector2_t origin, angle_t delta, boolean turnplayers, boolean turnothers) { static INT32 pomovecount = 10000; INT32 x, y; @@ -1153,7 +1155,7 @@ static void Polyobj_rotateThings(polyobj_t *po, vector2_t origin, angle_t delta, Polyobj_slideThing(mo, newxoff, newyoff); - if (turnthings == 2 || (turnthings == 1 && !mo->player)) { + if ((turnplayers && mo->player) || (turnothers && !mo->player)) { mo->angle += delta; if (mo->player) P_SetPlayerAngle(mo->player, mo->player->angleturn + delta); @@ -1165,7 +1167,7 @@ static void Polyobj_rotateThings(polyobj_t *po, vector2_t origin, angle_t delta, } // Rotates a polyobject around its start point. -boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings, boolean checkmobjs) +boolean Polyobj_rotate(polyobj_t *po, angle_t delta, boolean turnplayers, boolean turnothers, boolean checkmobjs) { size_t i; angle_t angle; @@ -1203,7 +1205,7 @@ boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings, boolean c for (i = 0; i < po->numLines; ++i) hitflags |= Polyobj_clipThings(po, po->lines[i]); - Polyobj_rotateThings(po, origin, delta, turnthings); + Polyobj_rotateThings(po, origin, delta, turnplayers, turnothers); } if (hitflags & 2) @@ -1414,7 +1416,7 @@ void Polyobj_MoveOnLoad(polyobj_t *po, angle_t angle, fixed_t x, fixed_t y) fixed_t dx, dy; // first, rotate to the saved angle - Polyobj_rotate(po, angle, false, false); + Polyobj_rotate(po, angle, false, false, false); // determine component distances to translate dx = x - po->spawnSpot.x; @@ -1457,7 +1459,7 @@ void T_PolyObjRotate(polyrotate_t *th) // rotate by 'speed' angle per frame // if distance == -1, this polyobject rotates perpetually - if (Polyobj_rotate(po, th->speed, th->turnobjs, true) && th->distance != -1) + if (Polyobj_rotate(po, th->speed, th->turnobjs & PTF_PLAYERS, th->turnobjs & PTF_OTHERS, true) && th->distance != -1) { INT32 avel = abs(th->speed); @@ -1859,7 +1861,7 @@ void T_PolyDoorSwing(polyswingdoor_t *th) // rotate by 'speed' angle per frame // if distance == -1, this polyobject rotates perpetually - if (Polyobj_rotate(po, th->speed, false, true) && th->distance != -1) + if (Polyobj_rotate(po, th->speed, false, false, true) && th->distance != -1) { INT32 avel = abs(th->speed); @@ -1990,7 +1992,7 @@ void T_PolyObjRotDisplace(polyrotdisplace_t *th) rotangle = FixedMul(th->rotscale, delta); - if (Polyobj_rotate(po, FixedAngle(rotangle), th->turnobjs, true)) + if (Polyobj_rotate(po, FixedAngle(rotangle), th->turnobjs & PTF_PLAYERS, th->turnobjs & PTF_OTHERS, true)) th->oldHeights = newheights; } @@ -2019,7 +2021,7 @@ boolean EV_DoPolyObjRotate(polyrotdata_t *prdata) return false; // check for override if this polyobj already has a thinker - if (po->thinker && !prdata->overRide) + if (po->thinker && !(prdata->flags & TMPR_OVERRIDE)) return false; // create a new thinker @@ -2034,10 +2036,10 @@ boolean EV_DoPolyObjRotate(polyrotdata_t *prdata) // use Hexen-style byte angles for speed and distance th->speed = Polyobj_AngSpeed(prdata->speed * prdata->direction); - if (prdata->distance == 360) // 360 means perpetual + if (prdata->flags & TMPR_CONTINUOUS) th->distance = -1; - else if (prdata->distance == 0) // 0 means 360 degrees - th->distance = 0xffffffff - 1; + else if (prdata->distance == 360) + th->distance = ANGLE_MAX - 1; else th->distance = FixedAngle(prdata->distance*FRACUNIT); @@ -2052,11 +2054,15 @@ boolean EV_DoPolyObjRotate(polyrotdata_t *prdata) oldpo = po; + th->turnobjs = 0; + if (!(prdata->flags & TMPR_DONTROTATEOTHERS)) + th->turnobjs |= PTF_OTHERS; + if (prdata->flags & TMPR_ROTATEPLAYERS) + th->turnobjs |= PTF_PLAYERS; + // interpolation R_CreateInterpolator_Polyobj(&th->thinker, po); - th->turnobjs = prdata->turnobjs; - // apply action to mirroring polyobjects as well start = 0; while ((po = Polyobj_GetChild(oldpo, &start))) diff --git a/src/p_polyobj.h b/src/p_polyobj.h index 8c2946965..91333a107 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -137,7 +137,7 @@ typedef struct polyrotate_s INT32 polyObjNum; // numeric id of polyobject (avoid C pointers here) INT32 speed; // speed of movement per frame INT32 distance; // distance to move - UINT8 turnobjs; // turn objects? 0=no, 1=everything but players, 2=everything + UINT8 turnobjs; // turn objects? PTF_ flags } polyrotate_t; typedef struct polymove_s @@ -247,14 +247,27 @@ typedef struct polyfade_s // Line Activation Data Structures // +typedef enum +{ + TMPR_DONTROTATEOTHERS = 1, + TMPR_ROTATEPLAYERS = 1<<1, + TMPR_CONTINUOUS = 1<<2, + TMPR_OVERRIDE = 1<<3, +} textmappolyrotate_t; + +typedef enum +{ + PTF_PLAYERS = 1, // Turn players with movement + PTF_OTHERS = 1<<1, // Turn other mobjs with movement +} polyturnflags_e; + typedef struct polyrotdata_s { INT32 polyObjNum; // numeric id of polyobject to affect INT32 direction; // direction of rotation INT32 speed; // angular speed INT32 distance; // distance to move - UINT8 turnobjs; // rotate objects being carried? - UINT8 overRide; // if true, will override any action on the object + UINT8 flags; // TMPR_ flags } polyrotdata_t; typedef struct polymovedata_s @@ -281,6 +294,20 @@ typedef struct polywaypointdata_s UINT8 flags; // PWF_ flags } polywaypointdata_t; +typedef enum +{ + TMPV_NOCHANGE = 1, + TMPV_VISIBLE = 1<<1, + TMPV_INVISIBLE = 1<<2, +} textmappolyvisibility_t; + +typedef enum +{ + TMPT_NOCHANGE = 1, + TMPT_TANGIBLE = 1<<1, + TMPT_INTANGIBLE = 1<<2, +} textmappolytangibility_t; + // polyobject door types typedef enum { @@ -322,6 +349,15 @@ typedef struct polyflagdata_s fixed_t momx; } polyflagdata_t; +typedef enum +{ + TMPF_RELATIVE = 1, + TMPF_OVERRIDE = 1<<1, + TMPF_TICBASED = 1<<2, + TMPF_IGNORECOLLISION = 1<<3, + TMPF_GHOSTFADE = 1<<4, +} textmappolyfade_t; + typedef struct polyfadedata_s { INT32 polyObjNum; @@ -337,7 +373,7 @@ typedef struct polyfadedata_s // boolean Polyobj_moveXY(polyobj_t *po, fixed_t x, fixed_t y, boolean checkmobjs); -boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings, boolean checkmobjs); +boolean Polyobj_rotate(polyobj_t *po, angle_t delta, boolean turnplayers, boolean turnothers, boolean checkmobjs); polyobj_t *Polyobj_GetForNum(INT32 id); void Polyobj_InitLevel(void); void Polyobj_MoveOnLoad(polyobj_t *po, angle_t angle, fixed_t x, fixed_t y); diff --git a/src/p_saveg.c b/src/p_saveg.c index 62f11e7ef..559deb186 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -999,6 +999,17 @@ static void P_NetUnArchiveTubeWaypoints(void) #define SD_TAGLIST 0x01 #define SD_COLORMAP 0x02 #define SD_CRUMBLESTATE 0x04 +#define SD_FLOORLIGHT 0x08 +#define SD_CEILLIGHT 0x10 +#define SD_FLAG 0x20 +#define SD_SPECIALFLAG 0x40 +#define SD_DIFF4 0x80 + +//diff4 flags +#define SD_DAMAGETYPE 0x01 +#define SD_TRIGGERTAG 0x02 +#define SD_TRIGGERER 0x04 +#define SD_GRAVITY 0x08 #define LD_FLAG 0x01 #define LD_SPECIAL 0x02 @@ -1137,11 +1148,11 @@ static void ArchiveSectors(void) size_t i, j; const sector_t *ss = sectors; const sector_t *spawnss = spawnsectors; - UINT8 diff, diff2, diff3; + UINT8 diff, diff2, diff3, diff4; for (i = 0; i < numsectors; i++, ss++, spawnss++) { - diff = diff2 = diff3 = 0; + diff = diff2 = diff3 = diff4 = 0; if (ss->floorheight != spawnss->floorheight) diff |= SD_FLOORHT; if (ss->ceilingheight != spawnss->ceilingheight) @@ -1180,9 +1191,29 @@ static void ArchiveSectors(void) if (ss->crumblestate) diff3 |= SD_CRUMBLESTATE; + if (ss->floorlightlevel != spawnss->floorlightlevel || ss->floorlightabsolute != spawnss->floorlightabsolute) + diff3 |= SD_FLOORLIGHT; + if (ss->ceilinglightlevel != spawnss->ceilinglightlevel || ss->ceilinglightabsolute != spawnss->ceilinglightabsolute) + diff3 |= SD_CEILLIGHT; + if (ss->flags != spawnss->flags) + diff3 |= SD_FLAG; + if (ss->specialflags != spawnss->specialflags) + diff3 |= SD_SPECIALFLAG; + if (ss->damagetype != spawnss->damagetype) + diff4 |= SD_DAMAGETYPE; + if (ss->triggertag != spawnss->triggertag) + diff4 |= SD_TRIGGERTAG; + if (ss->triggerer != spawnss->triggerer) + diff4 |= SD_TRIGGERER; + if (ss->gravity != spawnss->gravity) + diff4 |= SD_GRAVITY; + if (ss->ffloors && CheckFFloorDiff(ss)) diff |= SD_FFLOORS; + if (diff4) + diff3 |= SD_DIFF4; + if (diff3) diff2 |= SD_DIFF3; @@ -1197,6 +1228,8 @@ static void ArchiveSectors(void) WRITEUINT8(save_p, diff2); if (diff2 & SD_DIFF3) WRITEUINT8(save_p, diff3); + if (diff3 & SD_DIFF4) + WRITEUINT8(save_p, diff4); if (diff & SD_FLOORHT) WRITEFIXED(save_p, ss->floorheight); if (diff & SD_CEILHT) @@ -1233,6 +1266,28 @@ static void ArchiveSectors(void) // returns existing index if already added, or appends to net_colormaps and returns new index if (diff3 & SD_CRUMBLESTATE) WRITEINT32(save_p, ss->crumblestate); + if (diff3 & SD_FLOORLIGHT) + { + WRITEINT16(save_p, ss->floorlightlevel); + WRITEUINT8(save_p, ss->floorlightabsolute); + } + if (diff3 & SD_CEILLIGHT) + { + WRITEINT16(save_p, ss->ceilinglightlevel); + WRITEUINT8(save_p, ss->ceilinglightabsolute); + } + if (diff3 & SD_FLAG) + WRITEUINT32(save_p, ss->flags); + if (diff3 & SD_SPECIALFLAG) + WRITEUINT32(save_p, ss->specialflags); + if (diff4 & SD_DAMAGETYPE) + WRITEUINT8(save_p, ss->damagetype); + if (diff4 & SD_TRIGGERTAG) + WRITEINT16(save_p, ss->triggertag); + if (diff4 & SD_TRIGGERER) + WRITEUINT8(save_p, ss->triggerer); + if (diff4 & SD_GRAVITY) + WRITEFIXED(save_p, ss->gravity); if (diff & SD_FFLOORS) ArchiveFFloors(ss); } @@ -1244,7 +1299,7 @@ static void ArchiveSectors(void) static void UnArchiveSectors(void) { UINT16 i, j; - UINT8 diff, diff2, diff3; + UINT8 diff, diff2, diff3, diff4; for (;;) { i = READUINT16(save_p); @@ -1264,6 +1319,10 @@ static void UnArchiveSectors(void) diff3 = READUINT8(save_p); else diff3 = 0; + if (diff3 & SD_DIFF4) + diff4 = READUINT8(save_p); + else + diff4 = 0; if (diff & SD_FLOORHT) sectors[i].floorheight = READFIXED(save_p); @@ -1324,6 +1383,31 @@ static void UnArchiveSectors(void) sectors[i].extra_colormap = GetNetColormapFromList(READUINT32(save_p)); if (diff3 & SD_CRUMBLESTATE) sectors[i].crumblestate = READINT32(save_p); + if (diff3 & SD_FLOORLIGHT) + { + sectors[i].floorlightlevel = READINT16(save_p); + sectors[i].floorlightabsolute = READUINT8(save_p); + } + if (diff3 & SD_CEILLIGHT) + { + sectors[i].ceilinglightlevel = READINT16(save_p); + sectors[i].ceilinglightabsolute = READUINT8(save_p); + } + if (diff3 & SD_FLAG) + { + sectors[i].flags = READUINT32(save_p); + CheckForReverseGravity |= (sectors[i].flags & MSF_GRAVITYFLIP); + } + if (diff3 & SD_SPECIALFLAG) + sectors[i].specialflags = READUINT32(save_p); + if (diff4 & SD_DAMAGETYPE) + sectors[i].damagetype = READUINT8(save_p); + if (diff4 & SD_TRIGGERTAG) + sectors[i].triggertag = READINT16(save_p); + if (diff4 & SD_TRIGGERER) + sectors[i].triggerer = READUINT8(save_p); + if (diff4 & SD_GRAVITY) + sectors[i].gravity = READFIXED(save_p); if (diff & SD_FFLOORS) UnArchiveFFloors(§ors[i]); @@ -2195,7 +2279,6 @@ static void SaveEachTimeThinker(const thinker_t *th, const UINT8 type) for (i = 0; i < MAXPLAYERS; i++) { WRITECHAR(save_p, ht->playersInArea[i]); - WRITECHAR(save_p, ht->playersOnArea[i]); } WRITECHAR(save_p, ht->triggerOnExit); } @@ -2223,14 +2306,12 @@ static void SaveCeilingThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, ht->bottomheight); WRITEFIXED(save_p, ht->topheight); WRITEFIXED(save_p, ht->speed); - WRITEFIXED(save_p, ht->oldspeed); WRITEFIXED(save_p, ht->delay); WRITEFIXED(save_p, ht->delaytimer); WRITEUINT8(save_p, ht->crush); WRITEINT32(save_p, ht->texture); WRITEINT32(save_p, ht->direction); - WRITEINT32(save_p, ht->tag); - WRITEINT32(save_p, ht->olddirection); + WRITEINT16(save_p, ht->tag); WRITEFIXED(save_p, ht->origspeed); WRITEFIXED(save_p, ht->sourceline); } @@ -2249,6 +2330,8 @@ static void SaveFloormoveThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, ht->origspeed); WRITEFIXED(save_p, ht->delay); WRITEFIXED(save_p, ht->delaytimer); + WRITEINT16(save_p, ht->tag); + WRITEFIXED(save_p, ht->sourceline); } static void SaveLightflashThinker(const thinker_t *th, const UINT8 type) @@ -2266,8 +2349,8 @@ static void SaveStrobeThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, type); WRITEUINT32(save_p, SaveSector(ht->sector)); WRITEINT32(save_p, ht->count); - WRITEINT32(save_p, ht->minlight); - WRITEINT32(save_p, ht->maxlight); + WRITEINT16(save_p, ht->minlight); + WRITEINT16(save_p, ht->maxlight); WRITEINT32(save_p, ht->darktime); WRITEINT32(save_p, ht->brighttime); } @@ -2277,10 +2360,10 @@ static void SaveGlowThinker(const thinker_t *th, const UINT8 type) const glow_t *ht = (const void *)th; WRITEUINT8(save_p, type); WRITEUINT32(save_p, SaveSector(ht->sector)); - WRITEINT32(save_p, ht->minlight); - WRITEINT32(save_p, ht->maxlight); - WRITEINT32(save_p, ht->direction); - WRITEINT32(save_p, ht->speed); + WRITEINT16(save_p, ht->minlight); + WRITEINT16(save_p, ht->maxlight); + WRITEINT16(save_p, ht->direction); + WRITEINT16(save_p, ht->speed); } static inline void SaveFireflickerThinker(const thinker_t *th, const UINT8 type) @@ -2290,8 +2373,8 @@ static inline void SaveFireflickerThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, SaveSector(ht->sector)); WRITEINT32(save_p, ht->count); WRITEINT32(save_p, ht->resetcount); - WRITEINT32(save_p, ht->maxlight); - WRITEINT32(save_p, ht->minlight); + WRITEINT16(save_p, ht->maxlight); + WRITEINT16(save_p, ht->minlight); } static void SaveElevatorThinker(const thinker_t *th, const UINT8 type) @@ -2365,13 +2448,9 @@ static inline void SavePusherThinker(const thinker_t *th, const UINT8 type) const pusher_t *ht = (const void *)th; WRITEUINT8(save_p, type); WRITEUINT8(save_p, ht->type); - WRITEINT32(save_p, ht->x_mag); - WRITEINT32(save_p, ht->y_mag); - WRITEINT32(save_p, ht->magnitude); - WRITEINT32(save_p, ht->radius); - WRITEINT32(save_p, ht->x); - WRITEINT32(save_p, ht->y); - WRITEINT32(save_p, ht->z); + WRITEFIXED(save_p, ht->x_mag); + WRITEFIXED(save_p, ht->y_mag); + WRITEFIXED(save_p, ht->z_mag); WRITEINT32(save_p, ht->affectee); WRITEUINT8(save_p, ht->roverpusher); WRITEINT32(save_p, ht->referrer); @@ -2469,18 +2548,30 @@ static void SavePlaneDisplaceThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, ht->type); } -static inline void SaveDynamicSlopeThinker(const thinker_t *th, const UINT8 type) +static inline void SaveDynamicLineSlopeThinker(const thinker_t *th, const UINT8 type) { - const dynplanethink_t* ht = (const void*)th; + const dynlineplanethink_t* ht = (const void*)th; WRITEUINT8(save_p, type); WRITEUINT8(save_p, ht->type); WRITEUINT32(save_p, SaveSlope(ht->slope)); WRITEUINT32(save_p, SaveLine(ht->sourceline)); WRITEFIXED(save_p, ht->extent); +} - WRITEMEM(save_p, ht->tags, sizeof(ht->tags)); +static inline void SaveDynamicVertexSlopeThinker(const thinker_t *th, const UINT8 type) +{ + size_t i; + const dynvertexplanethink_t* ht = (const void*)th; + + WRITEUINT8(save_p, type); + WRITEUINT32(save_p, SaveSlope(ht->slope)); + for (i = 0; i < 3; i++) + WRITEUINT32(save_p, SaveSector(ht->secs[i])); WRITEMEM(save_p, ht->vex, sizeof(ht->vex)); + WRITEMEM(save_p, ht->origsecheights, sizeof(ht->origsecheights)); + WRITEMEM(save_p, ht->origvecheights, sizeof(ht->origvecheights)); + WRITEUINT8(save_p, ht->relative); } static inline void SavePolyrotatetThinker(const thinker_t *th, const UINT8 type) @@ -2805,12 +2896,12 @@ static void P_NetArchiveThinkers(void) } else if (th->function.acp1 == (actionf_p1)T_DynamicSlopeLine) { - SaveDynamicSlopeThinker(th, tc_dynslopeline); + SaveDynamicLineSlopeThinker(th, tc_dynslopeline); continue; } else if (th->function.acp1 == (actionf_p1)T_DynamicSlopeVert) { - SaveDynamicSlopeThinker(th, tc_dynslopevert); + SaveDynamicVertexSlopeThinker(th, tc_dynslopevert); continue; } #ifdef PARANOIA @@ -2968,7 +3059,7 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) { UINT16 spawnpointnum = READUINT16(save_p); - if (mapthings[spawnpointnum].type == 1705 || mapthings[spawnpointnum].type == 1713) // NiGHTS Hoop special case + if (mapthings[spawnpointnum].type == 1713) // NiGHTS Hoop special case { P_SpawnHoop(&mapthings[spawnpointnum]); return NULL; @@ -3379,7 +3470,6 @@ static thinker_t* LoadEachTimeThinker(actionf_p1 thinker) for (i = 0; i < MAXPLAYERS; i++) { ht->playersInArea[i] = READCHAR(save_p); - ht->playersOnArea[i] = READCHAR(save_p); } ht->triggerOnExit = READCHAR(save_p); return &ht->thinker; @@ -3409,14 +3499,12 @@ static thinker_t* LoadCeilingThinker(actionf_p1 thinker) ht->bottomheight = READFIXED(save_p); ht->topheight = READFIXED(save_p); ht->speed = READFIXED(save_p); - ht->oldspeed = READFIXED(save_p); ht->delay = READFIXED(save_p); ht->delaytimer = READFIXED(save_p); ht->crush = READUINT8(save_p); ht->texture = READINT32(save_p); ht->direction = READINT32(save_p); - ht->tag = READINT32(save_p); - ht->olddirection = READINT32(save_p); + ht->tag = READINT16(save_p); ht->origspeed = READFIXED(save_p); ht->sourceline = READFIXED(save_p); if (ht->sector) @@ -3438,6 +3526,8 @@ static thinker_t* LoadFloormoveThinker(actionf_p1 thinker) ht->origspeed = READFIXED(save_p); ht->delay = READFIXED(save_p); ht->delaytimer = READFIXED(save_p); + ht->tag = READINT16(save_p); + ht->sourceline = READFIXED(save_p); if (ht->sector) ht->sector->floordata = ht; return &ht->thinker; @@ -3461,8 +3551,8 @@ static thinker_t* LoadStrobeThinker(actionf_p1 thinker) ht->thinker.function.acp1 = thinker; ht->sector = LoadSector(READUINT32(save_p)); ht->count = READINT32(save_p); - ht->minlight = READINT32(save_p); - ht->maxlight = READINT32(save_p); + ht->minlight = READINT16(save_p); + ht->maxlight = READINT16(save_p); ht->darktime = READINT32(save_p); ht->brighttime = READINT32(save_p); if (ht->sector) @@ -3475,10 +3565,10 @@ static thinker_t* LoadGlowThinker(actionf_p1 thinker) glow_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; ht->sector = LoadSector(READUINT32(save_p)); - ht->minlight = READINT32(save_p); - ht->maxlight = READINT32(save_p); - ht->direction = READINT32(save_p); - ht->speed = READINT32(save_p); + ht->minlight = READINT16(save_p); + ht->maxlight = READINT16(save_p); + ht->direction = READINT16(save_p); + ht->speed = READINT16(save_p); if (ht->sector) ht->sector->lightingdata = ht; return &ht->thinker; @@ -3491,8 +3581,8 @@ static thinker_t* LoadFireflickerThinker(actionf_p1 thinker) ht->sector = LoadSector(READUINT32(save_p)); ht->count = READINT32(save_p); ht->resetcount = READINT32(save_p); - ht->maxlight = READINT32(save_p); - ht->minlight = READINT32(save_p); + ht->maxlight = READINT16(save_p); + ht->minlight = READINT16(save_p); if (ht->sector) ht->sector->lightingdata = ht; return &ht->thinker; @@ -3584,19 +3674,14 @@ static thinker_t* LoadPusherThinker(actionf_p1 thinker) pusher_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; ht->type = READUINT8(save_p); - ht->x_mag = READINT32(save_p); - ht->y_mag = READINT32(save_p); - ht->magnitude = READINT32(save_p); - ht->radius = READINT32(save_p); - ht->x = READINT32(save_p); - ht->y = READINT32(save_p); - ht->z = READINT32(save_p); + ht->x_mag = READFIXED(save_p); + ht->y_mag = READFIXED(save_p); + ht->z_mag = READFIXED(save_p); ht->affectee = READINT32(save_p); ht->roverpusher = READUINT8(save_p); ht->referrer = READINT32(save_p); ht->exclusive = READINT32(save_p); ht->slider = READINT32(save_p); - ht->source = P_GetPushThing(ht->affectee); return &ht->thinker; } @@ -3720,17 +3805,31 @@ static inline thinker_t* LoadPlaneDisplaceThinker(actionf_p1 thinker) return &ht->thinker; } -static inline thinker_t* LoadDynamicSlopeThinker(actionf_p1 thinker) +static inline thinker_t* LoadDynamicLineSlopeThinker(actionf_p1 thinker) { - dynplanethink_t* ht = Z_Malloc(sizeof(*ht), PU_LEVSPEC, NULL); + dynlineplanethink_t* ht = Z_Malloc(sizeof(*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; ht->type = READUINT8(save_p); ht->slope = LoadSlope(READUINT32(save_p)); ht->sourceline = LoadLine(READUINT32(save_p)); ht->extent = READFIXED(save_p); - READMEM(save_p, ht->tags, sizeof(ht->tags)); + return &ht->thinker; +} + +static inline thinker_t* LoadDynamicVertexSlopeThinker(actionf_p1 thinker) +{ + size_t i; + dynvertexplanethink_t* ht = Z_Malloc(sizeof(*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + + ht->slope = LoadSlope(READUINT32(save_p)); + for (i = 0; i < 3; i++) + ht->secs[i] = LoadSector(READUINT32(save_p)); READMEM(save_p, ht->vex, sizeof(ht->vex)); + READMEM(save_p, ht->origsecheights, sizeof(ht->origsecheights)); + READMEM(save_p, ht->origvecheights, sizeof(ht->origvecheights)); + ht->relative = READUINT8(save_p); return &ht->thinker; } @@ -4043,11 +4142,11 @@ static void P_NetUnArchiveThinkers(void) break; case tc_dynslopeline: - th = LoadDynamicSlopeThinker((actionf_p1)T_DynamicSlopeLine); + th = LoadDynamicLineSlopeThinker((actionf_p1)T_DynamicSlopeLine); break; case tc_dynslopevert: - th = LoadDynamicSlopeThinker((actionf_p1)T_DynamicSlopeVert); + th = LoadDynamicVertexSlopeThinker((actionf_p1)T_DynamicSlopeVert); break; case tc_scroll: diff --git a/src/p_setup.c b/src/p_setup.c index bd5fa62a8..585e83641 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -652,7 +652,7 @@ void P_ReloadRings(void) mt->mobj = NULL; P_SpawnMapThing(mt); } - else if (mt->type >= 600 && mt->type <= 609) // Item patterns + else if (mt->type >= 600 && mt->type <= 611) // Item patterns { mt->mobj = NULL; P_SpawnItemPattern(mt); @@ -700,9 +700,9 @@ static void P_SpawnMapThings(boolean spawnemblems) mt->mobj = NULL; - if (mt->type >= 600 && mt->type <= 609) // item patterns + if (mt->type >= 600 && mt->type <= 611) // item patterns P_SpawnItemPattern(mt); - else if (mt->type == 1705 || mt->type == 1713) // hoops + else if (mt->type == 1713) // hoops P_SpawnHoop(mt); else // Everything else P_SpawnMapThing(mt); @@ -710,6 +710,7 @@ static void P_SpawnMapThings(boolean spawnemblems) } // Experimental groovy write function! +/* void P_WriteThings(void) { const char * filename; @@ -749,6 +750,7 @@ void P_WriteThings(void) CONS_Printf(M_GetText("%s saved.\n"), filename); } +*/ // // MAP LOADING FUNCTIONS @@ -805,9 +807,7 @@ static void P_InitializeSector(sector_t *ss) ss->extra_colormap = NULL; - ss->gravity = NULL; - ss->verticalflip = false; - ss->flags = SF_FLIPSPECIAL_FLOOR; + ss->gravityptr = NULL; ss->cullheight = NULL; @@ -849,8 +849,21 @@ static void P_LoadSectors(UINT8 *data) ss->floorpic_angle = ss->ceilingpic_angle = 0; + ss->floorlightlevel = ss->ceilinglightlevel = 0; + ss->floorlightabsolute = ss->ceilinglightabsolute = false; + ss->colormap_protected = false; + ss->gravity = FRACUNIT; + + ss->flags = MSF_FLIPSPECIAL_FLOOR; + ss->specialflags = 0; + ss->damagetype = SD_NONE; + ss->triggertag = 0; + ss->triggerer = TO_PLAYER; + + ss->friction = ORIG_FRICTION; + P_InitializeSector(ss); } } @@ -864,6 +877,8 @@ static void P_InitializeLinedef(line_t *ld) ld->dx = v2->x - v1->x; ld->dy = v2->y - v1->y; + ld->angle = R_PointToAngle2(0, 0, ld->dx, ld->dy); + ld->bbox[BOXLEFT] = min(v1->x, v2->x); ld->bbox[BOXRIGHT] = max(v1->x, v2->x); ld->bbox[BOXBOTTOM] = min(v1->y, v2->y); @@ -1009,7 +1024,7 @@ static void P_LoadSidedefs(UINT8 *data) isfrontside = sd->line->sidenum[0] == i; // Repeat count for midtexture - if (((sd->line->flags & (ML_TWOSIDED|ML_EFFECT5)) == (ML_TWOSIDED|ML_EFFECT5)) + if (((sd->line->flags & (ML_TWOSIDED|ML_WRAPMIDTEX)) == (ML_TWOSIDED|ML_WRAPMIDTEX)) && !(sd->special >= 300 && sd->special < 500)) // exempt linedef exec specials { sd->repeatcnt = (INT16)(((UINT16)textureoffset) >> 12); @@ -1032,11 +1047,8 @@ static void P_LoadSidedefs(UINT8 *data) case 455: // Fade colormaps! mazmazz 9/12/2018 (:flag_us:) // SoM: R_CreateColormap will only create a colormap in software mode... // Perhaps we should just call it instead of doing the calculations here. - if (!udmf) - { - sd->colormap_data = R_CreateColormapFromLinedef(msd->toptexture, msd->midtexture, msd->bottomtexture); - sd->toptexture = sd->midtexture = sd->bottomtexture = 0; - } + sd->colormap_data = R_CreateColormapFromLinedef(msd->toptexture, msd->midtexture, msd->bottomtexture); + sd->toptexture = sd->midtexture = sd->bottomtexture = 0; break; case 413: // Change music @@ -1078,7 +1090,6 @@ static void P_LoadSidedefs(UINT8 *data) } case 4: // Speed pad parameters - case 414: // Play SFX { sd->toptexture = sd->midtexture = sd->bottomtexture = 0; if (msd->toptexture[0] != '-' || msd->toptexture[1] != '\0') @@ -1091,34 +1102,23 @@ static void P_LoadSidedefs(UINT8 *data) break; } - case 423: // Change Sky + case 414: // Play SFX { - char process[8*3+1]; - memset(process,0,8*3+1); sd->toptexture = sd->midtexture = sd->bottomtexture = 0; if (msd->toptexture[0] != '-' || msd->toptexture[1] != '\0') - M_Memcpy(process,msd->toptexture,8); - if (msd->midtexture[0] != '-' || msd->midtexture[1] != '\0') - M_Memcpy(process+strlen(process), msd->midtexture, 8); - if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0') - M_Memcpy(process+strlen(process), msd->bottomtexture, 8); - if (!strlen(process)) - break; - sd->text = Z_Malloc(strlen(process)+1, PU_LEVEL, NULL); - M_Memcpy(sd->text, process, strlen(process)+1); + { + char process[8 + 1]; + M_Memcpy(process, msd->toptexture, 8); + process[8] = '\0'; + sd->text = Z_Malloc(strlen(process) + 1, PU_LEVEL, NULL); + M_Memcpy(sd->text, process, strlen(process) + 1); + } break; } case 9: // Mace parameters case 14: // Bustable block parameters case 15: // Fan particle spawner parameters - case 334: // Trigger linedef executor: Object dye - Continuous - case 335: // Trigger linedef executor: Object dye - Each time - case 336: // Trigger linedef executor: Object dye - Once - case 425: // Calls P_SetMobjState on calling mobj - case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors - case 461: // Spawns an object on the map based on texture offsets - case 463: // Colorizes an object { char process[8*3+1]; memset(process,0,8*3+1); @@ -1138,8 +1138,16 @@ static void P_LoadSidedefs(UINT8 *data) case 331: // Trigger linedef executor: Skin - Continuous case 332: // Trigger linedef executor: Skin - Each time case 333: // Trigger linedef executor: Skin - Once + case 334: // Trigger linedef executor: Object dye - Continuous + case 335: // Trigger linedef executor: Object dye - Each time + case 336: // Trigger linedef executor: Object dye - Once + case 425: // Calls P_SetMobjState on calling mobj + case 434: // Custom Power + case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors case 443: // Calls a named Lua function case 459: // Control text prompt (named tag) + case 461: // Spawns an object on the map based on texture offsets + case 463: // Colorizes an object { char process[8*3+1]; memset(process,0,8*3+1); @@ -1232,9 +1240,9 @@ UINT32 vertexesPos[UINT16_MAX]; UINT32 sectorsPos[UINT16_MAX]; // Determine total amount of map data in TEXTMAP. -static boolean TextmapCount(UINT8 *data, size_t size) +static boolean TextmapCount(size_t size) { - char *tkn = M_GetToken((char *)data); + const char *tkn = M_TokenizerRead(0); UINT8 brackets = 0; nummapthings = 0; @@ -1246,20 +1254,16 @@ static boolean TextmapCount(UINT8 *data, size_t size) // Look for namespace at the beginning. if (!fastcmp(tkn, "namespace")) { - Z_Free(tkn); CONS_Alert(CONS_ERROR, "No namespace at beginning of lump!\n"); return false; } - Z_Free(tkn); // Check if namespace is valid. - tkn = M_GetToken(NULL); + tkn = M_TokenizerRead(0); if (!fastcmp(tkn, "srb2")) CONS_Alert(CONS_WARNING, "Invalid namespace '%s', only 'srb2' is supported.\n", tkn); - Z_Free(tkn); - tkn = M_GetToken(NULL); - while (tkn && M_GetTokenPos() < size) + while ((tkn = M_TokenizerRead(0)) && M_TokenizerGetEndPos() < size) { // Avoid anything inside bracketed stuff, only look for external keywords. if (brackets) @@ -1271,24 +1275,19 @@ static boolean TextmapCount(UINT8 *data, size_t size) brackets++; // Check for valid fields. else if (fastcmp(tkn, "thing")) - mapthingsPos[nummapthings++] = M_GetTokenPos(); + mapthingsPos[nummapthings++] = M_TokenizerGetEndPos(); else if (fastcmp(tkn, "linedef")) - linesPos[numlines++] = M_GetTokenPos(); + linesPos[numlines++] = M_TokenizerGetEndPos(); else if (fastcmp(tkn, "sidedef")) - sidesPos[numsides++] = M_GetTokenPos(); + sidesPos[numsides++] = M_TokenizerGetEndPos(); else if (fastcmp(tkn, "vertex")) - vertexesPos[numvertexes++] = M_GetTokenPos(); + vertexesPos[numvertexes++] = M_TokenizerGetEndPos(); else if (fastcmp(tkn, "sector")) - sectorsPos[numsectors++] = M_GetTokenPos(); + sectorsPos[numsectors++] = M_TokenizerGetEndPos(); else CONS_Alert(CONS_NOTICE, "Unknown field '%s'.\n", tkn); - - Z_Free(tkn); - tkn = M_GetToken(NULL); } - Z_Free(tkn); - if (brackets) { CONS_Alert(CONS_ERROR, "Unclosed brackets detected in textmap lump.\n"); @@ -1298,7 +1297,7 @@ static boolean TextmapCount(UINT8 *data, size_t size) return true; } -static void ParseTextmapVertexParameter(UINT32 i, char *param, char *val) +static void ParseTextmapVertexParameter(UINT32 i, const char *param, const char *val) { if (fastcmp(param, "x")) vertexes[i].x = FLOAT_TO_FIXED(atof(val)); @@ -1345,7 +1344,7 @@ typedef struct textmap_plane_s { textmap_plane_t textmap_planefloor = {0, 0, 0, 0, 0}; textmap_plane_t textmap_planeceiling = {0, 0, 0, 0, 0}; -static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val) +static void ParseTextmapSectorParameter(UINT32 i, const char *param, const char *val) { if (fastcmp(param, "heightfloor")) sectors[i].floorheight = atol(val) << FRACBITS; @@ -1357,13 +1356,19 @@ static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val) sectors[i].ceilingpic = P_AddLevelFlat(val, foundflats); else if (fastcmp(param, "lightlevel")) sectors[i].lightlevel = atol(val); - else if (fastcmp(param, "special")) - sectors[i].special = atol(val); + else if (fastcmp(param, "lightfloor")) + sectors[i].floorlightlevel = atol(val); + else if (fastcmp(param, "lightfloorabsolute") && fastcmp("true", val)) + sectors[i].floorlightabsolute = true; + else if (fastcmp(param, "lightceiling")) + sectors[i].ceilinglightlevel = atol(val); + else if (fastcmp(param, "lightceilingabsolute") && fastcmp("true", val)) + sectors[i].ceilinglightabsolute = true; else if (fastcmp(param, "id")) Tag_FSet(§ors[i].tags, atol(val)); else if (fastcmp(param, "moreids")) { - char* id = val; + const char* id = val; while (id) { Tag_Add(§ors[i].tags, atol(id)); @@ -1465,9 +1470,68 @@ static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val) } else if (fastcmp(param, "colormapprotected") && fastcmp("true", val)) sectors[i].colormap_protected = true; + else if (fastcmp(param, "flipspecial_nofloor") && fastcmp("true", val)) + sectors[i].flags &= ~MSF_FLIPSPECIAL_FLOOR; + else if (fastcmp(param, "flipspecial_ceiling") && fastcmp("true", val)) + sectors[i].flags |= MSF_FLIPSPECIAL_CEILING; + else if (fastcmp(param, "triggerspecial_touch") && fastcmp("true", val)) + sectors[i].flags |= MSF_TRIGGERSPECIAL_TOUCH; + else if (fastcmp(param, "triggerspecial_headbump") && fastcmp("true", val)) + sectors[i].flags |= MSF_TRIGGERSPECIAL_HEADBUMP; + else if (fastcmp(param, "triggerline_plane") && fastcmp("true", val)) + sectors[i].flags |= MSF_TRIGGERLINE_PLANE; + else if (fastcmp(param, "triggerline_mobj") && fastcmp("true", val)) + sectors[i].flags |= MSF_TRIGGERLINE_MOBJ; + else if (fastcmp(param, "invertprecip") && fastcmp("true", val)) + sectors[i].flags |= MSF_INVERTPRECIP; + else if (fastcmp(param, "gravityflip") && fastcmp("true", val)) + sectors[i].flags |= MSF_GRAVITYFLIP; + else if (fastcmp(param, "heatwave") && fastcmp("true", val)) + sectors[i].flags |= MSF_HEATWAVE; + else if (fastcmp(param, "noclipcamera") && fastcmp("true", val)) + sectors[i].flags |= MSF_NOCLIPCAMERA; + else if (fastcmp(param, "nostepup") && fastcmp("true", val)) + sectors[i].specialflags |= SSF_NOSTEPUP; + else if (fastcmp(param, "doublestepup") && fastcmp("true", val)) + sectors[i].specialflags |= SSF_DOUBLESTEPUP; + else if (fastcmp(param, "nostepdown") && fastcmp("true", val)) + sectors[i].specialflags |= SSF_NOSTEPDOWN; + else if (fastcmp(param, "speedpad") && fastcmp("true", val)) + sectors[i].specialflags |= SSF_SPEEDPAD; + else if (fastcmp(param, "starpostactivator") && fastcmp("true", val)) + sectors[i].specialflags |= SSF_STARPOSTACTIVATOR; + else if (fastcmp(param, "exit") && fastcmp("true", val)) + sectors[i].specialflags |= SSF_EXIT; + else if (fastcmp(param, "deleteitems") && fastcmp("true", val)) + sectors[i].specialflags |= SSF_DELETEITEMS; + else if (fastcmp(param, "fan") && fastcmp("true", val)) + sectors[i].specialflags |= SSF_FAN; + else if (fastcmp(param, "zoomtubestart") && fastcmp("true", val)) + sectors[i].specialflags |= SSF_ZOOMTUBESTART; + else if (fastcmp(param, "zoomtubeend") && fastcmp("true", val)) + sectors[i].specialflags |= SSF_ZOOMTUBEEND; + else if (fastcmp(param, "friction")) + sectors[i].friction = FLOAT_TO_FIXED(atof(val)); + else if (fastcmp(param, "gravity")) + sectors[i].gravity = FLOAT_TO_FIXED(atof(val)); + else if (fastcmp(param, "damagetype")) + { + if (fastcmp(val, "Generic")) + sectors[i].damagetype = SD_GENERIC; + if (fastcmp(val, "Lava")) + sectors[i].damagetype = SD_LAVA; + if (fastcmp(val, "DeathPit")) + sectors[i].damagetype = SD_DEATHPIT; + if (fastcmp(val, "Instakill")) + sectors[i].damagetype = SD_INSTAKILL; + } + else if (fastcmp(param, "triggertag")) + sectors[i].triggertag = atol(val); + else if (fastcmp(param, "triggerer")) + sectors[i].triggerer = atol(val); } -static void ParseTextmapSidedefParameter(UINT32 i, char *param, char *val) +static void ParseTextmapSidedefParameter(UINT32 i, const char *param, const char *val) { if (fastcmp(param, "offsetx")) sides[i].textureoffset = atol(val)< 9) { - size_t argnum = param[3] - '0'; + size_t argnum = atol(param + 9); if (argnum >= NUMLINESTRINGARGS) return; lines[i].stringargs[argnum] = Z_Malloc(strlen(val) + 1, PU_LEVEL, NULL); @@ -1556,19 +1620,19 @@ static void ParseTextmapLinedefParameter(UINT32 i, char *param, char *val) else if (fastcmp(param, "dontpegbottom") && fastcmp("true", val)) lines[i].flags |= ML_DONTPEGBOTTOM; else if (fastcmp(param, "skewtd") && fastcmp("true", val)) - lines[i].flags |= ML_EFFECT1; + lines[i].flags |= ML_SKEWTD; else if (fastcmp(param, "noclimb") && fastcmp("true", val)) lines[i].flags |= ML_NOCLIMB; else if (fastcmp(param, "noskew") && fastcmp("true", val)) - lines[i].flags |= ML_EFFECT2; + lines[i].flags |= ML_NOSKEW; else if (fastcmp(param, "midpeg") && fastcmp("true", val)) - lines[i].flags |= ML_EFFECT3; + lines[i].flags |= ML_MIDPEG; else if (fastcmp(param, "midsolid") && fastcmp("true", val)) - lines[i].flags |= ML_EFFECT4; + lines[i].flags |= ML_MIDSOLID; else if (fastcmp(param, "wrapmidtex") && fastcmp("true", val)) - lines[i].flags |= ML_EFFECT5; - else if (fastcmp(param, "effect6") && fastcmp("true", val)) - lines[i].flags |= ML_EFFECT6; + lines[i].flags |= ML_WRAPMIDTEX; + /*else if (fastcmp(param, "effect6") && fastcmp("true", val)) + lines[i].flags |= ML_EFFECT6;*/ else if (fastcmp(param, "nonet") && fastcmp("true", val)) lines[i].flags |= ML_NONET; else if (fastcmp(param, "netonly") && fastcmp("true", val)) @@ -1579,13 +1643,13 @@ static void ParseTextmapLinedefParameter(UINT32 i, char *param, char *val) lines[i].flags |= ML_TFERLINE; } -static void ParseTextmapThingParameter(UINT32 i, char *param, char *val) +static void ParseTextmapThingParameter(UINT32 i, const char *param, const char *val) { if (fastcmp(param, "id")) Tag_FSet(&mapthings[i].tags, atol(val)); else if (fastcmp(param, "moreids")) { - char* id = val; + const char* id = val; while (id) { Tag_Add(&mapthings[i].tags, atol(id)); @@ -1610,18 +1674,12 @@ static void ParseTextmapThingParameter(UINT32 i, char *param, char *val) else if (fastcmp(param, "scale") || fastcmp(param, "scalex") || fastcmp(param, "scaley")) mapthings[i].scale = FixedMul(mapobjectscale, FLOAT_TO_FIXED(atof(val))); // Flags - else if (fastcmp(param, "extra") && fastcmp("true", val)) - mapthings[i].options |= MTF_EXTRA; else if (fastcmp(param, "flip") && fastcmp("true", val)) mapthings[i].options |= MTF_OBJECTFLIP; - else if (fastcmp(param, "objectspecial") && fastcmp("true", val)) - mapthings[i].options |= MTF_OBJECTSPECIAL; - else if (fastcmp(param, "ambush") && fastcmp("true", val)) - mapthings[i].options |= MTF_AMBUSH; - else if (strlen(param) == 7 && fastncmp(param, "arg", 3) && fastncmp(param + 4, "str", 3)) + else if (fastncmp(param, "stringarg", 9) && strlen(param) > 9) { - size_t argnum = param[3] - '0'; + size_t argnum = atol(param + 9); if (argnum >= NUMMAPTHINGSTRINGARGS) return; mapthings[i].stringargs[argnum] = Z_Malloc(strlen(val) + 1, PU_LEVEL, NULL); @@ -1642,32 +1700,25 @@ static void ParseTextmapThingParameter(UINT32 i, char *param, char *val) * \param Structure number (mapthings, sectors, ...). * \param Parser function pointer. */ -static void TextmapParse(UINT32 dataPos, size_t num, void (*parser)(UINT32, char *, char *)) +static void TextmapParse(UINT32 dataPos, size_t num, void (*parser)(UINT32, const char *, const char *)) { - char *param, *val; + const char *param, *val; - M_SetTokenPos(dataPos); - param = M_GetToken(NULL); + M_TokenizerSetEndPos(dataPos); + param = M_TokenizerRead(0); if (!fastcmp(param, "{")) { - Z_Free(param); CONS_Alert(CONS_WARNING, "Invalid UDMF data capsule!\n"); return; } - Z_Free(param); while (true) { - param = M_GetToken(NULL); + param = M_TokenizerRead(0); if (fastcmp(param, "}")) - { - Z_Free(param); break; - } - val = M_GetToken(NULL); + val = M_TokenizerRead(1); parser(num, param, val); - Z_Free(param); - Z_Free(val); } } @@ -1696,6 +1747,29 @@ static void TextmapFixFlatOffsets(sector_t *sec) } } +static void TextmapUnfixFlatOffsets(sector_t *sec) +{ + if (sec->floorpic_angle) + { + fixed_t pc = FINECOSINE(sec->floorpic_angle >> ANGLETOFINESHIFT); + fixed_t ps = FINESINE(sec->floorpic_angle >> ANGLETOFINESHIFT); + fixed_t xoffs = sec->floor_xoffs; + fixed_t yoffs = sec->floor_yoffs; + sec->floor_xoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); + sec->floor_yoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); + } + + if (sec->ceilingpic_angle) + { + fixed_t pc = FINECOSINE(sec->ceilingpic_angle >> ANGLETOFINESHIFT); + fixed_t ps = FINESINE(sec->ceilingpic_angle >> ANGLETOFINESHIFT); + fixed_t xoffs = sec->ceiling_xoffs; + fixed_t yoffs = sec->ceiling_yoffs; + sec->ceiling_xoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); + sec->ceiling_yoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); + } +} + static INT32 P_ColorToRGBA(INT32 color, UINT8 alpha) { UINT8 r = (color >> 16) & 0xFF; @@ -1704,6 +1778,619 @@ static INT32 P_ColorToRGBA(INT32 color, UINT8 alpha) return R_PutRgbaRGBA(r, g, b, alpha); } +static INT32 P_RGBAToColor(INT32 rgba) +{ + UINT8 r = R_GetRgbaR(rgba); + UINT8 g = R_GetRgbaG(rgba); + UINT8 b = R_GetRgbaB(rgba); + return (r << 16) | (g << 8) | b; +} + +typedef struct +{ + mapthing_t *teleport; + mapthing_t *altview; + mapthing_t *angleanchor; +} sectorspecialthings_t; + +static void P_WriteTextmap(void) +{ + size_t i, j; + FILE *f; + char *filepath = va(pandf, srb2home, "TEXTMAP"); + mtag_t firsttag; + mapthing_t *wmapthings; + vertex_t *wvertexes; + sector_t *wsectors; + line_t *wlines; + side_t *wsides; + mtag_t freetag; + sectorspecialthings_t *specialthings; + + f = fopen(filepath, "w"); + if (!f) + { + CONS_Alert(CONS_ERROR, M_GetText("Couldn't save map file %s\n"), filepath); + return; + } + + wmapthings = Z_Calloc(nummapthings * sizeof(*mapthings), PU_LEVEL, NULL); + wvertexes = Z_Calloc(numvertexes * sizeof(*vertexes), PU_LEVEL, NULL); + wsectors = Z_Calloc(numsectors * sizeof(*sectors), PU_LEVEL, NULL); + wlines = Z_Calloc(numlines * sizeof(*lines), PU_LEVEL, NULL); + wsides = Z_Calloc(numsides * sizeof(*sides), PU_LEVEL, NULL); + specialthings = Z_Calloc(numsectors * sizeof(*sectors), PU_LEVEL, NULL); + + memcpy(wmapthings, mapthings, nummapthings * sizeof(*mapthings)); + memcpy(wvertexes, vertexes, numvertexes * sizeof(*vertexes)); + memcpy(wsectors, sectors, numsectors * sizeof(*sectors)); + memcpy(wlines, lines, numlines * sizeof(*lines)); + memcpy(wsides, sides, numsides * sizeof(*sides)); + + for (i = 0; i < nummapthings; i++) + if (mapthings[i].tags.count) + wmapthings[i].tags.tags = memcpy(Z_Malloc(mapthings[i].tags.count * sizeof(mtag_t), PU_LEVEL, NULL), mapthings[i].tags.tags, mapthings[i].tags.count * sizeof(mtag_t)); + + for (i = 0; i < numsectors; i++) + if (sectors[i].tags.count) + wsectors[i].tags.tags = memcpy(Z_Malloc(sectors[i].tags.count*sizeof(mtag_t), PU_LEVEL, NULL), sectors[i].tags.tags, sectors[i].tags.count*sizeof(mtag_t)); + + for (i = 0; i < numlines; i++) + if (lines[i].tags.count) + wlines[i].tags.tags = memcpy(Z_Malloc(lines[i].tags.count * sizeof(mtag_t), PU_LEVEL, NULL), lines[i].tags.tags, lines[i].tags.count * sizeof(mtag_t)); + + freetag = Tag_NextUnused(0); + + for (i = 0; i < nummapthings; i++) + { + subsector_t *ss; + INT32 s; + + if (wmapthings[i].type != 751 && wmapthings[i].type != 752 && wmapthings[i].type != 758) + continue; + + ss = R_PointInSubsector(wmapthings[i].x << FRACBITS, wmapthings[i].y << FRACBITS); + + if (!ss) + continue; + + s = ss->sector - sectors; + + switch (wmapthings[i].type) + { + case 751: + if (!specialthings[s].teleport) + specialthings[s].teleport = &wmapthings[i]; + break; + case 752: + if (!specialthings[s].altview) + specialthings[s].altview = &wmapthings[i]; + break; + case 758: + if (!specialthings[s].angleanchor) + specialthings[s].angleanchor = &wmapthings[i]; + break; + default: + break; + } + } + + for (i = 0; i < numlines; i++) + { + INT32 s; + + switch (wlines[i].special) + { + case 1: + TAG_ITER_SECTORS(Tag_FGet(&wlines[i].tags), s) + { + CONS_Alert(CONS_WARNING, M_GetText("Linedef %d applies custom gravity to sector %d. Changes to this gravity at runtime will not be reflected in the converted map. Use linedef type 469 for this.\n"), i, s); + wsectors[s].gravity = FixedDiv(lines[i].frontsector->floorheight >> FRACBITS, 1000); + } + break; + case 2: + CONS_Alert(CONS_WARNING, M_GetText("Custom exit linedef %d detected. Changes to the next map at runtime will not be reflected in the converted map. Use linedef type 468 for this.\n"), i); + wlines[i].args[0] = lines[i].frontsector->floorheight >> FRACBITS; + wlines[i].args[2] = lines[i].frontsector->ceilingheight >> FRACBITS; + break; + case 5: + case 50: + case 51: + CONS_Alert(CONS_WARNING, M_GetText("Linedef %d has type %d, which is not supported in UDMF.\n"), i, wlines[i].special); + break; + case 61: + if (wlines[i].flags & ML_MIDSOLID) + continue; + if (!wlines[i].args[1]) + continue; + CONS_Alert(CONS_WARNING, M_GetText("Linedef %d with crusher type 61 rises twice as fast on spawn. This behavior is not supported in UDMF.\n"), i); + break; + case 76: + if (freetag == (mtag_t)MAXTAGS) + { + CONS_Alert(CONS_WARNING, M_GetText("No unused tag found. Linedef %d with type 76 cannot be converted.\n"), i); + break; + } + TAG_ITER_SECTORS(wlines[i].args[0], s) + for (j = 0; (unsigned)j < wsectors[s].linecount; j++) + { + line_t *line = wsectors[s].lines[j] - lines + wlines; + if (line->special < 100 || line->special >= 300) + continue; + Tag_Add(&line->tags, freetag); + } + wlines[i].args[0] = freetag; + freetag = Tag_NextUnused(freetag); + break; + case 259: + if (wlines[i].args[3] & FF_QUICKSAND) + CONS_Alert(CONS_WARNING, M_GetText("Quicksand properties of custom FOF on linedef %d cannot be converted. Use linedef type 75 instead.\n"), i); + if (wlines[i].args[3] & FF_BUSTUP) + CONS_Alert(CONS_WARNING, M_GetText("Bustable properties of custom FOF on linedef %d cannot be converted. Use linedef type 74 instead.\n"), i); + break; + case 412: + if ((s = Tag_Iterate_Sectors(wlines[i].args[0], 0)) < 0) + break; + if (!specialthings[s].teleport) + break; + if (freetag == (mtag_t)MAXTAGS) + { + CONS_Alert(CONS_WARNING, M_GetText("No unused tag found. Linedef %d with type 412 cannot be converted.\n"), i); + break; + } + Tag_Add(&specialthings[s].teleport->tags, freetag); + wlines[i].args[0] = freetag; + freetag = Tag_NextUnused(freetag); + break; + case 422: + if ((s = Tag_Iterate_Sectors(wlines[i].args[0], 0)) < 0) + break; + if (!specialthings[s].altview) + break; + if (freetag == (mtag_t)MAXTAGS) + { + CONS_Alert(CONS_WARNING, M_GetText("No unused tag found. Linedef %d with type 422 cannot be converted.\n"), i); + break; + } + Tag_Add(&specialthings[s].altview->tags, freetag); + wlines[i].args[0] = freetag; + specialthings[s].altview->pitch = wlines[i].args[2]; + freetag = Tag_NextUnused(freetag); + break; + case 447: + CONS_Alert(CONS_WARNING, M_GetText("Linedef %d has change colormap action, which cannot be converted automatically. Tag arg0 to a sector with the desired colormap.\n"), i); + if (wlines[i].flags & ML_TFERLINE) + CONS_Alert(CONS_WARNING, M_GetText("Linedef %d mixes front and back colormaps, which is not supported in UDMF. Copy one colormap to the target sector first, then mix in the second one.\n"), i); + break; + case 455: + CONS_Alert(CONS_WARNING, M_GetText("Linedef %d has fade colormap action, which cannot be converted automatically. Tag arg0 to a sector with the desired colormap.\n"), i); + if (wlines[i].flags & ML_TFERLINE) + CONS_Alert(CONS_WARNING, M_GetText("Linedef %d specifies starting colormap for the fade, which is not supported in UDMF. Change the colormap with linedef type 447 instead.\n"), i); + break; + case 457: + if ((s = Tag_Iterate_Sectors(wlines[i].args[0], 0)) < 0) + break; + if (!specialthings[s].angleanchor) + break; + if (freetag == (mtag_t)MAXTAGS) + { + CONS_Alert(CONS_WARNING, M_GetText("No unused tag found. Linedef %d with type 457 cannot be converted.\n"), i); + break; + } + Tag_Add(&specialthings[s].angleanchor->tags, freetag); + wlines[i].args[0] = freetag; + freetag = Tag_NextUnused(freetag); + break; + case 606: + if (wlines[i].args[0] == MTAG_GLOBAL) + { + sector_t *sec = wlines[i].frontsector - sectors + wsectors; + sec->extra_colormap = wsides[wlines[i].sidenum[0]].colormap_data; + } + else + { + TAG_ITER_SECTORS(wlines[i].args[0], s) + { + if (wsectors[s].colormap_protected) + continue; + + wsectors[s].extra_colormap = wsides[wlines[i].sidenum[0]].colormap_data; + if (freetag == (mtag_t)MAXTAGS) + { + CONS_Alert(CONS_WARNING, M_GetText("No unused tag found. Linedef %d with type 606 cannot be converted.\n"), i); + break; + } + Tag_Add(&wsectors[s].tags, freetag); + wlines[i].args[1] = freetag; + freetag = Tag_NextUnused(freetag); + break; + } + } + break; + default: + break; + } + + if (wlines[i].special >= 300 && wlines[i].special < 400 && wlines[i].flags & ML_WRAPMIDTEX) + CONS_Alert(CONS_WARNING, M_GetText("Linedef executor trigger linedef %d has disregard order flag, which is not supported in UDMF.\n"), i); + } + + for (i = 0; i < numsectors; i++) + { + if (Tag_Find(&wsectors[i].tags, LE_CAPSULE0)) + CONS_Alert(CONS_WARNING, M_GetText("Sector %d has reserved tag %d, which is not supported in UDMF. Use arg3 of the boss mapthing instead.\n"), i, LE_CAPSULE0); + if (Tag_Find(&wsectors[i].tags, LE_CAPSULE1)) + CONS_Alert(CONS_WARNING, M_GetText("Sector %d has reserved tag %d, which is not supported in UDMF. Use arg3 of the boss mapthing instead.\n"), i, LE_CAPSULE1); + if (Tag_Find(&wsectors[i].tags, LE_CAPSULE2)) + CONS_Alert(CONS_WARNING, M_GetText("Sector %d has reserved tag %d, which is not supported in UDMF. Use arg3 of the boss mapthing instead.\n"), i, LE_CAPSULE2); + + switch (GETSECSPECIAL(wsectors[i].special, 1)) + { + case 9: + case 10: + CONS_Alert(CONS_WARNING, M_GetText("Sector %d has ring drainer effect, which is not supported in UDMF. Use linedef type 462 instead.\n"), i); + break; + default: + break; + } + + switch (GETSECSPECIAL(wsectors[i].special, 2)) + { + case 6: + CONS_Alert(CONS_WARNING, M_GetText("Sector %d has emerald check trigger type, which is not supported in UDMF. Use linedef types 337-339 instead.\n"), i); + break; + case 7: + CONS_Alert(CONS_WARNING, M_GetText("Sector %d has NiGHTS mare trigger type, which is not supported in UDMF. Use linedef types 340-342 instead.\n"), i); + break; + case 9: + CONS_Alert(CONS_WARNING, M_GetText("Sector %d has Egg Capsule type, which is not supported in UDMF. Use linedef type 464 instead.\n"), i); + break; + default: + break; + } + } + + fprintf(f, "namespace = \"srb2\";\n"); + for (i = 0; i < nummapthings; i++) + { + fprintf(f, "thing // %d\n", i); + fprintf(f, "{\n"); + firsttag = Tag_FGet(&wmapthings[i].tags); + if (firsttag != 0) + fprintf(f, "id = %d;\n", firsttag); + if (wmapthings[i].tags.count > 1) + { + fprintf(f, "moreids = \""); + for (j = 1; j < wmapthings[i].tags.count; j++) + { + if (j > 1) + fprintf(f, " "); + fprintf(f, "%d", wmapthings[i].tags.tags[j]); + } + fprintf(f, "\";\n"); + } + fprintf(f, "x = %d;\n", wmapthings[i].x); + fprintf(f, "y = %d;\n", wmapthings[i].y); + if (wmapthings[i].z != 0) + fprintf(f, "height = %d;\n", wmapthings[i].z); + fprintf(f, "angle = %d;\n", wmapthings[i].angle); + if (wmapthings[i].pitch != 0) + fprintf(f, "pitch = %d;\n", wmapthings[i].pitch); + if (wmapthings[i].roll != 0) + fprintf(f, "roll = %d;\n", wmapthings[i].roll); + if (wmapthings[i].type != 0) + fprintf(f, "type = %d;\n", wmapthings[i].type); + if (wmapthings[i].scale != FRACUNIT) + fprintf(f, "scale = %f;\n", FIXED_TO_FLOAT(wmapthings[i].scale)); + if (wmapthings[i].options & MTF_OBJECTFLIP) + fprintf(f, "flip = true;\n"); + for (j = 0; j < NUMMAPTHINGARGS; j++) + if (wmapthings[i].args[j] != 0) + fprintf(f, "arg%d = %d;\n", j, wmapthings[i].args[j]); + for (j = 0; j < NUMMAPTHINGSTRINGARGS; j++) + if (mapthings[i].stringargs[j]) + fprintf(f, "stringarg%d = \"%s\";\n", j, mapthings[i].stringargs[j]); + fprintf(f, "}\n"); + fprintf(f, "\n"); + } + + for (i = 0; i < numvertexes; i++) + { + fprintf(f, "vertex // %d\n", i); + fprintf(f, "{\n"); + fprintf(f, "x = %f;\n", FIXED_TO_FLOAT(wvertexes[i].x)); + fprintf(f, "y = %f;\n", FIXED_TO_FLOAT(wvertexes[i].y)); + if (wvertexes[i].floorzset) + fprintf(f, "zfloor = %f;\n", FIXED_TO_FLOAT(wvertexes[i].floorz)); + if (wvertexes[i].ceilingzset) + fprintf(f, "zceiling = %f;\n", FIXED_TO_FLOAT(wvertexes[i].ceilingz)); + fprintf(f, "}\n"); + fprintf(f, "\n"); + } + + for (i = 0; i < numlines; i++) + { + fprintf(f, "linedef // %d\n", i); + fprintf(f, "{\n"); + fprintf(f, "v1 = %d;\n", wlines[i].v1 - vertexes); + fprintf(f, "v2 = %d;\n", wlines[i].v2 - vertexes); + fprintf(f, "sidefront = %d;\n", wlines[i].sidenum[0]); + if (wlines[i].sidenum[1] != 0xffff) + fprintf(f, "sideback = %d;\n", wlines[i].sidenum[1]); + firsttag = Tag_FGet(&wlines[i].tags); + if (firsttag != 0) + fprintf(f, "id = %d;\n", firsttag); + if (wlines[i].tags.count > 1) + { + fprintf(f, "moreids = \""); + for (j = 1; j < wlines[i].tags.count; j++) + { + if (j > 1) + fprintf(f, " "); + fprintf(f, "%d", wlines[i].tags.tags[j]); + } + fprintf(f, "\";\n"); + } + if (wlines[i].special != 0) + fprintf(f, "special = %d;\n", wlines[i].special); + for (j = 0; j < NUMLINEARGS; j++) + if (wlines[i].args[j] != 0) + fprintf(f, "arg%d = %d;\n", j, wlines[i].args[j]); + for (j = 0; j < NUMLINESTRINGARGS; j++) + if (lines[i].stringargs[j]) + fprintf(f, "stringarg%d = \"%s\";\n", j, lines[i].stringargs[j]); + if (wlines[i].alpha != FRACUNIT) + fprintf(f, "alpha = %f;\n", FIXED_TO_FLOAT(wlines[i].alpha)); + if (wlines[i].blendmode != AST_COPY) + { + switch (wlines[i].blendmode) + { + case AST_ADD: + fprintf(f, "renderstyle = \"add\";\n"); + break; + case AST_SUBTRACT: + fprintf(f, "renderstyle = \"subtract\";\n"); + break; + case AST_REVERSESUBTRACT: + fprintf(f, "renderstyle = \"reversesubtract\";\n"); + break; + case AST_MODULATE: + fprintf(f, "renderstyle = \"modulate\";\n"); + break; + case AST_FOG: + fprintf(f, "renderstyle = \"fog\";\n"); + break; + default: + break; + } + } + if (wlines[i].executordelay != 0 && wlines[i].backsector) + { + CONS_Alert(CONS_WARNING, M_GetText("Linedef %d has an executor delay. Changes to the delay at runtime will not be reflected in the converted map. Use linedef type 465 for this.\n"), i); + fprintf(f, "executordelay = %d;\n", (wlines[i].backsector->ceilingheight >> FRACBITS) + (wlines[i].backsector->floorheight >> FRACBITS)); + } + if (wlines[i].flags & ML_IMPASSABLE) + fprintf(f, "blocking = true;\n"); + if (wlines[i].flags & ML_BLOCKPLAYERS) + fprintf(f, "blockplayers = true;\n"); + if (wlines[i].flags & ML_TWOSIDED) + fprintf(f, "twosided = true;\n"); + if (wlines[i].flags & ML_DONTPEGTOP) + fprintf(f, "dontpegtop = true;\n"); + if (wlines[i].flags & ML_DONTPEGBOTTOM) + fprintf(f, "dontpegbottom = true;\n"); + if (wlines[i].flags & ML_SKEWTD) + fprintf(f, "skewtd = true;\n"); + if (wlines[i].flags & ML_NOCLIMB) + fprintf(f, "noclimb = true;\n"); + if (wlines[i].flags & ML_NOSKEW) + fprintf(f, "noskew = true;\n"); + if (wlines[i].flags & ML_MIDPEG) + fprintf(f, "midpeg = true;\n"); + if (wlines[i].flags & ML_MIDSOLID) + fprintf(f, "midsolid = true;\n"); + if (wlines[i].flags & ML_WRAPMIDTEX) + fprintf(f, "wrapmidtex = true;\n"); + if (wlines[i].flags & ML_NONET) + fprintf(f, "nonet = true;\n"); + if (wlines[i].flags & ML_NETONLY) + fprintf(f, "netonly = true;\n"); + if (wlines[i].flags & ML_NOTBOUNCY) + fprintf(f, "notbouncy = true;\n"); + if (wlines[i].flags & ML_TFERLINE) + fprintf(f, "transfer = true;\n"); + fprintf(f, "}\n"); + fprintf(f, "\n"); + } + + for (i = 0; i < numsides; i++) + { + fprintf(f, "sidedef // %d\n", i); + fprintf(f, "{\n"); + fprintf(f, "sector = %d;\n", wsides[i].sector - sectors); + if (wsides[i].textureoffset != 0) + fprintf(f, "offsetx = %d;\n", wsides[i].textureoffset >> FRACBITS); + if (wsides[i].rowoffset != 0) + fprintf(f, "offsety = %d;\n", wsides[i].rowoffset >> FRACBITS); + if (wsides[i].toptexture > 0 && wsides[i].toptexture < numtextures) + fprintf(f, "texturetop = \"%.*s\";\n", 8, textures[wsides[i].toptexture]->name); + if (wsides[i].bottomtexture > 0 && wsides[i].bottomtexture < numtextures) + fprintf(f, "texturebottom = \"%.*s\";\n", 8, textures[wsides[i].bottomtexture]->name); + if (wsides[i].midtexture > 0 && wsides[i].midtexture < numtextures) + fprintf(f, "texturemiddle = \"%.*s\";\n", 8, textures[wsides[i].midtexture]->name); + if (wsides[i].repeatcnt != 0) + fprintf(f, "repeatcnt = %d;\n", wsides[i].repeatcnt); + fprintf(f, "}\n"); + fprintf(f, "\n"); + } + + for (i = 0; i < numsectors; i++) + { + fprintf(f, "sector // %d\n", i); + fprintf(f, "{\n"); + fprintf(f, "heightfloor = %d;\n", wsectors[i].floorheight >> FRACBITS); + fprintf(f, "heightceiling = %d;\n", wsectors[i].ceilingheight >> FRACBITS); + if (wsectors[i].floorpic != -1) + fprintf(f, "texturefloor = \"%s\";\n", levelflats[wsectors[i].floorpic].name); + if (wsectors[i].ceilingpic != -1) + fprintf(f, "textureceiling = \"%s\";\n", levelflats[wsectors[i].ceilingpic].name); + fprintf(f, "lightlevel = %d;\n", wsectors[i].lightlevel); + if (wsectors[i].floorlightlevel != 0) + fprintf(f, "lightfloor = %d;\n", wsectors[i].floorlightlevel); + if (wsectors[i].floorlightabsolute) + fprintf(f, "lightfloorabsolute = true;\n"); + if (wsectors[i].ceilinglightlevel != 0) + fprintf(f, "lightceiling = %d;\n", wsectors[i].ceilinglightlevel); + if (wsectors[i].ceilinglightabsolute) + fprintf(f, "lightceilingabsolute = true;\n"); + firsttag = Tag_FGet(&wsectors[i].tags); + if (firsttag != 0) + fprintf(f, "id = %d;\n", firsttag); + if (wsectors[i].tags.count > 1) + { + fprintf(f, "moreids = \""); + for (j = 1; j < wsectors[i].tags.count; j++) + { + if (j > 1) + fprintf(f, " "); + fprintf(f, "%d", wsectors[i].tags.tags[j]); + } + fprintf(f, "\";\n"); + } + sector_t tempsec = wsectors[i]; + TextmapUnfixFlatOffsets(&tempsec); + if (tempsec.floor_xoffs != 0) + fprintf(f, "xpanningfloor = %f;\n", FIXED_TO_FLOAT(tempsec.floor_xoffs)); + if (tempsec.floor_yoffs != 0) + fprintf(f, "ypanningfloor = %f;\n", FIXED_TO_FLOAT(tempsec.floor_yoffs)); + if (tempsec.ceiling_xoffs != 0) + fprintf(f, "xpanningceiling = %f;\n", FIXED_TO_FLOAT(tempsec.ceiling_xoffs)); + if (tempsec.ceiling_yoffs != 0) + fprintf(f, "ypanningceiling = %f;\n", FIXED_TO_FLOAT(tempsec.ceiling_yoffs)); + if (wsectors[i].floorpic_angle != 0) + fprintf(f, "rotationfloor = %f;\n", FIXED_TO_FLOAT(AngleFixed(wsectors[i].floorpic_angle))); + if (wsectors[i].ceilingpic_angle != 0) + fprintf(f, "rotationceiling = %f;\n", FIXED_TO_FLOAT(AngleFixed(wsectors[i].ceilingpic_angle))); + if (wsectors[i].extra_colormap) + { + INT32 lightcolor = P_RGBAToColor(wsectors[i].extra_colormap->rgba); + UINT8 lightalpha = R_GetRgbaA(wsectors[i].extra_colormap->rgba); + INT32 fadecolor = P_RGBAToColor(wsectors[i].extra_colormap->fadergba); + UINT8 fadealpha = R_GetRgbaA(wsectors[i].extra_colormap->fadergba); + + if (lightcolor != 0) + fprintf(f, "lightcolor = %d;\n", lightcolor); + if (lightalpha != 25) + fprintf(f, "lightalpha = %d;\n", lightalpha); + if (fadecolor != 0) + fprintf(f, "fadecolor = %d;\n", fadecolor); + if (fadealpha != 25) + fprintf(f, "fadealpha = %d;\n", fadealpha); + if (wsectors[i].extra_colormap->fadestart != 0) + fprintf(f, "fadestart = %d;\n", wsectors[i].extra_colormap->fadestart); + if (wsectors[i].extra_colormap->fadeend != 31) + fprintf(f, "fadeend = %d;\n", wsectors[i].extra_colormap->fadeend); + if (wsectors[i].extra_colormap->flags & CMF_FOG) + fprintf(f, "colormapfog = true;\n"); + if (wsectors[i].extra_colormap->flags & CMF_FADEFULLBRIGHTSPRITES) + fprintf(f, "colormapfadesprites = true;\n"); + } + if (wsectors[i].colormap_protected) + fprintf(f, "colormapprotected = true;\n"); + if (!(wsectors[i].flags & MSF_FLIPSPECIAL_FLOOR)) + fprintf(f, "flipspecial_nofloor = true;\n"); + if (wsectors[i].flags & MSF_FLIPSPECIAL_CEILING) + fprintf(f, "flipspecial_ceiling = true;\n"); + if (wsectors[i].flags & MSF_TRIGGERSPECIAL_TOUCH) + fprintf(f, "triggerspecial_touch = true;\n"); + if (wsectors[i].flags & MSF_TRIGGERSPECIAL_HEADBUMP) + fprintf(f, "triggerspecial_headbump = true;\n"); + if (wsectors[i].flags & MSF_TRIGGERLINE_PLANE) + fprintf(f, "triggerline_plane = true;\n"); + if (wsectors[i].flags & MSF_TRIGGERLINE_MOBJ) + fprintf(f, "triggerline_mobj = true;\n"); + if (wsectors[i].flags & MSF_INVERTPRECIP) + fprintf(f, "invertprecip = true;\n"); + if (wsectors[i].flags & MSF_GRAVITYFLIP) + fprintf(f, "gravityflip = true;\n"); + if (wsectors[i].flags & MSF_HEATWAVE) + fprintf(f, "heatwave = true;\n"); + if (wsectors[i].flags & MSF_NOCLIPCAMERA) + fprintf(f, "noclipcamera = true;\n"); + if (wsectors[i].specialflags & SSF_NOSTEPUP) + fprintf(f, "nostepup = true;\n"); + if (wsectors[i].specialflags & SSF_DOUBLESTEPUP) + fprintf(f, "doublestepup = true;\n"); + if (wsectors[i].specialflags & SSF_NOSTEPDOWN) + fprintf(f, "nostepdown = true;\n"); + if (wsectors[i].specialflags & SSF_SPEEDPAD) + fprintf(f, "speedpad = true;\n"); + if (wsectors[i].specialflags & SSF_STARPOSTACTIVATOR) + fprintf(f, "starpostactivator = true;\n"); + if (wsectors[i].specialflags & SSF_EXIT) + fprintf(f, "exit = true;\n"); + if (wsectors[i].specialflags & SSF_DELETEITEMS) + fprintf(f, "deleteitems = true;\n"); + if (wsectors[i].specialflags & SSF_FAN) + fprintf(f, "fan = true;\n"); + if (wsectors[i].specialflags & SSF_ZOOMTUBESTART) + fprintf(f, "zoomtubestart = true;\n"); + if (wsectors[i].specialflags & SSF_ZOOMTUBEEND) + fprintf(f, "zoomtubeend = true;\n"); + if (wsectors[i].friction != ORIG_FRICTION) + fprintf(f, "friction = %f;\n", FIXED_TO_FLOAT(wsectors[i].friction)); + if (wsectors[i].gravity != FRACUNIT) + fprintf(f, "gravity = %f;\n", FIXED_TO_FLOAT(wsectors[i].gravity)); + if (wsectors[i].damagetype != SD_NONE) + { + switch (wsectors[i].damagetype) + { + case SD_GENERIC: + fprintf(f, "damagetype = \"Generic\";\n"); + break; + case SD_LAVA: + fprintf(f, "damagetype = \"Lava\";\n"); + break; + case SD_DEATHPIT: + fprintf(f, "damagetype = \"DeathPit\";\n"); + break; + case SD_INSTAKILL: + fprintf(f, "damagetype = \"Instakill\";\n"); + break; + default: + break; + } + } + if (wsectors[i].triggertag != 0) + fprintf(f, "triggertag = %d;\n", wsectors[i].triggertag); + if (wsectors[i].triggerer != 0) + fprintf(f, "triggerer = %d;\n", wsectors[i].triggerer); + fprintf(f, "}\n"); + fprintf(f, "\n"); + } + + fclose(f); + + for (i = 0; i < nummapthings; i++) + if (wmapthings[i].tags.count) + Z_Free(wmapthings[i].tags.tags); + + for (i = 0; i < numsectors; i++) + if (wsectors[i].tags.count) + Z_Free(wsectors[i].tags.tags); + + for (i = 0; i < numlines; i++) + if (wlines[i].tags.count) + Z_Free(wlines[i].tags.tags); + + Z_Free(wmapthings); + Z_Free(wvertexes); + Z_Free(wsectors); + Z_Free(wlines); + Z_Free(wsides); + Z_Free(specialthings); +} + /** Loads the textmap data, after obtaining the elements count and allocating their respective space. */ static void P_LoadTextmap(void) @@ -1757,8 +2444,21 @@ static void P_LoadTextmap(void) sc->floorpic_angle = sc->ceilingpic_angle = 0; + sc->floorlightlevel = sc->ceilinglightlevel = 0; + sc->floorlightabsolute = sc->ceilinglightabsolute = false; + sc->colormap_protected = false; + sc->gravity = FRACUNIT; + + sc->flags = MSF_FLIPSPECIAL_FLOOR; + sc->specialflags = 0; + sc->damagetype = SD_NONE; + sc->triggertag = 0; + sc->triggerer = TO_PLAYER; + + sc->friction = ORIG_FRICTION; + textmap_colormap.used = false; textmap_colormap.lightcolor = 0; textmap_colormap.lightalpha = 25; @@ -1947,6 +2647,9 @@ static void P_ProcessLinedefsAfterSidedefs(void) ld->alpha = 0; } + if (udmf) + continue; + switch (ld->special) { // Compile linedef 'text' from both sidedefs 'text' for appropriate specials. @@ -1967,8 +2670,6 @@ static void P_ProcessLinedefsAfterSidedefs(void) break; case 447: // Change colormap case 455: // Fade colormap - if (udmf) - break; if (ld->flags & ML_DONTPEGBOTTOM) // alternate alpha (by texture offsets) { extracolormap_t *exc = R_CopyColormap(sides[ld->sidenum[0]].colormap_data, false); @@ -2012,8 +2713,12 @@ static boolean P_LoadMapData(const virtres_t *virt) if (udmf) // Count how many entries for each type we got in textmap. { virtlump_t *textmap = vres_Find(virt, "TEXTMAP"); - if (!TextmapCount(textmap->data, textmap->size)) + M_TokenizerOpen((char *)textmap->data); + if (!TextmapCount(textmap->size)) + { + M_TokenizerClose(); return false; + } } else { @@ -2067,7 +2772,10 @@ static boolean P_LoadMapData(const virtres_t *virt) // Load map data. if (udmf) + { P_LoadTextmap(); + M_TokenizerClose(); + } else { P_LoadVertices(virtvertexes->data); @@ -2422,11 +3130,17 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype linenum = (nodetype == NT_XGL3) ? READUINT32((*data)) : READUINT16((*data)); if (linenum != 0xFFFF && linenum >= numlines) - I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %d has invalid linedef %d!\n", sizeu1(k), m, linenum); + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %d has invalid linedef %d!\n", sizeu1(k), i, linenum); segs[k].glseg = (linenum == 0xFFFF); segs[k].linedef = (linenum == 0xFFFF) ? NULL : &lines[linenum]; segs[k].side = READUINT8((*data)); } + while (segs[subsectors[i].firstline].glseg) + { + subsectors[i].firstline++; + if (subsectors[i].firstline == k) + I_Error("P_LoadExtendedSubsectorsAndSegs: Subsector %d does not have any valid segs!", i); + } break; case NT_XNOD: @@ -3055,7 +3769,7 @@ static void P_AddBinaryMapTags(void) boolean matches_target_tag = target_tag && Tag_Find(§ors[j].tags, target_tag); size_t k; for (k = 0; k < 4; k++) { - if (lines[i].flags & ML_EFFECT5) { + if (lines[i].flags & ML_WRAPMIDTEX) { if (matches_target_tag || (offset_tags[k] && Tag_Find(§ors[j].tags, offset_tags[k]))) { Tag_Add(§ors[j].tags, tag); break; @@ -3069,10 +3783,80 @@ static void P_AddBinaryMapTags(void) } } } + + for (i = 0; i < nummapthings; i++) + { + switch (mapthings[i].type) + { + case 291: + case 322: + case 750: + case 760: + case 761: + case 762: + Tag_FSet(&mapthings[i].tags, mapthings[i].angle); + break; + case 290: + case 292: + case 294: + case 780: + Tag_FSet(&mapthings[i].tags, mapthings[i].extrainfo); + break; + default: + break; + } + } } -//For maps in binary format, converts setup of specials to UDMF format. -static void P_ConvertBinaryMap(void) +static void P_WriteConstant(INT32 constant, char **target) +{ + char buffer[12]; + sprintf(buffer, "%d", constant); + *target = Z_Malloc(strlen(buffer) + 1, PU_LEVEL, NULL); + M_Memcpy(*target, buffer, strlen(buffer) + 1); +} + +static line_t *P_FindPointPushLine(taglist_t *list) +{ + INT32 i, l; + + for (i = 0; i < list->count; i++) + { + mtag_t tag = list->tags[i]; + TAG_ITER_LINES(tag, l) + { + if (Tag_FGet(&lines[l].tags) != tag) + continue; + + if (lines[l].special != 547) + continue; + + return &lines[l]; + } + } + + return NULL; +} + +static void P_SetBinaryFOFAlpha(line_t *line) +{ + if (sides[line->sidenum[0]].toptexture > 0) + { + line->args[1] = sides[line->sidenum[0]].toptexture; + if (sides[line->sidenum[0]].toptexture >= 1001) + { + line->args[2] = (sides[line->sidenum[0]].toptexture/1000); + line->args[1] %= 1000; + } + } + else + { + line->args[1] = 128; + line->args[2] = TMB_TRANSLUCENT; + } +} + +static void P_ConvertBinaryLinedefTypes(void) { size_t i; @@ -3082,6 +3866,114 @@ static void P_ConvertBinaryMap(void) switch (lines[i].special) { + case 2: //Custom exit + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[1] |= TMEF_SKIPTALLY; + if (lines[i].flags & ML_BLOCKPLAYERS) + lines[i].args[1] |= TMEF_EMERALDCHECK; + break; + case 3: //Zoom tube parameters + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + lines[i].args[2] = !!(lines[i].flags & ML_MIDSOLID); + break; + case 4: //Speed pad parameters + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + if (lines[i].flags & ML_MIDSOLID) + lines[i].args[1] |= TMSP_NOTELEPORT; + if (lines[i].flags & ML_WRAPMIDTEX) + lines[i].args[1] |= TMSP_FORCESPIN; + P_WriteConstant(sides[lines[i].sidenum[0]].toptexture ? sides[lines[i].sidenum[0]].toptexture : sfx_spdpad, &lines[i].stringargs[0]); + break; + case 7: //Sector flat alignment + lines[i].args[0] = tag; + if ((lines[i].flags & (ML_NETONLY|ML_NONET)) == (ML_NETONLY|ML_NONET)) + { + CONS_Alert(CONS_WARNING, M_GetText("Flat alignment linedef (tag %d) doesn't have anything to do.\nConsider changing the linedef's flag configuration or removing it entirely.\n"), tag); + lines[i].special = 0; + } + else if (lines[i].flags & ML_NETONLY) + lines[i].args[1] = TMP_CEILING; + else if (lines[i].flags & ML_NONET) + lines[i].args[1] = TMP_FLOOR; + else + lines[i].args[1] = TMP_BOTH; + lines[i].flags &= ~(ML_NETONLY|ML_NONET); + + if (lines[i].flags & ML_EFFECT6) // Set offset through x and y texture offsets + { + angle_t flatangle = InvAngle(R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y)); + fixed_t xoffs = sides[lines[i].sidenum[0]].textureoffset; + fixed_t yoffs = sides[lines[i].sidenum[0]].rowoffset; + + //If no tag is given, apply to front sector + if (lines[i].args[0] == 0) + P_ApplyFlatAlignment(lines[i].frontsector, flatangle, xoffs, yoffs, lines[i].args[1] != TMP_CEILING, lines[i].args[1] != TMP_FLOOR); + else + { + INT32 s; + TAG_ITER_SECTORS(lines[i].args[0], s) + P_ApplyFlatAlignment(sectors + s, flatangle, xoffs, yoffs, lines[i].args[1] != TMP_CEILING, lines[i].args[1] != TMP_FLOOR); + } + lines[i].special = 0; + } + break; + case 8: //Special sector properties + { + INT32 s; + + lines[i].args[0] = tag; + TAG_ITER_SECTORS(tag, s) + { + if (lines[i].flags & ML_NOCLIMB) + { + sectors[s].flags &= ~MSF_FLIPSPECIAL_FLOOR; + sectors[s].flags |= MSF_FLIPSPECIAL_CEILING; + } + else if (lines[i].flags & ML_MIDSOLID) + sectors[s].flags |= MSF_FLIPSPECIAL_BOTH; + + if (lines[i].flags & ML_MIDPEG) + sectors[s].flags |= MSF_TRIGGERSPECIAL_TOUCH; + if (lines[i].flags & ML_NOSKEW) + sectors[s].flags |= MSF_TRIGGERSPECIAL_HEADBUMP; + + if (lines[i].flags & ML_SKEWTD) + sectors[s].flags |= MSF_INVERTPRECIP; + } + + if (GETSECSPECIAL(lines[i].frontsector->special, 4) != 12) + lines[i].special = 0; + + break; + } + case 10: //Culling plane + lines[i].args[0] = tag; + lines[i].args[1] = !!(lines[i].flags & ML_NOCLIMB); + break; + case 11: //Rope hang parameters + lines[i].args[0] = (lines[i].flags & ML_NOCLIMB) ? 0 : sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + lines[i].args[2] = !!(lines[i].flags & ML_SKEWTD); + break; + case 13: //Heat wave effect + { + INT32 s; + + TAG_ITER_SECTORS(tag, s) + sectors[s].flags |= MSF_HEATWAVE; + + break; + } + case 14: //Bustable block parameters + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + lines[i].args[2] = !!(lines[i].flags & ML_SKEWTD); + P_WriteConstant(sides[lines[i].sidenum[0]].toptexture, &lines[i].stringargs[0]); + break; + case 16: //Minecart parameters + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + break; case 20: //PolyObject first line { INT32 check = -1; @@ -3116,15 +4008,15 @@ static void P_ConvertBinaryMap(void) : ((lines[paramline].frontsector->floorheight >> FRACBITS) / 100); //Flags - if (lines[paramline].flags & ML_EFFECT1) + if (lines[paramline].flags & ML_SKEWTD) lines[i].args[3] |= TMPF_NOINSIDES; - if (lines[paramline].flags & ML_EFFECT2) + if (lines[paramline].flags & ML_NOSKEW) lines[i].args[3] |= TMPF_INTANGIBLE; - if (lines[paramline].flags & ML_EFFECT3) + if (lines[paramline].flags & ML_MIDPEG) lines[i].args[3] |= TMPF_PUSHABLESTOP; - if (lines[paramline].flags & ML_EFFECT4) + if (lines[paramline].flags & ML_MIDSOLID) lines[i].args[3] &= ~TMPF_INVISIBLEPLANES; - /*if (lines[paramline].flags & ML_EFFECT5) + /*if (lines[paramline].flags & ML_WRAPMIDTEX) lines[i].args[3] |= TMPF_DONTCLIPPLANES;*/ if (lines[paramline].flags & ML_EFFECT6) lines[i].args[3] |= TMPF_SPLAT; @@ -3133,6 +4025,1067 @@ static void P_ConvertBinaryMap(void) break; } + case 30: //Polyobject - waving flag + lines[i].args[0] = tag; + lines[i].args[1] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; + lines[i].args[2] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + break; + case 31: //Polyobject - displacement by front sector + lines[i].args[0] = tag; + lines[i].args[1] = R_PointToDist2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y) >> FRACBITS; + break; + case 32: //Polyobject - angular displacement by front sector + lines[i].args[0] = tag; + lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset ? sides[lines[i].sidenum[0]].textureoffset >> FRACBITS : 128; + lines[i].args[2] = sides[lines[i].sidenum[0]].rowoffset ? sides[lines[i].sidenum[0]].rowoffset >> FRACBITS : 90; + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[3] |= TMPR_DONTROTATEOTHERS; + else if (lines[i].flags & ML_MIDSOLID) + lines[i].args[3] |= TMPR_ROTATEPLAYERS; + break; + case 50: //Instantly lower floor on level load + case 51: //Instantly raise ceiling on level load + lines[i].args[0] = tag; + break; + case 52: //Continuously falling sector + lines[i].args[0] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; + lines[i].args[1] = !!(lines[i].flags & ML_NOCLIMB); + break; + case 53: //Continuous floor/ceiling mover + case 54: //Continuous floor mover + case 55: //Continuous ceiling mover + lines[i].args[0] = tag; + lines[i].args[1] = (lines[i].special == 53) ? TMP_BOTH : lines[i].special - 54; + lines[i].args[2] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; + lines[i].args[3] = lines[i].args[2]; + lines[i].args[4] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + lines[i].args[5] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].special = 53; + break; + case 56: //Continuous two-speed floor/ceiling mover + case 57: //Continuous two-speed floor mover + case 58: //Continuous two-speed ceiling mover + lines[i].args[0] = tag; + lines[i].args[1] = (lines[i].special == 56) ? TMP_BOTH : lines[i].special - 57; + lines[i].args[2] = abs(lines[i].dx) >> FRACBITS; + lines[i].args[3] = abs(lines[i].dy) >> FRACBITS; + lines[i].args[4] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + lines[i].args[5] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].special = 56; + break; + case 59: //Activate moving platform + case 60: //Activate moving platform (adjustable speed) + lines[i].args[0] = tag; + lines[i].args[1] = (lines[i].special == 60) ? P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS : 8; + lines[i].args[2] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + lines[i].args[3] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[4] = (lines[i].flags & ML_NOCLIMB) ? 1 : 0; + lines[i].special = 60; + break; + case 61: //Crusher (Ceiling to floor) + case 62: //Crusher (Floor to ceiling) + lines[i].args[0] = tag; + lines[i].args[1] = lines[i].special - 61; + if (lines[i].flags & ML_MIDSOLID) + { + lines[i].args[2] = abs(lines[i].dx) >> FRACBITS; + lines[i].args[3] = lines[i].args[2]; + } + else + { + lines[i].args[2] = R_PointToDist2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y) >> (FRACBITS + 1); + lines[i].args[3] = lines[i].args[2] / 4; + } + lines[i].special = 61; + break; + case 63: //Fake floor/ceiling planes + lines[i].args[0] = tag; + break; + case 64: //Appearing/disappearing FOF + lines[i].args[0] = (lines[i].flags & ML_BLOCKPLAYERS) ? 0 : tag; + lines[i].args[1] = (lines[i].flags & ML_BLOCKPLAYERS) ? tag : Tag_FGet(&lines[i].frontsector->tags); + lines[i].args[2] = lines[i].dx >> FRACBITS; + lines[i].args[3] = lines[i].dy >> FRACBITS; + lines[i].args[4] = lines[i].frontsector->floorheight >> FRACBITS; + lines[i].args[5] = !!(lines[i].flags & ML_NOCLIMB); + break; + case 66: //Move floor by displacement + case 67: //Move ceiling by displacement + case 68: //Move floor and ceiling by displacement + lines[i].args[0] = tag; + lines[i].args[1] = lines[i].special - 66; + lines[i].args[2] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; + lines[i].special = 66; + break; + case 76: //Make FOF bouncy + lines[i].args[0] = tag; + lines[i].args[1] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; + break; + case 100: //FOF: solid, opaque, shadowcasting + case 101: //FOF: solid, opaque, non-shadowcasting + case 102: //FOF: solid, translucent + case 103: //FOF: solid, sides only + case 104: //FOF: solid, no sides + case 105: //FOF: solid, invisible + lines[i].args[0] = tag; + + //Alpha + if (lines[i].special == 102) + { + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[3] |= TMFA_INSIDES; + P_SetBinaryFOFAlpha(&lines[i]); + + //Replicate old hack: Translucent FOFs set to full opacity cut cyan pixels + if (lines[i].args[1] == 256) + lines[i].args[3] |= TMFA_SPLAT; + } + else + lines[i].args[1] = 255; + + //Appearance + if (lines[i].special == 105) + lines[i].args[3] |= TMFA_NOPLANES|TMFA_NOSIDES; + else if (lines[i].special == 104) + lines[i].args[3] |= TMFA_NOSIDES; + else if (lines[i].special == 103) + lines[i].args[3] |= TMFA_NOPLANES; + if (lines[i].special != 100 && (lines[i].special != 104 || !(lines[i].flags & ML_NOCLIMB))) + lines[i].args[3] |= TMFA_NOSHADE; + if (lines[i].flags & ML_EFFECT6) + lines[i].args[3] |= TMFA_SPLAT; + + //Tangibility + if (lines[i].flags & ML_SKEWTD) + lines[i].args[4] |= TMFT_DONTBLOCKOTHERS; + if (lines[i].flags & ML_NOSKEW) + lines[i].args[4] |= TMFT_DONTBLOCKPLAYER; + + lines[i].special = 100; + break; + case 120: //FOF: water, opaque + case 121: //FOF: water, translucent + case 122: //FOF: water, opaque, no sides + case 123: //FOF: water, translucent, no sides + case 124: //FOF: goo water, translucent + case 125: //FOF: goo water, translucent, no sides + lines[i].args[0] = tag; + + //Alpha + if (lines[i].special == 120 || lines[i].special == 122) + lines[i].args[1] = 255; + else + { + P_SetBinaryFOFAlpha(&lines[i]); + + //Replicate old hack: Translucent FOFs set to full opacity cut cyan pixels + if (lines[i].args[1] == 256) + lines[i].args[3] |= TMFW_SPLAT; + } + + //No sides? + if (lines[i].special == 122 || lines[i].special == 123 || lines[i].special == 125) + lines[i].args[3] |= TMFW_NOSIDES; + + //Flags + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[3] |= TMFW_DOUBLESHADOW; + if (lines[i].flags & ML_MIDSOLID) + lines[i].args[3] |= TMFW_COLORMAPONLY; + if (!(lines[i].flags & ML_WRAPMIDTEX)) + lines[i].args[3] |= TMFW_NORIPPLE; + + //Goo? + if (lines[i].special >= 124) + lines[i].args[3] |= TMFW_GOOWATER; + + //Splat rendering? + if (lines[i].flags & ML_EFFECT6) + lines[i].args[3] |= TMFW_SPLAT; + + lines[i].special = 120; + break; + case 140: //FOF: intangible from bottom, opaque + case 141: //FOF: intangible from bottom, translucent + case 142: //FOF: intangible from bottom, translucent, no sides + case 143: //FOF: intangible from top, opaque + case 144: //FOF: intangible from top, translucent + case 145: //FOF: intangible from top, translucent, no sides + case 146: //FOF: only tangible from sides + lines[i].args[0] = tag; + + //Alpha + if (lines[i].special == 141 || lines[i].special == 142 || lines[i].special == 144 || lines[i].special == 145) + { + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[3] |= TMFA_INSIDES; + P_SetBinaryFOFAlpha(&lines[i]); + + //Replicate old hack: Translucent FOFs set to full opacity cut cyan pixels + if (lines[i].args[1] == 256) + lines[i].args[3] |= TMFA_SPLAT; + } + else + lines[i].args[1] = 255; + + //Appearance + if (lines[i].special == 142 || lines[i].special == 145) + lines[i].args[3] |= TMFA_NOSIDES; + else if (lines[i].special == 146) + lines[i].args[3] |= TMFA_NOPLANES; + if (lines[i].special != 146 && (lines[i].flags & ML_NOCLIMB)) + lines[i].args[3] |= TMFA_NOSHADE; + if (lines[i].flags & ML_EFFECT6) + lines[i].args[3] |= TMFA_SPLAT; + + //Tangibility + if (lines[i].special <= 142) + lines[i].args[4] |= TMFT_INTANGIBLEBOTTOM; + else if (lines[i].special <= 145) + lines[i].args[4] |= TMFT_INTANGIBLETOP; + else + lines[i].args[4] |= TMFT_INTANGIBLEBOTTOM|TMFT_INTANGIBLETOP; + + if (lines[i].flags & ML_SKEWTD) + lines[i].args[4] |= TMFT_DONTBLOCKOTHERS; + if (lines[i].flags & ML_NOSKEW) + lines[i].args[4] |= TMFT_DONTBLOCKPLAYER; + + lines[i].special = 100; + break; + case 150: //FOF: Air bobbing + case 151: //FOF: Air bobbing (adjustable) + case 152: //FOF: Reverse air bobbing (adjustable) + case 153: //FOF: Dynamically sinking platform + lines[i].args[0] = tag; + lines[i].args[1] = (lines[i].special == 150) ? 16 : (P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS); + + //Flags + if (lines[i].special == 152) + lines[i].args[2] |= TMFB_REVERSE; + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[2] |= TMFB_SPINDASH; + if (lines[i].special == 153) + lines[i].args[2] |= TMFB_DYNAMIC; + + lines[i].special = 150; + break; + case 160: //FOF: Water bobbing + lines[i].args[0] = tag; + break; + case 170: //FOF: Crumbling, respawn + case 171: //FOF: Crumbling, no respawn + case 172: //FOF: Crumbling, respawn, intangible from bottom + case 173: //FOF: Crumbling, no respawn, intangible from bottom + case 174: //FOF: Crumbling, respawn, intangible from bottom, translucent + case 175: //FOF: Crumbling, no respawn, intangible from bottom, translucent + case 176: //FOF: Crumbling, respawn, floating, bobbing + case 177: //FOF: Crumbling, no respawn, floating, bobbing + case 178: //FOF: Crumbling, respawn, floating + case 179: //FOF: Crumbling, no respawn, floating + case 180: //FOF: Crumbling, respawn, air bobbing + lines[i].args[0] = tag; + + //Alpha + if (lines[i].special >= 174 && lines[i].special <= 175) + { + P_SetBinaryFOFAlpha(&lines[i]); + + //Replicate old hack: Translucent FOFs set to full opacity cut cyan pixels + if (lines[i].args[1] == 256) + lines[i].args[4] |= TMFC_SPLAT; + } + else + lines[i].args[1] = 255; + + if (lines[i].special >= 172 && lines[i].special <= 175) + { + lines[i].args[3] |= TMFT_INTANGIBLEBOTTOM; + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[4] |= TMFC_NOSHADE; + } + + if (lines[i].special % 2 == 1) + lines[i].args[4] |= TMFC_NORETURN; + if (lines[i].special == 176 || lines[i].special == 177 || lines[i].special == 180) + lines[i].args[4] |= TMFC_AIRBOB; + if (lines[i].special >= 176 && lines[i].special <= 179) + lines[i].args[4] |= TMFC_FLOATBOB; + if (lines[i].flags & ML_EFFECT6) + lines[i].args[4] |= TMFC_SPLAT; + + if (lines[i].flags & ML_SKEWTD) + lines[i].args[3] |= TMFT_DONTBLOCKOTHERS; + if (lines[i].flags & ML_NOSKEW) + lines[i].args[3] |= TMFT_DONTBLOCKPLAYER; + + lines[i].special = 170; + break; + case 190: // FOF: Rising, solid, opaque, shadowcasting + case 191: // FOF: Rising, solid, opaque, non-shadowcasting + case 192: // FOF: Rising, solid, translucent + case 193: // FOF: Rising, solid, invisible + case 194: // FOF: Rising, intangible from bottom, opaque + case 195: // FOF: Rising, intangible from bottom, translucent + lines[i].args[0] = tag; + + //Translucency + if (lines[i].special == 192 || lines[i].special == 195) + { + P_SetBinaryFOFAlpha(&lines[i]); + + //Replicate old hack: Translucent FOFs set to full opacity cut cyan pixels + if (lines[i].args[1] == 256) + lines[i].args[3] |= TMFA_SPLAT; + } + else + lines[i].args[1] = 255; + + //Appearance + if (lines[i].special == 193) + lines[i].args[3] |= TMFA_NOPLANES|TMFA_NOSIDES; + if (lines[i].special >= 194) + lines[i].args[3] |= TMFA_INSIDES; + if (lines[i].special != 190 && (lines[i].special <= 193 || lines[i].flags & ML_NOCLIMB)) + lines[i].args[3] |= TMFA_NOSHADE; + if (lines[i].flags & ML_EFFECT6) + lines[i].args[3] |= TMFA_SPLAT; + + //Tangibility + if (lines[i].flags & ML_SKEWTD) + lines[i].args[4] |= TMFT_DONTBLOCKOTHERS; + if (lines[i].flags & ML_NOSKEW) + lines[i].args[4] |= TMFT_DONTBLOCKPLAYER; + if (lines[i].special >= 194) + lines[i].args[4] |= TMFT_INTANGIBLEBOTTOM; + + //Speed + lines[i].args[5] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; + + //Flags + if (lines[i].flags & ML_BLOCKPLAYERS) + lines[i].args[6] |= TMFR_REVERSE; + if (lines[i].flags & ML_BLOCKPLAYERS) + lines[i].args[6] |= TMFR_SPINDASH; + + lines[i].special = 190; + break; + case 200: //FOF: Light block + case 201: //FOF: Half light block + lines[i].args[0] = tag; + if (lines[i].special == 201) + lines[i].args[1] = 1; + lines[i].special = 200; + break; + case 202: //FOF: Fog block + case 223: //FOF: Intangible, invisible + lines[i].args[0] = tag; + break; + case 220: //FOF: Intangible, opaque + case 221: //FOF: Intangible, translucent + case 222: //FOF: Intangible, sides only + lines[i].args[0] = tag; + + //Alpha + if (lines[i].special == 221) + { + P_SetBinaryFOFAlpha(&lines[i]); + + //Replicate old hack: Translucent FOFs set to full opacity cut cyan pixels + if (lines[i].args[1] == 256) + lines[i].args[3] |= TMFA_SPLAT; + } + else + lines[i].args[1] = 255; + + //Appearance + if (lines[i].special == 222) + lines[i].args[3] |= TMFA_NOPLANES; + if (lines[i].special == 221) + lines[i].args[3] |= TMFA_INSIDES; + if (lines[i].special != 220 && !(lines[i].flags & ML_NOCLIMB)) + lines[i].args[3] |= TMFA_NOSHADE; + if (lines[i].flags & ML_EFFECT6) + lines[i].args[3] |= TMFA_SPLAT; + + lines[i].special = 220; + break; + case 250: //FOF: Mario block + lines[i].args[0] = tag; + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[1] |= TMFM_BRICK; + if (lines[i].flags & ML_SKEWTD) + lines[i].args[1] |= TMFM_INVISIBLE; + break; + case 251: //FOF: Thwomp block + lines[i].args[0] = tag; + if (lines[i].flags & ML_WRAPMIDTEX) //Custom speeds + { + lines[i].args[1] = lines[i].dy >> FRACBITS; + lines[i].args[2] = lines[i].dx >> FRACBITS; + } + else + { + lines[i].args[1] = 80; + lines[i].args[2] = 16; + } + if (lines[i].flags & ML_MIDSOLID) + P_WriteConstant(sides[lines[i].sidenum[0]].textureoffset >> FRACBITS, &lines[i].stringargs[0]); + break; + case 252: //FOF: Shatter block + case 253: //FOF: Shatter block, translucent + case 254: //FOF: Bustable block + case 255: //FOF: Spin-bustable block + case 256: //FOF: Spin-bustable block, translucent + lines[i].args[0] = tag; + + //Alpha + if (lines[i].special == 253 || lines[i].special == 256) + { + P_SetBinaryFOFAlpha(&lines[i]); + + //Replicate old hack: Translucent FOFs set to full opacity cut cyan pixels + if (lines[i].args[1] == 256) + lines[i].args[4] |= TMFB_SPLAT; + } + else + lines[i].args[1] = 255; + + //Bustable type + if (lines[i].special <= 253) + lines[i].args[3] = TMFB_TOUCH; + else if (lines[i].special >= 255) + lines[i].args[3] = TMFB_SPIN; + else if (lines[i].flags & ML_NOCLIMB) + lines[i].args[3] = TMFB_STRONG; + else + lines[i].args[3] = TMFB_REGULAR; + + //Flags + if (lines[i].flags & ML_MIDSOLID) + lines[i].args[4] |= TMFB_PUSHABLES; + if (lines[i].flags & ML_WRAPMIDTEX) + { + lines[i].args[4] |= TMFB_EXECUTOR; + lines[i].args[5] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; + } + if (lines[i].special == 252 && lines[i].flags & ML_NOCLIMB) + lines[i].args[4] |= TMFB_ONLYBOTTOM; + if (lines[i].flags & ML_EFFECT6) + lines[i].args[4] |= TMFB_SPLAT; + + lines[i].special = 254; + break; + case 257: //FOF: Quicksand + lines[i].args[0] = tag; + if (!(lines[i].flags & ML_WRAPMIDTEX)) + lines[i].args[1] = 1; //No ripple effect + lines[i].args[2] = lines[i].dx >> FRACBITS; //Sinking speed + lines[i].args[3] = lines[i].dy >> FRACBITS; //Friction + break; + case 258: //FOF: Laser + lines[i].args[0] = tag; + + //Alpha + P_SetBinaryFOFAlpha(&lines[i]); + + //Flags + if (lines[i].flags & ML_SKEWTD) + lines[i].args[3] |= TMFL_NOBOSSES; + //Replicate old hack: Translucent FOFs set to full opacity cut cyan pixels + if (lines[i].flags & ML_EFFECT6 || lines[i].args[1] == 256) + lines[i].args[3] |= TMFL_SPLAT; + + break; + case 259: //Custom FOF + if (lines[i].sidenum[1] == 0xffff) + I_Error("Custom FOF (tag %d) found without a linedef back side!", tag); + + lines[i].args[0] = tag; + lines[i].args[3] = sides[lines[i].sidenum[1]].toptexture; + if (lines[i].flags & ML_EFFECT6) + lines[i].args[3] |= FF_SPLAT; + lines[i].args[4] = sides[lines[i].sidenum[1]].midtexture; + if (lines[i].args[3] & FF_TRANSLUCENT) + { + P_SetBinaryFOFAlpha(&lines[i]); + + //Replicate old hack: Translucent FOFs set to full opacity cut cyan pixels + if (lines[i].args[1] == 256) + lines[i].args[3] |= FF_SPLAT; + } + else + lines[i].args[1] = 255; + break; + case 300: //Trigger linedef executor - Continuous + case 301: //Trigger linedef executor - Each time + case 302: //Trigger linedef executor - Once + if (lines[i].special == 302) + lines[i].args[0] = TMT_ONCE; + else if (lines[i].special == 301) + lines[i].args[0] = (lines[i].flags & ML_NOTBOUNCY) ? TMT_EACHTIMEENTERANDEXIT : TMT_EACHTIMEENTER; + else + lines[i].args[0] = TMT_CONTINUOUS; + lines[i].special = 300; + break; + case 303: //Ring count - Continuous + case 304: //Ring count - Once + lines[i].args[0] = (lines[i].special == 304) ? TMT_ONCE : TMT_CONTINUOUS; + lines[i].args[1] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[2] = TMC_LTE; + else if (lines[i].flags & ML_BLOCKPLAYERS) + lines[i].args[2] = TMC_GTE; + else + lines[i].args[2] = TMC_EQUAL; + lines[i].args[3] = !!(lines[i].flags & ML_MIDSOLID); + lines[i].special = 303; + break; + case 305: //Character ability - Continuous + case 306: //Character ability - Each time + case 307: //Character ability - Once + if (lines[i].special == 307) + lines[i].args[0] = TMT_ONCE; + else if (lines[i].special == 306) + lines[i].args[0] = (lines[i].flags & ML_NOTBOUNCY) ? TMT_EACHTIMEENTERANDEXIT : TMT_EACHTIMEENTER; + else + lines[i].args[0] = TMT_CONTINUOUS; + lines[i].args[1] = (P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS) / 10; + lines[i].special = 305; + break; + case 308: //Race only - once + lines[i].args[0] = TMT_ONCE; + lines[i].args[1] = GTR_CIRCUIT; + lines[i].args[2] = TMF_HASANY; + break; + case 309: //CTF red team - continuous + case 310: //CTF red team - each time + case 311: //CTF blue team - continuous + case 312: //CTF blue team - each time + if (lines[i].special % 2 == 0) + lines[i].args[0] = (lines[i].flags & ML_NOTBOUNCY) ? TMT_EACHTIMEENTERANDEXIT : TMT_EACHTIMEENTER; + else + lines[i].args[0] = TMT_CONTINUOUS; + lines[i].args[1] = (lines[i].special > 310) ? TMT_BLUE : TMT_RED; + lines[i].special = 309; + break; + case 313: //No more enemies - once + lines[i].args[0] = tag; + break; + case 314: //Number of pushables - Continuous + case 315: //Number of pushables - Once + lines[i].args[0] = (lines[i].special == 315) ? TMT_ONCE : TMT_CONTINUOUS; + lines[i].args[1] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[2] = TMC_GTE; + else if (lines[i].flags & ML_MIDSOLID) + lines[i].args[2] = TMC_LTE; + else + lines[i].args[2] = TMC_EQUAL; + lines[i].special = 314; + break; + case 317: //Condition set trigger - Continuous + case 318: //Condition set trigger - Once + lines[i].args[0] = (lines[i].special == 318) ? TMT_ONCE : TMT_CONTINUOUS; + lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].special = 317; + break; + case 319: //Unlockable trigger - Continuous + case 320: //Unlockable trigger - Once + lines[i].args[0] = (lines[i].special == 320) ? TMT_ONCE : TMT_CONTINUOUS; + lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].special = 319; + break; + case 321: //Trigger after X calls - Continuous + case 322: //Trigger after X calls - Each time + if (lines[i].special % 2 == 0) + lines[i].args[0] = (lines[i].flags & ML_NOTBOUNCY) ? TMXT_EACHTIMEENTERANDEXIT : TMXT_EACHTIMEENTER; + else + lines[i].args[0] = TMXT_CONTINUOUS; + lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + if (lines[i].flags & ML_NOCLIMB) + { + lines[i].args[2] = 1; + lines[i].args[3] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + } + else + lines[i].args[2] = lines[i].args[3] = 0; + lines[i].special = 321; + break; + case 323: //NiGHTSerize - Each time + case 324: //NiGHTSerize - Once + case 325: //DeNiGHTSerize - Each time + case 326: //DeNiGHTSerize - Once + case 327: //NiGHTS lap - Each time + case 328: //NiGHTS lap - Once + case 329: //Ideya capture touch - Each time + case 330: //Ideya capture touch - Once + lines[i].args[0] = (lines[i].special + 1) % 2; + lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[2] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[3] = TMC_LTE; + else if (lines[i].flags & ML_BLOCKPLAYERS) + lines[i].args[3] = TMC_GTE; + else + lines[i].args[3] = TMC_EQUAL; + if (lines[i].flags & ML_SKEWTD) + lines[i].args[4] = TMC_LTE; + else if (lines[i].flags & ML_NOSKEW) + lines[i].args[4] = TMC_GTE; + else + lines[i].args[4] = TMC_EQUAL; + if (lines[i].flags & ML_DONTPEGBOTTOM) + lines[i].args[5] = TMNP_SLOWEST; + else if (lines[i].flags & ML_MIDSOLID) + lines[i].args[5] = TMNP_TRIGGERER; + else + lines[i].args[5] = TMNP_FASTEST; + if (lines[i].special % 2 == 0) + lines[i].special--; + if (lines[i].special == 323) + { + if (lines[i].flags & ML_TFERLINE) + lines[i].args[6] = TMN_FROMNONIGHTS; + else if (lines[i].flags & ML_DONTPEGTOP) + lines[i].args[6] = TMN_FROMNIGHTS; + else + lines[i].args[6] = TMN_ALWAYS; + + if (lines[i].flags & ML_MIDPEG) + lines[i].args[7] |= TMN_BONUSLAPS; + if (lines[i].flags & ML_NOTBOUNCY) + lines[i].args[7] |= TMN_LEVELCOMPLETION; + } + else if (lines[i].special == 325) + { + if (lines[i].flags & ML_TFERLINE) + lines[i].args[6] = TMD_NOBODYNIGHTS; + else if (lines[i].flags & ML_DONTPEGTOP) + lines[i].args[6] = TMD_SOMEBODYNIGHTS; + else + lines[i].args[6] = TMD_ALWAYS; + + lines[i].args[7] = !!(lines[i].flags & ML_MIDPEG); + } + else if (lines[i].special == 327) + lines[i].args[6] = !!(lines[i].flags & ML_MIDPEG); + else + { + if (lines[i].flags & ML_DONTPEGTOP) + lines[i].args[6] = TMS_ALWAYS; + else if (lines[i].flags & ML_NOTBOUNCY) + lines[i].args[6] = TMS_IFNOTENOUGH; + else + lines[i].args[6] = TMS_IFENOUGH; + + if (lines[i].flags & ML_MIDPEG) + lines[i].args[7] |= TMI_BONUSLAPS; + if (lines[i].flags & ML_TFERLINE) + lines[i].args[7] |= TMI_ENTER; + } + break; + case 331: // Player skin - continuous + case 332: // Player skin - each time + case 333: // Player skin - once + if (lines[i].special == 303) + lines[i].args[0] = TMT_ONCE; + else if (lines[i].special == 302) + lines[i].args[0] = (lines[i].flags & ML_NOTBOUNCY) ? TMT_EACHTIMEENTERANDEXIT : TMT_EACHTIMEENTER; + else + lines[i].args[0] = TMT_CONTINUOUS; + lines[i].args[1] = !!(lines[i].flags & ML_NOCLIMB); + if (lines[i].text) + { + lines[i].stringargs[0] = Z_Malloc(strlen(lines[i].text) + 1, PU_LEVEL, NULL); + M_Memcpy(lines[i].stringargs[0], lines[i].text, strlen(lines[i].text) + 1); + } + lines[i].special = 331; + break; + case 334: // Object dye - continuous + case 335: // Object dye - each time + case 336: // Object dye - once + if (lines[i].special == 336) + lines[i].args[0] = TMT_ONCE; + else if (lines[i].special == 335) + lines[i].args[0] = (lines[i].flags & ML_NOTBOUNCY) ? TMT_EACHTIMEENTERANDEXIT : TMT_EACHTIMEENTER; + else + lines[i].args[0] = TMT_CONTINUOUS; + lines[i].args[1] = !!(lines[i].flags & ML_NOCLIMB); + if (sides[lines[i].sidenum[0]].text) + { + lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL); + M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1); + } + lines[i].special = 334; + break; + case 337: //Emerald check - continuous + case 338: //Emerald check - each time + case 339: //Emerald check - once + if (lines[i].special == 339) + lines[i].args[0] = TMT_ONCE; + else if (lines[i].special == 338) + lines[i].args[0] = (lines[i].flags & ML_NOTBOUNCY) ? TMT_EACHTIMEENTERANDEXIT : TMT_EACHTIMEENTER; + else + lines[i].args[0] = TMT_CONTINUOUS; + lines[i].args[1] = EMERALD_ALLCHAOS; + lines[i].args[2] = TMF_HASALL; + lines[i].special = 337; + break; + case 340: //NiGHTS mare - continuous + case 341: //NiGHTS mare - each time + case 342: //NiGHTS mare - once + if (lines[i].special == 342) + lines[i].args[0] = TMT_ONCE; + else if (lines[i].special == 341) + lines[i].args[0] = (lines[i].flags & ML_NOTBOUNCY) ? TMT_EACHTIMEENTERANDEXIT : TMT_EACHTIMEENTER; + else + lines[i].args[0] = TMT_CONTINUOUS; + lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[2] = TMC_LTE; + else if (lines[i].flags & ML_BLOCKPLAYERS) + lines[i].args[2] = TMC_GTE; + else + lines[i].args[2] = TMC_EQUAL; + lines[i].special = 340; + break; + case 400: //Set tagged sector's floor height/texture + case 401: //Set tagged sector's ceiling height/texture + lines[i].args[0] = tag; + lines[i].args[1] = lines[i].special - 400; + lines[i].args[2] = !(lines[i].flags & ML_NOCLIMB); + lines[i].special = 400; + break; + case 402: //Copy light level + lines[i].args[0] = tag; + lines[i].args[1] = 0; + break; + case 403: //Move tagged sector's floor + case 404: //Move tagged sector's ceiling + lines[i].args[0] = tag; + lines[i].args[1] = lines[i].special - 403; + lines[i].args[2] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; + lines[i].args[3] = (lines[i].flags & ML_BLOCKPLAYERS) ? sides[lines[i].sidenum[0]].textureoffset >> FRACBITS : 0; + lines[i].args[4] = !!(lines[i].flags & ML_NOCLIMB); + lines[i].special = 403; + break; + case 405: //Move floor according to front texture offsets + case 407: //Move ceiling according to front texture offsets + lines[i].args[0] = tag; + lines[i].args[1] = (lines[i].special == 405) ? TMP_FLOOR : TMP_CEILING; + lines[i].args[2] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + lines[i].args[3] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[4] = !!(lines[i].flags & ML_NOCLIMB); + lines[i].special = 405; + break; + case 408: //Set flats + lines[i].args[0] = tag; + if ((lines[i].flags & (ML_NOCLIMB|ML_MIDSOLID)) == (ML_NOCLIMB|ML_MIDSOLID)) + { + CONS_Alert(CONS_WARNING, M_GetText("Set flats linedef (tag %d) doesn't have anything to do.\nConsider changing the linedef's flag configuration or removing it entirely.\n"), tag); + lines[i].special = 0; + } + else if (lines[i].flags & ML_NOCLIMB) + lines[i].args[1] = TMP_CEILING; + else if (lines[i].flags & ML_MIDSOLID) + lines[i].args[1] = TMP_FLOOR; + else + lines[i].args[1] = TMP_BOTH; + break; + case 409: //Change tagged sector's tag + lines[i].args[0] = tag; + lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[2] = TMT_ADD; + else if (lines[i].flags & ML_BLOCKPLAYERS) + lines[i].args[2] = TMT_REMOVE; + else + lines[i].args[2] = TMT_REPLACEFIRST; + break; + case 410: //Change front sector's tag + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[1] = TMT_ADD; + else if (lines[i].flags & ML_BLOCKPLAYERS) + lines[i].args[1] = TMT_REMOVE; + else + lines[i].args[1] = TMT_REPLACEFIRST; + break; + case 411: //Stop plane movement + lines[i].args[0] = tag; + break; + case 412: //Teleporter + lines[i].args[0] = tag; + if (lines[i].flags & ML_BLOCKPLAYERS) + lines[i].args[1] |= TMT_SILENT; + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[1] |= TMT_KEEPANGLE; + if (lines[i].flags & ML_MIDSOLID) + lines[i].args[1] |= TMT_KEEPMOMENTUM; + if (lines[i].flags & ML_MIDPEG) + lines[i].args[1] |= TMT_RELATIVE; + lines[i].args[2] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[3] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + lines[i].args[4] = lines[i].frontsector->ceilingheight >> FRACBITS; + break; + case 413: //Change music + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[0] |= TMM_ALLPLAYERS; + if (lines[i].flags & ML_SKEWTD) + lines[i].args[0] |= TMM_OFFSET; + if (lines[i].flags & ML_NOSKEW) + lines[i].args[0] |= TMM_FADE; + if (lines[i].flags & ML_BLOCKPLAYERS) + lines[i].args[0] |= TMM_NORELOAD; + if (lines[i].flags & ML_NOTBOUNCY) + lines[i].args[0] |= TMM_FORCERESET; + if (lines[i].flags & ML_MIDSOLID) + lines[i].args[0] |= TMM_NOLOOP; + lines[i].args[1] = sides[lines[i].sidenum[0]].midtexture; + lines[i].args[2] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[3] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + lines[i].args[4] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : 0; + lines[i].args[5] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].rowoffset >> FRACBITS : -1; + lines[i].args[6] = sides[lines[i].sidenum[0]].bottomtexture; + if (sides[lines[i].sidenum[0]].text) + { + lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL); + M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1); + } + break; + case 414: //Play sound effect + lines[i].args[2] = tag; + if (tag != 0) + { + if (lines[i].flags & ML_WRAPMIDTEX) + { + lines[i].args[0] = TMSS_TAGGEDSECTOR; + lines[i].args[1] = TMSL_EVERYONE; + } + else + { + lines[i].args[0] = TMSS_NOWHERE; + lines[i].args[1] = TMSL_TAGGEDSECTOR; + } + } + else + { + if (lines[i].flags & ML_NOCLIMB) + { + lines[i].args[0] = TMSS_NOWHERE; + lines[i].args[1] = TMSL_TRIGGERER; + } + else if (lines[i].flags & ML_MIDSOLID) + { + lines[i].args[0] = TMSS_NOWHERE; + lines[i].args[1] = TMSL_EVERYONE; + } + else if (lines[i].flags & ML_BLOCKPLAYERS) + { + lines[i].args[0] = TMSS_TRIGGERSECTOR; + lines[i].args[1] = TMSL_EVERYONE; + } + else + { + lines[i].args[0] = TMSS_TRIGGERMOBJ; + lines[i].args[1] = TMSL_EVERYONE; + } + } + if (sides[lines[i].sidenum[0]].text) + { + lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL); + M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1); + } + break; + case 415: //Run script + { + INT32 scrnum; + + lines[i].stringargs[0] = Z_Malloc(9, PU_LEVEL, NULL); + strcpy(lines[i].stringargs[0], G_BuildMapName(gamemap)); + lines[i].stringargs[0][0] = 'S'; + lines[i].stringargs[0][1] = 'C'; + lines[i].stringargs[0][2] = 'R'; + + scrnum = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + if (scrnum < 0 || scrnum > 999) + { + scrnum = 0; + lines[i].stringargs[0][5] = lines[i].stringargs[0][6] = lines[i].stringargs[0][7] = '0'; + } + else + { + lines[i].stringargs[0][5] = (char)('0' + (char)((scrnum / 100))); + lines[i].stringargs[0][6] = (char)('0' + (char)((scrnum % 100) / 10)); + lines[i].stringargs[0][7] = (char)('0' + (char)(scrnum % 10)); + } + lines[i].stringargs[0][8] = '\0'; + break; + } + case 416: //Start adjustable flickering light + case 417: //Start adjustable pulsating light + case 602: //Adjustable pulsating light + case 603: //Adjustable flickering light + lines[i].args[0] = tag; + lines[i].args[1] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; + lines[i].args[2] = lines[i].frontsector->lightlevel; + if ((lines[i].flags & ML_NOCLIMB) && lines[i].backsector) + lines[i].args[4] = lines[i].backsector->lightlevel; + else + lines[i].args[3] = 1; + break; + case 418: //Start adjustable blinking light (unsynchronized) + case 419: //Start adjustable blinking light (synchronized) + case 604: //Adjustable blinking light (unsynchronized) + case 605: //Adjustable blinking light (synchronized) + lines[i].args[0] = tag; + lines[i].args[1] = abs(lines[i].dx) >> FRACBITS; + lines[i].args[2] = abs(lines[i].dy) >> FRACBITS; + lines[i].args[3] = lines[i].frontsector->lightlevel; + if ((lines[i].flags & ML_NOCLIMB) && lines[i].backsector) + lines[i].args[5] = lines[i].backsector->lightlevel; + else + lines[i].args[4] |= TMB_USETARGET; + if (lines[i].special % 2 == 1) + { + lines[i].args[4] |= TMB_SYNC; + lines[i].special--; + } + break; + case 420: //Fade light level + lines[i].args[0] = tag; + if (lines[i].flags & ML_DONTPEGBOTTOM) + { + lines[i].args[1] = max(sides[lines[i].sidenum[0]].textureoffset >> FRACBITS, 0); + // failsafe: if user specifies Back Y Offset and NOT Front Y Offset, use the Back Offset + // to be consistent with other light and fade specials + lines[i].args[2] = ((lines[i].sidenum[1] != 0xFFFF && !(sides[lines[i].sidenum[0]].rowoffset >> FRACBITS)) ? + max(min(sides[lines[i].sidenum[1]].rowoffset >> FRACBITS, 255), 0) + : max(min(sides[lines[i].sidenum[0]].rowoffset >> FRACBITS, 255), 0)); + } + else + { + lines[i].args[1] = lines[i].frontsector->lightlevel; + lines[i].args[2] = abs(P_AproxDistance(lines[i].dx, lines[i].dy)) >> FRACBITS; + } + if (lines[i].flags & ML_MIDSOLID) + lines[i].args[3] |= TMF_TICBASED; + if (lines[i].flags & ML_WRAPMIDTEX) + lines[i].args[3] |= TMF_OVERRIDE; + break; + case 421: //Stop lighting effect + lines[i].args[0] = tag; + break; + case 422: //Switch to cut-away view + lines[i].args[0] = tag; + lines[i].args[1] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; + lines[i].args[2] = (lines[i].flags & ML_NOCLIMB) ? sides[lines[i].sidenum[0]].textureoffset >> FRACBITS : 0; + break; + case 423: //Change sky + case 424: //Change weather + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[1] = !!(lines[i].flags & ML_NOCLIMB); + break; + case 425: //Change object state + if (sides[lines[i].sidenum[0]].text) + { + lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL); + M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1); + } + break; + case 426: //Stop object + lines[i].args[0] = !!(lines[i].flags & ML_NOCLIMB); + break; + case 427: //Award score + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + break; + case 428: //Start platform movement + lines[i].args[0] = tag; + lines[i].args[1] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; + lines[i].args[2] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + lines[i].args[3] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[4] = (lines[i].flags & ML_NOCLIMB) ? 1 : 0; + break; + case 429: //Crush ceiling once + case 430: //Crush floor once + case 431: //Crush floor and ceiling once + lines[i].args[0] = tag; + lines[i].args[1] = (lines[i].special == 429) ? TMP_CEILING : ((lines[i].special == 430) ? TMP_FLOOR : TMP_BOTH); + if (lines[i].special == 430 || lines[i].flags & ML_MIDSOLID) + { + lines[i].args[2] = abs(lines[i].dx) >> FRACBITS; + lines[i].args[3] = lines[i].args[2]; + } + else + { + lines[i].args[2] = R_PointToDist2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y) >> (FRACBITS + 1); + lines[i].args[3] = lines[i].args[2] / 4; + } + lines[i].special = 429; + break; + case 432: //Enable/disable 2D mode + lines[i].args[0] = !!(lines[i].flags & ML_NOCLIMB); + break; + case 433: //Enable/disable gravity flip + lines[i].args[0] = !!(lines[i].flags & ML_NOCLIMB); + break; + case 434: //Award power-up + if (sides[lines[i].sidenum[0]].text) + { + lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL); + M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1); + } + if (lines[i].sidenum[1] != 0xffff && lines[i].flags & ML_BLOCKPLAYERS) // read power from back sidedef + { + lines[i].stringargs[1] = Z_Malloc(strlen(sides[lines[i].sidenum[1]].text) + 1, PU_LEVEL, NULL); + M_Memcpy(lines[i].stringargs[1], sides[lines[i].sidenum[1]].text, strlen(sides[lines[i].sidenum[1]].text) + 1); + } + else + P_WriteConstant((lines[i].flags & ML_NOCLIMB) ? -1 : (sides[lines[i].sidenum[0]].textureoffset >> FRACBITS), &lines[i].stringargs[1]); + break; + case 435: //Change plane scroller direction + lines[i].args[0] = tag; + lines[i].args[1] = R_PointToDist2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y) >> FRACBITS; + break; + case 436: //Shatter FOF + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + break; + case 437: //Disable player control + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[1] = !!(lines[i].flags & ML_NOCLIMB); + break; + case 438: //Change object size + lines[i].args[0] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; + break; + case 439: //Change tagged linedef's textures + lines[i].args[0] = tag; + lines[i].args[1] = TMSD_FRONTBACK; + lines[i].args[2] = !!(lines[i].flags & ML_NOCLIMB); + break; + case 441: //Condition set trigger + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + break; + case 442: //Change object type state + lines[i].args[0] = tag; + if (sides[lines[i].sidenum[0]].text) + { + lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL); + M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1); + } + if (lines[i].sidenum[1] == 0xffff) + lines[i].args[1] = 1; + else + { + lines[i].args[1] = 0; + if (sides[lines[i].sidenum[1]].text) + { + lines[i].stringargs[1] = Z_Malloc(strlen(sides[lines[i].sidenum[1]].text) + 1, PU_LEVEL, NULL); + M_Memcpy(lines[i].stringargs[1], sides[lines[i].sidenum[1]].text, strlen(sides[lines[i].sidenum[1]].text) + 1); + } + } + break; case 443: //Call Lua function if (lines[i].text) { @@ -3142,47 +5095,444 @@ static void P_ConvertBinaryMap(void) else CONS_Alert(CONS_WARNING, "Linedef %s is missing the hook name of the Lua function to call! (This should be given in the front texture fields)\n", sizeu1(i)); break; + case 444: //Earthquake + lines[i].args[0] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; + lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[2] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + break; + case 445: //Make FOF disappear/reappear + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + lines[i].args[2] = !!(lines[i].flags & ML_NOCLIMB); + break; + case 446: //Make FOF crumble + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[2] |= TMFR_NORETURN; + if (lines[i].flags & ML_BLOCKPLAYERS) + lines[i].args[2] |= TMFR_CHECKFLAG; + break; case 447: //Change colormap - lines[i].args[0] = Tag_FGet(&lines[i].tags); - if (lines[i].flags & ML_EFFECT3) + lines[i].args[0] = tag; + if (lines[i].flags & ML_MIDPEG) lines[i].args[2] |= TMCF_RELATIVE; - if (lines[i].flags & ML_EFFECT1) + if (lines[i].flags & ML_SKEWTD) lines[i].args[2] |= TMCF_SUBLIGHTR|TMCF_SUBFADER; if (lines[i].flags & ML_NOCLIMB) lines[i].args[2] |= TMCF_SUBLIGHTG|TMCF_SUBFADEG; - if (lines[i].flags & ML_EFFECT2) + if (lines[i].flags & ML_NOSKEW) lines[i].args[2] |= TMCF_SUBLIGHTB|TMCF_SUBFADEB; break; + case 448: //Change skybox + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + if ((lines[i].flags & (ML_MIDSOLID|ML_BLOCKPLAYERS)) == ML_MIDSOLID) // Solid Midtexture is on but Block Enemies is off? + { + CONS_Alert(CONS_WARNING, + M_GetText("Skybox switch linedef (tag %d) doesn't have anything to do.\nConsider changing the linedef's flag configuration or removing it entirely.\n"), + tag); + lines[i].special = 0; + break; + } + else if ((lines[i].flags & (ML_MIDSOLID|ML_BLOCKPLAYERS)) == (ML_MIDSOLID|ML_BLOCKPLAYERS)) + lines[i].args[2] = TMS_CENTERPOINT; + else if (lines[i].flags & ML_BLOCKPLAYERS) + lines[i].args[2] = TMS_BOTH; + else + lines[i].args[2] = TMS_VIEWPOINT; + lines[i].args[3] = !!(lines[i].flags & ML_NOCLIMB); + break; + case 449: //Enable bosses with parameters + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[1] = !!(lines[i].flags & ML_NOCLIMB); + break; + case 450: //Execute linedef executor (specific tag) + lines[i].args[0] = tag; + break; + case 451: //Execute linedef executor (random tag in range) + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + break; + case 452: //Set FOF translucency + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + lines[i].args[2] = lines[i].sidenum[1] != 0xffff ? (sides[lines[i].sidenum[1]].textureoffset >> FRACBITS) : (P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS); + if (lines[i].flags & ML_MIDPEG) + lines[i].args[3] |= TMST_RELATIVE; + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[3] |= TMST_DONTDOTRANSLUCENT; + break; + case 453: //Fade FOF + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + lines[i].args[2] = lines[i].sidenum[1] != 0xffff ? (sides[lines[i].sidenum[1]].textureoffset >> FRACBITS) : (lines[i].dx >> FRACBITS); + lines[i].args[3] = lines[i].sidenum[1] != 0xffff ? (sides[lines[i].sidenum[1]].rowoffset >> FRACBITS) : (abs(lines[i].dy) >> FRACBITS); + if (lines[i].flags & ML_MIDPEG) + lines[i].args[4] |= TMFT_RELATIVE; + if (lines[i].flags & ML_WRAPMIDTEX) + lines[i].args[4] |= TMFT_OVERRIDE; + if (lines[i].flags & ML_MIDSOLID) + lines[i].args[4] |= TMFT_TICBASED; + if (lines[i].flags & ML_NOTBOUNCY) + lines[i].args[4] |= TMFT_IGNORECOLLISION; + if (lines[i].flags & ML_SKEWTD) + lines[i].args[4] |= TMFT_GHOSTFADE; + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[4] |= TMFT_DONTDOTRANSLUCENT; + if (lines[i].flags & ML_BLOCKPLAYERS) + lines[i].args[4] |= TMFT_DONTDOEXISTS; + if (lines[i].flags & ML_NOSKEW) + lines[i].args[4] |= (TMFT_DONTDOLIGHTING|TMFT_DONTDOCOLORMAP); + if (lines[i].flags & ML_TFERLINE) + lines[i].args[4] |= TMFT_USEEXACTALPHA; + break; + case 454: //Stop fading FOF + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + lines[i].args[2] = !!(lines[i].flags & ML_BLOCKPLAYERS); + break; case 455: //Fade colormap { INT32 speed = (INT32)((((lines[i].flags & ML_DONTPEGBOTTOM) || !sides[lines[i].sidenum[0]].rowoffset) && lines[i].sidenum[1] != 0xFFFF) ? abs(sides[lines[i].sidenum[1]].rowoffset >> FRACBITS) : abs(sides[lines[i].sidenum[0]].rowoffset >> FRACBITS)); - lines[i].args[0] = Tag_FGet(&lines[i].tags); - if (lines[i].flags & ML_EFFECT4) + lines[i].args[0] = tag; + if (lines[i].flags & ML_MIDSOLID) lines[i].args[2] = speed; else lines[i].args[2] = (256 + speed - 1)/speed; - if (lines[i].flags & ML_EFFECT3) + if (lines[i].flags & ML_MIDPEG) lines[i].args[3] |= TMCF_RELATIVE; - if (lines[i].flags & ML_EFFECT1) + if (lines[i].flags & ML_SKEWTD) lines[i].args[3] |= TMCF_SUBLIGHTR|TMCF_SUBFADER; if (lines[i].flags & ML_NOCLIMB) lines[i].args[3] |= TMCF_SUBLIGHTG|TMCF_SUBFADEG; - if (lines[i].flags & ML_EFFECT2) + if (lines[i].flags & ML_NOSKEW) lines[i].args[3] |= TMCF_SUBLIGHTB|TMCF_SUBFADEB; if (lines[i].flags & ML_NOTBOUNCY) lines[i].args[3] |= TMCF_FROMBLACK; - if (lines[i].flags & ML_EFFECT5) + if (lines[i].flags & ML_WRAPMIDTEX) lines[i].args[3] |= TMCF_OVERRIDE; break; } case 456: //Stop fading colormap - lines[i].args[0] = Tag_FGet(&lines[i].tags); + lines[i].args[0] = tag; + break; + case 457: //Track object's angle + lines[i].args[0] = tag; + lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[2] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + lines[i].args[3] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].rowoffset >> FRACBITS : 0; + lines[i].args[4] = !!(lines[i].flags & ML_NOSKEW); + break; + case 459: //Control text prompt + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + if (lines[i].flags & ML_BLOCKPLAYERS) + lines[i].args[2] |= TMP_CLOSE; + if (lines[i].flags & ML_SKEWTD) + lines[i].args[2] |= TMP_RUNPOSTEXEC; + if (lines[i].flags & ML_TFERLINE) + lines[i].args[2] |= TMP_CALLBYNAME; + if (lines[i].flags & ML_NOSKEW) + lines[i].args[2] |= TMP_KEEPCONTROLS; + if (lines[i].flags & ML_MIDPEG) + lines[i].args[2] |= TMP_KEEPREALTIME; + /*if (lines[i].flags & ML_NOCLIMB) + lines[i].args[2] |= TMP_ALLPLAYERS; + if (lines[i].flags & ML_MIDSOLID) + lines[i].args[2] |= TMP_FREEZETHINKERS;*/ + lines[i].args[3] = (lines[i].sidenum[1] != 0xFFFF) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : tag; + if (sides[lines[i].sidenum[0]].text) + { + lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL); + M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1); + } + break; + case 460: //Award rings + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + break; + case 461: //Spawn object + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + lines[i].args[2] = lines[i].frontsector->floorheight >> FRACBITS; + lines[i].args[3] = (lines[i].flags & ML_SKEWTD) ? AngleFixed(R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y)) >> FRACBITS : 0; + if (lines[i].flags & ML_NOCLIMB) + { + if (lines[i].sidenum[1] != 0xffff) // Make sure the linedef has a back side + { + lines[i].args[4] = 1; + lines[i].args[5] = sides[lines[i].sidenum[1]].textureoffset >> FRACBITS; + lines[i].args[6] = sides[lines[i].sidenum[1]].rowoffset >> FRACBITS; + lines[i].args[7] = lines[i].frontsector->ceilingheight >> FRACBITS; + } + else + { + CONS_Alert(CONS_WARNING, "Linedef Type %d - Spawn Object: Linedef is set for random range but has no back side.\n", lines[i].special); + lines[i].args[4] = 0; + } + } + else + lines[i].args[4] = 0; + if (sides[lines[i].sidenum[0]].text) + { + lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL); + M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1); + } + break; + case 463: //Dye object + if (sides[lines[i].sidenum[0]].text) + { + lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL); + M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1); + } + break; + case 464: //Trigger egg capsule + lines[i].args[0] = tag; + lines[i].args[1] = !!(lines[i].flags & ML_NOCLIMB); + break; + case 466: //Set level failure state + lines[i].args[0] = !!(lines[i].flags & ML_NOCLIMB); + break; + case 467: //Set light level + lines[i].args[0] = tag; + lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[2] = TML_SECTOR; + lines[i].args[3] = !!(lines[i].flags & ML_MIDPEG); + break; + case 480: //Polyobject - door slide + case 481: //Polyobject - door move + lines[i].args[0] = tag; + lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[2] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + if (lines[i].sidenum[1] != 0xffff) + lines[i].args[3] = sides[lines[i].sidenum[1]].textureoffset >> FRACBITS; + break; + case 482: //Polyobject - move + case 483: //Polyobject - move, override + lines[i].args[0] = tag; + lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[2] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + lines[i].args[3] = lines[i].special == 483; + lines[i].special = 482; + break; + case 484: //Polyobject - rotate right + case 485: //Polyobject - rotate right, override + case 486: //Polyobject - rotate left + case 487: //Polyobject - rotate left, override + lines[i].args[0] = tag; + lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[2] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + if (lines[i].args[2] == 360) + lines[i].args[3] |= TMPR_CONTINUOUS; + else if (lines[i].args[2] == 0) + lines[i].args[2] = 360; + if (lines[i].special < 486) + lines[i].args[2] *= -1; + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[3] |= TMPR_DONTROTATEOTHERS; + else if (lines[i].flags & ML_MIDSOLID) + lines[i].args[3] |= TMPR_ROTATEPLAYERS; + if (lines[i].special % 2 == 1) + lines[i].args[3] |= TMPR_OVERRIDE; + lines[i].special = 484; + break; + case 488: //Polyobject - move by waypoints + lines[i].args[0] = tag; + lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[2] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + if (lines[i].flags & ML_MIDPEG) + lines[i].args[3] = PWR_WRAP; + else if (lines[i].flags & ML_NOSKEW) + lines[i].args[3] = PWR_COMEBACK; + else + lines[i].args[3] = PWR_STOP; + if (lines[i].flags & ML_SKEWTD) + lines[i].args[4] |= PWF_REVERSE; + if (lines[i].flags & ML_MIDSOLID) + lines[i].args[4] |= PWF_LOOP; + break; + case 489: //Polyobject - turn invisible, intangible + case 490: //Polyobject - turn visible, tangible + lines[i].args[0] = tag; + lines[i].args[1] = 491 - lines[i].special; + if (!(lines[i].flags & ML_NOCLIMB)) + lines[i].args[2] = lines[i].args[1]; + lines[i].special = 489; + break; + case 491: //Polyobject - set translucency + lines[i].args[0] = tag; + // If Front X Offset is specified, use that. Else, use floorheight. + lines[i].args[1] = (sides[lines[i].sidenum[0]].textureoffset ? sides[lines[i].sidenum[0]].textureoffset : lines[i].frontsector->floorheight) >> FRACBITS; + // If DONTPEGBOTTOM, specify raw translucency value. Else, take it out of 1000. + if (!(lines[i].flags & ML_DONTPEGBOTTOM)) + lines[i].args[1] /= 100; + lines[i].args[2] = !!(lines[i].flags & ML_MIDPEG); + break; + case 492: //Polyobject - fade translucency + lines[i].args[0] = tag; + // If Front X Offset is specified, use that. Else, use floorheight. + lines[i].args[1] = (sides[lines[i].sidenum[0]].textureoffset ? sides[lines[i].sidenum[0]].textureoffset : lines[i].frontsector->floorheight) >> FRACBITS; + // If DONTPEGBOTTOM, specify raw translucency value. Else, take it out of 1000. + if (!(lines[i].flags & ML_DONTPEGBOTTOM)) + lines[i].args[1] /= 100; + // allow Back Y Offset to be consistent with other fade specials + lines[i].args[2] = (lines[i].sidenum[1] != 0xffff && !sides[lines[i].sidenum[0]].rowoffset) ? + abs(sides[lines[i].sidenum[1]].rowoffset >> FRACBITS) + : abs(sides[lines[i].sidenum[0]].rowoffset >> FRACBITS); + if (lines[i].flags & ML_MIDPEG) + lines[i].args[3] |= TMPF_RELATIVE; + if (lines[i].flags & ML_WRAPMIDTEX) + lines[i].args[3] |= TMPF_OVERRIDE; + if (lines[i].flags & ML_MIDSOLID) + lines[i].args[3] |= TMPF_TICBASED; + if (lines[i].flags & ML_NOTBOUNCY) + lines[i].args[3] |= TMPF_IGNORECOLLISION; + if (lines[i].flags & ML_SKEWTD) + lines[i].args[3] |= TMPF_GHOSTFADE; + break; + case 500: //Scroll front wall left + case 501: //Scroll front wall right + lines[i].args[0] = 0; + lines[i].args[1] = (lines[i].special == 500) ? -1 : 1; + lines[i].args[2] = 0; + lines[i].special = 500; + break; + case 502: //Scroll tagged wall + case 503: //Scroll tagged wall (accelerative) + case 504: //Scroll tagged wall (displacement) + lines[i].args[0] = tag; + if (lines[i].flags & ML_MIDPEG) + { + if (lines[i].sidenum[1] == 0xffff) + { + CONS_Debug(DBG_GAMELOGIC, "Line special %d (line #%s) missing back side!\n", lines[i].special, sizeu1(i)); + lines[i].special = 0; + break; + } + lines[i].args[1] = 1; + } + else + lines[i].args[1] = 0; + if (lines[i].flags & ML_NOSKEW) + { + lines[i].args[2] = lines[i].dx >> (FRACBITS + SCROLL_SHIFT); + lines[i].args[3] = lines[i].dy >> (FRACBITS + SCROLL_SHIFT); + } + else + { + lines[i].args[2] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[3] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + } + lines[i].args[4] = lines[i].special - 502; + lines[i].special = 502; + break; + case 505: //Scroll front wall by front side offsets + case 506: //Scroll front wall by back side offsets + case 507: //Scroll back wall by front side offsets + case 508: //Scroll back wall by back side offsets + lines[i].args[0] = lines[i].special >= 507; + if (lines[i].special % 2 == 0) + { + if (lines[i].sidenum[1] == 0xffff) + { + CONS_Debug(DBG_GAMELOGIC, "Line special %d (line #%s) missing back side!\n", lines[i].special, sizeu1(i)); + lines[i].special = 0; + break; + } + lines[i].args[1] = sides[lines[i].sidenum[1]].textureoffset >> FRACBITS; + lines[i].args[2] = sides[lines[i].sidenum[1]].rowoffset >> FRACBITS; + } + else + { + lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + lines[i].args[2] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + } + lines[i].special = 500; + break; + case 510: //Scroll floor texture + case 511: //Scroll floor texture (accelerative) + case 512: //Scroll floor texture (displacement) + case 513: //Scroll ceiling texture + case 514: //Scroll ceiling texture (accelerative) + case 515: //Scroll ceiling texture (displacement) + case 520: //Carry objects on floor + case 521: //Carry objects on floor (accelerative) + case 522: //Carry objects on floor (displacement) + case 523: //Carry objects on ceiling + case 524: //Carry objects on ceiling (accelerative) + case 525: //Carry objects on ceiling (displacement) + case 530: //Scroll floor texture and carry objects + case 531: //Scroll floor texture and carry objects (accelerative) + case 532: //Scroll floor texture and carry objects (displacement) + case 533: //Scroll ceiling texture and carry objects + case 534: //Scroll ceiling texture and carry objects (accelerative) + case 535: //Scroll ceiling texture and carry objects (displacement) + lines[i].args[0] = tag; + lines[i].args[1] = ((lines[i].special % 10) < 3) ? TMP_FLOOR : TMP_CEILING; + lines[i].args[2] = ((lines[i].special - 510)/10 + 1) % 3; + lines[i].args[3] = R_PointToDist2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y) >> FRACBITS; + lines[i].args[4] = (lines[i].special % 10) % 3; + if (lines[i].args[2] != TMS_SCROLLONLY && !(lines[i].flags & ML_NOCLIMB)) + lines[i].args[4] |= TMST_NONEXCLUSIVE; + lines[i].special = 510; + break; + case 540: //Floor friction + { + INT32 s; + fixed_t strength; // friction value of sector + fixed_t friction; // friction value to be applied during movement + + strength = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + if (strength > 0) // sludge + strength = strength*2; // otherwise, the maximum sludginess value is +967... + + // The following might seem odd. At the time of movement, + // the move distance is multiplied by 'friction/0x10000', so a + // higher friction value actually means 'less friction'. + friction = ORIG_FRICTION - (0x1EB8*strength)/0x80; // ORIG_FRICTION is 0xE800 + + TAG_ITER_SECTORS(tag, s) + sectors[s].friction = friction; + break; + } + case 541: //Wind + case 542: //Upwards wind + case 543: //Downwards wind + case 544: //Current + case 545: //Upwards current + case 546: //Downwards current + lines[i].args[0] = tag; + switch ((lines[i].special - 541) % 3) + { + case 0: + lines[i].args[1] = R_PointToDist2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y) >> FRACBITS; + break; + case 1: + lines[i].args[2] = R_PointToDist2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y) >> FRACBITS; + break; + case 2: + lines[i].args[2] = -R_PointToDist2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y) >> FRACBITS; + break; + } + lines[i].args[3] = (lines[i].special >= 544) ? p_current : p_wind; + if (lines[i].flags & ML_MIDSOLID) + lines[i].args[4] |= TMPF_SLIDE; + if (!(lines[i].flags & ML_NOCLIMB)) + lines[i].args[4] |= TMPF_NONEXCLUSIVE; + lines[i].special = 541; + break; + case 600: //Floor lighting + case 601: //Ceiling lighting + lines[i].args[0] = tag; + lines[i].args[1] = (lines[i].special == 601) ? TMP_CEILING : TMP_FLOOR; + lines[i].special = 600; break; case 606: //Colormap - lines[i].args[0] = Tag_FGet(&lines[i].tags); + lines[i].args[0] = tag; break; case 700: //Slope front sector floor case 701: //Slope front sector ceiling @@ -3205,6 +5555,8 @@ static void P_ConvertBinaryMap(void) lines[i].args[2] |= TMSL_NOPHYSICS; if (lines[i].flags & ML_NONET) lines[i].args[2] |= TMSL_DYNAMIC; + if (lines[i].flags & ML_TFERLINE) + lines[i].args[2] |= TMSL_COPY; lines[i].special = 700; break; @@ -3287,6 +5639,9 @@ static void P_ConvertBinaryMap(void) lines[i].args[4] |= TMSC_BACKTOFRONTCEILING; lines[i].special = 720; break; + case 799: //Set dynamic slope vertex to front sector height + lines[i].args[0] = !!(lines[i].flags & ML_NOCLIMB); + break; case 909: //Fog wall lines[i].blendmode = AST_FOG; break; @@ -3323,25 +5678,449 @@ static void P_ConvertBinaryMap(void) lines[i].executordelay = 1; } } +} + +static void P_ConvertBinarySectorTypes(void) +{ + size_t i; + + for (i = 0; i < numsectors; i++) + { + mtag_t tag = Tag_FGet(§ors[i].tags); + + switch(GETSECSPECIAL(sectors[i].special, 1)) + { + case 1: //Damage + case 5: //Spikes + sectors[i].damagetype = SD_GENERIC; + break; + case 2: //Offroad (Weak) + sectors[i].offroad = FRACUNIT; + break; + case 3: //Offroad + sectors[i].offroad = 2*FRACUNIT; + break; + case 4: //Offroad (Strong) + sectors[i].offroad = 3*FRACUNIT; + break; + case 6: //Death pit (camera tilt) + case 7: //Death pit (no camera tilt) + sectors[i].damagetype = SD_DEATHPIT; + break; + case 8: //Instakill + sectors[i].damagetype = SD_INSTAKILL; + break; + case 11: //Special stage damage + //sectors[i].damagetype = SD_SPECIALSTAGE; + break; + case 12: //Space countdown + //sectors[i].specialflags |= SSF_OUTERSPACE; + break; + case 13: //Ramp sector + sectors[i].specialflags |= SSF_DOUBLESTEPUP; + break; + case 14: //Non-ramp sector + sectors[i].specialflags |= SSF_NOSTEPDOWN; + break; + default: + break; + } + + switch(GETSECSPECIAL(sectors[i].special, 2)) + { + case 1: //Trigger linedef executor (pushable objects) + sectors[i].triggertag = tag; + sectors[i].flags |= MSF_TRIGGERLINE_PLANE; + sectors[i].triggerer = TO_MOBJ; + break; + case 2: //Trigger linedef executor (Anywhere in sector, all players) + sectors[i].triggertag = tag; + sectors[i].flags &= ~MSF_TRIGGERLINE_PLANE; + sectors[i].triggerer = TO_ALLPLAYERS; + break; + case 3: //Trigger linedef executor (Floor touch, all players) + sectors[i].triggertag = tag; + sectors[i].flags |= MSF_TRIGGERLINE_PLANE; + sectors[i].triggerer = TO_ALLPLAYERS; + break; + case 4: //Trigger linedef executor (Anywhere in sector) + sectors[i].triggertag = tag; + sectors[i].flags &= ~MSF_TRIGGERLINE_PLANE; + sectors[i].triggerer = TO_PLAYER; + break; + case 5: //Trigger linedef executor (Floor touch) + sectors[i].triggertag = tag; + sectors[i].flags |= MSF_TRIGGERLINE_PLANE; + sectors[i].triggerer = TO_PLAYER; + break; + case 8: //Check for linedef executor on FOFs + sectors[i].flags |= MSF_TRIGGERLINE_MOBJ; + break; + default: + break; + } + + switch(GETSECSPECIAL(sectors[i].special, 3)) + { + case 5: //Speed pad + sectors[i].specialflags |= SSF_SPEEDPAD; + break; + default: + break; + } + + switch(GETSECSPECIAL(sectors[i].special, 4)) + { + case 1: //Star post activator + sectors[i].specialflags |= SSF_STARPOSTACTIVATOR; + break; + case 2: //Exit/Special Stage pit/Return flag + sectors[i].specialflags |= SSF_EXIT; + break; + case 5: //Fan sector + sectors[i].specialflags |= SSF_FAN; + break; + case 8: //Zoom tube start + sectors[i].specialflags |= SSF_ZOOMTUBESTART; + break; + case 9: //Zoom tube end + sectors[i].specialflags |= SSF_ZOOMTUBEEND; + break; + default: + break; + } + } +} + +static void P_ConvertBinaryThingTypes(void) +{ + size_t i; + mobjtype_t mobjtypeofthing[4096] = {0}; + mobjtype_t mobjtype; + + for (i = 0; i < NUMMOBJTYPES; i++) + { + if (mobjinfo[i].doomednum < 0 || mobjinfo[i].doomednum >= 4096) + continue; + + mobjtypeofthing[mobjinfo[i].doomednum] = (mobjtype_t)i; + } for (i = 0; i < nummapthings; i++) { + mobjtype = mobjtypeofthing[mapthings[i].type]; + if (mobjtype) + { + if (mobjinfo[mobjtype].flags & MF_BOSS) + { + INT32 paramoffset = mapthings[i].extrainfo*LE_PARAMWIDTH; + mapthings[i].args[0] = mapthings[i].extrainfo; + mapthings[i].args[1] = !!(mapthings[i].options & MTF_OBJECTSPECIAL); + mapthings[i].args[2] = LE_BOSSDEAD + paramoffset; + mapthings[i].args[3] = LE_ALLBOSSESDEAD + paramoffset; + mapthings[i].args[4] = LE_PINCHPHASE + paramoffset; + } + if (mobjinfo[mobjtype].flags & MF_PUSHABLE) + { + if ((mapthings[i].options & (MTF_OBJECTSPECIAL|MTF_AMBUSH)) == (MTF_OBJECTSPECIAL|MTF_AMBUSH)) + mapthings[i].args[0] = TMP_CLASSIC; + else if (mapthings[i].options & MTF_OBJECTSPECIAL) + mapthings[i].args[0] = TMP_SLIDE; + else if (mapthings[i].options & MTF_AMBUSH) + mapthings[i].args[0] = TMP_IMMOVABLE; + else + mapthings[i].args[0] = TMP_NORMAL; + } + } + + if (mapthings[i].type >= 1 && mapthings[i].type <= 35) //Player starts + { + mapthings[i].args[0] = !!(mapthings[i].options & MTF_AMBUSH); + continue; + } + else if (mapthings[i].type >= 2200 && mapthings[i].type <= 2217) //Flickies + { + mapthings[i].args[0] = mapthings[i].angle; + if (mapthings[i].options & MTF_EXTRA) + mapthings[i].args[1] |= TMFF_AIMLESS; + if (mapthings[i].options & MTF_OBJECTSPECIAL) + mapthings[i].args[1] |= TMFF_STATIONARY; + if (mapthings[i].options & MTF_AMBUSH) + mapthings[i].args[1] |= TMFF_HOP; + if (mapthings[i].type == 2207) + mapthings[i].args[2] = mapthings[i].extrainfo; + continue; + } + switch (mapthings[i].type) { - case 750: - Tag_FSet(&mapthings[i].tags, mapthings[i].angle); + case 102: //SDURF + case 1805: //Puma + mapthings[i].args[0] = mapthings[i].angle; break; - case 760: - case 761: - Tag_FSet(&mapthings[i].tags, mapthings[i].angle); + case 110: //THZ Turret + mapthings[i].args[0] = LE_TURRET; break; - case 762: + case 111: //Pop-up Turret + mapthings[i].args[0] = mapthings[i].angle; + break; + case 103: //Buzz (Gold) + case 104: //Buzz (Red) + case 105: //Jetty-syn Bomber + case 106: //Jetty-syn Gunner + case 117: //Robo-Hood + case 126: //Crushstacean + case 128: //Bumblebore + case 132: //Cacolantern + case 138: //Banpyura + case 1602: //Pian + mapthings[i].args[0] = !!(mapthings[i].options & MTF_AMBUSH); + break; + case 119: //Egg Guard + if ((mapthings[i].options & (MTF_EXTRA|MTF_OBJECTSPECIAL)) == MTF_OBJECTSPECIAL) + mapthings[i].args[0] = TMGD_LEFT; + else if ((mapthings[i].options & (MTF_EXTRA|MTF_OBJECTSPECIAL)) == MTF_EXTRA) + mapthings[i].args[0] = TMGD_RIGHT; + else + mapthings[i].args[0] = TMGD_BACK; + mapthings[i].args[1] = !!(mapthings[i].options & MTF_AMBUSH); + break; + case 127: //Hive Elemental + mapthings[i].args[0] = mapthings[i].extrainfo; + break; + case 135: //Pterabyte Spawner + mapthings[i].args[0] = mapthings[i].extrainfo + 1; + break; + case 136: //Pyre Fly + mapthings[i].args[0] = !!(mapthings[i].options & MTF_AMBUSH); + break; + case 201: //Egg Slimer + mapthings[i].args[5] = !(mapthings[i].options & MTF_AMBUSH); + break; + case 203: //Egg Colosseum + mapthings[i].args[5] = LE_BOSS4DROP + mapthings[i].extrainfo * LE_PARAMWIDTH; + break; + case 204: //Fang + mapthings[i].args[4] = LE_BOSS4DROP + mapthings[i].extrainfo*LE_PARAMWIDTH; + if (mapthings[i].options & MTF_EXTRA) + mapthings[i].args[5] |= TMF_GRAYSCALE; + if (mapthings[i].options & MTF_AMBUSH) + mapthings[i].args[5] |= TMF_SKIPINTRO; + break; + case 206: //Brak Eggman (Old) + mapthings[i].args[5] = LE_BRAKPLATFORM + mapthings[i].extrainfo*LE_PARAMWIDTH; + break; + case 207: //Metal Sonic (Race) + case 2104: //Amy Cameo + mapthings[i].args[0] = !!(mapthings[i].options & MTF_EXTRA); + break; + case 208: //Metal Sonic (Battle) + mapthings[i].args[5] = !!(mapthings[i].options & MTF_EXTRA); + break; + case 209: //Brak Eggman + mapthings[i].args[5] = LE_BRAKVILEATACK + mapthings[i].extrainfo*LE_PARAMWIDTH; + if (mapthings[i].options & MTF_EXTRA) + mapthings[i].args[6] |= TMB_NODEATHFLING; + if (mapthings[i].options & MTF_AMBUSH) + mapthings[i].args[6] |= TMB_BARRIER; + break; + case 292: //Boss waypoint + mapthings[i].args[0] = mapthings[i].angle; + mapthings[i].args[1] = mapthings[i].options & 7; + break; + case 294: //Fang waypoint + mapthings[i].args[0] = !!(mapthings[i].options & MTF_AMBUSH); + break; + case 300: //Ring + case 301: //Bounce ring + case 302: //Rail ring + case 303: //Infinity ring + case 304: //Automatic ring + case 305: //Explosion ring + case 306: //Scatter ring + case 307: //Grenade ring + case 308: //Red team ring + case 309: //Blue team ring + case 312: //Emerald token + case 320: //Emerald hunt location + case 321: //Match chaos emerald spawn + case 322: //Emblem + case 330: //Bounce ring panel + case 331: //Rail ring panel + case 332: //Automatic ring panel + case 333: //Explosion ring panel + case 334: //Scatter ring panel + case 335: //Grenade ring panel + case 520: //Bomb sphere + case 521: //Spikeball + case 1706: //Blue sphere + case 1800: //Coin + mapthings[i].args[0] = !(mapthings[i].options & MTF_AMBUSH); + break; + case 409: //Extra life monitor + mapthings[i].args[2] = !(mapthings[i].options & (MTF_AMBUSH|MTF_OBJECTSPECIAL)); + break; + case 500: //Air bubble patch + mapthings[i].args[0] = !!(mapthings[i].options & MTF_AMBUSH); + break; + case 502: //Star post + if (mapthings[i].extrainfo) + // Allow thing Parameter to define star post num too! + // For starposts above param 15 (the 16th), add 360 to the angle like before and start parameter from 1 (NOT 0)! + // So the 16th starpost is angle=0 param=15, the 17th would be angle=360 param=1. + // This seems more intuitive for mappers to use, since most SP maps won't have over 16 consecutive star posts. + mapthings[i].args[0] = mapthings[i].extrainfo + (mapthings[i].angle/360) * 15; + else + // Old behavior if Parameter is 0; add 360 to the angle for each consecutive star post. + mapthings[i].args[0] = (mapthings[i].angle/360); + mapthings[i].args[1] = !!(mapthings[i].options & MTF_OBJECTSPECIAL); + break; + case 522: //Wall spike + if (mapthings[i].options & MTF_OBJECTSPECIAL) + { + mapthings[i].args[0] = mobjinfo[MT_WALLSPIKE].speed + mapthings[i].angle/360; + mapthings[i].args[1] = (16 - mapthings[i].extrainfo) * mapthings[i].args[0]/16; + if (mapthings[i].options & MTF_EXTRA) + mapthings[i].args[2] |= TMSF_RETRACTED; + } + if (mapthings[i].options & MTF_AMBUSH) + mapthings[i].args[2] |= TMSF_INTANGIBLE; + break; + case 523: //Spike + if (mapthings[i].options & MTF_OBJECTSPECIAL) + { + mapthings[i].args[0] = mobjinfo[MT_SPIKE].speed + mapthings[i].angle; + mapthings[i].args[1] = (16 - mapthings[i].extrainfo) * mapthings[i].args[0]/16; + if (mapthings[i].options & MTF_EXTRA) + mapthings[i].args[2] |= TMSF_RETRACTED; + } + if (mapthings[i].options & MTF_AMBUSH) + mapthings[i].args[2] |= TMSF_INTANGIBLE; + break; + case 540: //Fan + mapthings[i].args[0] = mapthings[i].angle; + if (mapthings[i].options & MTF_OBJECTSPECIAL) + mapthings[i].args[1] |= TMF_INVISIBLE; + if (mapthings[i].options & MTF_AMBUSH) + mapthings[i].args[1] |= TMF_NODISTANCECHECK; + break; + case 541: //Gas jet + mapthings[i].args[0] = !!(mapthings[i].options & MTF_AMBUSH); + break; + case 543: //Balloon + if (mapthings[i].angle > 0) + P_WriteConstant(((mapthings[i].angle - 1) % (numskincolors - 1)) + 1, &mapthings[i].stringargs[0]); + mapthings[i].args[0] = !!(mapthings[i].options & MTF_AMBUSH); + break; + case 555: //Diagonal yellow spring + case 556: //Diagonal red spring + case 557: //Diagonal blue spring + if (mapthings[i].options & MTF_OBJECTSPECIAL) + mapthings[i].args[0] |= TMDS_NOGRAVITY; + if (mapthings[i].options & MTF_AMBUSH) + mapthings[i].args[0] |= TMDS_ROTATEEXTRA; + break; + case 558: //Horizontal yellow spring + case 559: //Horizontal red spring + case 560: //Horizontal blue spring + mapthings[i].args[0] = !(mapthings[i].options & MTF_AMBUSH); + break; + case 700: //Water ambience A + case 701: //Water ambience B + case 702: //Water ambience C + case 703: //Water ambience D + case 704: //Water ambience E + case 705: //Water ambience F + case 706: //Water ambience G + case 707: //Water ambience H + mapthings[i].args[0] = 35; + P_WriteConstant(sfx_amwtr1 + mapthings[i].type - 700, &mapthings[i].stringargs[0]); + mapthings[i].type = 700; + break; + case 708: //Disco ambience + mapthings[i].args[0] = 512; + P_WriteConstant(sfx_ambint, &mapthings[i].stringargs[0]); + mapthings[i].type = 700; + break; + case 709: //Volcano ambience + mapthings[i].args[0] = 220; + P_WriteConstant(sfx_ambin2, &mapthings[i].stringargs[0]); + mapthings[i].type = 700; + break; + case 710: //Machine ambience + mapthings[i].args[0] = 24; + P_WriteConstant(sfx_ambmac, &mapthings[i].stringargs[0]); + mapthings[i].type = 700; + break; + case 750: //Slope vertex + mapthings[i].args[0] = mapthings[i].extrainfo; + break; + case 753: //Zoom tube waypoint + mapthings[i].args[0] = mapthings[i].angle >> 8; + mapthings[i].args[1] = mapthings[i].angle & 255; + break; + case 754: //Push point + case 755: //Pull point + { + subsector_t *ss = R_PointInSubsector(mapthings[i].x << FRACBITS, mapthings[i].y << FRACBITS); + sector_t *s; + line_t *line; + + if (!ss) + { + CONS_Debug(DBG_GAMELOGIC, "Push/pull point: Placed outside of map bounds!\n"); + break; + } + + s = ss->sector; + line = P_FindPointPushLine(&s->tags); + + if (!line) + { + CONS_Debug(DBG_GAMELOGIC, "Push/pull point: Unable to find line of type 547 tagged to sector %s!\n", sizeu1((size_t)(s - sectors))); + break; + } + + mapthings[i].args[0] = mapthings[i].angle; + mapthings[i].args[1] = P_AproxDistance(line->dx >> FRACBITS, line->dy >> FRACBITS); + if (mapthings[i].type == 755) + mapthings[i].args[1] *= -1; + if (mapthings[i].options & MTF_OBJECTSPECIAL) + mapthings[i].args[2] |= TMPP_NOZFADE; + if (mapthings[i].options & MTF_AMBUSH) + mapthings[i].args[2] |= TMPP_PUSHZ; + if (!(line->flags & ML_NOCLIMB)) + mapthings[i].args[2] |= TMPP_NONEXCLUSIVE; + mapthings[i].type = 754; + break; + } + case 756: //Blast linedef executor + mapthings[i].args[0] = mapthings[i].angle; + break; + case 757: //Fan particle generator + { + INT32 j = Tag_FindLineSpecial(15, mapthings[i].angle); + + if (j == -1) + { + CONS_Debug(DBG_GAMELOGIC, "Particle generator (mapthing #%d) needs to be tagged to a #15 parameter line (trying to find tag %d).\n", i, mapthings[i].angle); + break; + } + mapthings[i].args[0] = mapthings[i].z; + mapthings[i].args[1] = R_PointToDist2(lines[j].v1->x, lines[j].v1->y, lines[j].v2->x, lines[j].v2->y) >> FRACBITS; + mapthings[i].args[2] = sides[lines[j].sidenum[0]].textureoffset >> FRACBITS; + mapthings[i].args[3] = sides[lines[j].sidenum[0]].rowoffset >> FRACBITS; + mapthings[i].args[4] = lines[j].backsector ? sides[lines[j].sidenum[1]].textureoffset >> FRACBITS : 0; + mapthings[i].args[6] = mapthings[i].angle; + if (sides[lines[j].sidenum[0]].toptexture) + P_WriteConstant(sides[lines[j].sidenum[0]].toptexture, &mapthings[i].stringargs[0]); + break; + } + case 762: //PolyObject spawn point (crush) { INT32 check = -1; INT32 firstline = -1; - mtag_t tag = mapthings[i].angle; - - Tag_FSet(&mapthings[i].tags, tag); + mtag_t tag = Tag_FGet(&mapthings[i].tags); TAG_ITER_LINES(tag, check) { @@ -3358,8 +6137,201 @@ static void P_ConvertBinaryMap(void) mapthings[i].type = 761; break; } - case 780: - Tag_FSet(&mapthings[i].tags, mapthings[i].extrainfo); + case 780: //Skybox + mapthings[i].args[0] = !!(mapthings[i].options & MTF_OBJECTSPECIAL); + break; + case 799: //Tutorial plant + mapthings[i].args[0] = mapthings[i].extrainfo; + break; + case 1002: //Dripping water + mapthings[i].args[0] = mapthings[i].angle; + break; + case 1007: //Kelp + case 1008: //Stalagmite (DSZ1) + case 1011: //Stalagmite (DSZ2) + mapthings[i].args[0] = !!(mapthings[i].options & MTF_OBJECTSPECIAL); + break; + case 1102: //Eggman Statue + mapthings[i].args[1] = !!(mapthings[i].options & MTF_EXTRA); + break; + case 1104: //Mace spawnpoint + case 1105: //Chain with maces spawnpoint + case 1106: //Chained spring spawnpoint + case 1107: //Chain spawnpoint + case 1109: //Firebar spawnpoint + case 1110: //Custom mace spawnpoint + { + mtag_t tag = (mtag_t)mapthings[i].angle; + INT32 j = Tag_FindLineSpecial(9, tag); + + if (j == -1) + { + CONS_Debug(DBG_GAMELOGIC, "Chain/mace setup: Unable to find parameter line 9 (tag %d)!\n", tag); + break; + } + + mapthings[i].angle = lines[j].frontsector->ceilingheight >> FRACBITS; + mapthings[i].pitch = lines[j].frontsector->floorheight >> FRACBITS; + mapthings[i].args[0] = lines[j].dx >> FRACBITS; + mapthings[i].args[1] = mapthings[i].extrainfo; + mapthings[i].args[3] = lines[j].dy >> FRACBITS; + mapthings[i].args[4] = sides[lines[j].sidenum[0]].textureoffset >> FRACBITS; + mapthings[i].args[7] = -sides[lines[j].sidenum[0]].rowoffset >> FRACBITS; + if (lines[j].backsector) + { + mapthings[i].roll = lines[j].backsector->ceilingheight >> FRACBITS; + mapthings[i].args[2] = sides[lines[j].sidenum[1]].rowoffset >> FRACBITS; + mapthings[i].args[5] = lines[j].backsector->floorheight >> FRACBITS; + mapthings[i].args[6] = sides[lines[j].sidenum[1]].textureoffset >> FRACBITS; + } + if (mapthings[i].options & MTF_AMBUSH) + mapthings[i].args[8] |= TMM_DOUBLESIZE; + if (mapthings[i].options & MTF_OBJECTSPECIAL) + mapthings[i].args[8] |= TMM_SILENT; + if (lines[j].flags & ML_NOCLIMB) + mapthings[i].args[8] |= TMM_ALLOWYAWCONTROL; + if (lines[j].flags & ML_SKEWTD) + mapthings[i].args[8] |= TMM_SWING; + if (lines[j].flags & ML_NOSKEW) + mapthings[i].args[8] |= TMM_MACELINKS; + if (lines[j].flags & ML_MIDPEG) + mapthings[i].args[8] |= TMM_CENTERLINK; + if (lines[j].flags & ML_MIDSOLID) + mapthings[i].args[8] |= TMM_CLIP; + if (lines[j].flags & ML_WRAPMIDTEX) + mapthings[i].args[8] |= TMM_ALWAYSTHINK; + if (mapthings[i].type == 1110) + { + P_WriteConstant(sides[lines[j].sidenum[0]].toptexture, &mapthings[i].stringargs[0]); + P_WriteConstant(lines[j].backsector ? sides[lines[j].sidenum[1]].toptexture : MT_NULL, &mapthings[i].stringargs[1]); + } + break; + } + case 1101: //Torch + case 1119: //Candle + case 1120: //Candle pricket + mapthings[i].args[0] = !!(mapthings[i].options & MTF_EXTRA); + break; + case 1121: //Flame holder + if (mapthings[i].options & MTF_OBJECTSPECIAL) + mapthings[i].args[0] |= TMFH_NOFLAME; + if (mapthings[i].options & MTF_EXTRA) + mapthings[i].args[0] |= TMFH_CORONA; + break; + case 1127: //Spectator EggRobo + if (mapthings[i].options & MTF_AMBUSH) + mapthings[i].args[0] = TMED_LEFT; + else if (mapthings[i].options & MTF_OBJECTSPECIAL) + mapthings[i].args[0] = TMED_RIGHT; + else + mapthings[i].args[0] = TMED_NONE; + break; + case 1200: //Tumbleweed (Big) + case 1201: //Tumbleweed (Small) + mapthings[i].args[0] = !!(mapthings[i].options & MTF_AMBUSH); + break; + case 1202: //Rock spawner + { + mtag_t tag = (mtag_t)mapthings[i].angle; + INT32 j = Tag_FindLineSpecial(12, tag); + + if (j == -1) + { + CONS_Debug(DBG_GAMELOGIC, "Rock spawner: Unable to find parameter line 12 (tag %d)!\n", tag); + break; + } + mapthings[i].angle = AngleFixed(R_PointToAngle2(lines[j].v2->x, lines[j].v2->y, lines[j].v1->x, lines[j].v1->y)) >> FRACBITS; + mapthings[i].args[0] = P_AproxDistance(lines[j].dx, lines[j].dy) >> FRACBITS; + mapthings[i].args[1] = sides[lines[j].sidenum[0]].textureoffset >> FRACBITS; + mapthings[i].args[2] = !!(lines[j].flags & ML_NOCLIMB); + P_WriteConstant(MT_ROCKCRUMBLE1 + (sides[lines[j].sidenum[0]].rowoffset >> FRACBITS), &mapthings[i].stringargs[0]); + break; + } + case 1221: //Minecart saloon door + mapthings[i].args[0] = !!(mapthings[i].options & MTF_AMBUSH); + break; + case 1229: //Minecart switch point + mapthings[i].args[0] = !!(mapthings[i].options & MTF_AMBUSH); + break; + case 1300: //Flame jet (horizontal) + case 1301: //Flame jet (vertical) + mapthings[i].args[0] = (mapthings[i].angle >> 13)*TICRATE/2; + mapthings[i].args[1] = ((mapthings[i].angle >> 10) & 7)*TICRATE/2; + mapthings[i].args[2] = 80 - 5*mapthings[i].extrainfo; + mapthings[i].args[3] = !!(mapthings[i].options & MTF_AMBUSH); + break; + case 1304: //Lavafall + mapthings[i].args[0] = mapthings[i].angle; + mapthings[i].args[1] = !!(mapthings[i].options & MTF_AMBUSH); + break; + case 1305: //Rollout Rock + mapthings[i].args[0] = !!(mapthings[i].options & MTF_AMBUSH); + break; + case 1500: //Glaregoyle + case 1501: //Glaregoyle (Up) + case 1502: //Glaregoyle (Down) + case 1503: //Glaregoyle (Long) + if (mapthings[i].angle >= 360) + mapthings[i].args[1] = 7*(mapthings[i].angle/360) + 1; + break; + case 1700: //Axis + mapthings[i].args[2] = mapthings[i].angle & 16383; + mapthings[i].args[3] = !!(mapthings[i].angle & 16384); + /* FALLTHRU */ + case 1701: //Axis transfer + case 1702: //Axis transfer line + mapthings[i].args[0] = mapthings[i].extrainfo; + mapthings[i].args[1] = mapthings[i].options; + break; + case 1703: //Ideya drone + mapthings[i].args[0] = mapthings[i].angle & 0xFFF; + mapthings[i].args[1] = mapthings[i].extrainfo*32; + mapthings[i].args[2] = ((mapthings[i].angle & 0xF000) >> 12)*32; + if ((mapthings[i].options & (MTF_OBJECTSPECIAL|MTF_EXTRA)) == (MTF_OBJECTSPECIAL|MTF_EXTRA)) + mapthings[i].args[3] = TMDA_BOTTOM; + else if ((mapthings[i].options & (MTF_OBJECTSPECIAL|MTF_EXTRA)) == MTF_OBJECTSPECIAL) + mapthings[i].args[3] = TMDA_TOP; + else if ((mapthings[i].options & (MTF_OBJECTSPECIAL|MTF_EXTRA)) == MTF_EXTRA) + mapthings[i].args[3] = TMDA_MIDDLE; + else + mapthings[i].args[3] = TMDA_BOTTOMOFFSET; + mapthings[i].args[4] = !!(mapthings[i].options & MTF_AMBUSH); + break; + case 1704: //NiGHTS bumper + mapthings[i].pitch = 30 * (((mapthings[i].options & 15) + 9) % 12); + mapthings[i].options &= ~0xF; + break; + case 1705: //Hoop + case 1713: //Hoop (Customizable) + { + UINT16 oldangle = mapthings[i].angle; + mapthings[i].angle = ((oldangle >> 8)*360)/256; + mapthings[i].pitch = ((oldangle & 255)*360)/256; + mapthings[i].args[0] = (mapthings[i].type == 1705) ? 96 : (mapthings[i].options & 0xF)*16 + 32; + mapthings[i].options &= ~0xF; + mapthings[i].type = 1713; + break; + } + case 1710: //Ideya capture + mapthings[i].args[0] = mapthings[i].extrainfo; + mapthings[i].args[1] = mapthings[i].angle; + break; + case 1714: //Ideya anchor point + mapthings[i].args[0] = mapthings[i].extrainfo; + break; + case 1806: //King Bowser + mapthings[i].args[0] = LE_KOOPA; + break; + case 1807: //Axe + mapthings[i].args[0] = LE_AXE; + break; + case 2000: //Smashing spikeball + mapthings[i].args[0] = mapthings[i].angle; + break; + case 2006: //Jack-o'-lantern 1 + case 2007: //Jack-o'-lantern 2 + case 2008: //Jack-o'-lantern 3 + mapthings[i].args[0] = !!(mapthings[i].options & MTF_EXTRA); break; case 2001: // MT_WAYPOINT { @@ -3396,6 +6368,52 @@ static void P_ConvertBinaryMap(void) } } +static void P_ConvertBinaryLinedefFlags(void) +{ + size_t i; + + for (i = 0; i < numlines; i++) + { + if (!!(lines[i].flags & ML_DONTPEGBOTTOM) ^ !!(lines[i].flags & ML_MIDPEG)) + lines[i].flags |= ML_MIDPEG; + else + lines[i].flags &= ~ML_MIDPEG; + + if (lines[i].special >= 100 && lines[i].special < 300) + { + if (lines[i].flags & ML_DONTPEGTOP) + lines[i].flags |= ML_SKEWTD; + else + lines[i].flags &= ~ML_SKEWTD; + + if ((lines[i].flags & ML_TFERLINE) && lines[i].frontsector) + { + size_t j; + + for (j = 0; j < lines[i].frontsector->linecount; j++) + { + if (lines[i].frontsector->lines[j]->flags & ML_DONTPEGTOP) + lines[i].frontsector->lines[j]->flags |= ML_SKEWTD; + else + lines[i].frontsector->lines[j]->flags &= ~ML_SKEWTD; + } + } + } + + } +} + +//For maps in binary format, converts setup of specials to UDMF format. +static void P_ConvertBinaryMap(void) +{ + P_ConvertBinaryLinedefTypes(); + P_ConvertBinarySectorTypes(); + P_ConvertBinaryThingTypes(); + P_ConvertBinaryLinedefFlags(); + if (M_CheckParm("-writetextmap")) + P_WriteTextmap(); +} + /** Compute MD5 message digest for bytes read from memory source * * The resulting message digest number will be written into the 16 bytes diff --git a/src/p_setup.h b/src/p_setup.h index 3db26a7ba..6b4c34885 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -113,7 +113,7 @@ UINT8 P_InitMapData(INT32 numexistingmapheaders); boolean P_RunSOC(const char *socfilename); void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 num); void P_LoadMusicsRange(UINT16 wadnum, UINT16 first, UINT16 num); -void P_WriteThings(void); +//void P_WriteThings(void); void P_UpdateSegLightOffset(seg_t *li); boolean P_ApplyLightOffset(UINT8 baselightnum); boolean P_ApplyLightOffsetFine(UINT8 baselightlevel); diff --git a/src/p_sight.c b/src/p_sight.c index 10d670ede..aee5798c3 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -752,7 +752,7 @@ static boolean P_CrossBotTraversalSubsector(size_t num, register traceblocking_t tmx = tb->compareThing->x; tmy = tb->compareThing->y; P_LineOpening(line, tb->compareThing); - maxstep = P_GetThingStepUp(tb->compareThing); + maxstep = P_GetThingStepUp(tb->compareThing, tmx, tmy); if ((openrange < tb->compareThing->height) // doesn't fit || (opentop - tb->compareThing->z < tb->compareThing->height) // mobj is too high diff --git a/src/p_slopes.c b/src/p_slopes.c index 1347a8759..5b4ead3e3 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -230,7 +230,7 @@ static void ReconfigureViaConstants (pslope_t *slope, const fixed_t a, const fix } /// Recalculate dynamic slopes. -void T_DynamicSlopeLine (dynplanethink_t* th) +void T_DynamicSlopeLine (dynlineplanethink_t* th) { pslope_t* slope = th->slope; line_t* srcline = th->sourceline; @@ -270,50 +270,59 @@ void T_DynamicSlopeLine (dynplanethink_t* th) } /// Mapthing-defined -void T_DynamicSlopeVert (dynplanethink_t* th) +void T_DynamicSlopeVert (dynvertexplanethink_t* th) { - pslope_t* slope = th->slope; - size_t i; - INT32 l; - for (i = 0; i < 3; i++) { - l = Tag_FindLineSpecial(799, th->tags[i]); - if (l != -1) { - th->vex[i].z = lines[l].frontsector->floorheight; - } + for (i = 0; i < 3; i++) + { + if (th->relative & (1 << i)) + th->vex[i].z = th->origvecheights[i] + (th->secs[i]->floorheight - th->origsecheights[i]); else - th->vex[i].z = 0; + th->vex[i].z = th->secs[i]->floorheight; } - P_ReconfigureViaVertexes(slope, th->vex[0], th->vex[1], th->vex[2]); + P_ReconfigureViaVertexes(th->slope, th->vex[0], th->vex[1], th->vex[2]); } -static inline void P_AddDynSlopeThinker (pslope_t* slope, dynplanetype_t type, line_t* sourceline, fixed_t extent, const INT16 tags[3], const vector3_t vx[3]) +static inline void P_AddDynLineSlopeThinker (pslope_t* slope, dynplanetype_t type, line_t* sourceline, fixed_t extent) { - dynplanethink_t* th = Z_Calloc(sizeof (*th), PU_LEVSPEC, NULL); - switch (type) - { - case DP_VERTEX: - th->thinker.function.acp1 = (actionf_p1)T_DynamicSlopeVert; - memcpy(th->tags, tags, sizeof(th->tags)); - memcpy(th->vex, vx, sizeof(th->vex)); - break; - default: - th->thinker.function.acp1 = (actionf_p1)T_DynamicSlopeLine; - th->sourceline = sourceline; - th->extent = extent; - } - + dynlineplanethink_t* th = Z_Calloc(sizeof (*th), PU_LEVSPEC, NULL); + th->thinker.function.acp1 = (actionf_p1)T_DynamicSlopeLine; th->slope = slope; th->type = type; - + th->sourceline = sourceline; + th->extent = extent; P_AddThinker(THINK_DYNSLOPE, &th->thinker); // interpolation R_CreateInterpolator_DynSlope(&th->thinker, slope); } +static inline void P_AddDynVertexSlopeThinker (pslope_t* slope, const INT16 tags[3], const vector3_t vx[3]) +{ + dynvertexplanethink_t* th = Z_Calloc(sizeof (*th), PU_LEVSPEC, NULL); + size_t i; + INT32 l; + th->thinker.function.acp1 = (actionf_p1)T_DynamicSlopeVert; + th->slope = slope; + + for (i = 0; i < 3; i++) { + l = Tag_FindLineSpecial(799, tags[i]); + if (l == -1) + { + Z_Free(th); + return; + } + th->secs[i] = lines[l].frontsector; + th->vex[i] = vx[i]; + th->origsecheights[i] = lines[l].frontsector->floorheight; + th->origvecheights[i] = vx[i].z; + if (lines[l].args[0]) + th->relative |= 1<thinker); +} /// Create a new slope and add it to the slope list. static inline pslope_t* Slope_Add (const UINT8 flags) @@ -380,6 +389,27 @@ static fixed_t GetExtent(sector_t *sector, line_t *line) return fardist; } +static boolean P_CopySlope(pslope_t** toslope, pslope_t* fromslope) +{ + if (*toslope || !fromslope) + return true; + + *toslope = fromslope; + return true; +} + +static void P_UpdateHasSlope(sector_t *sec) +{ + size_t i; + + sec->hasslope = true; + + // if this is an FOF control sector, make sure any target sectors also are marked as having slopes + if (sec->numattached) + for (i = 0; i < sec->numattached; i++) + sectors[sec->attached[i]].hasslope = true; +} + /// Creates one or more slopes based on the given line type and front/back sectors. static void line_SpawnViaLine(const int linenum, const boolean spawnthinker) { @@ -472,7 +502,7 @@ static void line_SpawnViaLine(const int linenum, const boolean spawnthinker) P_CalculateSlopeNormal(fslope); if (spawnthinker && (flags & SL_DYNAMIC)) - P_AddDynSlopeThinker(fslope, DP_FRONTFLOOR, line, extent, NULL, NULL); + P_AddDynLineSlopeThinker(fslope, DP_FRONTFLOOR, line, extent); } if(frontceil) { @@ -491,7 +521,7 @@ static void line_SpawnViaLine(const int linenum, const boolean spawnthinker) P_CalculateSlopeNormal(cslope); if (spawnthinker && (flags & SL_DYNAMIC)) - P_AddDynSlopeThinker(cslope, DP_FRONTCEIL, line, extent, NULL, NULL); + P_AddDynLineSlopeThinker(cslope, DP_FRONTCEIL, line, extent); } } if(backfloor || backceil) @@ -533,7 +563,7 @@ static void line_SpawnViaLine(const int linenum, const boolean spawnthinker) P_CalculateSlopeNormal(fslope); if (spawnthinker && (flags & SL_DYNAMIC)) - P_AddDynSlopeThinker(fslope, DP_BACKFLOOR, line, extent, NULL, NULL); + P_AddDynLineSlopeThinker(fslope, DP_BACKFLOOR, line, extent); } if(backceil) { @@ -552,9 +582,26 @@ static void line_SpawnViaLine(const int linenum, const boolean spawnthinker) P_CalculateSlopeNormal(cslope); if (spawnthinker && (flags & SL_DYNAMIC)) - P_AddDynSlopeThinker(cslope, DP_BACKCEIL, line, extent, NULL, NULL); + P_AddDynLineSlopeThinker(cslope, DP_BACKCEIL, line, extent); } } + + if (line->args[2] & TMSL_COPY) + { + if (frontfloor) + P_CopySlope(&line->backsector->f_slope, line->frontsector->f_slope); + if (backfloor) + P_CopySlope(&line->frontsector->f_slope, line->backsector->f_slope); + if (frontceil) + P_CopySlope(&line->backsector->c_slope, line->frontsector->c_slope); + if (backceil) + P_CopySlope(&line->frontsector->c_slope, line->backsector->c_slope); + + if (backfloor || backceil) + P_UpdateHasSlope(line->frontsector); + if (frontfloor || frontceil) + P_UpdateHasSlope(line->backsector); + } } /// Creates a new slope from three mapthings with the specified IDs @@ -589,14 +636,14 @@ static pslope_t *MakeViaMapthings(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flag vx[i].x = mt->x << FRACBITS; vx[i].y = mt->y << FRACBITS; vx[i].z = mt->z << FRACBITS; - if (!mt->extrainfo) + if (!mt->args[0]) vx[i].z += R_PointInSubsector(vx[i].x, vx[i].y)->sector->floorheight; } P_ReconfigureViaVertexes(ret, vx[0], vx[1], vx[2]); if (spawnthinker && (flags & SL_DYNAMIC)) - P_AddDynSlopeThinker(ret, DP_VERTEX, NULL, 0, tags, vx); + P_AddDynVertexSlopeThinker(ret, tags, vx); return ret; } @@ -712,27 +759,6 @@ static boolean P_SetSlopeFromTag(sector_t *sec, INT32 tag, boolean ceiling) return false; } -static boolean P_CopySlope(pslope_t **toslope, pslope_t *fromslope) -{ - if (*toslope || !fromslope) - return true; - - *toslope = fromslope; - return true; -} - -static void P_UpdateHasSlope(sector_t *sec) -{ - size_t i; - - sec->hasslope = true; - - // if this is an FOF control sector, make sure any target sectors also are marked as having slopes - if (sec->numattached) - for (i = 0; i < sec->numattached; i++) - sectors[sec->attached[i]].hasslope = true; -} - // // P_CopySectorSlope // diff --git a/src/p_slopes.h b/src/p_slopes.h index 5eb4f83bb..12d10e020 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -44,7 +44,8 @@ typedef enum typedef enum { TMSL_NOPHYSICS = 1, - TMSL_DYNAMIC = 2, + TMSL_DYNAMIC = 1<<1, + TMSL_COPY = 1<<2, } textmapslopeflags_t; void P_LinkSlopeThinkers (void); @@ -99,26 +100,29 @@ typedef enum { DP_FRONTCEIL, DP_BACKFLOOR, DP_BACKCEIL, - DP_VERTEX } dynplanetype_t; /// Permit slopes to be dynamically altered through a thinker. typedef struct { thinker_t thinker; - - pslope_t* slope; + pslope_t *slope; dynplanetype_t type; - - // Used by line slopes. - line_t* sourceline; + line_t *sourceline; fixed_t extent; +} dynlineplanethink_t; - // Used by mapthing vertex slopes. - INT16 tags[3]; +typedef struct +{ + thinker_t thinker; + pslope_t *slope; + sector_t *secs[3]; vector3_t vex[3]; -} dynplanethink_t; + fixed_t origsecheights[3]; + fixed_t origvecheights[3]; + UINT8 relative; +} dynvertexplanethink_t; -void T_DynamicSlopeLine (dynplanethink_t* th); -void T_DynamicSlopeVert (dynplanethink_t* th); +void T_DynamicSlopeLine (dynlineplanethink_t* th); +void T_DynamicSlopeVert (dynvertexplanethink_t* th); #endif // #ifndef P_SLOPES_H__ diff --git a/src/p_spec.c b/src/p_spec.c index d0ae292a0..5e2eb4bc0 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -15,6 +15,7 @@ /// utility functions, etc. /// Line Tag handling. Line and Sector triggers. +#include "dehacked.h" #include "doomdef.h" #include "g_game.h" #include "p_local.h" @@ -56,12 +57,6 @@ mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs -// Amount (dx, dy) vector linedef is shifted right to get scroll amount -#define SCROLL_SHIFT 5 - -// 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<tags); // polyobject id + pdd.polyObjNum = line->args[0]; // polyobject id switch(line->special) { case 480: // Polyobj_DoorSlide pdd.doorType = POLY_DOOR_SLIDE; - pdd.speed = sides[line->sidenum[0]].textureoffset / 8; + pdd.speed = line->args[1] << (FRACBITS - 3); pdd.angle = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y); // angle of motion - pdd.distance = sides[line->sidenum[0]].rowoffset; - - if (line->sidenum[1] != 0xffff) - pdd.delay = sides[line->sidenum[1]].textureoffset >> FRACBITS; // delay in tics - else - pdd.delay = 0; + pdd.distance = line->args[2] << FRACBITS; + pdd.delay = line->args[3]; // delay in tics break; case 481: // Polyobj_DoorSwing pdd.doorType = POLY_DOOR_SWING; - pdd.speed = sides[line->sidenum[0]].textureoffset >> FRACBITS; // angular speed - pdd.distance = sides[line->sidenum[0]].rowoffset >> FRACBITS; // angular distance - - if (line->sidenum[1] != 0xffff) - pdd.delay = sides[line->sidenum[1]].textureoffset >> FRACBITS; // delay in tics - else - pdd.delay = 0; + pdd.speed = line->args[1]; // angular speed + pdd.distance = line->args[2]; // angular distance + pdd.delay = line->args[3]; // delay in tics break; default: return 0; // ??? @@ -1050,31 +1037,29 @@ static boolean PolyDoor(line_t *line) return EV_DoPolyDoor(&pdd); } -// Parses arguments for parameterized polyobject move specials +// Parses arguments for parameterized polyobject move special static boolean PolyMove(line_t *line) { polymovedata_t pmd; - pmd.polyObjNum = Tag_FGet(&line->tags); - pmd.speed = sides[line->sidenum[0]].textureoffset / 8; + pmd.polyObjNum = line->args[0]; + pmd.speed = line->args[1] << (FRACBITS - 3); pmd.angle = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y); - pmd.distance = sides[line->sidenum[0]].rowoffset; + pmd.distance = line->args[2] << FRACBITS; - pmd.overRide = (line->special == 483); // Polyobj_OR_Move + pmd.overRide = !!line->args[3]; // Polyobj_OR_Move return EV_DoPolyObjMove(&pmd); } -// Makes a polyobject invisible and intangible -// If NOCLIMB is ticked, the polyobject will still be tangible, just not visible. -static void PolyInvisible(line_t *line) +static void PolySetVisibilityTangibility(line_t *line) { - INT32 polyObjNum = Tag_FGet(&line->tags); - polyobj_t *po; + INT32 polyObjNum = line->args[0]; + polyobj_t* po; if (!(po = Polyobj_GetForNum(polyObjNum))) { - CONS_Debug(DBG_POLYOBJ, "PolyInvisible: bad polyobj %d\n", polyObjNum); + CONS_Debug(DBG_POLYOBJ, "PolySetVisibilityTangibility: bad polyobj %d\n", polyObjNum); return; } @@ -1082,49 +1067,32 @@ static void PolyInvisible(line_t *line) if (po->isBad) return; - if (!(line->flags & ML_NOCLIMB)) - po->flags &= ~POF_SOLID; - - po->flags |= POF_NOSPECIALS; - po->flags &= ~POF_RENDERALL; -} - -// Makes a polyobject visible and tangible -// If NOCLIMB is ticked, the polyobject will not be tangible, just visible. -static void PolyVisible(line_t *line) -{ - INT32 polyObjNum = Tag_FGet(&line->tags); - polyobj_t *po; - - if (!(po = Polyobj_GetForNum(polyObjNum))) + if (line->args[1] == TMPV_VISIBLE) { - CONS_Debug(DBG_POLYOBJ, "PolyVisible: bad polyobj %d\n", polyObjNum); - return; + po->flags &= ~POF_NOSPECIALS; + po->flags |= (po->spawnflags & POF_RENDERALL); + } + else if (line->args[1] == TMPV_INVISIBLE) + { + po->flags |= POF_NOSPECIALS; + po->flags &= ~POF_RENDERALL; } - // don't allow line actions to affect bad polyobjects - if (po->isBad) - return; - - if (!(line->flags & ML_NOCLIMB)) + if (line->args[2] == TMPT_TANGIBLE) po->flags |= POF_SOLID; - - po->flags &= ~POF_NOSPECIALS; - po->flags |= (po->spawnflags & POF_RENDERALL); + else if (line->args[2] == TMPT_INTANGIBLE) + po->flags &= ~POF_SOLID; } - // Sets the translucency of a polyobject -// Frontsector floor / 100 = translevel static void PolyTranslucency(line_t *line) { - INT32 polyObjNum = Tag_FGet(&line->tags); + INT32 polyObjNum = line->args[0]; polyobj_t *po; - INT32 value; if (!(po = Polyobj_GetForNum(polyObjNum))) { - CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjWaypoint: bad polyobj %d\n", polyObjNum); + CONS_Debug(DBG_POLYOBJ, "PolyTranslucency: bad polyobj %d\n", polyObjNum); return; } @@ -1132,17 +1100,10 @@ static void PolyTranslucency(line_t *line) if (po->isBad) return; - // If Front X Offset is specified, use that. Else, use floorheight. - value = (sides[line->sidenum[0]].textureoffset ? sides[line->sidenum[0]].textureoffset : line->frontsector->floorheight) >> FRACBITS; - - // If DONTPEGBOTTOM, specify raw translucency value. Else, take it out of 1000. - if (!(line->flags & ML_DONTPEGBOTTOM)) - value /= 100; - - if (line->flags & ML_EFFECT3) // relative calc - po->translucency += value; + if (lines->args[2]) // relative calc + po->translucency += line->args[1]; else - po->translucency = value; + po->translucency = line->args[1]; po->translucency = max(min(po->translucency, NUMTRANSMAPS), 0); } @@ -1150,10 +1111,9 @@ static void PolyTranslucency(line_t *line) // Makes a polyobject translucency fade and applies tangibility static boolean PolyFade(line_t *line) { - INT32 polyObjNum = Tag_FGet(&line->tags); + INT32 polyObjNum = line->args[0]; polyobj_t *po; polyfadedata_t pfd; - INT32 value; if (!(po = Polyobj_GetForNum(polyObjNum))) { @@ -1166,7 +1126,7 @@ static boolean PolyFade(line_t *line) return 0; // Prevent continuous execs from interfering on an existing fade - if (!(line->flags & ML_EFFECT5) + if (!(line->args[3] & TMPF_OVERRIDE) && po->thinker && po->thinker->function.acp1 == (actionf_p1)T_PolyObjFade) { @@ -1176,17 +1136,10 @@ static boolean PolyFade(line_t *line) pfd.polyObjNum = polyObjNum; - // If Front X Offset is specified, use that. Else, use floorheight. - value = (sides[line->sidenum[0]].textureoffset ? sides[line->sidenum[0]].textureoffset : line->frontsector->floorheight) >> FRACBITS; - - // If DONTPEGBOTTOM, specify raw translucency value. Else, take it out of 1000. - if (!(line->flags & ML_DONTPEGBOTTOM)) - value /= 100; - - if (line->flags & ML_EFFECT3) // relative calc - pfd.destvalue = po->translucency + value; + if (line->args[3] & TMPF_RELATIVE) // relative calc + pfd.destvalue = po->translucency + line->args[1]; else - pfd.destvalue = value; + pfd.destvalue = line->args[1]; pfd.destvalue = max(min(pfd.destvalue, NUMTRANSMAPS), 0); @@ -1194,15 +1147,11 @@ static boolean PolyFade(line_t *line) if (po->translucency == pfd.destvalue) return 1; - pfd.docollision = !(line->flags & ML_NOTBOUNCY); // do not handle collision flags - pfd.doghostfade = (line->flags & ML_EFFECT1); // do ghost fade (no collision flags during fade) - pfd.ticbased = (line->flags & ML_EFFECT4); // Speed = Tic Duration - - // allow Back Y Offset to be consistent with other fade specials - pfd.speed = (line->sidenum[1] != 0xFFFF && !sides[line->sidenum[0]].rowoffset) ? - abs(sides[line->sidenum[1]].rowoffset>>FRACBITS) - : abs(sides[line->sidenum[0]].rowoffset>>FRACBITS); + pfd.docollision = !(line->args[3] & TMPF_IGNORECOLLISION); // do not handle collision flags + pfd.doghostfade = (line->args[3] & TMPF_GHOSTFADE); // do ghost fade (no collision flags during fade) + pfd.ticbased = (line->args[3] & TMPF_TICBASED); // Speed = Tic Duration + pfd.speed = line->args[2]; return EV_DoPolyObjFade(&pfd); } @@ -1212,49 +1161,25 @@ static boolean PolyWaypoint(line_t *line) { polywaypointdata_t pwd; - pwd.polyObjNum = Tag_FGet(&line->tags); - pwd.speed = sides[line->sidenum[0]].textureoffset / 8; - pwd.sequence = sides[line->sidenum[0]].rowoffset >> FRACBITS; // Sequence # - - // Behavior after reaching the last waypoint? - if (line->flags & ML_EFFECT3) - pwd.returnbehavior = PWR_WRAP; // Wrap back to first waypoint - else if (line->flags & ML_EFFECT2) - pwd.returnbehavior = PWR_COMEBACK; // Go through sequence in reverse - else - pwd.returnbehavior = PWR_STOP; // Stop - - // Flags - pwd.flags = 0; - if (line->flags & ML_EFFECT1) - pwd.flags |= PWF_REVERSE; - if (line->flags & ML_EFFECT4) - pwd.flags |= PWF_LOOP; + pwd.polyObjNum = line->args[0]; + pwd.speed = line->args[1] << (FRACBITS - 3); + pwd.sequence = line->args[2]; + pwd.returnbehavior = line->args[3]; + pwd.flags = line->args[4]; return EV_DoPolyObjWaypoint(&pwd); } -// Parses arguments for parameterized polyobject rotate specials +// Parses arguments for parameterized polyobject rotate special static boolean PolyRotate(line_t *line) { polyrotdata_t prd; - prd.polyObjNum = Tag_FGet(&line->tags); - prd.speed = sides[line->sidenum[0]].textureoffset >> FRACBITS; // angular speed - prd.distance = sides[line->sidenum[0]].rowoffset >> FRACBITS; // angular distance - - // Polyobj_(OR_)RotateRight have dir == -1 - prd.direction = (line->special == 484 || line->special == 485) ? -1 : 1; - - // Polyobj_OR types have override set to true - prd.overRide = (line->special == 485 || line->special == 487); - - if (line->flags & ML_NOCLIMB) - prd.turnobjs = 0; - else if (line->flags & ML_EFFECT4) - prd.turnobjs = 2; - else - prd.turnobjs = 1; + prd.polyObjNum = line->args[0]; + prd.speed = line->args[1]; // angular speed + prd.distance = abs(line->args[2]); // angular distance + prd.direction = (line->args[2] < 0) ? -1 : 1; + prd.flags = line->args[3]; return EV_DoPolyObjRotate(&prd); } @@ -1264,10 +1189,10 @@ static boolean PolyFlag(line_t *line) { polyflagdata_t pfd; - pfd.polyObjNum = Tag_FGet(&line->tags); - pfd.speed = P_AproxDistance(line->dx, line->dy) >> FRACBITS; - pfd.angle = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y) >> ANGLETOFINESHIFT; - pfd.momx = sides[line->sidenum[0]].textureoffset >> FRACBITS; + pfd.polyObjNum = line->args[0]; + pfd.speed = line->args[1]; + pfd.angle = line->angle >> ANGLETOFINESHIFT; + pfd.momx = line->args[2]; return EV_DoPolyObjFlag(&pfd); } @@ -1276,12 +1201,14 @@ static boolean PolyFlag(line_t *line) static boolean PolyDisplace(line_t *line) { polydisplacedata_t pdd; + fixed_t length = R_PointToDist2(line->v2->x, line->v2->y, line->v1->x, line->v1->y); + fixed_t speed = line->args[1] << FRACBITS; - pdd.polyObjNum = Tag_FGet(&line->tags); + pdd.polyObjNum = line->args[0]; pdd.controlSector = line->frontsector; - pdd.dx = line->dx>>8; - pdd.dy = line->dy>>8; + pdd.dx = FixedMul(FixedDiv(line->dx, length), speed) >> 8; + pdd.dy = FixedMul(FixedDiv(line->dy, length), speed) >> 8; return EV_DoPolyObjDisplace(&pdd); } @@ -1292,27 +1219,20 @@ static boolean PolyRotDisplace(line_t *line) polyrotdisplacedata_t pdd; fixed_t anginter, distinter; - pdd.polyObjNum = Tag_FGet(&line->tags); + pdd.polyObjNum = line->args[0]; pdd.controlSector = line->frontsector; // Rotate 'anginter' interval for each 'distinter' interval from the control sector. - // Use default values if not provided as fallback. - anginter = sides[line->sidenum[0]].rowoffset ? sides[line->sidenum[0]].rowoffset : 90*FRACUNIT; - distinter = sides[line->sidenum[0]].textureoffset ? sides[line->sidenum[0]].textureoffset : 128*FRACUNIT; + anginter = line->args[2] << FRACBITS; + distinter = line->args[1] << FRACBITS; pdd.rotscale = FixedDiv(anginter, distinter); // Same behavior as other rotators when carrying things. - if (line->flags & ML_NOCLIMB) - pdd.turnobjs = 0; - else if (line->flags & ML_EFFECT4) - pdd.turnobjs = 2; - else - pdd.turnobjs = 1; + pdd.turnobjs = line->args[3]; return EV_DoPolyObjRotDisplace(&pdd); } - /** Finds minimum light from an adjacent sector. * * \param sector Sector to start in. @@ -1378,226 +1298,98 @@ static void P_AddExecutorDelay(line_t *line, mobj_t *mobj, sector_t *sector) P_AddThinker(THINK_MAIN, &e->thinker); } -/** Used by P_LinedefExecute to check a trigger linedef's conditions - * The linedef executor specials in the trigger linedef's sector are run if all conditions are met. - * Return false cancels P_LinedefExecute, this happens if a condition is not met. - * - * \param triggerline Trigger linedef to check conditions for; should NEVER be NULL. - * \param actor Object initiating the action; should not be NULL. - * \param caller Sector in which the action was started. May be NULL. - * \sa P_ProcessLineSpecial, P_LinedefExecute - */ -boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller) +static boolean P_CheckPlayerRings(line_t *triggerline, mobj_t *actor) { - sector_t *ctlsector; - fixed_t dist = P_AproxDistance(triggerline->dx, triggerline->dy)>>FRACBITS; - size_t i, linecnt, sectori; - INT16 specialtype = triggerline->special; + INT32 rings = 0; + INT32 targetrings = triggerline->args[1]; + size_t i; - ///////////////////////////////////////////////// - // Distance-checking/sector trigger conditions // - ///////////////////////////////////////////////// - - // Linetypes 303 and 304 require a specific - // number, or minimum or maximum, of rings. - if (specialtype == 303 || specialtype == 304) + // Count all players' rings. + if (triggerline->args[3]) { - fixed_t rings = 0; - - // With the passuse flag, count all player's - // rings. - if (triggerline->flags & ML_EFFECT4) + for (i = 0; i < MAXPLAYERS; i++) { - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - continue; + if (!playeringame[i] || players[i].spectator) + continue; - if (!players[i].mo || players[i].rings <= 0) - continue; + if (!players[i].mo || ((gametyperules & GTR_SPHERES) ? players[i].spheres : players[i].rings) <= 0) + continue; - rings += players[i].rings; - } - } - else - { - if (!(actor && actor->player)) - return false; // no player to count rings from here, sorry - - rings = actor->player->rings; - } - - if (triggerline->flags & ML_NOCLIMB) - { - if (rings > dist) - return false; - } - else if (triggerline->flags & ML_BLOCKPLAYERS) - { - if (rings < dist) - return false; - } - else - { - if (rings != dist) - return false; + rings += (gametyperules & GTR_SPHERES) ? players[i].spheres : players[i].rings; } } - else if (specialtype >= 314 && specialtype <= 315) + else { - msecnode_t *node; - mobj_t *mo; - INT32 numpush = 0; - INT32 numneeded = dist; + if (!(actor && actor->player)) + return false; // no player to count rings from here, sorry - if (!caller) - return false; // we need a calling sector to find pushables in, silly! - - // Count the pushables in this sector - node = caller->touching_thinglist; // things touching this sector - while (node) - { - mo = node->m_thing; - if ((mo->flags & MF_PUSHABLE) || ((mo->info->flags & MF_PUSHABLE) && mo->fuse)) - numpush++; - node = node->m_thinglist_next; - } - - if (triggerline->flags & ML_NOCLIMB) // Need at least or more - { - if (numpush < numneeded) - return false; - } - else if (triggerline->flags & ML_EFFECT4) // Need less than - { - if (numpush >= numneeded) - return false; - } - else // Need exact - { - if (numpush != numneeded) - return false; - } - } - else if (caller) - { - if (GETSECSPECIAL(caller->special, 2) == 6) - { - if (!(ALLCHAOSEMERALDS(emeralds))) - return false; - } - - // If we were not triggered by a sector type especially for the purpose, - // a Linedef Executor linedef trigger is not handling sector triggers properly, return. - - else if ((!GETSECSPECIAL(caller->special, 2) || GETSECSPECIAL(caller->special, 2) > 7) && (specialtype > 322)) - { - CONS_Alert(CONS_WARNING, - M_GetText("Linedef executor trigger isn't handling sector triggers properly!\nspecialtype = %d, if you are not a dev, report this warning instance\nalong with the wad that caused it!\n"), - specialtype); - return false; - } + rings = (gametyperules & GTR_SPHERES) ? actor->player->spheres : actor->player->rings; } - ////////////////////////////////////// - // Miscellaneous trigger conditions // - ////////////////////////////////////// - - switch (specialtype) + switch (triggerline->args[2]) { - case 309: // continuous - case 310: // each time - // Only red team members can activate this. - if (!(actor && actor->player && actor->player->ctfteam == 1)) - return false; - break; - case 311: // continuous - case 312: // each time - // Only blue team members can activate this. - if (!(actor && actor->player && actor->player->ctfteam == 2)) - return false; - break; - case 317: // continuous - case 318: // once - { // Unlockable triggers required - INT32 trigid = (INT32)(sides[triggerline->sidenum[0]].textureoffset>>FRACBITS); - - if ((modifiedgame && !savemoddata) || (netgame || multiplayer)) - return false; - else if (trigid < 0 || trigid > 31) // limited by 32 bit variable - { - CONS_Debug(DBG_GAMELOGIC, "Unlockable trigger (sidedef %hu): bad trigger ID %d\n", triggerline->sidenum[0], trigid); - return false; - } - else if (!(unlocktriggers & (1 << trigid))) - return false; - } - break; - case 319: // continuous - case 320: // once - { // An unlockable itself must be unlocked! - INT32 unlockid = (INT32)(sides[triggerline->sidenum[0]].textureoffset>>FRACBITS); - - if ((modifiedgame && !savemoddata) || (netgame || multiplayer)) - return false; - else if (unlockid < 0 || unlockid >= MAXUNLOCKABLES) // limited by unlockable count - { - CONS_Debug(DBG_GAMELOGIC, "Unlockable check (sidedef %hu): bad unlockable ID %d\n", triggerline->sidenum[0], unlockid); - return false; - } - else if (!(unlockables[unlockid-1].unlocked)) - return false; - } - break; - case 321: // continuous - case 322: // each time - // decrement calls left before triggering - if (triggerline->callcount > 0) - { - if (--triggerline->callcount > 0) - return false; - } - break; - case 331: // continuous - case 332: // each time - case 333: // once - if (!(actor && actor->player && ((stricmp(triggerline->text, skins[actor->player->skin].name) == 0) ^ ((triggerline->flags & ML_NOCLIMB) == ML_NOCLIMB)))) - return false; - break; - case 334: // object dye - continuous - case 335: // object dye - each time - case 336: // object dye - once - { - INT32 triggercolor = (INT32)sides[triggerline->sidenum[0]].toptexture; - UINT16 color = (actor->player ? actor->player->dye : actor->color); - boolean invert = (triggerline->flags & ML_NOCLIMB ? true : false); - - if (invert ^ (triggercolor != color)) - return false; - } + case TMC_EQUAL: default: - break; + return rings == targetrings; + case TMC_GTE: + return rings >= targetrings; + case TMC_LTE: + return rings <= targetrings; + } +} + +static boolean P_CheckPushables(line_t *triggerline, sector_t *caller) +{ + msecnode_t *node; + mobj_t *mo; + INT32 numpushables = 0; + INT32 targetpushables = triggerline->args[1]; + + if (!caller) + return false; // we need a calling sector to find pushables in, silly! + + // Count the pushables in this sector + for (node = caller->touching_thinglist; node; node = node->m_thinglist_next) + { + mo = node->m_thing; + if ((mo->flags & MF_PUSHABLE) || ((mo->info->flags & MF_PUSHABLE) && mo->fuse)) + numpushables++; } - ///////////////////////////////// - // Processing linedef specials // - ///////////////////////////////// + switch (triggerline->args[2]) + { + case TMC_EQUAL: + default: + return numpushables == targetpushables; + case TMC_GTE: + return numpushables >= targetpushables; + case TMC_LTE: + return numpushables <= targetpushables; + } +} - ctlsector = triggerline->frontsector; - sectori = (size_t)(ctlsector - sectors); - linecnt = ctlsector->linecount; +static void P_ActivateLinedefExecutor(line_t *line, mobj_t *actor, sector_t *caller) +{ + if (line->special < 400 || line->special >= 500) + return; - if (triggerline->flags & ML_EFFECT5) // disregard order for efficiency + if (line->executordelay) + P_AddExecutorDelay(line, actor, caller); + else + P_ProcessLineSpecial(line, actor, caller); +} + +static boolean P_ActivateLinedefExecutorsInSector(line_t *triggerline, mobj_t *actor, sector_t *caller) +{ + sector_t *ctlsector = triggerline->frontsector; + size_t sectori = (size_t)(ctlsector - sectors); + size_t linecnt = ctlsector->linecount; + size_t i; + + if (!udmf && triggerline->flags & ML_WRAPMIDTEX) // disregard order for efficiency { for (i = 0; i < linecnt; i++) - if (ctlsector->lines[i]->special >= 400 - && ctlsector->lines[i]->special < 500) - { - if (ctlsector->lines[i]->executordelay) - P_AddExecutorDelay(ctlsector->lines[i], actor, caller); - else - P_ProcessLineSpecial(ctlsector->lines[i], actor, caller); - } + P_ActivateLinedefExecutor(ctlsector->lines[i], actor, caller); } else // walk around the sector in a defined order { @@ -1678,37 +1470,143 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller if (i == masterlineindex) break; - if (ctlsector->lines[i]->special >= 400 - && ctlsector->lines[i]->special < 500) - { - if (ctlsector->lines[i]->executordelay) - P_AddExecutorDelay(ctlsector->lines[i], actor, caller); - else - P_ProcessLineSpecial(ctlsector->lines[i], actor, caller); - } + P_ActivateLinedefExecutor(ctlsector->lines[i], actor, caller); } } - // "Trigger on X calls" linedefs reset if noclimb is set - if ((specialtype == 321 || specialtype == 322) && triggerline->flags & ML_NOCLIMB) - triggerline->callcount = sides[triggerline->sidenum[0]].textureoffset>>FRACBITS; + return true; +} + +/** Used by P_LinedefExecute to check a trigger linedef's conditions + * The linedef executor specials in the trigger linedef's sector are run if all conditions are met. + * Return false cancels P_LinedefExecute, this happens if a condition is not met. + * + * \param triggerline Trigger linedef to check conditions for; should NEVER be NULL. + * \param actor Object initiating the action; should not be NULL. + * \param caller Sector in which the action was started. May be NULL. + * \sa P_ProcessLineSpecial, P_LinedefExecute + */ +boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller) +{ + INT16 specialtype = triggerline->special; + + //////////////////////// + // Trigger conditions // + //////////////////////// + + switch (specialtype) + { + case 303: + if (!P_CheckPlayerRings(triggerline, actor)) + return false; + break; + case 309: + // Only red/blue team members can activate this. + if (!(actor && actor->player)) + return false; + if (actor->player->ctfteam != ((triggerline->args[1] == TMT_RED) ? 1 : 2)) + return false; + break; + case 314: + if (!P_CheckPushables(triggerline, caller)) + return false; + break; + case 317: + { // Unlockable triggers required + INT32 trigid = triggerline->args[1]; + + if ((modifiedgame && !savemoddata) || (netgame || multiplayer)) + return false; + else if (trigid < 0 || trigid > 31) // limited by 32 bit variable + { + CONS_Debug(DBG_GAMELOGIC, "Unlockable trigger (sidedef %hu): bad trigger ID %d\n", triggerline->sidenum[0], trigid); + return false; + } + else if (!(unlocktriggers & (1 << trigid))) + return false; + } + break; + case 319: + { // An unlockable itself must be unlocked! + INT32 unlockid = triggerline->args[1]; + + if ((modifiedgame && !savemoddata) || (netgame || multiplayer)) + return false; + else if (unlockid < 0 || unlockid >= MAXUNLOCKABLES) // limited by unlockable count + { + CONS_Debug(DBG_GAMELOGIC, "Unlockable check (sidedef %hu): bad unlockable ID %d\n", triggerline->sidenum[0], unlockid); + return false; + } + else if (!(unlockables[unlockid-1].unlocked)) + return false; + } + break; + case 321: + // decrement calls left before triggering + if (triggerline->callcount > 0) + { + if (--triggerline->callcount > 0) + return false; + } + break; + case 331: + if (!(actor && actor->player)) + return false; + if (!triggerline->stringargs[0]) + return false; + if (!(stricmp(triggerline->stringargs[0], skins[actor->player->skin].name) == 0) ^ !!(triggerline->args[1])) + return false; + break; + case 334: // object dye + { + INT32 triggercolor = triggerline->stringargs[0] ? get_number(triggerline->stringargs[0]) : SKINCOLOR_NONE; + UINT16 color = (actor->player ? actor->player->dye : actor->color); + + if (!!(triggerline->args[1]) ^ (triggercolor != color)) + return false; + } + break; + default: + break; + } + + ///////////////////////////////// + // Processing linedef specials // + ///////////////////////////////// + + if (!P_ActivateLinedefExecutorsInSector(triggerline, actor, caller)) + return false; + + // "Trigger on X calls" linedefs reset if args[2] is set + if (specialtype == 321 && triggerline->args[2]) + triggerline->callcount = triggerline->args[3]; else - // These special types work only once - if (specialtype == 302 // Once - || specialtype == 304 // Ring count - Once - || specialtype == 307 // Character ability - Once - || specialtype == 308 // Race only - Once - || specialtype == 313 // No More Enemies - Once - || specialtype == 315 // No of pushables - Once - || specialtype == 318 // Unlockable trigger - Once - || specialtype == 320 // Unlockable - Once - || specialtype == 321 || specialtype == 322 // Trigger on X calls - Continuous + Each Time - || specialtype == 333 // Skin - Once - || specialtype == 336 // Dye - Once - || specialtype == 399 // Level Load - || specialtype == 328 // SRB2Kart Encore Load - ) - triggerline->special = 0; // Clear it out + { + // These special types work only once + if (specialtype == 313 // No more enemies + || specialtype == 321 // Trigger on X calls + || specialtype == 399) // Level Load + triggerline->special = 0; + else if ((specialtype == 323 // Nightserize + || specialtype == 325 // DeNightserize + || specialtype == 327 // Nights lap + || specialtype == 329) // Nights bonus time + && triggerline->args[0]) + triggerline->special = 0; + else if ((specialtype == 300 // Basic + || specialtype == 303 // Ring count + || specialtype == 305 // Character ability + || specialtype == 308 // Gametype + || specialtype == 309 // CTF team + || specialtype == 314 // No of pushables + || specialtype == 317 // Unlockable trigger + || specialtype == 319 // Unlockable + || specialtype == 331 // Player skin + || specialtype == 334 // Object dye + || specialtype == 337) // Emerald check + && triggerline->args[0] == TMT_ONCE) + triggerline->special = 0; + } return true; } @@ -1728,42 +1626,144 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller */ void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller) { - size_t masterline; + INT32 masterline; CONS_Debug(DBG_GAMELOGIC, "P_LinedefExecute: Executing trigger linedefs of tag %d\n", tag); I_Assert(!actor || !P_MobjWasRemoved(actor)); // If actor is there, it must be valid. - for (masterline = 0; masterline < numlines; masterline++) + TAG_ITER_LINES(tag, masterline) { - if (Tag_FGet(&lines[masterline].tags) != tag) - continue; - - // "No More Enemies" and "Level Load" take care of themselves. - if (lines[masterline].special == 313 - || lines[masterline].special == 399 - || lines[masterline].special == 328 - || lines[masterline].special == 2002 // SRB2Kart race lap trigger - || lines[masterline].special == 323 - // Each-time executors handle themselves, too - || lines[masterline].special == 301 // Each time - || lines[masterline].special == 306 // Character ability - Each time - || lines[masterline].special == 310 // CTF Red team - Each time - || lines[masterline].special == 312 // CTF Blue team - Each time - || lines[masterline].special == 322 // Trigger on X calls - Each Time - || lines[masterline].special == 332 // Skin - Each time - || lines[masterline].special == 335)// Dye - Each time - continue; - if (lines[masterline].special < 300 || lines[masterline].special > 399) continue; + // "No More Enemies" and "Level Load" take care of themselves. + if (lines[masterline].special == 313 || lines[masterline].special == 399) + continue; + + // Each-time executors handle themselves, too + if ((lines[masterline].special == 300 // Basic + || lines[masterline].special == 303 // Ring count + || lines[masterline].special == 305 // Character ability + || lines[masterline].special == 308 // Gametype + || lines[masterline].special == 309 // CTF team + || lines[masterline].special == 314 // Number of pushables + || lines[masterline].special == 317 // Condition set trigger + || lines[masterline].special == 319 // Unlockable trigger + || lines[masterline].special == 331 // Player skin + || lines[masterline].special == 334 // Object dye + || lines[masterline].special == 337) // Emerald check + && lines[masterline].args[0] > TMT_EACHTIMEMASK) + continue; + + if (lines[masterline].special == 321 && lines[masterline].args[0] > TMXT_EACHTIMEMASK) // Trigger after X calls + continue; + if (!P_RunTriggerLinedef(&lines[masterline], actor, caller)) return; // cancel P_LinedefExecute if function returns false } } +static void P_PlaySFX(INT32 sfxnum, mobj_t *mo, sector_t *callsec, INT16 tag, textmapsoundsource_t source, textmapsoundlistener_t listener) +{ + if (sfxnum == sfx_None) + return; // Do nothing! + + if (sfxnum < sfx_None || sfxnum >= NUMSFX) + { + CONS_Debug(DBG_GAMELOGIC, "Line type 414 Executor: sfx number %d is invalid!\n", sfxnum); + return; + } + + // Check if you can hear the sound + switch (listener) + { + case TMSL_TRIGGERER: // only play sound if displayplayer + if (!mo) + return; + + if (!mo->player) + return; + + if (!P_IsDisplayPlayer(mo->player)) + return; + + break; + case TMSL_TAGGEDSECTOR: // only play if touching tagged sectors + { + UINT8 i = 0; + mobj_t *camobj = players[displayplayers[0]].mo; + ffloor_t *rover; + boolean foundit = false; + + for (i = 0; i <= r_splitscreen; camobj = players[displayplayers[i]].mo, i++) + { + if (!camobj) + continue; + + if (foundit || Tag_Find(&camobj->subsector->sector->tags, tag)) + { + foundit = true; + break; + } + + // Only trigger if mobj is touching the tag + for (rover = camobj->subsector->sector->ffloors; rover; rover = rover->next) + { + if (!Tag_Find(&rover->master->frontsector->tags, tag)) + continue; + + if (camobj->z > P_GetSpecialTopZ(camobj, sectors + rover->secnum, camobj->subsector->sector)) + continue; + + if (camobj->z + camobj->height < P_GetSpecialBottomZ(camobj, sectors + rover->secnum, camobj->subsector->sector)) + continue; + + foundit = true; + break; + } + } + + if (!foundit) + return; + + break; + } + case TMSL_EVERYONE: // no additional check + default: + break; + } + + // Play the sound from the specified source + switch (source) + { + case TMSS_TRIGGERMOBJ: // play the sound from mobj that triggered it + if (mo) + S_StartSound(mo, sfxnum); + break; + case TMSS_TRIGGERSECTOR: // play the sound from calling sector's soundorg + if (callsec) + S_StartSound(&callsec->soundorg, sfxnum); + else if (mo) + S_StartSound(&mo->subsector->sector->soundorg, sfxnum); + break; + case TMSS_NOWHERE: // play the sound from nowhere + S_StartSound(NULL, sfxnum); + break; + case TMSS_TAGGEDSECTOR: // play the sound from tagged sectors' soundorgs + { + INT32 secnum; + + TAG_ITER_SECTORS(tag, secnum) + S_StartSound(§ors[secnum].soundorg, sfxnum); + break; + } + default: + break; + } +} + // // P_SwitchWeather // @@ -1996,7 +1996,7 @@ static void K_HandleLapIncrement(player_t *player) { UINT8 lap; - if (lines[i].flags & ML_EFFECT4) + if (lines[i].flags & ML_MIDSOLID) { lap = player->laps; } @@ -2138,19 +2138,52 @@ static mobj_t *P_GetObjectTypeInSectorNum(mobjtype_t type, size_t s) return NULL; } -static void P_SwitchSkybox(INT32 ldflags, player_t *player, skybox_t *skybox) +static void P_SwitchSkybox(INT32 args, player_t *player, skybox_t *skybox) { - if (!(ldflags & ML_EFFECT4)) // Solid Midtexture turns off viewpoint setting + if (args != TMS_CENTERPOINT) // Only viewpoint, or both. { player->skybox.viewpoint = skybox->viewpoint; } - if (ldflags & ML_BLOCKPLAYERS) // Block Enemies turns ON centerpoint setting + if (args != TMS_VIEWPOINT) // Only centerpoint, or both. { player->skybox.centerpoint = skybox->centerpoint; } } +static mobj_t* P_FindObjectTypeFromTag(mobjtype_t type, mtag_t tag) +{ + if (udmf) + { + INT32 mtnum; + mobj_t *mo; + + TAG_ITER_THINGS(tag, mtnum) + { + mo = mapthings[mtnum].mobj; + + if (!mo) + continue; + + if (mo->type != type) + continue; + + return mo; + } + + return NULL; + } + else + { + INT32 secnum; + + if ((secnum = Tag_Iterate_Sectors(tag, 0)) < 0) + return NULL; + + return P_GetObjectTypeInSectorNum(type, secnum); + } +} + /** Processes the line special triggered by an object. * * \param line Line with the special command on it. @@ -2168,97 +2201,133 @@ static void P_SwitchSkybox(INT32 ldflags, player_t *player, skybox_t *skybox) static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) { INT32 secnum = -1; - mtag_t tag = Tag_FGet(&line->tags); - - I_Assert(!mo || !P_MobjWasRemoved(mo)); // If mo is there, mo must be valid! + mobj_t *bot = NULL; // note: only commands with linedef types >= 400 && < 500 can be used switch (line->special) { - case 400: // Set tagged sector's floor height/pic - EV_DoFloor(line, instantMoveFloorByFrontSector); + case 400: // Set tagged sector's heights/flats + if (line->args[1] != TMP_CEILING) + EV_DoFloor(line->args[0], line, instantMoveFloorByFrontSector); + if (line->args[1] != TMP_FLOOR) + EV_DoCeiling(line->args[0], line, instantMoveCeilingByFrontSector); break; - case 401: // Set tagged sector's ceiling height/pic - EV_DoCeiling(line, instantMoveCeilingByFrontSector); - break; - - case 402: // Set tagged sector's light level + case 402: // Copy light level to tagged sectors { INT16 newlightlevel; + INT16 newfloorlightlevel, newceilinglightlevel; + boolean newfloorlightabsolute, newceilinglightabsolute; INT32 newfloorlightsec, newceilinglightsec; newlightlevel = line->frontsector->lightlevel; + newfloorlightlevel = line->frontsector->floorlightlevel; + newfloorlightabsolute = line->frontsector->floorlightabsolute; + newceilinglightlevel = line->frontsector->ceilinglightlevel; + newceilinglightabsolute = line->frontsector->ceilinglightabsolute; newfloorlightsec = line->frontsector->floorlightsec; newceilinglightsec = line->frontsector->ceilinglightsec; - // act on all sectors with the same tag as the triggering linedef - TAG_ITER_SECTORS(tag, secnum) + TAG_ITER_SECTORS(line->args[0], secnum) { if (sectors[secnum].lightingdata) { // Stop the lighting madness going on in this sector! - P_RemoveThinker(&((elevator_t *)sectors[secnum].lightingdata)->thinker); + P_RemoveThinker(&((thinkerdata_t *)sectors[secnum].lightingdata)->thinker); sectors[secnum].lightingdata = NULL; - - // No, it's not an elevator_t, but any struct with a thinker_t named - // 'thinker' at the beginning will do here. (We don't know what it - // actually is: could be lightlevel_t, fireflicker_t, glow_t, etc.) } - sectors[secnum].lightlevel = newlightlevel; - sectors[secnum].floorlightsec = newfloorlightsec; - sectors[secnum].ceilinglightsec = newceilinglightsec; + if (!(line->args[1] & TMLC_NOSECTOR)) + sectors[secnum].lightlevel = newlightlevel; + if (!(line->args[1] & TMLC_NOFLOOR)) + { + sectors[secnum].floorlightlevel = newfloorlightlevel; + sectors[secnum].floorlightabsolute = newfloorlightabsolute; + sectors[secnum].floorlightsec = newfloorlightsec; + } + if (!(line->args[1] & TMLC_NOCEILING)) + { + sectors[secnum].ceilinglightlevel = newceilinglightlevel; + sectors[secnum].ceilinglightabsolute = newceilinglightabsolute; + sectors[secnum].ceilinglightsec = newceilinglightsec; + } } } break; - case 403: // Move floor, linelen = speed, frontsector floor = dest height - EV_DoFloor(line, moveFloorByFrontSector); + case 403: // Move planes by front sector + if (line->args[1] != TMP_CEILING) + EV_DoFloor(line->args[0], line, moveFloorByFrontSector); + if (line->args[1] != TMP_FLOOR) + EV_DoCeiling(line->args[0], line, moveCeilingByFrontSector); break; - case 404: // Move ceiling, linelen = speed, frontsector ceiling = dest height - EV_DoCeiling(line, moveCeilingByFrontSector); + case 405: // Move planes by distance + if (line->args[1] != TMP_CEILING) + EV_DoFloor(line->args[0], line, moveFloorByDistance); + if (line->args[1] != TMP_FLOOR) + EV_DoCeiling(line->args[0], line, moveCeilingByDistance); break; - case 405: // Move floor by front side texture offsets, offset x = speed, offset y = amount to raise/lower - EV_DoFloor(line, moveFloorByFrontTexture); + case 408: // Set flats + { + TAG_ITER_SECTORS(line->args[0], secnum) + { + if (line->args[1] != TMP_CEILING) + sectors[secnum].floorpic = line->frontsector->floorpic; + if (line->args[1] != TMP_FLOOR) + sectors[secnum].ceilingpic = line->frontsector->ceilingpic; + } break; - - case 407: // Move ceiling by front side texture offsets, offset x = speed, offset y = amount to raise/lower - EV_DoCeiling(line, moveCeilingByFrontTexture); - break; - -/* case 405: // Lower floor by line, dx = speed, dy = amount to lower - EV_DoFloor(line, lowerFloorByLine); - break; - - case 406: // Raise floor by line, dx = speed, dy = amount to raise - EV_DoFloor(line, raiseFloorByLine); - break; - - case 407: // Lower ceiling by line, dx = speed, dy = amount to lower - EV_DoCeiling(line, lowerCeilingByLine); - break; - - case 408: // Raise ceiling by line, dx = speed, dy = amount to raise - EV_DoCeiling(line, raiseCeilingByLine); - break;*/ + } case 409: // Change tagged sectors' tag // (formerly "Change calling sectors' tag", but behavior was changed) { - TAG_ITER_SECTORS(tag, secnum) - Tag_SectorFSet(secnum,(INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS)); + mtag_t newtag = line->args[1]; + + TAG_ITER_SECTORS(line->args[0], secnum) + { + switch (line->args[2]) + { + case TMT_ADD: + Tag_SectorAdd(secnum, newtag); + break; + case TMT_REMOVE: + Tag_SectorRemove(secnum, newtag); + break; + case TMT_REPLACEFIRST: + default: + Tag_SectorFSet(secnum, newtag); + break; + } + } break; } case 410: // Change front sector's tag - Tag_SectorFSet((UINT32)(line->frontsector - sectors), (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS)); + { + mtag_t newtag = line->args[1]; + secnum = (UINT32)(line->frontsector - sectors); + + switch (line->args[2]) + { + case TMT_ADD: + Tag_SectorAdd(secnum, newtag); + break; + case TMT_REMOVE: + Tag_SectorRemove(secnum, newtag); + break; + case TMT_REPLACEFIRST: + default: + Tag_SectorFSet(secnum, newtag); + break; + } break; + } case 411: // Stop floor/ceiling movement in tagged sector(s) - TAG_ITER_SECTORS(tag, secnum) + TAG_ITER_SECTORS(line->args[0], secnum) { if (sectors[secnum].floordata) { @@ -2292,13 +2361,13 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if (!mo) // nothing to teleport return; - if (line->flags & ML_EFFECT3) // Relative silent teleport + if (line->args[1] & TMT_RELATIVE) // Relative silent teleport { fixed_t x, y, z; - x = sides[line->sidenum[0]].textureoffset; - y = sides[line->sidenum[0]].rowoffset; - z = line->frontsector->ceilingheight; + x = line->args[2] << FRACBITS; + y = line->args[3] << FRACBITS; + z = line->args[4] << FRACBITS; P_UnsetThingPosition(mo); mo->x += x; @@ -2325,39 +2394,40 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } else { - if ((secnum = Tag_Iterate_Sectors(tag, 0)) < 0) - return; + angle_t angle; + boolean silent, keepmomentum; - dest = P_GetObjectTypeInSectorNum(MT_TELEPORTMAN, secnum); + dest = P_FindObjectTypeFromTag(MT_TELEPORTMAN, line->args[0]); if (!dest) return; - if (line->flags & ML_BLOCKPLAYERS) - P_Teleport(mo, dest->x, dest->y, dest->z, (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle, false, (line->flags & ML_EFFECT4) == ML_EFFECT4); - else - { - P_Teleport(mo, dest->x, dest->y, dest->z, (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle, true, (line->flags & ML_EFFECT4) == ML_EFFECT4); - // Play the 'bowrwoosh!' sound - S_StartSound(dest, sfx_mixup); - } + angle = (line->args[1] & TMT_KEEPANGLE) ? mo->angle : dest->angle; + silent = !!(line->args[1] & TMT_SILENT); + keepmomentum = !!(line->args[1] & TMT_KEEPMOMENTUM); + + if (bot) + P_Teleport(bot, dest->x, dest->y, dest->z, angle, !silent, keepmomentum); + P_Teleport(mo, dest->x, dest->y, dest->z, angle, !silent, keepmomentum); + if (!silent) + S_StartSound(dest, sfx_mixup); // Play the 'bowrwoosh!' sound } } break; case 413: // Change music - // console player only unless NOCLIMB is set - if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player)) || titlemapinaction) + // console player only unless TMM_ALLPLAYERS is set + if ((line->args[0] & TMM_ALLPLAYERS) || (mo && mo->player && P_IsLocalPlayer(mo->player)) || titlemapinaction) { - boolean musicsame = (!sides[line->sidenum[0]].text[0] || !strnicmp(sides[line->sidenum[0]].text, S_MusicName(), 7)); - UINT16 tracknum = (UINT16)max(sides[line->sidenum[0]].bottomtexture, 0); - INT32 position = (INT32)max(sides[line->sidenum[0]].midtexture, 0); - UINT32 prefadems = (UINT32)max(sides[line->sidenum[0]].textureoffset >> FRACBITS, 0); - UINT32 postfadems = (UINT32)max(sides[line->sidenum[0]].rowoffset >> FRACBITS, 0); - UINT8 fadetarget = (UINT8)max((line->sidenum[1] != 0xffff) ? sides[line->sidenum[1]].textureoffset >> FRACBITS : 0, 0); - INT16 fadesource = (INT16)max((line->sidenum[1] != 0xffff) ? sides[line->sidenum[1]].rowoffset >> FRACBITS : -1, -1); + boolean musicsame = (!line->stringargs[0] || !line->stringargs[0][0] || !strnicmp(line->stringargs[0], S_MusicName(), 7)); + UINT16 tracknum = (UINT16)max(line->args[6], 0); + INT32 position = (INT32)max(line->args[1], 0); + UINT32 prefadems = (UINT32)max(line->args[2], 0); + UINT32 postfadems = (UINT32)max(line->args[3], 0); + UINT8 fadetarget = (UINT8)max(line->args[4], 0); + INT16 fadesource = (INT16)max(line->args[5], -1); // Seek offset from current song position - if (line->flags & ML_EFFECT1) + if (line->args[0] & TMM_OFFSET) { // adjust for loop point if subtracting if (position < 0 && S_GetMusicLength() && @@ -2369,7 +2439,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } // Fade current music to target volume (if music won't be changed) - if ((line->flags & ML_EFFECT2) && fadetarget && musicsame) + if ((line->args[0] & TMM_FADE) && fadetarget && musicsame) { // 0 fadesource means fade from current volume. // meaning that we can't specify volume 0 as the source volume -- this starts at 1. @@ -2381,7 +2451,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) else S_FadeMusicFromVolume(fadetarget, fadesource, postfadems); - if (!(line->flags & ML_EFFECT3)) + //if (!(line->flags & ML_EFFECT3)) // FIXME: UDMFify S_ShowMusicCredit(); if (position) @@ -2390,23 +2460,26 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) // Change the music and apply position/fade operations else { - strncpy(mapmusname, sides[line->sidenum[0]].text, 7); + if (!line->stringargs[0]) + break; + + strncpy(mapmusname, line->stringargs[0], 7); mapmusname[6] = 0; mapmusflags = tracknum & MUSIC_TRACKMASK; - if (!(line->flags & ML_BLOCKPLAYERS)) + if (!(line->args[0] & TMM_NORELOAD)) mapmusflags |= MUSIC_RELOADRESET; - if (line->flags & ML_NOTBOUNCY) + if (line->args[0] & TMM_FORCERESET) mapmusflags |= MUSIC_FORCERESET; mapmusposition = position; mapmusresume = 0; - S_ChangeMusicEx(mapmusname, mapmusflags, !(line->flags & ML_EFFECT4), position, - !(line->flags & ML_EFFECT2) ? prefadems : 0, - !(line->flags & ML_EFFECT2) ? postfadems : 0); + S_ChangeMusicEx(mapmusname, mapmusflags, !(line->args[0] & TMM_NOLOOP), position, + !(line->args[0] & TMM_FADE) ? prefadems : 0, + !(line->args[0] & TMM_FADE) ? postfadems : 0); - if ((line->flags & ML_EFFECT2) && fadetarget) + if ((line->args[0] & TMM_FADE) && fadetarget) { if (!postfadems) S_SetInternalMusicVolume(fadetarget); @@ -2415,308 +2488,55 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } } - // Except, you can use the ML_BLOCKPLAYERS flag to change this behavior. + // Except, you can use the TMM_NORELOAD flag to change this behavior. // if (mapmusflags & MUSIC_RELOADRESET) then it will reset the music in G_PlayerReborn. } break; case 414: // Play SFX - { - INT32 sfxnum; - - sfxnum = sides[line->sidenum[0]].toptexture; - - if (sfxnum == sfx_None) - return; // Do nothing! - if (sfxnum < sfx_None || sfxnum >= NUMSFX) - { - CONS_Debug(DBG_GAMELOGIC, "Line type 414 Executor: sfx number %d is invalid!\n", sfxnum); - return; - } - - if (tag != 0) // Do special stuff only if a non-zero linedef tag is set - { - // Play sounds from tagged sectors' origins. - if (line->flags & ML_EFFECT5) // Repeat Midtexture - { - // Additionally play the sound from tagged sectors' soundorgs - sector_t *sec; - - TAG_ITER_SECTORS(tag, secnum) - { - sec = §ors[secnum]; - S_StartSound(&sec->soundorg, sfxnum); - } - } - - // Play the sound without origin for anyone, as long as they're inside tagged areas. - else - { - UINT8 i = 0; - mobj_t* camobj; - ffloor_t *rover; - boolean foundit = false; - - for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) - { - camobj = players[displayplayers[i]].mo; - - if (!camobj) - continue; - - if (foundit || Tag_Find(&camobj->subsector->sector->tags, tag)) - { - foundit = true; - break; - } - - // Only trigger if mobj is touching the tag - for(rover = camobj->subsector->sector->ffloors; rover; rover = rover->next) - { - if (!Tag_Find(&rover->master->frontsector->tags, tag)) - continue; - - if (camobj->z > P_GetSpecialTopZ(camobj, sectors + rover->secnum, camobj->subsector->sector)) - continue; - - if (camobj->z + camobj->height < P_GetSpecialBottomZ(camobj, sectors + rover->secnum, camobj->subsector->sector)) - continue; - - foundit = true; - break; - } - } - - if (foundit) - S_StartSound(NULL, sfxnum); - } - } - else - { - if (line->flags & ML_NOCLIMB) - { - // play the sound from nowhere, but only if display player triggered it - if (mo && mo->player && P_IsDisplayPlayer(mo->player)) - S_StartSound(NULL, sfxnum); - } - else if (line->flags & ML_EFFECT4) - { - // play the sound from nowhere - S_StartSound(NULL, sfxnum); - } - else if (line->flags & ML_BLOCKPLAYERS) - { - // play the sound from calling sector's soundorg - if (callsec) - S_StartSound(&callsec->soundorg, sfxnum); - else if (mo) - S_StartSound(&mo->subsector->sector->soundorg, sfxnum); - } - else if (mo) - { - // play the sound from mobj that triggered it - S_StartSound(mo, sfxnum); - } - } - } + P_PlaySFX(line->stringargs[0] ? get_number(line->stringargs[0]) : sfx_None, mo, callsec, line->args[2], line->args[0], line->args[1]); break; case 415: // Run a script - // FIXME: cursed - CONS_Alert(CONS_WARNING, "Linedef special 415 is currently broken! Fix it later, BYE.\n"); -#if 0 if (cv_runscripts.value) { - INT32 scrnum; - lumpnum_t lumpnum; - char newname[9]; - - strcpy(newname, G_BuildMapName(gamemap)); - newname[0] = 'S'; - newname[1] = 'C'; - newname[2] = 'R'; - - scrnum = sides[line->sidenum[0]].textureoffset>>FRACBITS; - if (scrnum < 0 || scrnum > 999) - { - scrnum = 0; - newname[5] = newname[6] = newname[7] = '0'; - } - else - { - newname[5] = (char)('0' + (char)((scrnum/100))); - newname[6] = (char)('0' + (char)((scrnum%100)/10)); - newname[7] = (char)('0' + (char)(scrnum%10)); - } - newname[8] = '\0'; - - lumpnum = W_CheckNumForName(newname); + lumpnum_t lumpnum = W_CheckNumForName(line->stringargs[0]); if (lumpnum == LUMPERROR || W_LumpLength(lumpnum) == 0) - { - CONS_Debug(DBG_SETUP, "SOC Error: script lump %s not found/not valid.\n", newname); - } + CONS_Debug(DBG_SETUP, "Line type 415 Executor: script lump %s not found/not valid.\n", line->stringargs[0]); else COM_BufInsertText(W_CacheLumpNum(lumpnum, PU_CACHE)); } -#endif break; case 416: // Spawn adjustable fire flicker - TAG_ITER_SECTORS(tag, secnum) - { - if (line->flags & ML_NOCLIMB && line->backsector) - { - // Use front sector for min light level, back sector for max. - // This is tricky because P_SpawnAdjustableFireFlicker expects - // the maxsector (second argument) to also be the target - // sector, so we have to do some light level twiddling. - fireflicker_t *flick; - INT16 reallightlevel = sectors[secnum].lightlevel; - sectors[secnum].lightlevel = line->backsector->lightlevel; - - flick = P_SpawnAdjustableFireFlicker(line->frontsector, §ors[secnum], - P_AproxDistance(line->dx, line->dy)>>FRACBITS); - - // Make sure the starting light level is in range. - if (reallightlevel < flick->minlight) - reallightlevel = (INT16)flick->minlight; - else if (reallightlevel > flick->maxlight) - reallightlevel = (INT16)flick->maxlight; - - sectors[secnum].lightlevel = reallightlevel; - } - else - { - // Use front sector for min, target sector for max, - // the same way linetype 61 does it. - P_SpawnAdjustableFireFlicker(line->frontsector, §ors[secnum], - P_AproxDistance(line->dx, line->dy)>>FRACBITS); - } - } + TAG_ITER_SECTORS(line->args[0], secnum) + P_SpawnAdjustableFireFlicker(§ors[secnum], line->args[2], + line->args[3] ? sectors[secnum].lightlevel : line->args[4], line->args[1]); break; case 417: // Spawn adjustable glowing light - TAG_ITER_SECTORS(tag, secnum) - { - if (line->flags & ML_NOCLIMB && line->backsector) - { - // Use front sector for min light level, back sector for max. - // This is tricky because P_SpawnAdjustableGlowingLight expects - // the maxsector (second argument) to also be the target - // sector, so we have to do some light level twiddling. - glow_t *glow; - INT16 reallightlevel = sectors[secnum].lightlevel; - sectors[secnum].lightlevel = line->backsector->lightlevel; - - glow = P_SpawnAdjustableGlowingLight(line->frontsector, §ors[secnum], - P_AproxDistance(line->dx, line->dy)>>FRACBITS); - - // Make sure the starting light level is in range. - if (reallightlevel < glow->minlight) - reallightlevel = (INT16)glow->minlight; - else if (reallightlevel > glow->maxlight) - reallightlevel = (INT16)glow->maxlight; - - sectors[secnum].lightlevel = reallightlevel; - } - else - { - // Use front sector for min, target sector for max, - // the same way linetype 602 does it. - P_SpawnAdjustableGlowingLight(line->frontsector, §ors[secnum], - P_AproxDistance(line->dx, line->dy)>>FRACBITS); - } - } + TAG_ITER_SECTORS(line->args[0], secnum) + P_SpawnAdjustableGlowingLight(§ors[secnum], line->args[2], + line->args[3] ? sectors[secnum].lightlevel : line->args[4], line->args[1]); break; - case 418: // Spawn adjustable strobe flash (unsynchronized) - TAG_ITER_SECTORS(tag, secnum) - { - if (line->flags & ML_NOCLIMB && line->backsector) - { - // Use front sector for min light level, back sector for max. - // This is tricky because P_SpawnAdjustableGlowingLight expects - // the maxsector (second argument) to also be the target - // sector, so we have to do some light level twiddling. - strobe_t *flash; - INT16 reallightlevel = sectors[secnum].lightlevel; - sectors[secnum].lightlevel = line->backsector->lightlevel; - - flash = P_SpawnAdjustableStrobeFlash(line->frontsector, §ors[secnum], - abs(line->dx)>>FRACBITS, abs(line->dy)>>FRACBITS, false); - - // Make sure the starting light level is in range. - if (reallightlevel < flash->minlight) - reallightlevel = (INT16)flash->minlight; - else if (reallightlevel > flash->maxlight) - reallightlevel = (INT16)flash->maxlight; - - sectors[secnum].lightlevel = reallightlevel; - } - else - { - // Use front sector for min, target sector for max, - // the same way linetype 602 does it. - P_SpawnAdjustableStrobeFlash(line->frontsector, §ors[secnum], - abs(line->dx)>>FRACBITS, abs(line->dy)>>FRACBITS, false); - } - } - break; - - case 419: // Spawn adjustable strobe flash (synchronized) - TAG_ITER_SECTORS(tag, secnum) - { - if (line->flags & ML_NOCLIMB && line->backsector) - { - // Use front sector for min light level, back sector for max. - // This is tricky because P_SpawnAdjustableGlowingLight expects - // the maxsector (second argument) to also be the target - // sector, so we have to do some light level twiddling. - strobe_t *flash; - INT16 reallightlevel = sectors[secnum].lightlevel; - sectors[secnum].lightlevel = line->backsector->lightlevel; - - flash = P_SpawnAdjustableStrobeFlash(line->frontsector, §ors[secnum], - abs(line->dx)>>FRACBITS, abs(line->dy)>>FRACBITS, true); - - // Make sure the starting light level is in range. - if (reallightlevel < flash->minlight) - reallightlevel = (INT16)flash->minlight; - else if (reallightlevel > flash->maxlight) - reallightlevel = (INT16)flash->maxlight; - - sectors[secnum].lightlevel = reallightlevel; - } - else - { - // Use front sector for min, target sector for max, - // the same way linetype 602 does it. - P_SpawnAdjustableStrobeFlash(line->frontsector, §ors[secnum], - abs(line->dx)>>FRACBITS, abs(line->dy)>>FRACBITS, true); - } - } + case 418: // Spawn adjustable strobe flash + TAG_ITER_SECTORS(line->args[0], secnum) + P_SpawnAdjustableStrobeFlash(§ors[secnum], line->args[3], + (line->args[4] & TMB_USETARGET) ? sectors[secnum].lightlevel : line->args[5], + line->args[1], line->args[2], line->args[4] & TMB_SYNC); break; case 420: // Fade light levels in tagged sectors to new value - P_FadeLight(tag, - (line->flags & ML_DONTPEGBOTTOM) ? max(sides[line->sidenum[0]].textureoffset>>FRACBITS, 0) : line->frontsector->lightlevel, - // failsafe: if user specifies Back Y Offset and NOT Front Y Offset, use the Back Offset - // to be consistent with other light and fade specials - (line->flags & ML_DONTPEGBOTTOM) ? - ((line->sidenum[1] != 0xFFFF && !(sides[line->sidenum[0]].rowoffset>>FRACBITS)) ? - max(min(sides[line->sidenum[1]].rowoffset>>FRACBITS, 255), 0) - : max(min(sides[line->sidenum[0]].rowoffset>>FRACBITS, 255), 0)) - : abs(P_AproxDistance(line->dx, line->dy))>>FRACBITS, - (line->flags & ML_EFFECT4), - (line->flags & ML_EFFECT5)); + P_FadeLight(line->args[0], line->args[1], line->args[2], line->args[3] & TMF_TICBASED, line->args[3] & TMF_OVERRIDE, line->args[3] & TMF_RELATIVE); break; case 421: // Stop lighting effect in tagged sectors - TAG_ITER_SECTORS(tag, secnum) + TAG_ITER_SECTORS(line->args[0], secnum) if (sectors[secnum].lightingdata) { - P_RemoveThinker(&((elevator_t *)sectors[secnum].lightingdata)->thinker); + P_RemoveThinker(&((thinkerdata_t *)sectors[secnum].lightingdata)->thinker); sectors[secnum].lightingdata = NULL; } break; @@ -2724,15 +2544,13 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 422: // Cut away to another view { mobj_t *altview; + INT32 aim; if ((!mo || !mo->player) && !titlemapinaction) // only players have views, and title screens return; - if ((secnum = Tag_Iterate_Sectors(tag, 0)) < 0) - return; - - altview = P_GetObjectTypeInSectorNum(MT_ALTVIEWMAN, secnum); - if (!altview) + altview = P_FindObjectTypeFromTag(MT_ALTVIEWMAN, line->args[0]); + if (!altview || !altview->spawnpoint) return; // If titlemap, set the camera ref for title's thinker @@ -2742,59 +2560,50 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) else { P_SetTarget(&mo->player->awayviewmobj, altview); - mo->player->awayviewtics = P_AproxDistance(line->dx, line->dy)>>FRACBITS; + mo->player->awayviewtics = line->args[1]; } - - if (line->flags & ML_NOCLIMB) // lets you specify a vertical angle - { - INT32 aim; - - aim = sides[line->sidenum[0]].textureoffset>>FRACBITS; - aim = (aim + 360) % 360; - aim *= (ANGLE_90>>8); - aim /= 90; - aim <<= 8; - if (titlemapinaction) - titlemapcameraref->cusval = (angle_t)aim; - else - mo->player->awayviewaiming = (angle_t)aim; - } + aim = udmf ? altview->spawnpoint->pitch : line->args[2]; + aim = (aim + 360) % 360; + aim *= (ANGLE_90>>8); + aim /= 90; + aim <<= 8; + if (titlemapinaction) + titlemapcameraref->cusval = (angle_t)aim; else - { - // straight ahead - if (!titlemapinaction) - mo->player->awayviewaiming = 0; - // don't do cusval cause that's annoying - } + mo->player->awayviewaiming = (angle_t)aim; } break; case 423: // Change Sky - if ((mo && mo->player && P_IsLocalPlayer(mo->player)) || (line->flags & ML_NOCLIMB)) - P_SetupLevelSky(sides[line->sidenum[0]].text, (line->flags & ML_NOCLIMB)); + if ((mo && mo->player && P_IsLocalPlayer(mo->player)) || line->args[1]) + P_SetupLevelSky(line->stringargs[0], line->args[1]); break; case 424: // Change Weather - if (line->flags & ML_NOCLIMB) + if (line->args[1]) { - globalweather = (UINT8)(sides[line->sidenum[0]].textureoffset>>FRACBITS); + globalweather = (UINT8)(line->args[0]); P_SwitchWeather(globalweather); } else if (mo && mo->player && P_IsLocalPlayer(mo->player)) - P_SwitchWeather(sides[line->sidenum[0]].textureoffset>>FRACBITS); + P_SwitchWeather(line->args[0]); break; case 425: // Calls P_SetMobjState on calling mobj if (mo && !mo->player) - P_SetMobjState(mo, sides[line->sidenum[0]].toptexture); //P_AproxDistance(line->dx, line->dy)>>FRACBITS); + { + statenum_t state = line->stringargs[0] ? get_number(line->stringargs[0]) : S_NULL; + if (state >= 0 && state < NUMSTATES) + P_SetMobjState(mo, state); + } break; case 426: // Moves the mobj to its sector's soundorg and on the floor, and stops it if (!mo) return; - if (line->flags & ML_NOCLIMB) + if (line->args[0]) { P_UnsetThingPosition(mo); mo->x = mo->subsector->sector->soundorg.x; @@ -2817,30 +2626,29 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 427: // Awards points if the mobj is a player if (mo && mo->player) - P_AddPlayerScore(mo->player, sides[line->sidenum[0]].textureoffset>>FRACBITS); + P_AddPlayerScore(mo->player, line->args[0]); break; case 428: // Start floating platform movement - EV_DoElevator(line, elevateContinuous, true); + EV_DoElevator(line->args[0], line, elevateContinuous); break; - case 429: // Crush Ceiling Down Once - EV_DoCrush(line, crushCeilOnce); + case 429: // Crush planes once + if (line->args[1] == TMP_FLOOR) + EV_DoFloor(line->args[0], line, crushFloorOnce); + else if (line->args[1] == TMP_CEILING) + EV_DoCrush(line->args[0], line, crushCeilOnce); + else + EV_DoCrush(line->args[0], line, crushBothOnce); break; - case 430: // Crush Floor Up Once - EV_DoFloor(line, crushFloorOnce); - break; - - case 431: // Crush Floor & Ceiling to middle Once - EV_DoCrush(line, crushBothOnce); - break; - - case 433: // Flip gravity (Flop gravity if noclimb) Works on pushables, too! - if (line->flags & ML_NOCLIMB) + case 433: // Flip/flop gravity. Works on pushables, too! + if (line->args[0]) mo->flags2 &= ~MF2_OBJECTFLIP; else mo->flags2 |= MF2_OBJECTFLIP; + if (bot) + bot->flags2 = (bot->flags2 & ~MF2_OBJECTFLIP) | (mo->flags2 & MF2_OBJECTFLIP); break; case 435: // Change scroller direction @@ -2848,25 +2656,30 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) scroll_t *scroller; thinker_t *th; + fixed_t length = R_PointToDist2(line->v2->x, line->v2->y, line->v1->x, line->v1->y); + fixed_t speed = line->args[1] << FRACBITS; + fixed_t dx = FixedMul(FixedMul(FixedDiv(line->dx, length), speed) >> SCROLL_SHIFT, CARRYFACTOR); + fixed_t dy = FixedMul(FixedMul(FixedDiv(line->dy, length), speed) >> SCROLL_SHIFT, CARRYFACTOR); + for (th = thlist[THINK_MAIN].next; th != &thlist[THINK_MAIN]; th = th->next) { if (th->function.acp1 != (actionf_p1)T_Scroll) continue; scroller = (scroll_t *)th; - if (!Tag_Find(§ors[scroller->affectee].tags, tag)) + if (!Tag_Find(§ors[scroller->affectee].tags, line->args[0])) continue; - scroller->dx = FixedMul(line->dx>>SCROLL_SHIFT, CARRYFACTOR); - scroller->dy = FixedMul(line->dy>>SCROLL_SHIFT, CARRYFACTOR); + scroller->dx = dx; + scroller->dy = dy; } } break; case 436: // Shatter block remotely { - INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); - INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); + INT16 sectag = (INT16)(line->args[0]); + INT16 foftag = (INT16)(line->args[1]); sector_t *sec; // Sector that the FOF is visible in ffloor_t *rover; // FOF that we are going to crumble boolean foundrover = false; // for debug, "Can't find a FOF" message @@ -2903,10 +2716,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 437: // Disable Player Controls if (mo && mo->player) { - UINT16 fractime = (UINT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); + UINT16 fractime = (UINT16)(line->args[0]); if (fractime < 1) fractime = 1; //instantly wears off upon leaving - if (line->flags & ML_NOCLIMB) + if (line->args[1]) fractime |= 1<<15; //more crazy &ing, as if music stuff wasn't enough mo->player->nocontrol = fractime; } @@ -2915,7 +2728,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 438: // Set player scale if (mo) { - mo->destscale = FixedDiv(P_AproxDistance(line->dx, line->dy), 100<destscale = FixedDiv(line->args[0]<destscale < FRACUNIT/100) mo->destscale = FRACUNIT/100; } @@ -2925,30 +2738,33 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) { size_t linenum; side_t *set = &sides[line->sidenum[0]], *this; - boolean always = !(line->flags & ML_NOCLIMB); // If noclimb: Only change mid texture if mid texture already exists on tagged lines, etc. + boolean always = !(line->args[2]); // If args[2] is set: Only change mid texture if mid texture already exists on tagged lines, etc. for (linenum = 0; linenum < numlines; linenum++) { if (lines[linenum].special == 439) continue; // Don't override other set texture lines! - if (!Tag_Find(&lines[linenum].tags, tag)) + if (!Tag_Find(&lines[linenum].tags, line->args[0])) continue; // Find tagged lines // Front side - this = &sides[lines[linenum].sidenum[0]]; - if (always || this->toptexture) this->toptexture = set->toptexture; - if (always || this->midtexture) this->midtexture = set->midtexture; - if (always || this->bottomtexture) this->bottomtexture = set->bottomtexture; - - if (lines[linenum].sidenum[1] == 0xffff) - continue; // One-sided stops here. + if (line->args[1] != TMSD_BACK) + { + this = &sides[lines[linenum].sidenum[0]]; + if (always || this->toptexture) this->toptexture = set->toptexture; + if (always || this->midtexture) this->midtexture = set->midtexture; + if (always || this->bottomtexture) this->bottomtexture = set->bottomtexture; + } // Back side - this = &sides[lines[linenum].sidenum[1]]; - if (always || this->toptexture) this->toptexture = set->toptexture; - if (always || this->midtexture) this->midtexture = set->midtexture; - if (always || this->bottomtexture) this->bottomtexture = set->bottomtexture; + if (line->args[1] != TMSD_FRONT && lines[linenum].sidenum[1] != 0xffff) + { + this = &sides[lines[linenum].sidenum[1]]; + if (always || this->toptexture) this->toptexture = set->toptexture; + if (always || this->midtexture) this->midtexture = set->midtexture; + if (always || this->bottomtexture) this->bottomtexture = set->bottomtexture; + } } } break; @@ -2961,7 +2777,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 441: // Trigger unlockable if ((!modifiedgame || savemoddata) && !(netgame || multiplayer)) { - INT32 trigid = (INT32)(sides[line->sidenum[0]].textureoffset>>FRACBITS); + INT32 trigid = line->args[0]; if (trigid < 0 || trigid > 31) // limited by 32 bit variable CONS_Debug(DBG_GAMELOGIC, "Unlockable trigger (sidedef %hu): bad trigger ID %d\n", line->sidenum[0], trigid); @@ -2984,37 +2800,37 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors { - const mobjtype_t type = (mobjtype_t)sides[line->sidenum[0]].toptexture; + const mobjtype_t type = line->stringargs[0] ? get_number(line->stringargs[0]) : MT_NULL; statenum_t state = NUMSTATES; - sector_t *sec; mobj_t *thing; - if (line->sidenum[1] != 0xffff) - state = (statenum_t)sides[line->sidenum[1]].toptexture; + if (type < 0 || type >= NUMMOBJTYPES) + break; - TAG_ITER_SECTORS(tag, secnum) + if (!line->args[1]) + { + state = line->stringargs[1] ? get_number(line->stringargs[1]) : S_NULL; + + if (state < 0 || state >= NUMSTATES) + break; + } + + TAG_ITER_SECTORS(line->args[0], secnum) { boolean tryagain; - sec = sectors + secnum; do { tryagain = false; - for (thing = sec->thinglist; thing; thing = thing->snext) - if (thing->type == type) - { - if (state != NUMSTATES) - { - if (!P_SetMobjState(thing, state)) // set state to specific state - { // mobj was removed - tryagain = true; // snext is corrupt, we'll have to start over. - break; - } - } - else if (!P_SetMobjState(thing, thing->state->nextstate)) // set state to nextstate - { // mobj was removed - tryagain = true; // snext is corrupt, we'll have to start over. - break; - } + for (thing = sectors[secnum].thinglist; thing; thing = thing->snext) + { + if (thing->type != type) + continue; + + if (!P_SetMobjState(thing, line->args[1] ? thing->state->nextstate : state)) + { // mobj was removed + tryagain = true; // snext is corrupt, we'll have to start over. + break; } + } } while (tryagain); } break; @@ -3024,14 +2840,14 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if (line->stringargs[0]) LUA_HookLinedefExecute(line, mo, callsec); else - CONS_Alert(CONS_WARNING, "Linedef %s is missing the hook name of the Lua function to call! (This should be given in arg0str)\n", sizeu1(line-lines)); + CONS_Alert(CONS_WARNING, "Linedef %s is missing the hook name of the Lua function to call! (This should be given in stringarg0)\n", sizeu1(line-lines)); break; case 444: // Earthquake camera { - quake.intensity = sides[line->sidenum[0]].textureoffset; - quake.radius = sides[line->sidenum[0]].rowoffset; - quake.time = P_AproxDistance(line->dx, line->dy)>>FRACBITS; + quake.intensity = line->args[1] << FRACBITS; + quake.radius = line->args[2] << FRACBITS; + quake.time = line->args[0]; quake.epicenter = NULL; /// \todo @@ -3043,10 +2859,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; } - case 445: // Force block disappear remotely (reappear if noclimb) + case 445: // Force block disappear remotely (reappear if args[2] is set) { - INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); - INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); + INT16 sectag = (INT16)(line->args[0]); + INT16 foftag = (INT16)(line->args[1]); sector_t *sec; // Sector that the FOF is visible (or not visible) in ffloor_t *rover; // FOF to vanish/un-vanish boolean foundrover = false; // for debug, "Can't find a FOF" message @@ -3071,7 +2887,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) oldflags = rover->flags; // Abracadabra! - if (line->flags & ML_NOCLIMB) + if (line->args[2]) rover->flags |= FF_EXISTS; else rover->flags &= ~FF_EXISTS; @@ -3096,8 +2912,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 446: // Make block fall remotely (acts like FF_CRUMBLE) { - INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); - INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); + INT16 sectag = (INT16)(line->args[0]); + INT16 foftag = (INT16)(line->args[1]); sector_t *sec; // Sector that the FOF is visible in ffloor_t *rover; // FOF that we are going to make fall down boolean foundrover = false; // for debug, "Can't find a FOF" message @@ -3107,7 +2923,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if (mo) // NULL check player = mo->player; - if (line->flags & ML_NOCLIMB) // don't respawn! + if (line->args[2] & TMFR_NORETURN) // don't respawn! respawn = false; TAG_ITER_SECTORS(sectag, secnum) @@ -3126,8 +2942,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) { foundrover = true; - if (line->flags & ML_BLOCKPLAYERS) // FOF flags determine respawn ability instead? - respawn = !(rover->flags & FF_NORETURN) ^ !!(line->flags & ML_NOCLIMB); // no climb inverts + if (line->args[2] & TMFR_CHECKFLAG) // FOF flags determine respawn ability instead? + respawn = !(rover->flags & FF_NORETURN) ^ !!(line->args[2] & TMFR_NORETURN); // TMFR_NORETURN inverts EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), player, rover->alpha, respawn); } @@ -3209,66 +3025,64 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; } case 448: // Change skybox viewpoint/centerpoint - if ((mo && mo->player) || (line->flags & ML_NOCLIMB)) { - INT32 viewid = sides[line->sidenum[0]].textureoffset>>FRACBITS; - INT32 centerid = sides[line->sidenum[0]].rowoffset>>FRACBITS; + skybox_t skybox = {0}; - if ((line->flags & (ML_EFFECT4|ML_BLOCKPLAYERS)) == ML_EFFECT4) // Solid Midtexture is on but Block Enemies is off? - { - CONS_Alert(CONS_WARNING, - M_GetText("Skybox switch linedef (tag %d) doesn't have anything to do.\nConsider changing the linedef's flag configuration or removing it entirely.\n"), - tag); - } - else - { - skybox_t skybox; + INT32 viewid = line->args[0]; + INT32 centerid = line->args[1]; - // set viewpoint mobj + // set viewpoint mobj + if (line->args[2] != TMS_CENTERPOINT) + { if (viewid >= 0 && viewid < 16) skybox.viewpoint = skyboxviewpnts[viewid]; else skybox.viewpoint = NULL; + } - // set centerpoint mobj + // set centerpoint mobj + if (line->args[2] != TMS_VIEWPOINT) + { if (centerid >= 0 && centerid < 16) skybox.centerpoint = skyboxcenterpnts[centerid]; else skybox.centerpoint = NULL; + } - if (line->flags & ML_NOCLIMB) // Applies to all players + if (line->args[3]) // Applies to all players + { + INT32 i; + + for (i = 0; i < MAXPLAYERS; ++i) { - INT32 i; - - for (i = 0; i < MAXPLAYERS; ++i) - { - if (playeringame[i]) - P_SwitchSkybox(line->flags, &players[i], &skybox); - } + if (playeringame[i]) + P_SwitchSkybox(line->args[2], &players[i], &skybox); } - else - P_SwitchSkybox(line->flags, mo->player, &skybox); + } + else if (mo && mo->player) + { + P_SwitchSkybox(line->args[2], mo->player, &skybox); } CONS_Debug(DBG_GAMELOGIC, "Line type 448 Executor: viewid = %d, centerid = %d, viewpoint? = %s, centerpoint? = %s\n", viewid, centerid, - ((line->flags & ML_EFFECT4) ? "no" : "yes"), - ((line->flags & ML_BLOCKPLAYERS) ? "yes" : "no")); + ((line->args[2] == TMS_CENTERPOINT) ? "no" : "yes"), + ((line->args[2] == TMS_VIEWPOINT) ? "no" : "yes")); } break; case 449: // Enable bosses with parameter { - INT32 bossid = sides[line->sidenum[0]].textureoffset>>FRACBITS; + INT32 bossid = line->args[0]; if (bossid & ~15) // if any bits other than first 16 are set { CONS_Alert(CONS_WARNING, - M_GetText("Boss enable linedef (tag %d) has an invalid texture x offset.\nConsider changing it or removing it entirely.\n"), - tag); + M_GetText("Boss enable linedef has an invalid boss ID (%d).\nConsider changing it or removing it entirely.\n"), + bossid); break; } - if (line->flags & ML_NOCLIMB) + if (line->args[1]) { bossdisabled |= (1<args[0], mo, NULL); break; case 451: // Execute Random Linedef Executor { - INT32 rvalue1 = sides[line->sidenum[0]].textureoffset>>FRACBITS; - INT32 rvalue2 = sides[line->sidenum[0]].rowoffset>>FRACBITS; + INT32 rvalue1 = line->args[0]; + INT32 rvalue2 = line->args[1]; INT32 result; if (rvalue1 <= rvalue2) @@ -3302,10 +3116,9 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 452: // Set FOF alpha { - INT16 destvalue = line->sidenum[1] != 0xffff ? - (INT16)(sides[line->sidenum[1]].textureoffset>>FRACBITS) : (INT16)(P_AproxDistance(line->dx, line->dy)>>FRACBITS); - INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); - INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); + INT16 destvalue = (INT16)(line->args[2]); + INT16 sectag = (INT16)(line->args[0]); + INT16 foftag = (INT16)(line->args[1]); sector_t *sec; // Sector that the FOF is visible in ffloor_t *rover; // FOF that we are going to operate boolean foundrover = false; // for debug, "Can't find a FOF" message @@ -3329,7 +3142,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) // If fading an invisible FOF whose render flags we did not yet set, // initialize its alpha to 1 // for relative alpha calc - if (!(line->flags & ML_NOCLIMB) && // do translucent + if (!(line->args[3] & TMST_DONTDOTRANSLUCENT) && // do translucent (rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE !(rover->spawnflags & FF_RENDERSIDES) && !(rover->spawnflags & FF_RENDERPLANES) && @@ -3339,16 +3152,16 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) P_RemoveFakeFloorFader(rover); P_FadeFakeFloor(rover, rover->alpha, - max(1, min(256, (line->flags & ML_EFFECT3) ? rover->alpha + destvalue : destvalue)), - 0, // set alpha immediately - false, NULL, // tic-based logic - false, // do not handle FF_EXISTS - !(line->flags & ML_NOCLIMB), // handle FF_TRANSLUCENT - false, // do not handle lighting - false, // do not handle colormap - false, // do not handle collision - false, // do not do ghost fade (no collision during fade) - true); // use exact alpha values (for opengl) + max(1, min(256, (line->args[3] & TMST_RELATIVE) ? rover->alpha + destvalue : destvalue)), + 0, // set alpha immediately + false, NULL, // tic-based logic + false, // do not handle FF_EXISTS + !(line->args[3] & TMST_DONTDOTRANSLUCENT), // handle FF_TRANSLUCENT + false, // do not handle lighting + false, // do not handle colormap + false, // do not handle collision + false, // do not do ghost fade (no collision during fade) + true); // use exact alpha values (for opengl) } } @@ -3363,12 +3176,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 453: // Fade FOF { - INT16 destvalue = line->sidenum[1] != 0xffff ? - (INT16)(sides[line->sidenum[1]].textureoffset>>FRACBITS) : (INT16)(line->dx>>FRACBITS); - INT16 speed = line->sidenum[1] != 0xffff ? - (INT16)(abs(sides[line->sidenum[1]].rowoffset>>FRACBITS)) : (INT16)(abs(line->dy)>>FRACBITS); - INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); - INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); + INT16 destvalue = (INT16)(line->args[2]); + INT16 speed = (INT16)(line->args[3]); + INT16 sectag = (INT16)(line->args[0]); + INT16 foftag = (INT16)(line->args[1]); sector_t *sec; // Sector that the FOF is visible in ffloor_t *rover; // FOF that we are going to operate boolean foundrover = false; // for debug, "Can't find a FOF" message @@ -3391,7 +3202,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) foundrover = true; // Prevent continuous execs from interfering on an existing fade - if (!(line->flags & ML_EFFECT5) + if (!(line->args[4] & TMFT_OVERRIDE) && rover->fadingdata) //&& ((fade_t*)rover->fadingdata)->timer > (ticbased ? 2 : speed*2)) { @@ -3403,21 +3214,21 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) P_AddFakeFloorFader(rover, secnum, j, destvalue, speed, - (line->flags & ML_EFFECT4), // tic-based logic - (line->flags & ML_EFFECT3), // Relative destvalue - !(line->flags & ML_BLOCKPLAYERS), // do not handle FF_EXISTS - !(line->flags & ML_NOCLIMB), // do not handle FF_TRANSLUCENT - !(line->flags & ML_EFFECT2), // do not handle lighting - !(line->flags & ML_EFFECT2), // do not handle colormap (ran out of flags) - !(line->flags & ML_NOTBOUNCY), // do not handle collision - (line->flags & ML_EFFECT1), // do ghost fade (no collision during fade) - (line->flags & ML_TFERLINE)); // use exact alpha values (for opengl) + (line->args[4] & TMFT_TICBASED), // tic-based logic + (line->args[4] & TMFT_RELATIVE), // Relative destvalue + !(line->args[4] & TMFT_DONTDOEXISTS), // do not handle FF_EXISTS + !(line->args[4] & TMFT_DONTDOTRANSLUCENT), // do not handle FF_TRANSLUCENT + !(line->args[4] & TMFT_DONTDOLIGHTING), // do not handle lighting + !(line->args[4] & TMFT_DONTDOCOLORMAP), // do not handle colormap + !(line->args[4] & TMFT_IGNORECOLLISION), // do not handle collision + (line->args[4] & TMFT_GHOSTFADE), // do ghost fade (no collision during fade) + (line->args[4] & TMFT_USEEXACTALPHA)); // use exact alpha values (for opengl) else { // If fading an invisible FOF whose render flags we did not yet set, // initialize its alpha to 1 // for relative alpha calc - if (!(line->flags & ML_NOCLIMB) && // do translucent + if (!(line->args[4] & TMFT_DONTDOTRANSLUCENT) && // do translucent (rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE !(rover->spawnflags & FF_RENDERSIDES) && !(rover->spawnflags & FF_RENDERPLANES) && @@ -3427,16 +3238,16 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) P_RemoveFakeFloorFader(rover); P_FadeFakeFloor(rover, rover->alpha, - max(1, min(256, (line->flags & ML_EFFECT3) ? rover->alpha + destvalue : destvalue)), - 0, // set alpha immediately - false, NULL, // tic-based logic - !(line->flags & ML_BLOCKPLAYERS), // do not handle FF_EXISTS - !(line->flags & ML_NOCLIMB), // do not handle FF_TRANSLUCENT - !(line->flags & ML_EFFECT2), // do not handle lighting - !(line->flags & ML_EFFECT2), // do not handle colormap (ran out of flags) - !(line->flags & ML_NOTBOUNCY), // do not handle collision - (line->flags & ML_EFFECT1), // do ghost fade (no collision during fade) - (line->flags & ML_TFERLINE)); // use exact alpha values (for opengl) + max(1, min(256, (line->args[4] & TMFT_RELATIVE) ? rover->alpha + destvalue : destvalue)), + 0, // set alpha immediately + false, NULL, // tic-based logic + !(line->args[4] & TMFT_DONTDOEXISTS), // do not handle FF_EXISTS + !(line->args[4] & TMFT_DONTDOTRANSLUCENT), // do not handle FF_TRANSLUCENT + !(line->args[4] & TMFT_DONTDOLIGHTING), // do not handle lighting + !(line->args[4] & TMFT_DONTDOCOLORMAP), // do not handle colormap + !(line->args[4] & TMFT_IGNORECOLLISION), // do not handle collision + (line->args[4] & TMFT_GHOSTFADE), // do ghost fade (no collision during fade) + (line->args[4] & TMFT_USEEXACTALPHA)); // use exact alpha values (for opengl) } } j++; @@ -3453,8 +3264,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 454: // Stop fading FOF { - INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); - INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); + INT16 sectag = (INT16)(line->args[0]); + INT16 foftag = (INT16)(line->args[1]); sector_t *sec; // Sector that the FOF is visible in ffloor_t *rover; // FOF that we are going to operate boolean foundrover = false; // for debug, "Can't find a FOF" message @@ -3476,7 +3287,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) foundrover = true; P_ResetFakeFloorFader(rover, NULL, - !(line->flags & ML_BLOCKPLAYERS)); // do not finalize collision flags + !(line->args[2])); // do not finalize collision flags } } @@ -3597,17 +3408,13 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 457: // Track mobj angle to point if (mo) { - INT32 failureangle = FixedAngle((min(max(abs(sides[line->sidenum[0]].textureoffset>>FRACBITS), 0), 360))*FRACUNIT); - INT32 failuredelay = abs(sides[line->sidenum[0]].rowoffset>>FRACBITS); - INT32 failureexectag = line->sidenum[1] != 0xffff ? - (INT32)(sides[line->sidenum[1]].textureoffset>>FRACBITS) : 0; - boolean persist = (line->flags & ML_EFFECT2); + INT32 failureangle = FixedAngle((min(max(abs(line->args[1]), 0), 360))*FRACUNIT); + INT32 failuredelay = abs(line->args[2]); + INT32 failureexectag = line->args[3]; + boolean persist = !!(line->args[4]); mobj_t *anchormo; - if ((secnum = Tag_Iterate_Sectors(tag, 0)) < 0) - return; - - anchormo = P_GetObjectTypeInSectorNum(MT_ANGLEMAN, secnum); + anchormo = P_FindObjectTypeFromTag(MT_ANGLEMAN, line->args[0]); if (!anchormo) return; @@ -3630,27 +3437,27 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 459: // Control Text Prompt - // console player only unless NOCLIMB is set + // console player only if (mo && mo->player && P_IsLocalPlayer(mo->player)) { - INT32 promptnum = max(0, (sides[line->sidenum[0]].textureoffset>>FRACBITS)-1); - INT32 pagenum = max(0, (sides[line->sidenum[0]].rowoffset>>FRACBITS)-1); - INT32 postexectag = abs((line->sidenum[1] != 0xFFFF) ? sides[line->sidenum[1]].textureoffset>>FRACBITS : tag); + INT32 promptnum = max(0, line->args[0] - 1); + INT32 pagenum = max(0, line->args[1] - 1); + INT32 postexectag = abs(line->args[3]); - boolean closetextprompt = (line->flags & ML_BLOCKPLAYERS); - //boolean allplayers = (line->flags & ML_NOCLIMB); - boolean runpostexec = (line->flags & ML_EFFECT1); - boolean blockcontrols = !(line->flags & ML_EFFECT2); - boolean freezerealtime = !(line->flags & ML_EFFECT3); - //boolean freezethinkers = (line->flags & ML_EFFECT4); - boolean callbynamedtag = (line->flags & ML_TFERLINE); + boolean closetextprompt = (line->args[2] & TMP_CLOSE); + //boolean allplayers = (line->args[2] & TMP_ALLPLAYERS); + boolean runpostexec = (line->args[2] & TMP_RUNPOSTEXEC); + boolean blockcontrols = !(line->args[2] & TMP_KEEPCONTROLS); + boolean freezerealtime = !(line->args[2] & TMP_KEEPREALTIME); + //boolean freezethinkers = (line->args[2] & TMP_FREEZETHINKERS); + boolean callbynamedtag = (line->args[2] & TMP_CALLBYNAME); if (closetextprompt) F_EndTextPrompt(false, false); else { - if (callbynamedtag && sides[line->sidenum[0]].text && sides[line->sidenum[0]].text[0]) - F_GetPromptPageByNamedTag(sides[line->sidenum[0]].text, &promptnum, &pagenum); + if (callbynamedtag && line->stringargs[0] && line->stringargs[0][0]) + F_GetPromptPageByNamedTag(line->stringargs[0], &promptnum, &pagenum); F_StartTextPrompt(promptnum, pagenum, mo, runpostexec ? postexectag : 0, blockcontrols, freezerealtime); } } @@ -3658,8 +3465,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 460: // Award rings { - INT16 rings = (sides[line->sidenum[0]].textureoffset>>FRACBITS); - INT32 delay = (sides[line->sidenum[0]].rowoffset>>FRACBITS); + INT16 rings = line->args[0]; + INT32 delay = line->args[1]; if (mo && mo->player) { // Don't award rings while SPB is targetting you @@ -3678,34 +3485,28 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 461: // Spawns an object on the map based on texture offsets { - const mobjtype_t type = (mobjtype_t)(sides[line->sidenum[0]].toptexture); + const mobjtype_t type = line->stringargs[0] ? get_number(line->stringargs[0]) : MT_NULL; mobj_t *mobj; fixed_t x, y, z; - x = sides[line->sidenum[0]].textureoffset; - y = sides[line->sidenum[0]].rowoffset; - z = line->frontsector->floorheight; - if (line->flags & ML_NOCLIMB) // If noclimb is set, spawn randomly within a range + if (line->args[4]) // If args[4] is set, spawn randomly within a range { - if (line->sidenum[1] != 0xffff) // Make sure the linedef has a back side - { - x = P_RandomRange(PR_UNDEFINED, sides[line->sidenum[0]].textureoffset>>FRACBITS, sides[line->sidenum[1]].textureoffset>>FRACBITS)<sidenum[0]].rowoffset>>FRACBITS, sides[line->sidenum[1]].rowoffset>>FRACBITS)<frontsector->floorheight>>FRACBITS, line->frontsector->ceilingheight>>FRACBITS)<special); - break; - } + x = P_RandomRange(PR_UNDEFINED, line->args[0], line->args[5])<args[1], line->args[6])<args[2], line->args[7])<args[0] << FRACBITS; + y = line->args[1] << FRACBITS; + z = line->args[2] << FRACBITS; } mobj = P_SpawnMobj(x, y, z, type); if (mobj) { - if (line->flags & ML_EFFECT1) - mobj->angle = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y); + mobj->angle = FixedAngle(line->args[3] << FRACBITS); CONS_Debug(DBG_GAMELOGIC, "Linedef Type %d - Spawn Object: %d spawned at (%d, %d, %d)\n", line->special, mobj->type, mobj->x>>FRACBITS, mobj->y>>FRACBITS, mobj->z>>FRACBITS); //TODO: Convert mobj->type to a string somehow. } else @@ -3730,10 +3531,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 463: // Dye object { - INT32 color = sides[line->sidenum[0]].toptexture; - if (mo) { + INT32 color = line->stringargs[0] ? get_number(line->stringargs[0]) : SKINCOLOR_NONE; + if (color < 0 || color >= numskincolors) return; @@ -3746,31 +3547,28 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 464: // Trigger Egg Capsule { - thinker_t *th; + INT32 mtnum; mobj_t *mo2; // Find the center of the Eggtrap and release all the pretty animals! // The chimps are my friends.. heeheeheheehehee..... - LouisJM - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + TAG_ITER_THINGS(line->args[0], mtnum) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; + mo2 = mapthings[mtnum].mobj; - mo2 = (mobj_t *)th; + if (!mo2) + continue; if (mo2->type != MT_EGGTRAP) continue; - if (!mo2->spawnpoint) - continue; - - if (mo2->spawnpoint->angle != tag) + if (mo2->thinker.function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) continue; P_KillMobj(mo2, NULL, mo, DMG_NORMAL); } - if (!(line->flags & ML_NOCLIMB)) + if (!(line->args[1])) { INT32 i; @@ -3802,28 +3600,121 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } break; + case 466: // Set level failure state + { + if (line->args[1]) + { + stagefailed = false; + CONS_Debug(DBG_GAMELOGIC, "Stage can be completed successfully!\n"); + } + else + { + stagefailed = true; + CONS_Debug(DBG_GAMELOGIC, "Stage will end in failure...\n"); + } + } + break; + + case 467: // Set light level + TAG_ITER_SECTORS(line->args[0], secnum) + { + if (sectors[secnum].lightingdata) + { + // Stop any lighting effects going on in the sector + P_RemoveThinker(&((thinkerdata_t *)sectors[secnum].lightingdata)->thinker); + sectors[secnum].lightingdata = NULL; + } + + if (line->args[2] == TML_FLOOR) + { + if (line->args[3]) + sectors[secnum].floorlightlevel += line->args[1]; + else + sectors[secnum].floorlightlevel = line->args[1]; + } + else if (line->args[2] == TML_CEILING) + { + if (line->args[3]) + sectors[secnum].ceilinglightlevel += line->args[1]; + else + sectors[secnum].ceilinglightlevel = line->args[1]; + } + else + { + if (line->args[3]) + sectors[secnum].lightlevel += line->args[1]; + else + sectors[secnum].lightlevel = line->args[1]; + sectors[secnum].lightlevel = max(0, min(255, sectors[secnum].lightlevel)); + } + } + break; + + case 468: // Change linedef executor argument + { + INT32 linenum; + + if (!udmf) + break; + + if (line->args[1] < 0 || line->args[1] >= NUMLINEARGS) + { + CONS_Debug(DBG_GAMELOGIC, "Linedef type 468: Invalid linedef arg %d\n", line->args[1]); + break; + } + + TAG_ITER_LINES(line->args[0], linenum) + { + if (line->args[3]) + lines[linenum].args[line->args[1]] += line->args[2]; + else + lines[linenum].args[line->args[1]] = line->args[2]; + } + } + break; + + case 469: // Change sector gravity + { + fixed_t gravityvalue; + + if (!udmf) + break; + + if (!line->stringargs[0]) + break; + + gravityvalue = FloatToFixed(atof(line->stringargs[0])); + + TAG_ITER_SECTORS(line->args[0], secnum) + { + if (line->args[1]) + sectors[secnum].gravity = FixedMul(sectors[secnum].gravity, gravityvalue); + else + sectors[secnum].gravity = gravityvalue; + + if (line->args[2] == TMF_ADD) + sectors[secnum].flags |= MSF_GRAVITYFLIP; + else if (line->args[2] == TMF_REMOVE) + sectors[secnum].flags &= ~MSF_GRAVITYFLIP; + } + } + break; + case 480: // Polyobj_DoorSlide case 481: // Polyobj_DoorSwing PolyDoor(line); break; case 482: // Polyobj_Move - case 483: // Polyobj_OR_Move PolyMove(line); break; case 484: // Polyobj_RotateRight - case 485: // Polyobj_OR_RotateRight - case 486: // Polyobj_RotateLeft - case 487: // Polyobj_OR_RotateLeft PolyRotate(line); break; case 488: // Polyobj_Waypoint PolyWaypoint(line); break; case 489: - PolyInvisible(line); - break; - case 490: - PolyVisible(line); + PolySetVisibilityTangibility(line); break; case 491: PolyTranslucency(line); @@ -3844,7 +3735,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; } - TAG_ITER_SECTORS(tag, secnum) + TAG_ITER_SECTORS(line->args[0], secnum) { sec = sectors + secnum; @@ -4004,54 +3895,237 @@ void P_SetupSignExit(player_t *player) } } -// -// P_IsFlagAtBase -// -// Checks to see if a flag is at its base. -// -boolean P_IsFlagAtBase(mobjtype_t flag) +static boolean P_IsMobjTouchingPlane(mobj_t *mo, sector_t *sec, fixed_t floorz, fixed_t ceilingz) { - thinker_t *think; - mobj_t *mo; - INT32 specialnum = (flag == MT_REDFLAG) ? 3 : 4; + boolean floorallowed = ((sec->flags & MSF_FLIPSPECIAL_FLOOR) && ((sec->flags & MSF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->z == floorz)); + boolean ceilingallowed = ((sec->flags & MSF_FLIPSPECIAL_CEILING) && ((sec->flags & MSF_TRIGGERSPECIAL_HEADBUMP) || (mo->eflags & MFE_VERTICALFLIP)) && (mo->z + mo->height == ceilingz)); + return (floorallowed || ceilingallowed); +} - for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) +boolean P_IsMobjTouchingSectorPlane(mobj_t *mo, sector_t *sec) +{ + return P_IsMobjTouchingPlane(mo, sec, P_GetSpecialBottomZ(mo, sec, sec), P_GetSpecialTopZ(mo, sec, sec)); +} + +boolean P_IsMobjTouching3DFloor(mobj_t *mo, ffloor_t *ffloor, sector_t *sec) +{ + fixed_t topheight = P_GetSpecialTopZ(mo, sectors + ffloor->secnum, sec); + fixed_t bottomheight = P_GetSpecialBottomZ(mo, sectors + ffloor->secnum, sec); + + if (((ffloor->flags & FF_BLOCKPLAYER) && mo->player) + || ((ffloor->flags & FF_BLOCKOTHERS) && !mo->player)) { - if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo = (mobj_t *)think; - - if (mo->type != flag) - continue; - - if (GETSECSPECIAL(mo->subsector->sector->special, 4) == specialnum) - return true; - else if (mo->subsector->sector->ffloors) // Check the 3D floors - { - ffloor_t *rover; - - for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS)) - continue; - - if (GETSECSPECIAL(rover->master->frontsector->special, 4) != specialnum) - continue; - - if (!(mo->z <= P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector) - && mo->z >= P_GetSpecialBottomZ(mo, sectors + rover->secnum, mo->subsector->sector))) - continue; - - return true; - } - } + // Solid 3D floor: Mobj must touch the top or bottom + return P_IsMobjTouchingPlane(mo, ffloor->master->frontsector, topheight, bottomheight); } - return false; + else + { + // Water or intangible 3D floor: Mobj must be inside + return mo->z <= topheight && (mo->z + mo->height) >= bottomheight; + } +} + +boolean P_IsMobjTouchingPolyobj(mobj_t *mo, polyobj_t *po, sector_t *polysec) +{ + if (!(po->flags & POF_TESTHEIGHT)) // Don't do height checking + return true; + + if (po->flags & POF_SOLID) + { + // Solid polyobject: Player must touch the top or bottom + return P_IsMobjTouchingPlane(mo, polysec, polysec->ceilingheight, polysec->floorheight); + } + else + { + // Water or intangible polyobject: Player must be inside + return mo->z <= polysec->ceilingheight && (mo->z + mo->height) >= polysec->floorheight; + } +} + +static sector_t *P_MobjTouching3DFloorSpecial(mobj_t *mo, sector_t *sector, INT32 section, INT32 number) +{ + ffloor_t *rover; + + for (rover = sector->ffloors; rover; rover = rover->next) + { + if (GETSECSPECIAL(rover->master->frontsector->special, section) != number) + continue; + + if (!(rover->flags & FF_EXISTS)) + continue; + + if (!P_IsMobjTouching3DFloor(mo, rover, sector)) + continue; + + // This FOF has the special we're looking for, but are we allowed to touch it? + if (sector == mo->subsector->sector + || (rover->master->frontsector->flags & MSF_TRIGGERSPECIAL_TOUCH)) + return rover->master->frontsector; + } + + return NULL; +} + +static sector_t *P_MobjTouching3DFloorSpecialFlag(mobj_t *mo, sector_t *sector, sectorspecialflags_t flag) +{ + ffloor_t *rover; + + for (rover = sector->ffloors; rover; rover = rover->next) + { + if (!(rover->master->frontsector->specialflags & flag)) + continue; + + if (!(rover->flags & FF_EXISTS)) + continue; + + if (!P_IsMobjTouching3DFloor(mo, rover, sector)) + continue; + + // This FOF has the special we're looking for, but are we allowed to touch it? + if (sector == mo->subsector->sector + || (rover->master->frontsector->flags & MSF_TRIGGERSPECIAL_TOUCH)) + return rover->master->frontsector; + } + + return NULL; +} + +static sector_t *P_MobjTouchingPolyobjSpecial(mobj_t *mo, INT32 section, INT32 number) +{ + polyobj_t *po; + sector_t *polysec; + boolean touching = false; + boolean inside = false; + + for (po = mo->subsector->polyList; po; po = (polyobj_t *)(po->link.next)) + { + if (po->flags & POF_NOSPECIALS) + continue; + + polysec = po->lines[0]->backsector; + + if (GETSECSPECIAL(polysec->special, section) != number) + continue; + + touching = (polysec->flags & MSF_TRIGGERSPECIAL_TOUCH) && P_MobjTouchingPolyobj(po, mo); + inside = P_MobjInsidePolyobj(po, mo); + + if (!(inside || touching)) + continue; + + if (!P_IsMobjTouchingPolyobj(mo, po, polysec)) + continue; + + return polysec; + } + + return NULL; +} + +static sector_t *P_MobjTouchingPolyobjSpecialFlag(mobj_t *mo, sectorspecialflags_t flag) +{ + polyobj_t *po; + sector_t *polysec; + boolean touching = false; + boolean inside = false; + + for (po = mo->subsector->polyList; po; po = (polyobj_t *)(po->link.next)) + { + if (po->flags & POF_NOSPECIALS) + continue; + + polysec = po->lines[0]->backsector; + + if (!(polysec->specialflags & flag)) + continue; + + touching = (polysec->flags & MSF_TRIGGERSPECIAL_TOUCH) && P_MobjTouchingPolyobj(po, mo); + inside = P_MobjInsidePolyobj(po, mo); + + if (!(inside || touching)) + continue; + + if (!P_IsMobjTouchingPolyobj(mo, po, polysec)) + continue; + + return polysec; + } + + return NULL; +} + +sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number) +{ + msecnode_t *node; + sector_t *result; + + result = P_MobjTouching3DFloorSpecial(mo, mo->subsector->sector, section, number); + if (result) + return result; + + result = P_MobjTouchingPolyobjSpecial(mo, section, number); + if (result) + return result; + + if (GETSECSPECIAL(mo->subsector->sector->special, section) == number) + return mo->subsector->sector; + + for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) + { + if (node->m_sector == mo->subsector->sector) // Don't duplicate + continue; + + result = P_MobjTouching3DFloorSpecial(mo, node->m_sector, section, number); + if (result) + return result; + + if (!(node->m_sector->flags & MSF_TRIGGERSPECIAL_TOUCH)) + continue; + + if (GETSECSPECIAL(node->m_sector->special, section) == number) + return node->m_sector; + } + + return NULL; +} + +sector_t *P_MobjTouchingSectorSpecialFlag(mobj_t *mo, sectorspecialflags_t flag) +{ + msecnode_t *node; + sector_t *result; + + result = P_MobjTouching3DFloorSpecialFlag(mo, mo->subsector->sector, flag); + if (result) + return result; + + result = P_MobjTouchingPolyobjSpecialFlag(mo, flag); + if (result) + return result; + + if (mo->subsector->sector->specialflags & flag) + return mo->subsector->sector; + + for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) + { + if (node->m_sector == mo->subsector->sector) // Don't duplicate + continue; + + result = P_MobjTouching3DFloorSpecialFlag(mo, node->m_sector, flag); + if (result) + return result; + + if (!(node->m_sector->flags & MSF_TRIGGERSPECIAL_TOUCH)) + continue; + + if (node->m_sector->specialflags & flag) + return node->m_sector; + } + + return NULL; } // -// P_MobjTouchingSectorSpecial +// P_PlayerTouchingSectorSpecial // // Replaces the old player->specialsector. // This allows a player to touch more than @@ -4061,316 +4135,539 @@ boolean P_IsFlagAtBase(mobjtype_t flag) // the particular type that it finds. // Returns NULL if it doesn't find it. // -// Sal: Couldn't see a reason for this to -// be a player_t only function. -// -sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number, boolean touchground) +sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 number) +{ + if (!player->mo) + return NULL; + + return P_MobjTouchingSectorSpecial(player->mo, section, number); +} + +sector_t *P_PlayerTouchingSectorSpecialFlag(player_t *player, sectorspecialflags_t flag) +{ + if (!player->mo) + return NULL; + + return P_MobjTouchingSectorSpecialFlag(player->mo, flag); +} + +static sector_t *P_CheckPlayer3DFloorTrigger(player_t *player, sector_t *sector, line_t *sourceline) { - fixed_t topheight, bottomheight; - msecnode_t *node; ffloor_t *rover; - if (mo == NULL || P_MobjWasRemoved(mo) == true) + for (rover = sector->ffloors; rover; rover = rover->next) { - return NULL; - } + if (!rover->master->frontsector->triggertag) + continue; - // Check default case first - if (GETSECSPECIAL(mo->subsector->sector->special, section) == number) - { - if (touchground) - { - topheight = P_GetSpecialTopZ(mo, mo->subsector->sector, mo->subsector->sector); - bottomheight = P_GetSpecialBottomZ(mo, mo->subsector->sector, mo->subsector->sector); - - // Thing must be on top of the floor to be affected... - if (mo->subsector->sector->flags & SF_FLIPSPECIAL_FLOOR) - { - if (!(mo->eflags & MFE_VERTICALFLIP) && mo->z <= bottomheight) - return mo->subsector->sector; - } - - if (mo->subsector->sector->flags & SF_FLIPSPECIAL_CEILING) - { - if ((mo->eflags & MFE_VERTICALFLIP) && mo->z + mo->height >= topheight) - return mo->subsector->sector; - } - } - else - { - return mo->subsector->sector; - } - } - - // Hmm.. maybe there's a FOF that has it... - for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next) - { - if (GETSECSPECIAL(rover->master->frontsector->special, section) != number) + if (rover->master->frontsector->triggerer == TO_MOBJ) continue; if (!(rover->flags & FF_EXISTS)) continue; - topheight = P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector); - bottomheight = P_GetSpecialBottomZ(mo, sectors + rover->secnum, mo->subsector->sector); + if (!Tag_Find(&sourceline->tags, rover->master->frontsector->triggertag)) + continue; - // Check the 3D floor's type... - if (((rover->flags & FF_BLOCKPLAYER) && mo->player) - || ((rover->flags & FF_BLOCKOTHERS) && !mo->player)) - { - boolean floorallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) - && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) - || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->z == topheight)); + if (!P_IsMobjTouching3DFloor(player->mo, rover, sector)) + continue; - boolean ceilingallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) - && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) - || (mo->eflags & MFE_VERTICALFLIP)) && (mo->z + mo->height == bottomheight)); - // Thing must be on top of the floor to be affected... - - if (!(floorallowed || ceilingallowed)) - continue; - } - else - { - // Water and DEATH FOG!!! heh - if (mo->z > topheight || (mo->z + mo->height) < bottomheight) - continue; - } - - // This FOF has the special we're looking for! - return rover->master->frontsector; - } - - // Allow sector specials to be applied to polyobjects! - if (mo->subsector->polyList) - { - polyobj_t *po = mo->subsector->polyList; - sector_t *polysec; - boolean touching = false; - boolean inside = false; - - while (po) - { - if (po->flags & POF_NOSPECIALS) - { - po = (polyobj_t *)(po->link.next); - continue; - } - - polysec = po->lines[0]->backsector; - - if (GETSECSPECIAL(polysec->special, section) != number) - { - po = (polyobj_t *)(po->link.next); - continue; - } - - if ((polysec->flags & SF_TRIGGERSPECIAL_TOUCH)) - touching = P_MobjTouchingPolyobj(po, mo); - else - touching = false; - - inside = P_MobjInsidePolyobj(po, mo); - - if (!(inside || touching)) - { - po = (polyobj_t *)(po->link.next); - continue; - } - - topheight = polysec->ceilingheight; - bottomheight = polysec->floorheight; - - // We're inside it! Yess... - if (!(po->flags & POF_TESTHEIGHT)) // Don't do height checking - { - } - else if (po->flags & POF_SOLID) - { - // Thing must be on top of the floor to be affected... - if ((polysec->flags & SF_FLIPSPECIAL_FLOOR) - && !(polysec->flags & SF_FLIPSPECIAL_CEILING)) - { - if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != topheight) - { - po = (polyobj_t *)(po->link.next); - continue; - } - } - else if ((polysec->flags & SF_FLIPSPECIAL_CEILING) - && !(polysec->flags & SF_FLIPSPECIAL_FLOOR)) - { - if (!(mo->eflags & MFE_VERTICALFLIP) || mo->z + mo->height != bottomheight) - { - po = (polyobj_t *)(po->link.next); - continue; - } - } - else if (polysec->flags & SF_FLIPSPECIAL_BOTH) - { - if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == bottomheight) - || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == topheight))) - { - po = (polyobj_t *)(po->link.next); - continue; - } - } - } - else - { - // Water and DEATH FOG!!! heh - if (mo->z > topheight || (mo->z + mo->height) < bottomheight) - { - po = (polyobj_t *)(po->link.next); - continue; - } - } - - return polysec; - } - } - - for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) - { - if (GETSECSPECIAL(node->m_sector->special, section) == number) - { - // This sector has the special we're looking for, but - // are we allowed to touch it? - if (node->m_sector == mo->subsector->sector - || (node->m_sector->flags & SF_TRIGGERSPECIAL_TOUCH)) - { - if (touchground) - { - topheight = P_GetSpecialTopZ(mo, node->m_sector, node->m_sector); - bottomheight = P_GetSpecialBottomZ(mo, node->m_sector, node->m_sector); - - // Thing must be on top of the floor to be affected... - if (node->m_sector->flags & SF_FLIPSPECIAL_FLOOR) - { - if (!(mo->eflags & MFE_VERTICALFLIP) && mo->z <= bottomheight) - return node->m_sector; - } - - if (node->m_sector->flags & SF_FLIPSPECIAL_CEILING) - { - if ((mo->eflags & MFE_VERTICALFLIP) && mo->z + mo->height >= topheight) - return node->m_sector; - } - } - else - { - return node->m_sector; - } - } - } - - // Hmm.. maybe there's a FOF that has it... - for (rover = node->m_sector->ffloors; rover; rover = rover->next) - { - if (GETSECSPECIAL(rover->master->frontsector->special, section) != number) - continue; - - if (!(rover->flags & FF_EXISTS)) - continue; - - topheight = P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector); - bottomheight = P_GetSpecialBottomZ(mo, sectors + rover->secnum, mo->subsector->sector); - - // Check the 3D floor's type... - if (((rover->flags & FF_BLOCKPLAYER) && mo->player) - || ((rover->flags & FF_BLOCKOTHERS) && !mo->player)) - { - boolean floorallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) - && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) - || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->z == topheight)); - - boolean ceilingallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) - && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) - || (mo->eflags & MFE_VERTICALFLIP)) && (mo->z + mo->height == bottomheight)); - // Thing must be on top of the floor to be affected... - - if (!(floorallowed || ceilingallowed)) - continue; - } - else - { - // Water and DEATH FOG!!! heh - if (mo->z > topheight || (mo->z + mo->height) < bottomheight) - continue; - } - - // This FOF has the special we're looking for, but are we allowed to touch it? - if (node->m_sector == mo->subsector->sector - || (rover->master->frontsector->flags & SF_TRIGGERSPECIAL_TOUCH)) - return rover->master->frontsector; - } + // This FOF has the special we're looking for, but are we allowed to touch it? + if (sector == player->mo->subsector->sector + || (rover->master->frontsector->flags & MSF_TRIGGERSPECIAL_TOUCH)) + return rover->master->frontsector; } return NULL; } -// -// P_ThingIsOnThe3DFloor -// -// This checks whether the mobj is on/in the FOF we want it to be at -// Needed for the "All players" trigger sector specials only -// -static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *targetsec) +static sector_t *P_CheckPlayerPolyobjTrigger(player_t *player, line_t *sourceline) { - ffloor_t *rover; - fixed_t top, bottom; + polyobj_t *po; + sector_t *polysec; + boolean touching = false; + boolean inside = false; - if (!mo->player) // should NEVER happen - return false; - - if (!targetsec->ffloors) // also should NEVER happen - return false; - - for (rover = targetsec->ffloors; rover; rover = rover->next) + for (po = player->mo->subsector->polyList; po; po = (polyobj_t *)(po->link.next)) { - if (rover->master->frontsector != sector) + if (po->flags & POF_NOSPECIALS) continue; - // we're assuming the FOF existed when the first player touched it - //if (!(rover->flags & FF_EXISTS)) - // return false; + polysec = po->lines[0]->backsector; - top = P_GetSpecialTopZ(mo, sector, targetsec); - bottom = P_GetSpecialBottomZ(mo, sector, targetsec); + if (!polysec->triggertag) + continue; - // Check the 3D floor's type... - if (rover->flags & FF_BLOCKPLAYER) - { - boolean floorallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->z == top)); - boolean ceilingallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (mo->eflags & MFE_VERTICALFLIP)) && (mo->z + mo->height == bottom)); - // Thing must be on top of the floor to be affected... - if (!(floorallowed || ceilingallowed)) - continue; - } - else - { - // Water and intangible FOFs - if (mo->z > top || (mo->z + mo->height) < bottom) - return false; - } + if (polysec->triggerer == TO_MOBJ) + continue; - return true; + if (!Tag_Find(&sourceline->tags, polysec->triggertag)) + continue; + + touching = (polysec->flags & MSF_TRIGGERSPECIAL_TOUCH) && P_MobjTouchingPolyobj(po, player->mo); + inside = P_MobjInsidePolyobj(po, player->mo); + + if (!(inside || touching)) + continue; + + if (!P_IsMobjTouchingPolyobj(player->mo, po, polysec)) + continue; + + return polysec; + } + + return NULL; +} + +static boolean P_CheckPlayerSectorTrigger(player_t *player, sector_t *sector, line_t *sourceline) +{ + if (!sector->triggertag) + return false; + + if (sector->triggerer == TO_MOBJ) + return false; + + if (!Tag_Find(&sourceline->tags, sector->triggertag)) + return false; + + if (!(sector->flags & MSF_TRIGGERLINE_PLANE)) + return true; // Don't require plane touch + + return P_IsMobjTouchingSectorPlane(player->mo, sector); + +} + +sector_t *P_FindPlayerTrigger(player_t *player, line_t *sourceline) +{ + sector_t *originalsector; + sector_t *loopsector; + msecnode_t *node; + sector_t *caller; + + if (!player->mo) + return NULL; + + originalsector = player->mo->subsector->sector; + + caller = P_CheckPlayer3DFloorTrigger(player, originalsector, sourceline); // Handle FOFs first. + + if (caller) + return caller; + + // Allow sector specials to be applied to polyobjects! + caller = P_CheckPlayerPolyobjTrigger(player, sourceline); + + if (caller) + return caller; + + if (P_CheckPlayerSectorTrigger(player, originalsector, sourceline)) + return originalsector; + + // Iterate through touching_sectorlist for SF_TRIGGERSPECIAL_TOUCH + for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next) + { + loopsector = node->m_sector; + + if (loopsector == originalsector) // Don't duplicate + continue; + + // Check 3D floors... + caller = P_CheckPlayer3DFloorTrigger(player, loopsector, sourceline); // Handle FOFs first. + + if (caller) + return caller; + + if (!(loopsector->flags & MSF_TRIGGERSPECIAL_TOUCH)) + continue; + + if (P_CheckPlayerSectorTrigger(player, loopsector, sourceline)) + return loopsector; } return false; } -// -// P_MobjReadyToTrigger -// -// Is player standing on the sector's "ground"? -// -static boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec) +boolean P_IsPlayerValid(size_t playernum) { - boolean floorallowed = ((sec->flags & SF_FLIPSPECIAL_FLOOR) && ((sec->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->z == P_GetSpecialBottomZ(mo, sec, sec))); - boolean ceilingallowed = ((sec->flags & SF_FLIPSPECIAL_CEILING) && ((sec->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (mo->eflags & MFE_VERTICALFLIP)) && (mo->z + mo->height == P_GetSpecialTopZ(mo, sec, sec))); - // Thing must be on top of the floor to be affected... - return (floorallowed || ceilingallowed); + if (!playeringame[playernum]) + return false; + + if (!players[playernum].mo) + return false; + + if (players[playernum].mo->health <= 0) + return false; + + if (players[playernum].spectator) + return false; + + return true; +} + +boolean P_CanPlayerTrigger(size_t playernum) +{ + return P_IsPlayerValid(playernum) && !players[playernum].bot; +} + +/// \todo check continues for proper splitscreen support? +static boolean P_DoAllPlayersTrigger(mtag_t triggertag) +{ + INT32 i; + line_t dummyline; + dummyline.tags.count = 1; + dummyline.tags.tags = &triggertag; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!P_CanPlayerTrigger(i)) + continue; + if (!P_FindPlayerTrigger(&players[i], &dummyline)) + return false; + } + + return true; +} + +static void P_ProcessEggCapsule(player_t *player, sector_t *sector) +{ + thinker_t *th; + mobj_t *mo2; + INT32 i; + + if (player->bot || sector->ceilingdata || sector->floordata) + return; + + // Find the center of the Eggtrap and release all the pretty animals! + // The chimps are my friends.. heeheeheheehehee..... - LouisJM + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mo2 = (mobj_t *)th; + if (mo2->type != MT_EGGTRAP) + continue; + P_KillMobj(mo2, NULL, player->mo, 0); + } + + // clear the special so you can't push the button twice. + sector->special = 0; + + // Move the button down + EV_DoElevator(LE_CAPSULE0, NULL, elevateDown); + + // Open the top FOF + EV_DoFloor(LE_CAPSULE1, NULL, raiseFloorToNearestFast); + // Open the bottom FOF + EV_DoCeiling(LE_CAPSULE2, NULL, lowerToLowestFast); + + // Mark all players with the time to exit thingy! + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + P_DoPlayerExit(&players[i]); + } +} + +static void P_ProcessSpeedPad(player_t *player, sector_t *sector, sector_t *roversector, mtag_t sectag) +{ + INT32 lineindex = -1; + angle_t lineangle; + fixed_t linespeed; + fixed_t playerspeed; + fixed_t sfxnum; + size_t i; + + (void)roversector; + + // Try for lines facing the sector itself, with tag 0. + for (i = 0; i < sector->linecount; i++) + { + line_t *li = sector->lines[i]; + + if (li->frontsector != sector) + continue; + + if (li->special != 4) + continue; + + if (!Tag_Find(&li->tags, 0)) + continue; + + lineindex = li - lines; + break; + } + + // Nothing found? Look via tag. + if (lineindex == -1) + lineindex = Tag_FindLineSpecial(4, sectag); + + if (lineindex == -1) + { + CONS_Debug(DBG_GAMELOGIC, "ERROR: Speed pad missing line special #4.\n"); + return; + } + + lineangle = lines[lineindex].angle; + linespeed = lines[lineindex].args[0] << FRACBITS; + + if (linespeed == 0) + { + CONS_Debug(DBG_GAMELOGIC, "ERROR: Speed pad (tag %d) at zero speed.\n", sectag); + return; + } + + if (player->floorboost != 0) + { + player->floorboost = 2; + return; + } + + playerspeed = P_AproxDistance(player->mo->momx, player->mo->momy); + + // SRB2Kart: Scale the speed you get from them! + // This is scaled differently from other horizontal speed boosts from stuff like springs, because of how this is used for some ramp jumps. + if (player->mo->scale > mapobjectscale) + { + linespeed = FixedMul(linespeed, mapobjectscale + (player->mo->scale - mapobjectscale)); + } + + lineangle = K_ReflectAngle( + K_MomentumAngle(player->mo), lineangle, + playerspeed, linespeed + ); + + P_InstaThrust(player->mo, lineangle, max(linespeed, 2*playerspeed)); + + player->dashpadcooldown = TICRATE/3; + player->trickpanel = 0; + player->floorboost = 2; + + sfxnum = lines[lineindex].stringargs[0] ? get_number(lines[lineindex].stringargs[0]) : sfx_cdfm62; + + if (!sfxnum) + sfxnum = sfx_cdfm62; + + S_StartSound(player->mo, sfxnum); +} + +static void P_ProcessExitSector(player_t *player, mtag_t sectag) +{ +#if 1 + (void)player; + (void)sectag; +#else + INT32 lineindex; + + if (!(gametyperules & GTR_ALLOWEXIT)) + return; + + // Exit (for FOF exits; others are handled in P_PlayerThink in p_user.c) + P_DoPlayerFinish(player); + + P_SetupSignExit(player); + + if (!G_CoopGametype()) + return; + + // Custom exit! + // important: use sectag on next line instead of player->mo->subsector->tag + // this part is different from in P_PlayerThink, this is what was causing + // FOF custom exits not to work. + lineindex = Tag_FindLineSpecial(2, sectag); + + if (lineindex == -1) + { + CONS_Debug(DBG_GAMELOGIC, "ERROR: Exit sector missing line special #2.\n"); + return; + } + + // Special goodies depending on emeralds collected + if ((lines[lineindex].args[1] & TMEF_EMERALDCHECK) && ALLCHAOSEMERALDS(emeralds)) + nextmapoverride = (INT16)(udmf ? lines[lineindex].args[2] : lines[lineindex].frontsector->ceilingheight>>FRACBITS); + else + nextmapoverride = (INT16)(udmf ? lines[lineindex].args[0] : lines[lineindex].frontsector->floorheight>>FRACBITS); + + if (lines[lineindex].args[1] & TMEF_SKIPTALLY) + skipstats = 1; +#endif +} + +static void P_ProcessZoomTube(player_t *player, mtag_t sectag, boolean end) +{ + INT32 sequence; + fixed_t speed; + INT32 lineindex; + mobj_t *waypoint = NULL; + angle_t an; + + if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->carry == CR_ZOOMTUBE) + return; + + // Find line #3 tagged to this sector + lineindex = Tag_FindLineSpecial(3, sectag); + + if (lineindex == -1) + { + CONS_Debug(DBG_GAMELOGIC, "ERROR: Zoom tube missing line special #3.\n"); + return; + } + + // Grab speed and sequence values + speed = abs(lines[lineindex].args[0])<<(FRACBITS-3); + if (end) + speed *= -1; + sequence = abs(lines[lineindex].args[1]); + + if (speed == 0) + { + CONS_Debug(DBG_GAMELOGIC, "ERROR: Waypoint sequence %d at zero speed.\n", sequence); + return; + } + + waypoint = end ? P_GetLastTubeWaypoint(sequence) : P_GetFirstTubeWaypoint(sequence); + + if (!waypoint) + { + CONS_Debug(DBG_GAMELOGIC, "ERROR: %s WAYPOINT IN SEQUENCE %d NOT FOUND.\n", end ? "LAST" : "FIRST", sequence); + return; + } + + CONS_Debug(DBG_GAMELOGIC, "Waypoint %d found in sequence %d - speed = %d\n", waypoint->health, sequence, speed); + + an = R_PointToAngle2(player->mo->x, player->mo->y, waypoint->x, waypoint->y) - player->mo->angle; + + if (an > ANGLE_90 && an < ANGLE_270 && !(lines[lineindex].args[2])) + return; // behind back + + P_SetTarget(&player->mo->tracer, waypoint); + player->carry = CR_ZOOMTUBE; + player->speed = speed; + + if (player->mo->state-states != S_KART_SPINOUT) + { + P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); + S_StartSound(player->mo, sfx_spin); + } +} + +static boolean P_SectorHasSpecial(sector_t *sec) +{ + if (sec->specialflags) + return true; + + if (sec->damagetype != SD_NONE) + return true; + + if (sec->triggertag) + return true; + + if (sec->special) + return true; + + return false; +} + +static void P_EvaluateSpecialFlags(player_t *player, sector_t *sector, sector_t *roversector, boolean isTouching) +{ + mtag_t sectag = Tag_FGet(§or->tags); + + if (sector->specialflags & SSF_WINDCURRENT) + player->onconveyor = 2; + if (sector->specialflags & SSF_CONVEYOR) + player->onconveyor = 4; + if ((sector->specialflags & SSF_SPEEDPAD) && isTouching) + P_ProcessSpeedPad(player, sector, roversector, sectag); + if (sector->specialflags & SSF_STARPOSTACTIVATOR) + { + mobj_t *post = P_GetObjectTypeInSectorNum(MT_STARPOST, sector - sectors); + if (post) + P_TouchStarPost(post, player, false); + } + if (sector->specialflags & SSF_EXIT) + P_ProcessExitSector(player, sectag); + if (sector->specialflags & SSF_FAN) + { + player->mo->momz += mobjinfo[MT_FAN].mass/4; + + if (player->mo->momz > mobjinfo[MT_FAN].mass) + player->mo->momz = mobjinfo[MT_FAN].mass; + + P_ResetPlayer(player); + /* + if (player->panim != PA_FALL) + P_SetPlayerMobjState(player->mo, S_PLAY_FALL); + */ + } + if (sector->specialflags & SSF_ZOOMTUBESTART) + P_ProcessZoomTube(player, sectag, false); + if (sector->specialflags & SSF_ZOOMTUBEEND) + P_ProcessZoomTube(player, sectag, true); +} + +static void P_EvaluateDamageType(player_t *player, sector_t *sector, boolean isTouching) +{ + switch (sector->damagetype) + { + case SD_GENERIC: + if (isTouching && K_IsRidingFloatingTop(player) == false) + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_NORMAL); + break; + case SD_DEATHPIT: + if (isTouching) + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DEATHPIT); + break; + case SD_INSTAKILL: + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL); + break; + default: + break; + } +} + +static void P_EvaluateLinedefExecutorTrigger(player_t *player, sector_t *sector, boolean isTouching) +{ + if (player->bot) + return; + + if (!sector->triggertag) + return; + + if (sector->triggerer == TO_MOBJ) + return; + else if (sector->triggerer == TO_ALLPLAYERS && !P_DoAllPlayersTrigger(sector->triggertag)) + return; + + if ((sector->flags & MSF_TRIGGERLINE_PLANE) && !isTouching) + return; + + P_LinedefExecute(sector->triggertag, player->mo, sector); +} + +static void P_EvaluateOldSectorSpecial(player_t *player, sector_t *sector, sector_t *roversector, boolean isTouching) +{ + switch (GETSECSPECIAL(sector->special, 1)) + { + case 9: // Ring Drainer (Floor Touch) + if (!isTouching) + break; + /* FALLTHRU */ + case 10: // Ring Drainer (No Floor Touch) + if (leveltime % (TICRATE/2) == 0 && player->rings > 0) + { + player->rings--; + S_StartSound(player->mo, sfx_antiri); + } + break; + } + + switch (GETSECSPECIAL(sector->special, 2)) + { + case 9: // Egg trap capsule + if (roversector) + P_ProcessEggCapsule(player, sector); + break; + } } /** Applies a sector special to a player. @@ -4379,20 +4676,14 @@ static boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec) * \param sector Sector with the special. * \param roversector If !NULL, sector is actually an FOF; otherwise, sector * is being physically contacted by the player. - * \todo Split up into multiple functions. * \sa P_PlayerInSpecialSector, P_PlayerOnSpecial3DFloor */ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *roversector) { - INT32 i = 0; - INT32 section1, section2, section3, section4; - INT32 special; - mtag_t sectag = Tag_FGet(§or->tags); + boolean isTouching; - section1 = GETSECSPECIAL(sector->special, 1); - section2 = GETSECSPECIAL(sector->special, 2); - section3 = GETSECSPECIAL(sector->special, 3); - section4 = GETSECSPECIAL(sector->special, 4); + if (!P_SectorHasSpecial(sector)) + return; // Ignore spectators if (player->spectator) @@ -4404,514 +4695,17 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers if (player->playerstate != PST_LIVE) return; - // Conveyor stuff - if (section3 == 2 || section3 == 4) - { - player->onconveyor = section3; - } + isTouching = roversector || P_IsMobjTouchingSectorPlane(player->mo, sector); - special = section1; + P_EvaluateSpecialFlags(player, sector, roversector, isTouching); + P_EvaluateDamageType(player, sector, isTouching); + P_EvaluateLinedefExecutorTrigger(player, sector, isTouching); - // Process Section 1 - switch (special) - { - case 1: // Damage (Generic) - if (!K_IsRidingFloatingTop(player) && (roversector || P_MobjReadyToTrigger(player->mo, sector))) - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_NORMAL); - break; - case 2: // Damage (Water) // SRB2kart - These three damage types are now offroad sectors - case 3: // Damage (Fire) - case 4: // Damage (Electrical) - break; - case 5: // Spikes - if (!K_IsRidingFloatingTop(player) && (roversector || P_MobjReadyToTrigger(player->mo, sector))) - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_NORMAL); - break; - case 6: // Death Pit (Camera Mod) - case 7: // Death Pit (No Camera Mod) - if (roversector || P_MobjReadyToTrigger(player->mo, sector)) - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DEATHPIT); - break; - case 8: // Instant Kill - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL); - break; - case 9: // Ring Drainer (Floor Touch) - case 10: // Ring Drainer (No Floor Touch) - if (leveltime % (TICRATE/2) == 0 && player->rings > 0) - { - player->rings--; - S_StartSound(player->mo, sfx_antiri); - } - break; - case 11: // Unused - case 12: // Wall Sector (Don't step-up/down) - case 13: // Ramp Sector (Increase step-up/down) - case 14: // Non-Ramp Sector (Don't step-down) - case 15: // Bouncy Sector (FOF Control Only) - break; - } - - special = section2; - - // Process Section 2 - switch (special) - { - case 1: // Trigger Linedef Exec (Pushable Objects) - break; - case 2: // Linedef executor requires all players present+doesn't require touching floor - case 3: // Linedef executor requires all players present - /// \todo check continues for proper splitscreen support? - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - if (!players[i].mo) - continue; - if (players[i].spectator) - continue; - if (players[i].bot) - continue; - if (roversector) - { - if (sector->flags & SF_TRIGGERSPECIAL_TOUCH) - { - msecnode_t *node; - for (node = players[i].mo->touching_sectorlist; node; node = node->m_sectorlist_next) - { - if (P_ThingIsOnThe3DFloor(players[i].mo, sector, node->m_sector)) - break; - } - if (!node) - goto DoneSection2; - } - else if (players[i].mo->subsector && !P_ThingIsOnThe3DFloor(players[i].mo, sector, players[i].mo->subsector->sector)) // this function handles basically everything for us lmao - goto DoneSection2; - } - else - { - if (players[i].mo->subsector->sector == sector) - ; - else if (sector->flags & SF_TRIGGERSPECIAL_TOUCH) - { - msecnode_t *node; - for (node = players[i].mo->touching_sectorlist; node; node = node->m_sectorlist_next) - { - if (node->m_sector == sector) - break; - } - if (!node) - goto DoneSection2; - } - else - goto DoneSection2; - - if (special == 3 && !P_MobjReadyToTrigger(players[i].mo, sector)) - goto DoneSection2; - } - } - /* FALLTHRU */ - case 4: // Linedef executor that doesn't require touching floor - case 5: // Linedef executor - case 6: // Linedef executor (7 Emeralds) - case 7: // Linedef executor (NiGHTS Mare) - P_LinedefExecute(sectag, player->mo, sector); - break; - case 8: // Tells pushable things to check FOFs - break; - case 9: // Egg trap capsule - { - thinker_t *th; - mobj_t *mo2; - line_t junk; - - if (sector->ceilingdata || sector->floordata) - return; - - // Find the center of the Eggtrap and release all the pretty animals! - // The chimps are my friends.. heeheeheheehehee..... - LouisJM - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - mo2 = (mobj_t *)th; - if (mo2->type != MT_EGGTRAP) - continue; - P_KillMobj(mo2, NULL, player->mo, DMG_NORMAL); - } - - // clear the special so you can't push the button twice. - sector->special = 0; - - // Initialize my junk - junk.tags.tags = NULL; - junk.tags.count = 0; - - // Move the button down - Tag_FSet(&junk.tags, LE_CAPSULE0); - EV_DoElevator(&junk, elevateDown, false); - - // Open the top FOF - Tag_FSet(&junk.tags, LE_CAPSULE1); - EV_DoFloor(&junk, raiseFloorToNearestFast); - // Open the bottom FOF - Tag_FSet(&junk.tags, LE_CAPSULE2); - EV_DoCeiling(&junk, lowerToLowestFast); - - // Mark all players with the time to exit thingy! - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - P_DoPlayerExit(&players[i]); - } - break; - } - case 10: // Special Stage Time/Rings - case 11: // Custom Gravity - break; - case 12: // Lua sector special - break; - case 15: // Invert Encore Remap - break; - } -DoneSection2: - - special = section3; - - // Process Section 3 - switch (special) - { - case 1: // SRB2kart: Spring Panel - case 3: - if (roversector || P_MobjReadyToTrigger(player->mo, sector)) - { - const fixed_t hscale = mapobjectscale + (mapobjectscale - player->mo->scale); - const fixed_t minspeed = 24*hscale; - fixed_t speed = FixedHypot(player->mo->momx, player->mo->momy); - fixed_t upwards = 32*FRACUNIT; - - if (player->mo->eflags & MFE_SPRUNG) - { - break; - } - - if (special == 3) - { - upwards /= 2; - } - - player->trickpanel = 1; - player->pflags |= PF_TRICKDELAY; - K_DoPogoSpring(player->mo, upwards, 1); - - // Reduce speed - speed /= 2; - - if (speed < minspeed) - { - speed = minspeed; - } - - P_InstaThrust(player->mo, player->mo->angle, speed); - } - break; - - case 2: // Wind/Current - break; - - case 4: // Conveyor Belt - break; - - case 5: // Speed pad - if (player->floorboost != 0) - { - player->floorboost = 2; - break; - } - - i = Tag_FindLineSpecial(4, sectag); - - if (i != -1) - { - angle_t lineangle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y); - fixed_t linespeed = P_AproxDistance(lines[i].v2->x-lines[i].v1->x, lines[i].v2->y-lines[i].v1->y); - fixed_t playerspeed = P_AproxDistance(player->mo->momx, player->mo->momy); - - if (linespeed == 0) - { - CONS_Debug(DBG_GAMELOGIC, "ERROR: Speed pad (tag %d) at zero speed.\n", sectag); - break; - } - - // SRB2Kart: Scale the speed you get from them! - // This is scaled differently from other horizontal speed boosts from stuff like springs, because of how this is used for some ramp jumps. - if (player->mo->scale > mapobjectscale) - { - linespeed = FixedMul(linespeed, mapobjectscale + (player->mo->scale - mapobjectscale)); - } - - lineangle = K_ReflectAngle( - K_MomentumAngle(player->mo), lineangle, - playerspeed, linespeed - ); - - P_InstaThrust(player->mo, lineangle, max(linespeed, 2*playerspeed)); - - player->dashpadcooldown = TICRATE/3; - player->trickpanel = 0; - player->floorboost = 2; - S_StartSound(player->mo, sfx_cdfm62); - } - break; - - case 6: // Unused - case 7: // Unused - case 8: // Unused - case 9: // Unused - case 10: // Unused - case 11: // Unused - case 12: // Unused - case 13: // Unused - case 14: // Unused - case 15: // Unused - break; - } - - special = section4; - - // Process Section 4 - switch (special) - { - case 1: // Starpost Activator - { - mobj_t *post = P_GetObjectTypeInSectorNum(MT_STARPOST, sector - sectors); - - if (!post) - break; - - P_TouchStarPost(post, player, false); - break; - } - - case 2: // Special stage GOAL sector / Exit Sector / CTF Flag Return - // Exit (for FOF exits; others are handled in P_PlayerThink in p_user.c) - { - INT32 lineindex; - - P_DoPlayerExit(player); - - P_SetupSignExit(player); - // important: use sector->tag on next line instead of player->mo->subsector->tag - // this part is different from in P_PlayerThink, this is what was causing - // FOF custom exits not to work. - lineindex = Tag_FindLineSpecial(2, sectag); - - if (lineindex != -1) // Custom exit! - { - nextmapoverride = (INT16)(lines[lineindex].frontsector->floorheight>>FRACBITS); - - if (lines[lineindex].flags & ML_NOCLIMB) - skipstats = 1; - } - } - break; - - case 3: // Red Team's goal - case 4: // Blue Team's goal - break; - - case 5: // Fan sector - player->mo->momz += mobjinfo[MT_FAN].mass/4; - - if (player->mo->momz > mobjinfo[MT_FAN].mass) - player->mo->momz = mobjinfo[MT_FAN].mass; - - P_ResetPlayer(player); - break; - - case 6: // SRB2kart 190117 - Sneaker Panel - if (roversector || P_MobjReadyToTrigger(player->mo, sector)) - { - if (player->floorboost == 0) - player->floorboost = 3; - else - player->floorboost = 2; - K_DoSneaker(player, 0); - } - break; - - case 7: // SRB2Kart: Destroy items - break; - - case 8: // Zoom Tube Start - { - INT32 sequence; - fixed_t speed; - INT32 lineindex; - mobj_t *waypoint = NULL; - angle_t an; - - if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->carry == CR_ZOOMTUBE) - break; - - // Find line #3 tagged to this sector - lineindex = Tag_FindLineSpecial(3, sectag); - - if (lineindex == -1) - { - CONS_Debug(DBG_GAMELOGIC, "ERROR: Sector special %d missing line special #3.\n", sector->special); - break; - } - - // Grab speed and sequence values - speed = abs(sides[lines[lineindex].sidenum[0]].textureoffset)/8; - sequence = abs(sides[lines[lineindex].sidenum[0]].rowoffset)>>FRACBITS; - - if (speed == 0) - { - CONS_Debug(DBG_GAMELOGIC, "ERROR: Waypoint sequence %d at zero speed.\n", sequence); - break; - } - - waypoint = P_GetFirstTubeWaypoint(sequence); - - if (!waypoint) - { - CONS_Debug(DBG_GAMELOGIC, "ERROR: FIRST WAYPOINT IN SEQUENCE %d NOT FOUND.\n", sequence); - break; - } - else - { - CONS_Debug(DBG_GAMELOGIC, "Waypoint %d found in sequence %d - speed = %d\n", waypoint->health, sequence, speed); - } - - an = R_PointToAngle2(player->mo->x, player->mo->y, waypoint->x, waypoint->y) - player->mo->angle; - - if (an > ANGLE_90 && an < ANGLE_270 && !(lines[lineindex].flags & ML_EFFECT4)) - break; // behind back - - P_SetTarget(&player->mo->tracer, waypoint); - player->carry = CR_ZOOMTUBE; - player->speed = speed; - } - break; - - case 9: // Zoom Tube End - { - INT32 sequence; - fixed_t speed; - INT32 lineindex; - mobj_t *waypoint = NULL; - angle_t an; - - if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->carry == CR_ZOOMTUBE) - break; - - // Find line #11 tagged to this sector - lineindex = Tag_FindLineSpecial(11, sectag); - - if (lineindex == -1) - { - CONS_Debug(DBG_GAMELOGIC, "ERROR: Sector special %d missing line special #3.\n", sector->special); - break; - } - - // Grab speed and sequence values - speed = -abs(sides[lines[lineindex].sidenum[0]].textureoffset)/8; // Negative means reverse - sequence = abs(sides[lines[lineindex].sidenum[0]].rowoffset)>>FRACBITS; - - if (speed == 0) - { - CONS_Debug(DBG_GAMELOGIC, "ERROR: Waypoint sequence %d at zero speed.\n", sequence); - break; - } - - waypoint = P_GetLastTubeWaypoint(sequence); - - if (!waypoint) - { - CONS_Debug(DBG_GAMELOGIC, "ERROR: LAST WAYPOINT IN SEQUENCE %d NOT FOUND.\n", sequence); - break; - } - else - { - CONS_Debug(DBG_GAMELOGIC, "Waypoint %d found in sequence %d - speed = %d\n", waypoint->health, sequence, speed); - } - - an = R_PointToAngle2(player->mo->x, player->mo->y, waypoint->x, waypoint->y) - player->mo->angle; - - if (an > ANGLE_90 && an < ANGLE_270 && !(lines[lineindex].flags & ML_EFFECT4)) - break; // behind back - - P_SetTarget(&player->mo->tracer, waypoint); - player->carry = CR_ZOOMTUBE; - player->speed = speed; - } - break; - - case 10: // Unused - case 11: // Unused - case 12: // Camera noclip - case 13: // Unused - case 14: // Unused - case 15: // Unused - break; - } + if (!udmf) + P_EvaluateOldSectorSpecial(player, sector, roversector, isTouching); } -/** Checks if an object is standing on or is inside a special 3D floor. - * If so, the sector is returned. - * - * \param mo Object to check. - * \return Pointer to the sector with a special type, or NULL if no special 3D - * floors are being contacted. - * \sa P_PlayerOnSpecial3DFloor - */ -sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo) -{ - sector_t *sector; - ffloor_t *rover; - fixed_t topheight, bottomheight; - - sector = mo->subsector->sector; - if (!sector->ffloors) - return NULL; - - for (rover = sector->ffloors; rover; rover = rover->next) - { - if (!rover->master->frontsector->special) - continue; - - if (!(rover->flags & FF_EXISTS)) - continue; - - topheight = P_GetSpecialTopZ(mo, sectors + rover->secnum, sector); - bottomheight = P_GetSpecialBottomZ(mo, sectors + rover->secnum, sector); - - // Check the 3D floor's type... - if (((rover->flags & FF_BLOCKPLAYER) && mo->player) - || ((rover->flags & FF_BLOCKOTHERS) && !mo->player)) - { - boolean floorallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(mo->eflags & MFE_VERTICALFLIP)) && (mo->z == topheight)); - boolean ceilingallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (mo->eflags & MFE_VERTICALFLIP)) && (mo->z + mo->height == bottomheight)); - // Thing must be on top of the floor to be affected... - if (!(floorallowed || ceilingallowed)) - continue; - } - else - { - // Water and intangible FOFs - if (mo->z > topheight || (mo->z + mo->height) < bottomheight) - continue; - } - - return rover->master->frontsector; - } - - return NULL; -} - -#define TELEPORTED (player->mo->subsector->sector != originalsector) +#define TELEPORTED(mo) (mo->subsector->sector != originalsector) /** Checks if a player is standing on or is inside a 3D floor (e.g. water) and * applies any specials. @@ -4923,192 +4717,58 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector) { sector_t *originalsector = player->mo->subsector->sector; ffloor_t *rover; - fixed_t topheight, bottomheight; for (rover = sector->ffloors; rover; rover = rover->next) { - if (!rover->master->frontsector->special) + if (!P_SectorHasSpecial(rover->master->frontsector)) continue; if (!(rover->flags & FF_EXISTS)) continue; - topheight = P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector); - bottomheight = P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector); - - // Check the 3D floor's type... - if (rover->flags & FF_BLOCKPLAYER) - { - boolean floorallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z == topheight)); - boolean ceilingallowed = ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && ((rover->master->frontsector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z + player->mo->height == bottomheight)); - // Thing must be on top of the floor to be affected... - if (!(floorallowed || ceilingallowed)) - continue; - } - else - { - // Water and DEATH FOG!!! heh - if (player->mo->z > topheight || (player->mo->z + player->mo->height) < bottomheight) - continue; - } + if (!P_IsMobjTouching3DFloor(player->mo, rover, sector)) + continue; // This FOF has the special we're looking for, but are we allowed to touch it? if (sector == player->mo->subsector->sector - || (rover->master->frontsector->flags & SF_TRIGGERSPECIAL_TOUCH)) + || (rover->master->frontsector->flags & MSF_TRIGGERSPECIAL_TOUCH)) { P_ProcessSpecialSector(player, rover->master->frontsector, sector); - if TELEPORTED return; - } - } - - // Allow sector specials to be applied to polyobjects! - if (player->mo->subsector->polyList) - { - polyobj_t *po = player->mo->subsector->polyList; - sector_t *polysec; - boolean touching = false; - boolean inside = false; - - while (po) - { - if (po->flags & POF_NOSPECIALS) - { - po = (polyobj_t *)(po->link.next); - continue; - } - - polysec = po->lines[0]->backsector; - - if ((polysec->flags & SF_TRIGGERSPECIAL_TOUCH)) - touching = P_MobjTouchingPolyobj(po, player->mo); - else - touching = false; - - inside = P_MobjInsidePolyobj(po, player->mo); - - if (!(inside || touching)) - { - po = (polyobj_t *)(po->link.next); - continue; - } - - // We're inside it! Yess... - if (!polysec->special) - { - po = (polyobj_t *)(po->link.next); - continue; - } - - if (!(po->flags & POF_TESTHEIGHT)) // Don't do height checking - ; - else if (po->flags & POF_SOLID) - { - boolean floorallowed = ((polysec->flags & SF_FLIPSPECIAL_FLOOR) && ((polysec->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z == polysec->ceilingheight)); - boolean ceilingallowed = ((polysec->flags & SF_FLIPSPECIAL_CEILING) && ((polysec->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z + player->mo->height == polysec->floorheight)); - // Thing must be on top of the floor to be affected... - if (!(floorallowed || ceilingallowed)) - { - po = (polyobj_t *)(po->link.next); - continue; - } - } - else - { - // Water and DEATH FOG!!! heh - if (player->mo->z > polysec->ceilingheight || (player->mo->z + player->mo->height) < polysec->floorheight) - { - po = (polyobj_t *)(po->link.next); - continue; - } - } - - P_ProcessSpecialSector(player, polysec, sector); - if TELEPORTED return; - - po = (polyobj_t *)(po->link.next); + if TELEPORTED(player->mo) return; } } } -#define VDOORSPEED (FRACUNIT*2) - -// -// P_RunSpecialSectorCheck -// -// Helper function to P_PlayerInSpecialSector -// -static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector) +static void P_PlayerOnSpecialPolyobj(player_t *player) { - boolean nofloorneeded = false; - fixed_t f_affectpoint, c_affectpoint; + sector_t *originalsector = player->mo->subsector->sector; + polyobj_t *po; + sector_t *polysec; + boolean touching = false; + boolean inside = false; - if (!sector->special) // nothing special, exit - return; - - if (GETSECSPECIAL(sector->special, 2) == 9) // Egg trap capsule -- should only be for 3dFloors! - return; - - // The list of specials that activate without floor touch - // Check Section 1 - switch(GETSECSPECIAL(sector->special, 1)) + for (po = player->mo->subsector->polyList; po; po = (polyobj_t *)(po->link.next)) { - //case 2: // Damage (water) - case 8: // Instant kill - case 10: // Ring drainer that doesn't require floor touch - case 12: // Space countdown - nofloorneeded = true; - break; + if (po->flags & POF_NOSPECIALS) + continue; + + polysec = po->lines[0]->backsector; + + if (!P_SectorHasSpecial(polysec)) + continue; + + touching = (polysec->flags & MSF_TRIGGERSPECIAL_TOUCH) && P_MobjTouchingPolyobj(po, player->mo); + inside = P_MobjInsidePolyobj(po, player->mo); + + if (!(inside || touching)) + continue; + + if (!P_IsMobjTouchingPolyobj(player->mo, po, polysec)) + continue; + + P_ProcessSpecialSector(player, polysec, originalsector); + if TELEPORTED(player->mo) return; } - - // Check Section 2 - switch(GETSECSPECIAL(sector->special, 2)) - { - case 2: // Linedef executor (All players needed) - case 4: // Linedef executor - case 6: // Linedef executor (7 Emeralds) - case 7: // Linedef executor (NiGHTS Mare) - nofloorneeded = true; - break; - } - - // Check Section 3 -/* switch(GETSECSPECIAL(sector->special, 3)) - { - - }*/ - - // Check Section 4 - switch(GETSECSPECIAL(sector->special, 4)) - { - case 1: // Starpost activator - case 2: // Level Exit / GOAL Sector / Flag Return - case 5: // Fan sector - case 6: // Super Sonic Transform - case 8: // Zoom Tube Start - case 9: // Zoom Tube End - case 10: // Finish line (Unused) - nofloorneeded = true; - break; - } - - if (nofloorneeded) - { - P_ProcessSpecialSector(player, sector, NULL); - return; - } - - f_affectpoint = P_GetSpecialBottomZ(player->mo, sector, sector); - c_affectpoint = P_GetSpecialTopZ(player->mo, sector, sector); - - { - boolean floorallowed = ((sector->flags & SF_FLIPSPECIAL_FLOOR) && ((sector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || !(player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z == f_affectpoint)); - boolean ceilingallowed = ((sector->flags & SF_FLIPSPECIAL_CEILING) && ((sector->flags & SF_TRIGGERSPECIAL_HEADBUMP) || (player->mo->eflags & MFE_VERTICALFLIP)) && (player->mo->z + player->mo->height == c_affectpoint)); - // Thing must be on top of the floor to be affected... - if (!(floorallowed || ceilingallowed)) - return; - } - - P_ProcessSpecialSector(player, sector, NULL); } /** Checks if the player is in a special sector or FOF and apply any specials. @@ -5129,10 +4789,14 @@ void P_PlayerInSpecialSector(player_t *player) originalsector = player->mo->subsector->sector; P_PlayerOnSpecial3DFloor(player, originalsector); // Handle FOFs first. - if TELEPORTED return; + if TELEPORTED(player->mo) return; - P_RunSpecialSectorCheck(player, originalsector); - if TELEPORTED return; + // Allow sector specials to be applied to polyobjects! + P_PlayerOnSpecialPolyobj(player); + if TELEPORTED(player->mo) return; + + P_ProcessSpecialSector(player, originalsector, NULL); + if TELEPORTED(player->mo) return; // Iterate through touching_sectorlist for SF_TRIGGERSPECIAL_TOUCH for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next) @@ -5144,16 +4808,110 @@ void P_PlayerInSpecialSector(player_t *player) // Check 3D floors... P_PlayerOnSpecial3DFloor(player, loopsector); - if TELEPORTED return; + if TELEPORTED(player->mo) return; - if (!(loopsector->flags & SF_TRIGGERSPECIAL_TOUCH)) + if (!(loopsector->flags & MSF_TRIGGERSPECIAL_TOUCH)) continue; - P_RunSpecialSectorCheck(player, loopsector); - if TELEPORTED return; + P_ProcessSpecialSector(player, loopsector, NULL); + if TELEPORTED(player->mo) return; } } +static void P_CheckMobj3DFloorTrigger(mobj_t *mo, sector_t *sec) +{ + sector_t *originalsector = mo->subsector->sector; + ffloor_t *rover; + + for (rover = sec->ffloors; rover; rover = rover->next) + { + if (!rover->master->frontsector->triggertag) + continue; + + if (rover->master->frontsector->triggerer != TO_MOBJ) + continue; + + if (!(rover->flags & FF_EXISTS)) + continue; + + if (!P_IsMobjTouching3DFloor(mo, rover, sec)) + continue; + + P_LinedefExecute(rover->master->frontsector->triggertag, mo, rover->master->frontsector); + if TELEPORTED(mo) return; + } +} + +static void P_CheckMobjPolyobjTrigger(mobj_t *mo) +{ + sector_t *originalsector = mo->subsector->sector; + polyobj_t *po; + sector_t *polysec; + boolean touching = false; + boolean inside = false; + + for (po = mo->subsector->polyList; po; po = (polyobj_t *)(po->link.next)) + { + if (po->flags & POF_NOSPECIALS) + continue; + + polysec = po->lines[0]->backsector; + + if (!polysec->triggertag) + continue; + + if (polysec->triggerer != TO_MOBJ) + continue; + + touching = (polysec->flags & MSF_TRIGGERSPECIAL_TOUCH) && P_MobjTouchingPolyobj(po, mo); + inside = P_MobjInsidePolyobj(po, mo); + + if (!(inside || touching)) + continue; + + if (!P_IsMobjTouchingPolyobj(mo, po, polysec)) + continue; + + P_LinedefExecute(polysec->triggertag, mo, polysec); + if TELEPORTED(mo) return; + } +} + +static void P_CheckMobjSectorTrigger(mobj_t *mo, sector_t *sec) +{ + if (!sec->triggertag) + return; + + if (sec->triggerer != TO_MOBJ) + return; + + if ((sec->flags & MSF_TRIGGERLINE_PLANE) && !P_IsMobjTouchingSectorPlane(mo, sec)) + return; + + P_LinedefExecute(sec->triggertag, mo, sec); +} + +void P_CheckMobjTrigger(mobj_t *mobj, boolean pushable) +{ + sector_t *originalsector; + + if (!mobj->subsector) + return; + + originalsector = mobj->subsector->sector; + + if (!pushable && !(originalsector->flags & MSF_TRIGGERLINE_MOBJ)) + return; + + P_CheckMobj3DFloorTrigger(mobj, originalsector); + if TELEPORTED(mobj) return; + + P_CheckMobjPolyobjTrigger(mobj); + if TELEPORTED(mobj) return; + + P_CheckMobjSectorTrigger(mobj, originalsector); +} + #undef TELEPORTED /** Animate planes, scroll walls, etc. and keeps track of level timelimit and exits if time is up. @@ -5303,12 +5061,14 @@ static inline void P_AddFFloorToList(sector_t *sec, ffloor_t *fflr) * \param sec Target sector. * \param sec2 Control sector. * \param master Control linedef. + * \param alpha Alpha value (0-255). + * \param blendmode Blending mode. * \param flags Options affecting this 3Dfloor. * \param secthinkers List of relevant thinkers sorted by sector. May be NULL. * \return Pointer to the new 3Dfloor. * \sa P_AddFFloor, P_AddFakeFloorsByLine, P_SpawnSpecials */ -static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, ffloortype_e flags, thinkerlist_t *secthinkers) +static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, INT32 alpha, UINT8 blendmode, ffloortype_e flags, thinkerlist_t *secthinkers) { ffloor_t *fflr; thinker_t *th; @@ -5326,7 +5086,7 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f { fixed_t tempceiling = sec2->ceilingheight; //flip the sector around and print an error instead of crashing 12.1.08 -Inuyasha - CONS_Alert(CONS_ERROR, M_GetText("FOF (line %s) has a top height below its bottom.\n"), sizeu1(master - lines)); + CONS_Alert(CONS_ERROR, M_GetText("A FOF tagged %d has a top height below its bottom.\n"), master->args[0]); sec2->ceilingheight = sec2->floorheight; sec2->floorheight = tempceiling; } @@ -5382,12 +5142,6 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f if (sec2->hasslope) sec->hasslope = true; - if ((flags & FF_SOLID) && (master->flags & ML_EFFECT1)) // Block player only - flags &= ~FF_BLOCKOTHERS; - - if ((flags & FF_SOLID) && (master->flags & ML_EFFECT2)) // Block all BUT player - flags &= ~FF_BLOCKPLAYER; - fflr->spawnflags = fflr->flags = flags; fflr->master = master; fflr->norender = INFTICS; @@ -5428,54 +5182,50 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f p = (pusher_t *)th; if (p->affectee == (INT32)sec2num) - Add_Pusher(p->type, p->x_mag<y_mag<source, (INT32)(sec-sectors), p->affectee, p->exclusive, p->slider); + Add_Pusher(p->type, p->x_mag, p->y_mag, p->z_mag, (INT32)(sec-sectors), p->affectee, p->exclusive, p->slider); } if(secthinkers) i++; else th = th->next; } - - if (flags & FF_TRANSLUCENT) + fflr->alpha = max(0, min(0xff, alpha)); + if (fflr->alpha < 0xff || flags & FF_SPLAT) { - if (sides[master->sidenum[0]].toptexture > 0) - { - // for future reference, "#0" is 1, and "#255" is 256. Be warned - fflr->alpha = sides[master->sidenum[0]].toptexture; - - if (fflr->alpha == 901) // additive special - { - fflr->blend = AST_ADD; - fflr->alpha = 0xff; - } - else if (fflr->alpha == 902) // subtractive special - { - fflr->blend = AST_SUBTRACT; - fflr->alpha = 0xff; - } - else if (fflr->alpha >= 1001) // fourth digit - { - fflr->blend = (fflr->alpha/1000)+1; // becomes an AST - fflr->alpha %= 1000; - } - } - else - fflr->alpha = 0x80; + fflr->flags |= FF_TRANSLUCENT; + fflr->spawnflags = fflr->flags; } - else - fflr->alpha = 0xff; - fflr->spawnalpha = fflr->alpha; // save for netgames + switch (blendmode) + { + case TMB_TRANSLUCENT: + default: + fflr->blend = AST_COPY; + break; + case TMB_ADD: + fflr->blend = AST_ADD; + break; + case TMB_SUBTRACT: + fflr->blend = AST_SUBTRACT; + break; + case TMB_REVERSESUBTRACT: + fflr->blend = AST_REVERSESUBTRACT; + break; + case TMB_MODULATE: + fflr->blend = AST_MODULATE; + break; + } + if (flags & FF_QUICKSAND) CheckForQuicksand = true; - if ((flags & FF_BUSTUP) || (flags & FF_SHATTER) || (flags & FF_SPINBUST)) + if (flags & FF_BUSTUP) CheckForBustableBlocks = true; if ((flags & FF_MARIO)) { - if (!(flags & FF_SHATTERBOTTOM)) // Don't change the textures of a brick block, just a question block + if (!(flags & FF_GOOWATER)) // Don't change the textures of a brick block, just a question block P_AddBlockThinker(sec2, master); CheckForMarioBlocks = true; } @@ -5485,7 +5235,7 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f if ((flags & FF_FLOATBOB)) { - P_AddFloatThinker(sec2, Tag_FGet(&master->tags), master); + P_AddFloatThinker(sec2, master->args[0], master); CheckForFloatBob = true; } @@ -5650,7 +5400,7 @@ static void P_AddRaiseThinker(sector_t *sec, INT16 tag, fixed_t speed, fixed_t c raise->ceilingtop = ceilingtop; raise->ceilingbottom = ceilingbottom; - raise->basespeed = speed; + raise->basespeed = speed >> 2; if (lower) raise->flags |= RF_REVERSE; @@ -5722,7 +5472,7 @@ static inline void P_AddThwompThinker(sector_t *sec, line_t *sourceline, fixed_t thwomp->floorstartheight = sec->floorheight; thwomp->ceilingstartheight = sec->ceilingheight; thwomp->delay = 1; - thwomp->tag = Tag_FGet(&sourceline->tags); + thwomp->tag = sourceline->args[0]; thwomp->sound = sound; sec->floordata = thwomp; @@ -5762,7 +5512,7 @@ static inline void P_AddNoEnemiesThinker(line_t *sourceline) * \sa P_SpawnSpecials, T_EachTimeThinker * \author SSNTails */ -static void P_AddEachTimeThinker(line_t *sourceline) +static void P_AddEachTimeThinker(line_t *sourceline, boolean triggerOnExit) { eachtime_t *eachtime; @@ -5773,7 +5523,7 @@ static void P_AddEachTimeThinker(line_t *sourceline) eachtime->thinker.function.acp1 = (actionf_p1)T_EachTimeThinker; eachtime->sourceline = sourceline; - eachtime->triggerOnExit = !!(sourceline->flags & ML_NOTBOUNCY); + eachtime->triggerOnExit = triggerOnExit; } /** Adds a camera scanner. @@ -5927,16 +5677,16 @@ void P_InitSpecials(void) curWeather = globalweather = mapheaderinfo[gamemap-1]->weather; } -static void P_ApplyFlatAlignment(line_t *master, sector_t *sector, angle_t flatangle, fixed_t xoffs, fixed_t yoffs) +void P_ApplyFlatAlignment(sector_t *sector, angle_t flatangle, fixed_t xoffs, fixed_t yoffs, boolean floor, boolean ceiling) { - if (!(master->flags & ML_NETONLY)) // Modify floor flat alignment unless ML_NETONLY flag is set + if (floor) { sector->floorpic_angle = flatangle; sector->floor_xoffs += xoffs; sector->floor_yoffs += yoffs; } - if (!(master->flags & ML_NONET)) // Modify ceiling flat alignment unless ML_NONET flag is set + if (ceiling) { sector->ceilingpic_angle = flatangle; sector->ceiling_xoffs += xoffs; @@ -5948,7 +5698,7 @@ static boolean P_IsLineDisabled (const line_t * line) { if (line->special != 7) // This is a hack. I can at least hope nobody wants to prevent flat alignment in netgames... { - if (netgame || multiplayer) + if (netgame) { if (line->flags & ML_NONET) { @@ -5964,6 +5714,58 @@ static boolean P_IsLineDisabled (const line_t * line) return false; } +static void P_MakeFOFBouncy(line_t *paramline, line_t *masterline) +{ + INT32 s; + + if (masterline->special < 100 || masterline->special >= 300) + return; + + TAG_ITER_SECTORS(masterline->args[0], s) + { + ffloor_t *rover; + + for (rover = sectors[s].ffloors; rover; rover = rover->next) + { + if (rover->master != masterline) + continue; + + rover->flags |= FF_BOUNCY; + rover->spawnflags |= FF_BOUNCY; + rover->bouncestrength = (paramline->args[1]<< FRACBITS)/100; + CheckForBouncySector = true; + break; + } + } + +} + +static boolean P_CheckGametypeRules(INT32 checktype, UINT32 target) +{ + switch (checktype) + { + case TMF_HASALL: + default: + return (gametyperules & target) == target; + case TMF_HASANY: + return !!(gametyperules & target); + case TMF_HASEXACTLY: + return gametyperules == target; + case TMF_DOESNTHAVEALL: + return (gametyperules & target) != target; + case TMF_DOESNTHAVEANY: + return !(gametyperules & target); + } +} + +fixed_t P_GetSectorGravityFactor(sector_t *sec) +{ + if (sec->gravityptr) + return FixedDiv(*sec->gravityptr >> FRACBITS, 1000); + else + return sec->gravity; +} + /** After the map has loaded, scans for specials that spawn 3Dfloors and * thinkers. * @@ -5992,6 +5794,8 @@ void P_SpawnSpecials(boolean fromnetsave) sector = sectors; for (i = 0; i < numsectors; i++, sector++) { + CheckForReverseGravity |= (sector->flags & MSF_GRAVITYFLIP); + if (!sector->special) continue; @@ -6000,11 +5804,14 @@ void P_SpawnSpecials(boolean fromnetsave) { case 5: // Spikes //Terrible hack to replace an even worse hack: - //Spike damage automatically sets SF_TRIGGERSPECIAL_TOUCH. + //Spike damage automatically sets MSF_TRIGGERSPECIAL_TOUCH. //Yes, this also affects other specials on the same sector. Sorry. - sector->flags |= SF_TRIGGERSPECIAL_TOUCH; + sector->flags |= MSF_TRIGGERSPECIAL_TOUCH; break; - case 15: // Bouncy sector + case 15: // Bouncy FOF + if (udmf) + break; + CONS_Alert(CONS_WARNING, M_GetText("Deprecated bouncy FOF sector type detected. Please use linedef type 76 instead.\n")); CheckForBouncySector = true; break; } @@ -6013,22 +5820,20 @@ void P_SpawnSpecials(boolean fromnetsave) switch(GETSECSPECIAL(sector->special, 2)) { case 11: // Custom global gravity! + if (udmf) + break; + CONS_Alert(CONS_WARNING, M_GetText("Deprecated sector type for global gravity detected. Please use the Gravity level header option instead.\n")); gravity = sector->floorheight/1000; break; } - // Process Section 3 -/* switch(GETSECSPECIAL(player->specialsector, 3)) - { - - }*/ - // Process Section 4 switch(GETSECSPECIAL(sector->special, 4)) { - case 10: // Circuit finish line (Unused) - // Remove before release - CONS_Alert(CONS_WARNING, "Finish line sector type is deprecated.\n"); + case 10: // Circuit finish line + if (udmf) + break; + CONS_Alert(CONS_WARNING, M_GetText("Deprecated finish line sector type detected. Please use the linedef type instead.\n")); break; } } @@ -6076,8 +5881,6 @@ void P_SpawnSpecials(boolean fromnetsave) // Init line EFFECTs for (i = 0; i < numlines; i++) { - mtag_t tag = Tag_FGet(&lines[i].tags); - if (P_IsLineDisabled(&lines[i])) { continue; @@ -6086,510 +5889,388 @@ void P_SpawnSpecials(boolean fromnetsave) switch (lines[i].special) { INT32 s; + INT32 l; size_t sec; ffloortype_e ffloorflags; case 1: // Definable gravity per sector + if (udmf) + break; + sec = sides[*lines[i].sidenum].sector - sectors; - TAG_ITER_SECTORS(tag, s) + TAG_ITER_SECTORS(Tag_FGet(&lines[i].tags), s) { - sectors[s].gravity = §ors[sec].floorheight; // This allows it to change in realtime! + sectors[s].gravityptr = §ors[sec].floorheight; // This allows it to change in realtime! if (lines[i].flags & ML_NOCLIMB) - sectors[s].verticalflip = true; + sectors[s].flags |= MSF_GRAVITYFLIP; else - sectors[s].verticalflip = false; + sectors[s].flags &= ~MSF_GRAVITYFLIP; - CheckForReverseGravity = sectors[s].verticalflip; + CheckForReverseGravity |= (sectors[s].flags & MSF_GRAVITYFLIP); } break; - case 2: // Custom exit - break; - - case 3: // Zoom Tube Parameters - break; - - case 4: // Speed pad (combines with sector special Section3:5 or Section3:6) - break; - case 5: // Change camera info + if (udmf) + break; + sec = sides[*lines[i].sidenum].sector - sectors; - TAG_ITER_SECTORS(tag, s) + TAG_ITER_SECTORS(Tag_FGet(&lines[i].tags), s) P_AddCameraScanner(§ors[sec], §ors[s], R_PointToAngle2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y)); break; case 7: // Flat alignment - redone by toast - if ((lines[i].flags & (ML_NETONLY|ML_NONET)) != (ML_NETONLY|ML_NONET)) // If you can do something... + { + // Set calculated offsets such that line's v1 is the apparent origin + angle_t flatangle = InvAngle(R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y)); + fixed_t xoffs = -lines[i].v1->x; + fixed_t yoffs = lines[i].v1->y; + + //If no tag is given, apply to front sector + if (lines[i].args[0] == 0) + P_ApplyFlatAlignment(lines[i].frontsector, flatangle, xoffs, yoffs, lines[i].args[1] != TMP_CEILING, lines[i].args[1] != TMP_FLOOR); + else { - angle_t flatangle = InvAngle(R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y)); - fixed_t xoffs; - fixed_t yoffs; - - if (lines[i].flags & ML_EFFECT6) // Set offset through x and y texture offsets if ML_EFFECT6 flag is set - { - xoffs = sides[lines[i].sidenum[0]].textureoffset; - yoffs = sides[lines[i].sidenum[0]].rowoffset; - } - else // Otherwise, set calculated offsets such that line's v1 is the apparent origin - { - xoffs = -lines[i].v1->x; - yoffs = lines[i].v1->y; - } - - //If no tag is given, apply to front sector - if (tag == 0) - P_ApplyFlatAlignment(lines + i, lines[i].frontsector, flatangle, xoffs, yoffs); - else - { - TAG_ITER_SECTORS(tag, s) - P_ApplyFlatAlignment(lines + i, sectors + s, flatangle, xoffs, yoffs); - } - } - else // Otherwise, print a helpful warning. Can I do no less? - CONS_Alert(CONS_WARNING, - M_GetText("Flat alignment linedef (tag %d) doesn't have anything to do.\nConsider changing the linedef's flag configuration or removing it entirely.\n"), - tag); - break; - - case 8: // Sector Parameters - TAG_ITER_SECTORS(tag, s) - { - if (lines[i].flags & ML_NOCLIMB) - { - sectors[s].flags &= ~SF_FLIPSPECIAL_FLOOR; - sectors[s].flags |= SF_FLIPSPECIAL_CEILING; - } - else if (lines[i].flags & ML_EFFECT4) - sectors[s].flags |= SF_FLIPSPECIAL_BOTH; - - if (lines[i].flags & ML_EFFECT3) - sectors[s].flags |= SF_TRIGGERSPECIAL_TOUCH; - if (lines[i].flags & ML_EFFECT2) - sectors[s].flags |= SF_TRIGGERSPECIAL_HEADBUMP; - - if (lines[i].flags & ML_EFFECT1) - sectors[s].flags |= SF_INVERTPRECIP; - - if (lines[i].flags & ML_DONTPEGTOP) - sectors[s].flags |= SF_RIPPLE_FLOOR; - - if (lines[i].flags & ML_DONTPEGBOTTOM) - sectors[s].flags |= SF_RIPPLE_CEILING; - - if (lines[i].frontsector && GETSECSPECIAL(lines[i].frontsector->special, 4) == 12) - sectors[s].camsec = sides[*lines[i].sidenum].sector-sectors; + TAG_ITER_SECTORS(lines[i].args[0], s) + P_ApplyFlatAlignment(sectors + s, flatangle, xoffs, yoffs, lines[i].args[1] != TMP_CEILING, lines[i].args[1] != TMP_FLOOR); } break; + } - case 9: // Chain Parameters + case 8: // Set camera collision planes + if (lines[i].frontsector) + TAG_ITER_SECTORS(lines[i].args[0], s) + sectors[s].camsec = lines[i].frontsector-sectors; break; case 10: // Vertical culling plane for sprites and FOFs - TAG_ITER_SECTORS(tag, s) + TAG_ITER_SECTORS(lines[i].args[0], s) sectors[s].cullheight = &lines[i]; // This allows it to change in realtime! break; case 50: // Insta-Lower Sector - EV_DoFloor(&lines[i], instantLower); + if (!udmf) + EV_DoFloor(lines[i].args[0], &lines[i], instantLower); break; case 51: // Instant raise for ceilings - EV_DoCeiling(&lines[i], instantRaise); + if (!udmf) + EV_DoCeiling(lines[i].args[0], &lines[i], instantRaise); break; case 52: // Continuously Falling sector - EV_DoContinuousFall(lines[i].frontsector, lines[i].backsector, P_AproxDistance(lines[i].dx, lines[i].dy), (lines[i].flags & ML_NOCLIMB)); + EV_DoContinuousFall(lines[i].frontsector, lines[i].backsector, lines[i].args[0] << FRACBITS, lines[i].args[1]); break; - case 53: // New super cool and awesome moving floor and ceiling type - case 54: // New super cool and awesome moving floor type + case 53: // Continuous plane movement (slowdown) if (lines[i].backsector) - EV_DoFloor(&lines[i], bounceFloor); - if (lines[i].special == 54) - break; - /* FALLTHRU */ - - case 55: // New super cool and awesome moving ceiling type - if (lines[i].backsector) - EV_DoCeiling(&lines[i], bounceCeiling); + { + if (lines[i].args[1] != TMP_CEILING) + EV_DoFloor(lines[i].args[0], &lines[i], bounceFloor); + if (lines[i].args[1] != TMP_FLOOR) + EV_DoCeiling(lines[i].args[0], &lines[i], bounceCeiling); + } break; - case 56: // New super cool and awesome moving floor and ceiling crush type - case 57: // New super cool and awesome moving floor crush type + case 56: // Continuous plane movement (constant) if (lines[i].backsector) - EV_DoFloor(&lines[i], bounceFloorCrush); - - if (lines[i].special == 57) - break; //only move the floor - /* FALLTHRU */ - - case 58: // New super cool and awesome moving ceiling crush type - if (lines[i].backsector) - EV_DoCeiling(&lines[i], bounceCeilingCrush); + { + if (lines[i].args[1] != TMP_CEILING) + EV_DoFloor(lines[i].args[0], &lines[i], bounceFloorCrush); + if (lines[i].args[1] != TMP_FLOOR) + EV_DoCeiling(lines[i].args[0], &lines[i], bounceCeilingCrush); + } break; - case 59: // Activate floating platform - EV_DoElevator(&lines[i], elevateContinuous, false); - break; - - case 60: // Floating platform with adjustable speed - EV_DoElevator(&lines[i], elevateContinuous, true); + case 60: // Moving platform + EV_DoElevator(lines[i].args[0], &lines[i], elevateContinuous); break; case 61: // Crusher! - EV_DoCrush(&lines[i], crushAndRaise); - break; - - case 62: // Crusher (up and then down)! - EV_DoCrush(&lines[i], fastCrushAndRaise); + EV_DoCrush(lines[i].args[0], &lines[i], lines[i].args[1] ? raiseAndCrush : crushAndRaise); break; case 63: // support for drawn heights coming from different sector sec = sides[*lines[i].sidenum].sector-sectors; - TAG_ITER_SECTORS(tag, s) + TAG_ITER_SECTORS(lines[i].args[0], s) sectors[s].heightsec = (INT32)sec; break; case 64: // Appearing/Disappearing FOF option - if (lines[i].flags & ML_BLOCKPLAYERS) { // Find FOFs by control sector tag - TAG_ITER_SECTORS(tag, s) - for (j = 0; (unsigned)j < sectors[s].linecount; j++) - if (sectors[s].lines[j]->special >= 100 && sectors[s].lines[j]->special < 300) - Add_MasterDisappearer(abs(lines[i].dx>>FRACBITS), abs(lines[i].dy>>FRACBITS), abs(sides[lines[i].sidenum[0]].sector->floorheight>>FRACBITS), (INT32)(sectors[s].lines[j]-lines), (INT32)i); - } else // Find FOFs by effect sector tag + if (lines[i].args[0] == 0) // Find FOFs by control sector tag { - TAG_ITER_LINES(tag, s) + TAG_ITER_SECTORS(lines[i].args[1], s) { - if ((size_t)s == i) + for (j = 0; (unsigned)j < sectors[s].linecount; j++) + { + if (sectors[s].lines[j]->special < 100 || sectors[s].lines[j]->special >= 300) + continue; + + Add_MasterDisappearer(abs(lines[i].args[2]), abs(lines[i].args[3]), abs(lines[i].args[4]), (INT32)(sectors[s].lines[j] - lines), (INT32)i); + } + } + } + else // Find FOFs by effect sector tag + { + TAG_ITER_LINES(lines[i].args[0], s) + { + if (lines[s].special < 100 || lines[s].special >= 300) continue; - if (Tag_Find(&sides[lines[s].sidenum[0]].sector->tags, Tag_FGet(&sides[lines[i].sidenum[0]].sector->tags))) - Add_MasterDisappearer(abs(lines[i].dx>>FRACBITS), abs(lines[i].dy>>FRACBITS), abs(sides[lines[i].sidenum[0]].sector->floorheight>>FRACBITS), s, (INT32)i); + + if (lines[i].args[1] != 0 && !Tag_Find(&lines[s].frontsector->tags, lines[i].args[1])) + continue; + + Add_MasterDisappearer(abs(lines[i].args[2]), abs(lines[i].args[3]), abs(lines[i].args[4]), s, (INT32)i); } } break; - case 66: // Displace floor by front sector - TAG_ITER_SECTORS(tag, s) - P_AddPlaneDisplaceThinker(pd_floor, FixedHypot(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); - break; - case 67: // Displace ceiling by front sector - TAG_ITER_SECTORS(tag, s) - P_AddPlaneDisplaceThinker(pd_ceiling, FixedHypot(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); - break; - case 68: // Displace both floor AND ceiling by front sector - TAG_ITER_SECTORS(tag, s) - P_AddPlaneDisplaceThinker(pd_both, FixedHypot(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); + case 66: // Displace planes by front sector + TAG_ITER_SECTORS(lines[i].args[0], s) + P_AddPlaneDisplaceThinker(lines[i].args[1], abs(lines[i].args[2])<<8, sides[lines[i].sidenum[0]].sector-sectors, s, lines[i].args[2] < 0); break; - case 100: // FOF (solid, opaque, shadows) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - break; - - case 101: // FOF (solid, opaque, no shadows) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_NOSHADE|FF_CUTLEVEL, secthinkers); - break; - - case 102: // TL block: FOF (solid, translucent) - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_NOSHADE|FF_TRANSLUCENT|FF_EXTRA|FF_CUTEXTRA; - - // Draw the 'insides' of the block too - if (lines[i].flags & ML_NOCLIMB) + case 70: // Add raise thinker to FOF + if (udmf) { - ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES; - ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA); + fixed_t destheight = lines[i].args[2] << FRACBITS; + fixed_t startheight, topheight, bottomheight; + + TAG_ITER_LINES(lines[i].args[0], l) + { + if (lines[l].special < 100 || lines[l].special >= 300) + continue; + + startheight = lines[l].frontsector->ceilingheight; + topheight = max(startheight, destheight); + bottomheight = min(startheight, destheight); + + P_AddRaiseThinker(lines[l].frontsector, lines[l].args[0], lines[i].args[1] << FRACBITS, topheight, bottomheight, (destheight < startheight), !!(lines[i].args[3])); + } + } + break; + + case 71: // Add air bob thinker to FOF + if (udmf) + { + TAG_ITER_LINES(lines[i].args[0], l) + { + if (lines[l].special < 100 || lines[l].special >= 300) + continue; + + P_AddAirbob(lines[l].frontsector, lines[l].args[0], lines[i].args[1] << FRACBITS, !!(lines[i].args[2] & TMFB_REVERSE), !!(lines[i].args[2] & TMFB_SPINDASH), !!(lines[i].args[2] & TMFB_DYNAMIC)); + } + } + break; + + case 72: // Add thwomp thinker to FOF + if (udmf) + { + UINT16 sound = (lines[i].stringargs[0]) ? get_number(lines[i].stringargs[0]) : sfx_thwomp; + + TAG_ITER_LINES(lines[i].args[0], l) + { + if (lines[l].special < 100 || lines[l].special >= 300) + continue; + + P_AddThwompThinker(lines[l].frontsector, &lines[l], lines[i].args[1] << (FRACBITS - 3), lines[i].args[2] << (FRACBITS - 3), sound); + } + } + break; + + case 73: // Add laser thinker to FOF + if (udmf) + { + TAG_ITER_LINES(lines[i].args[0], l) + { + if (lines[l].special < 100 || lines[l].special >= 300) + continue; + + P_AddLaserThinker(lines[l].args[0], lines + l, !!(lines[i].args[1])); + } + } + break; + + case 100: // FOF (solid) + ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL; + + //Appearance settings + if (lines[i].args[3] & TMFA_NOPLANES) + ffloorflags &= ~FF_RENDERPLANES; + if (lines[i].args[3] & TMFA_NOSIDES) + ffloorflags &= ~FF_RENDERSIDES; + if (lines[i].args[3] & TMFA_INSIDES) + { + if (ffloorflags & FF_RENDERPLANES) + ffloorflags |= FF_BOTHPLANES; + if (ffloorflags & FF_RENDERSIDES) + ffloorflags |= FF_ALLSIDES; + } + if (lines[i].args[3] & TMFA_ONLYINSIDES) + { + if (ffloorflags & FF_RENDERPLANES) + ffloorflags |= FF_INVERTPLANES; + if (ffloorflags & FF_RENDERSIDES) + ffloorflags |= FF_INVERTSIDES; + } + if (lines[i].args[3] & TMFA_NOSHADE) + ffloorflags |= FF_NOSHADE; + if (lines[i].args[3] & TMFA_SPLAT) + ffloorflags |= FF_SPLAT; + + //Tangibility settings + if (lines[i].args[4] & TMFT_INTANGIBLETOP) + ffloorflags |= FF_REVERSEPLATFORM; + if (lines[i].args[4] & TMFT_INTANGIBLEBOTTOM) + ffloorflags |= FF_PLATFORM; + if (lines[i].args[4] & TMFT_DONTBLOCKPLAYER) + ffloorflags &= ~FF_BLOCKPLAYER; + if (lines[i].args[4] & TMFT_DONTBLOCKOTHERS) + ffloorflags &= ~FF_BLOCKOTHERS; + + //Cutting options + if (ffloorflags & FF_RENDERALL) + { + //If translucent or player can enter it, cut inner walls + if ((lines[i].args[1] < 255) || (lines[i].args[4] & TMFT_VISIBLEFROMINSIDE)) + ffloorflags |= FF_CUTEXTRA|FF_EXTRA; + else + ffloorflags |= FF_CUTLEVEL; } - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); + P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); break; - case 103: // Solid FOF with no floor/ceiling (quite possibly useless) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERSIDES|FF_NOSHADE|FF_CUTLEVEL, secthinkers); - break; - - case 104: // 3D Floor type that doesn't draw sides - // If line has no-climb set, give it shadows, otherwise don't - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERPLANES|FF_CUTLEVEL; - if (!(lines[i].flags & ML_NOCLIMB)) - ffloorflags |= FF_NOSHADE; - - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - break; - - case 105: // FOF (solid, invisible) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_NOSHADE, secthinkers); - break; - - case 120: // Opaque water - ffloorflags = FF_EXISTS|FF_RENDERALL|FF_SWIMMABLE|FF_BOTHPLANES|FF_ALLSIDES|FF_CUTEXTRA|FF_EXTRA|FF_CUTSPRITES; - if (lines[i].flags & ML_NOCLIMB) - ffloorflags |= FF_DOUBLESHADOW; - if (lines[i].flags & ML_EFFECT4) - ffloorflags |= FF_COLORMAPONLY; - if (lines[i].flags & ML_EFFECT5) - ffloorflags |= FF_RIPPLE; - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - break; - - case 121: // TL water - ffloorflags = FF_EXISTS|FF_RENDERALL|FF_TRANSLUCENT|FF_SWIMMABLE|FF_BOTHPLANES|FF_ALLSIDES|FF_CUTEXTRA|FF_EXTRA|FF_CUTSPRITES; - if (lines[i].flags & ML_NOCLIMB) - ffloorflags |= FF_DOUBLESHADOW; - if (lines[i].flags & ML_EFFECT4) - ffloorflags |= FF_COLORMAPONLY; - if (lines[i].flags & ML_EFFECT5) - ffloorflags |= FF_RIPPLE; - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - break; - - case 122: // Opaque water, no sides + case 120: // FOF (water) ffloorflags = FF_EXISTS|FF_RENDERPLANES|FF_SWIMMABLE|FF_BOTHPLANES|FF_CUTEXTRA|FF_EXTRA|FF_CUTSPRITES; - if (lines[i].flags & ML_NOCLIMB) + if (!(lines[i].args[3] & TMFW_NOSIDES)) + ffloorflags |= FF_RENDERSIDES|FF_ALLSIDES; + if (lines[i].args[3] & TMFW_DOUBLESHADOW) ffloorflags |= FF_DOUBLESHADOW; - if (lines[i].flags & ML_EFFECT4) + if (lines[i].args[3] & TMFW_COLORMAPONLY) ffloorflags |= FF_COLORMAPONLY; - if (lines[i].flags & ML_EFFECT5) + if (!(lines[i].args[3] & TMFW_NORIPPLE)) ffloorflags |= FF_RIPPLE; - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); + if (lines[i].args[3] & TMFW_GOOWATER) + ffloorflags |= FF_GOOWATER; + if (lines[i].args[3] & TMFW_SPLAT) + ffloorflags |= FF_SPLAT; + P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); break; - case 123: // TL water, no sides - ffloorflags = FF_EXISTS|FF_RENDERPLANES|FF_TRANSLUCENT|FF_SWIMMABLE|FF_BOTHPLANES|FF_CUTEXTRA|FF_EXTRA|FF_CUTSPRITES; - if (lines[i].flags & ML_NOCLIMB) - ffloorflags |= FF_DOUBLESHADOW; - if (lines[i].flags & ML_EFFECT4) - ffloorflags |= FF_COLORMAPONLY; - if (lines[i].flags & ML_EFFECT5) - ffloorflags |= FF_RIPPLE; - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); + case 150: // FOF (Air bobbing) + P_AddFakeFloorsByLine(i, 0xff, TMB_TRANSLUCENT, FF_EXISTS|FF_SOLID|FF_RENDERALL, secthinkers); + P_AddAirbob(lines[i].frontsector, lines[i].args[0], lines[i].args[1] << FRACBITS, !!(lines[i].args[2] & TMFB_REVERSE), !!(lines[i].args[2] & TMFB_SPINDASH), !!(lines[i].args[2] & TMFB_DYNAMIC)); break; - case 124: // goo water - ffloorflags = FF_EXISTS|FF_RENDERALL|FF_TRANSLUCENT|FF_SWIMMABLE|FF_GOOWATER|FF_BOTHPLANES|FF_ALLSIDES|FF_CUTEXTRA|FF_EXTRA|FF_CUTSPRITES; - if (lines[i].flags & ML_NOCLIMB) - ffloorflags |= FF_DOUBLESHADOW; - if (lines[i].flags & ML_EFFECT4) - ffloorflags |= FF_COLORMAPONLY; - if (lines[i].flags & ML_EFFECT5) - ffloorflags |= FF_RIPPLE; - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); + case 160: // FOF (Water bobbing) + P_AddFakeFloorsByLine(i, 0xff, TMB_TRANSLUCENT, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_FLOATBOB, secthinkers); break; - case 125: // goo water, no sides - ffloorflags = FF_EXISTS|FF_RENDERPLANES|FF_TRANSLUCENT|FF_SWIMMABLE|FF_GOOWATER|FF_BOTHPLANES|FF_CUTEXTRA|FF_EXTRA|FF_CUTSPRITES; - if (lines[i].flags & ML_NOCLIMB) - ffloorflags |= FF_DOUBLESHADOW; - if (lines[i].flags & ML_EFFECT4) - ffloorflags |= FF_COLORMAPONLY; - if (lines[i].flags & ML_EFFECT5) - ffloorflags |= FF_RIPPLE; - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - break; + case 170: // FOF (Crumbling) + ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CRUMBLE; - case 140: // 'Platform' - You can jump up through it - // If line has no-climb set, don't give it shadows, otherwise do - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_PLATFORM|FF_BOTHPLANES|FF_ALLSIDES; - if (lines[i].flags & ML_NOCLIMB) + //Tangibility settings + if (lines[i].args[3] & TMFT_INTANGIBLETOP) + ffloorflags |= FF_REVERSEPLATFORM; + if (lines[i].args[3] & TMFT_INTANGIBLEBOTTOM) + ffloorflags |= FF_PLATFORM; + if (lines[i].args[3] & TMFT_DONTBLOCKPLAYER) + ffloorflags &= ~FF_BLOCKPLAYER; + if (lines[i].args[3] & TMFT_DONTBLOCKOTHERS) + ffloorflags &= ~FF_BLOCKOTHERS; + + //Flags + if (lines[i].args[4] & TMFC_NOSHADE) ffloorflags |= FF_NOSHADE; + if (lines[i].args[4] & TMFC_NORETURN) + ffloorflags |= FF_NORETURN; + if (lines[i].args[4] & TMFC_FLOATBOB) + ffloorflags |= FF_FLOATBOB; + if (lines[i].args[4] & TMFC_SPLAT) + ffloorflags |= FF_SPLAT; - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - break; + //If translucent or player can enter it, cut inner walls + if (lines[i].args[1] < 0xff || (lines[i].args[3] & TMFT_VISIBLEFROMINSIDE)) + ffloorflags |= FF_CUTEXTRA|FF_EXTRA; + else + ffloorflags |= FF_CUTLEVEL; - case 141: // Translucent "platform" - // If line has no-climb set, don't give it shadows, otherwise do - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_PLATFORM|FF_TRANSLUCENT|FF_EXTRA|FF_CUTEXTRA; - if (lines[i].flags & ML_NOCLIMB) - ffloorflags |= FF_NOSHADE; - - // Draw the 'insides' of the block too - if (lines[i].flags & ML_EFFECT2) + //If player can enter it, render insides + if (lines[i].args[3] & TMFT_VISIBLEFROMINSIDE) { - ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES; - ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA); + if (ffloorflags & FF_RENDERPLANES) + ffloorflags |= FF_BOTHPLANES; + if (ffloorflags & FF_RENDERSIDES) + ffloorflags |= FF_ALLSIDES; } - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); + P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); + if (lines[i].args[4] & TMFC_AIRBOB) + P_AddAirbob(lines[i].frontsector, lines[i].args[0], 16*FRACUNIT, false, false, false); break; - case 142: // Translucent "platform" with no sides - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERPLANES|FF_TRANSLUCENT|FF_PLATFORM|FF_EXTRA|FF_CUTEXTRA; - if (lines[i].flags & ML_NOCLIMB) // shade it unless no-climb - ffloorflags |= FF_NOSHADE; - - // Draw the 'insides' of the block too - if (lines[i].flags & ML_EFFECT2) - { - ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES; - ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA); - } - - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - break; - - case 143: // 'Reverse platform' - You fall through it - // If line has no-climb set, don't give it shadows, otherwise do - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_REVERSEPLATFORM|FF_BOTHPLANES|FF_ALLSIDES; - if (lines[i].flags & ML_NOCLIMB) - ffloorflags |= FF_NOSHADE; - - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - break; - - case 144: // Translucent "reverse platform" - // If line has no-climb set, don't give it shadows, otherwise do - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_REVERSEPLATFORM|FF_TRANSLUCENT|FF_EXTRA|FF_CUTEXTRA; - if (lines[i].flags & ML_NOCLIMB) - ffloorflags |= FF_NOSHADE; - - // Draw the 'insides' of the block too - if (lines[i].flags & ML_EFFECT2) - { - ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES; - ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA); - } - - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - break; - - case 145: // Translucent "reverse platform" with no sides - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERPLANES|FF_TRANSLUCENT|FF_REVERSEPLATFORM|FF_EXTRA|FF_CUTEXTRA; - if (lines[i].flags & ML_NOCLIMB) // shade it unless no-climb - ffloorflags |= FF_NOSHADE; - - // Draw the 'insides' of the block too - if (lines[i].flags & ML_EFFECT2) - { - ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES; - ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA); - } - - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - break; - - case 146: // Intangible floor/ceiling with solid sides (fences/hoops maybe?) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERSIDES|FF_ALLSIDES|FF_INTANGIBLEFLATS, secthinkers); - break; - - case 150: // Air bobbing platform - case 151: // Adjustable air bobbing platform + case 190: // FOF (Rising) { - fixed_t dist = (lines[i].special == 150) ? 16*FRACUNIT : P_AproxDistance(lines[i].dx, lines[i].dy); - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddAirbob(lines[i].frontsector, tag, dist, false, !!(lines[i].flags & ML_NOCLIMB), false); - break; - } - case 152: // Adjustable air bobbing platform in reverse - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddAirbob(lines[i].frontsector, tag, P_AproxDistance(lines[i].dx, lines[i].dy), true, !!(lines[i].flags & ML_NOCLIMB), false); - break; - case 153: // Dynamic Sinking Platform - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddAirbob(lines[i].frontsector, tag, P_AproxDistance(lines[i].dx, lines[i].dy), false, !!(lines[i].flags & ML_NOCLIMB), true); - break; - - case 160: // Float/bob platform - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_FLOATBOB, secthinkers); - break; - - case 170: // Crumbling platform - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_CRUMBLE, secthinkers); - break; - - case 171: // Crumbling platform that will not return - P_AddFakeFloorsByLine(i, - FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_CRUMBLE|FF_NORETURN, secthinkers); - break; - - case 172: // "Platform" that crumbles and returns - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_PLATFORM|FF_CRUMBLE|FF_BOTHPLANES|FF_ALLSIDES; - if (lines[i].flags & ML_NOCLIMB) // shade it unless no-climb - ffloorflags |= FF_NOSHADE; - - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - break; - - case 173: // "Platform" that crumbles and doesn't return - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_PLATFORM|FF_CRUMBLE|FF_NORETURN|FF_BOTHPLANES|FF_ALLSIDES; - if (lines[i].flags & ML_NOCLIMB) // shade it unless no-climb - ffloorflags |= FF_NOSHADE; - - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - break; - - case 174: // Translucent "platform" that crumbles and returns - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_PLATFORM|FF_CRUMBLE|FF_TRANSLUCENT|FF_BOTHPLANES|FF_ALLSIDES; - if (lines[i].flags & ML_NOCLIMB) // shade it unless no-climb - ffloorflags |= FF_NOSHADE; - - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - break; - - case 175: // Translucent "platform" that crumbles and doesn't return - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_PLATFORM|FF_CRUMBLE|FF_NORETURN|FF_TRANSLUCENT|FF_BOTHPLANES|FF_ALLSIDES; - if (lines[i].flags & ML_NOCLIMB) // shade it unless no-climb - ffloorflags |= FF_NOSHADE; - - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - break; - - case 176: // Air bobbing platform that will crumble and bob on the water when it falls and hits - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_FLOATBOB|FF_CRUMBLE, secthinkers); - P_AddAirbob(lines[i].frontsector, tag, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); - break; - - case 177: // Air bobbing platform that will crumble and bob on - // the water when it falls and hits, then never return - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_FLOATBOB|FF_CRUMBLE|FF_NORETURN, secthinkers); - P_AddAirbob(lines[i].frontsector, tag, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); - break; - - case 178: // Crumbling platform that will float when it hits water - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CRUMBLE|FF_FLOATBOB, secthinkers); - break; - - case 179: // Crumbling platform that will float when it hits water, but not return - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_CRUMBLE|FF_FLOATBOB|FF_NORETURN, secthinkers); - break; - - case 180: // Air bobbing platform that will crumble - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_CRUMBLE, secthinkers); - P_AddAirbob(lines[i].frontsector, tag, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); - break; - - case 190: // Rising Platform FOF (solid, opaque, shadows) - case 191: // Rising Platform FOF (solid, opaque, no shadows) - case 192: // Rising Platform TL block: FOF (solid, translucent) - case 193: // Rising Platform FOF (solid, invisible) - case 194: // Rising Platform 'Platform' - You can jump up through it - case 195: // Rising Platform Translucent "platform" - { - fixed_t speed = FixedDiv(P_AproxDistance(lines[i].dx, lines[i].dy), 4*FRACUNIT); fixed_t ceilingtop = P_FindHighestCeilingSurrounding(lines[i].frontsector); fixed_t ceilingbottom = P_FindLowestCeilingSurrounding(lines[i].frontsector); - ffloorflags = FF_EXISTS|FF_SOLID; - if (lines[i].special != 193) - ffloorflags |= FF_RENDERALL; - if (lines[i].special <= 191) - ffloorflags |= FF_CUTLEVEL; - if (lines[i].special == 192 || lines[i].special == 195) - ffloorflags |= FF_TRANSLUCENT|FF_EXTRA|FF_CUTEXTRA; - if (lines[i].special >= 194) - ffloorflags |= FF_PLATFORM|FF_BOTHPLANES|FF_ALLSIDES; - if (lines[i].special != 190 && (lines[i].special <= 193 || lines[i].flags & ML_NOCLIMB)) - ffloorflags |= FF_NOSHADE; - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); + ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL; - P_AddRaiseThinker(lines[i].frontsector, tag, speed, ceilingtop, ceilingbottom, !!(lines[i].flags & ML_BLOCKPLAYERS), !!(lines[i].flags & ML_NOCLIMB)); + //Appearance settings + if (lines[i].args[3] & TMFA_NOPLANES) + ffloorflags &= ~FF_RENDERPLANES; + if (lines[i].args[3] & TMFA_NOSIDES) + ffloorflags &= ~FF_RENDERSIDES; + if (lines[i].args[3] & TMFA_INSIDES) + { + if (ffloorflags & FF_RENDERPLANES) + ffloorflags |= FF_BOTHPLANES; + if (ffloorflags & FF_RENDERSIDES) + ffloorflags |= FF_ALLSIDES; + } + if (lines[i].args[3] & TMFA_ONLYINSIDES) + { + if (ffloorflags & FF_RENDERPLANES) + ffloorflags |= FF_INVERTPLANES; + if (ffloorflags & FF_RENDERSIDES) + ffloorflags |= FF_INVERTSIDES; + } + if (lines[i].args[3] & TMFA_NOSHADE) + ffloorflags |= FF_NOSHADE; + if (lines[i].args[3] & TMFA_SPLAT) + ffloorflags |= FF_SPLAT; + + //Tangibility settings + if (lines[i].args[4] & TMFT_INTANGIBLETOP) + ffloorflags |= FF_REVERSEPLATFORM; + if (lines[i].args[4] & TMFT_INTANGIBLEBOTTOM) + ffloorflags |= FF_PLATFORM; + if (lines[i].args[4] & TMFT_DONTBLOCKPLAYER) + ffloorflags &= ~FF_BLOCKPLAYER; + if (lines[i].args[4] & TMFT_DONTBLOCKOTHERS) + ffloorflags &= ~FF_BLOCKOTHERS; + + //Cutting options + if (ffloorflags & FF_RENDERALL) + { + //If translucent or player can enter it, cut inner walls + if ((lines[i].args[1] < 255) || (lines[i].args[4] & TMFT_VISIBLEFROMINSIDE)) + ffloorflags |= FF_CUTEXTRA|FF_EXTRA; + else + ffloorflags |= FF_CUTLEVEL; + } + + P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); + P_AddRaiseThinker(lines[i].frontsector, lines[i].args[0], lines[i].args[5] << FRACBITS, ceilingtop, ceilingbottom, !!(lines[i].args[6] & TMFR_REVERSE), !!(lines[i].args[6] & TMFR_SPINDASH)); break; } - - case 200: // Double light effect - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_CUTSPRITES|FF_DOUBLESHADOW, secthinkers); - break; - - case 201: // Light effect - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_CUTSPRITES, secthinkers); + case 200: // Light block + ffloorflags = FF_EXISTS|FF_CUTSPRITES; + if (!lines[i].args[1]) + ffloorflags |= FF_DOUBLESHADOW; + P_AddFakeFloorsByLine(i, 0xff, TMB_TRANSLUCENT, ffloorflags, secthinkers); break; case 202: // Fog @@ -6598,132 +6279,274 @@ void P_SpawnSpecials(boolean fromnetsave) // SoM: Because it's fog, check for an extra colormap and set the fog flag... if (sectors[sec].extra_colormap) sectors[sec].extra_colormap->flags = CMF_FOG; - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); + P_AddFakeFloorsByLine(i, 0xff, TMB_TRANSLUCENT, ffloorflags, secthinkers); break; - case 220: // Like opaque water, but not swimmable. (Good for snow effect on FOFs) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_RENDERALL|FF_BOTHPLANES|FF_ALLSIDES|FF_CUTEXTRA|FF_EXTRA|FF_CUTSPRITES, secthinkers); - break; + case 220: //Intangible + ffloorflags = FF_EXISTS|FF_RENDERALL|FF_CUTEXTRA|FF_EXTRA|FF_CUTSPRITES; - case 221: // FOF (intangible, translucent) - // If line has no-climb set, give it shadows, otherwise don't - ffloorflags = FF_EXISTS|FF_RENDERALL|FF_TRANSLUCENT|FF_EXTRA|FF_CUTEXTRA|FF_CUTSPRITES; - if (!(lines[i].flags & ML_NOCLIMB)) + //Appearance settings + if (lines[i].args[3] & TMFA_NOPLANES) + ffloorflags &= ~FF_RENDERPLANES; + if (lines[i].args[3] & TMFA_NOSIDES) + ffloorflags &= ~FF_RENDERSIDES; + if (!(lines[i].args[3] & TMFA_INSIDES)) + { + if (ffloorflags & FF_RENDERPLANES) + ffloorflags |= FF_BOTHPLANES; + if (ffloorflags & FF_RENDERSIDES) + ffloorflags |= FF_ALLSIDES; + } + if (lines[i].args[3] & TMFA_ONLYINSIDES) + { + if (ffloorflags & FF_RENDERPLANES) + ffloorflags |= FF_INVERTPLANES; + if (ffloorflags & FF_RENDERSIDES) + ffloorflags |= FF_INVERTSIDES; + } + if (lines[i].args[3] & TMFA_NOSHADE) ffloorflags |= FF_NOSHADE; + if (lines[i].args[3] & TMFA_SPLAT) + ffloorflags |= FF_SPLAT; - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - break; - - case 222: // FOF with no floor/ceiling (good for GFZGRASS effect on FOFs) - // If line has no-climb set, give it shadows, otherwise don't - ffloorflags = FF_EXISTS|FF_RENDERSIDES|FF_ALLSIDES; - if (!(lines[i].flags & ML_NOCLIMB)) - ffloorflags |= FF_NOSHADE|FF_CUTSPRITES; - - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); + P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); break; case 223: // FOF (intangible, invisible) - for combining specials in a sector - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_NOSHADE, secthinkers); + P_AddFakeFloorsByLine(i, 0xff, TMB_TRANSLUCENT, FF_EXISTS|FF_NOSHADE, secthinkers); break; case 250: // Mario Block ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_MARIO; - if (lines[i].flags & ML_NOCLIMB) - ffloorflags |= FF_SHATTERBOTTOM; - if (lines[i].flags & ML_EFFECT1) + if (lines[i].args[1] & TMFM_BRICK) + ffloorflags |= FF_GOOWATER; + if (lines[i].args[1] & TMFM_INVISIBLE) ffloorflags &= ~(FF_SOLID|FF_RENDERALL|FF_CUTLEVEL); - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); + P_AddFakeFloorsByLine(i, 0xff, TMB_TRANSLUCENT, ffloorflags, secthinkers); break; case 251: // A THWOMP! { - fixed_t crushspeed = (lines[i].flags & ML_EFFECT5) ? lines[i].dy >> 3 : 10*FRACUNIT; - fixed_t retractspeed = (lines[i].flags & ML_EFFECT5) ? lines[i].dx >> 3 : 2*FRACUNIT; - UINT16 sound = (lines[i].flags & ML_EFFECT4) ? sides[lines[i].sidenum[0]].textureoffset >> FRACBITS : sfx_thwomp; - P_AddThwompThinker(lines[i].frontsector, &lines[i], crushspeed, retractspeed, sound); - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); + UINT16 sound = (lines[i].stringargs[0]) ? get_number(lines[i].stringargs[0]) : sfx_thwomp; + P_AddThwompThinker(lines[i].frontsector, &lines[i], lines[i].args[1] << (FRACBITS - 3), lines[i].args[2] << (FRACBITS - 3), sound); + P_AddFakeFloorsByLine(i, 0xff, TMB_TRANSLUCENT, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); break; } - case 252: // Shatter block (breaks when touched) - ffloorflags = FF_EXISTS|FF_BLOCKOTHERS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER; - if (lines[i].flags & ML_NOCLIMB) - ffloorflags |= FF_BLOCKPLAYER|FF_SHATTERBOTTOM; - - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - break; - - case 253: // Translucent shatter block (see 76) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_BLOCKOTHERS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER|FF_TRANSLUCENT, secthinkers); - break; - case 254: // Bustable block - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP; - if (lines[i].flags & ML_NOCLIMB) - ffloorflags |= FF_STRONGBUST; + { + UINT8 busttype = BT_REGULAR; + ffloorbustflags_e bustflags = 0; - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); + ffloorflags = FF_EXISTS|FF_BLOCKOTHERS|FF_RENDERALL|FF_BUSTUP; + + //Bustable type + switch (lines[i].args[3]) + { + case TMFB_TOUCH: + busttype = BT_TOUCH; + break; + case TMFB_SPIN: + busttype = BT_SPINBUST; + break; + case TMFB_REGULAR: + busttype = BT_REGULAR; + break; + case TMFB_STRONG: + busttype = BT_STRONG; + break; + } + + //Flags + if (lines[i].args[4] & TMFB_PUSHABLES) + bustflags |= FB_PUSHABLES; + if (lines[i].args[4] & TMFB_EXECUTOR) + bustflags |= FB_EXECUTOR; + if (lines[i].args[4] & TMFB_ONLYBOTTOM) + bustflags |= FB_ONLYBOTTOM; + if (lines[i].args[4] & TMFB_SPLAT) + ffloorflags |= FF_SPLAT; + + if (busttype != BT_TOUCH || bustflags & FB_ONLYBOTTOM) + ffloorflags |= FF_BLOCKPLAYER; + + TAG_ITER_SECTORS(lines[i].args[0], s) + { + ffloor_t *fflr = P_AddFakeFloor(§ors[s], lines[i].frontsector, lines + i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); + if (!fflr) + continue; + fflr->bustflags = bustflags; + fflr->busttype = busttype; + fflr->busttag = lines[i].args[5]; + } break; - - case 255: // Spin bust block (breaks when jumped or spun downwards onto) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP|FF_SPINBUST, secthinkers); - break; - - case 256: // Translucent spin bust block (see 78) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP|FF_SPINBUST|FF_TRANSLUCENT, secthinkers); - break; - + } case 257: // Quicksand ffloorflags = FF_EXISTS|FF_QUICKSAND|FF_RENDERALL|FF_ALLSIDES|FF_CUTSPRITES; - if (lines[i].flags & ML_EFFECT5) + if (!(lines[i].args[1])) ffloorflags |= FF_RIPPLE; - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); + TAG_ITER_SECTORS(lines[i].args[0], s) + { + ffloor_t *fflr = P_AddFakeFloor(§ors[s], lines[i].frontsector, lines + i, 0xff, TMB_TRANSLUCENT, ffloorflags, secthinkers); + if (!fflr) + continue; + fflr->sinkspeed = abs(lines[i].args[2]) << (FRACBITS - 1); + fflr->friction = abs(lines[i].args[3]) << (FRACBITS - 6); + } break; case 258: // Laser block - P_AddLaserThinker(tag, lines + i, !!(lines[i].flags & ML_EFFECT1)); - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_RENDERALL|FF_NOSHADE|FF_EXTRA|FF_CUTEXTRA|FF_TRANSLUCENT, secthinkers); + ffloorflags = FF_EXISTS|FF_RENDERALL|FF_NOSHADE|FF_EXTRA|FF_CUTEXTRA|FF_TRANSLUCENT; + P_AddLaserThinker(lines[i].args[0], lines + i, !!(lines[i].args[3] & TMFL_NOBOSSES)); + if (lines[i].args[3] & TMFL_SPLAT) + ffloorflags |= FF_SPLAT; + P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); break; case 259: // Custom FOF - if (lines[i].sidenum[1] != 0xffff) + TAG_ITER_SECTORS(lines[i].args[0], s) { - ffloortype_e fofflags = sides[lines[i].sidenum[1]].toptexture; - P_AddFakeFloorsByLine(i, fofflags, secthinkers); + ffloor_t *fflr = P_AddFakeFloor(§ors[s], lines[i].frontsector, lines + i, lines[i].args[1], lines[i].args[2], lines[i].args[3], secthinkers); + if (!fflr) + continue; + if (!udmf) // Ugly backwards compatibility stuff + { + if (lines[i].args[3] & FF_QUICKSAND) + { + fflr->sinkspeed = abs(lines[i].dx) >> 1; + fflr->friction = abs(lines[i].dy) >> 6; + } + if (lines[i].args[3] & FF_BUSTUP) + { + switch (lines[i].args[4] % TMFB_ONLYBOTTOM) + { + case TMFB_TOUCH: + fflr->busttype = BT_TOUCH; + break; + case TMFB_SPIN: + fflr->busttype = BT_SPINBUST; + break; + case TMFB_REGULAR: + fflr->busttype = BT_REGULAR; + break; + case TMFB_STRONG: + fflr->busttype = BT_STRONG; + break; + } + + if (lines[i].args[4] & TMFB_ONLYBOTTOM) + fflr->bustflags |= FB_ONLYBOTTOM; + if (lines[i].flags & ML_MIDSOLID) + fflr->bustflags |= FB_PUSHABLES; + if (lines[i].flags & ML_WRAPMIDTEX) + { + fflr->bustflags |= FB_EXECUTOR; + fflr->busttag = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; + } + } + } } - else - I_Error("Custom FOF (tag %d) found without a linedef back side!", tag); break; - case 300: // Linedef executor (combines with sector special 974/975) and commands - case 302: - case 303: - case 304: + case 260: // GZDoom-like 3D Floor. + { + UINT8 dtype = lines[i].args[1] & 3; + UINT8 dflags1 = lines[i].args[1] - dtype; + UINT8 dflags2 = lines[i].args[2]; + UINT8 dopacity = lines[i].args[3]; + boolean isfog = false; + + if (dtype == 0) + dtype = 1; + + ffloorflags = FF_EXISTS; + + if (dflags2 & 1) ffloorflags |= FF_NOSHADE; // Disable light effects (Means no shadowcast) + if (dflags2 & 2) ffloorflags |= FF_DOUBLESHADOW; // Restrict light inside (Means doubleshadow) + if (dflags2 & 4) isfog = true; // Fog effect (Explicitly render like a fog block) + + if (dflags1 & 4) ffloorflags |= FF_BOTHPLANES|FF_ALLSIDES; // Render-inside + if (dflags1 & 16) ffloorflags |= FF_INVERTSIDES|FF_INVERTPLANES; // Invert visibility rules + + // Fog block + if (isfog) + ffloorflags |= FF_RENDERALL|FF_CUTEXTRA|FF_CUTSPRITES|FF_BOTHPLANES|FF_EXTRA|FF_FOG|FF_INVERTPLANES|FF_ALLSIDES|FF_INVERTSIDES; + else + { + ffloorflags |= FF_RENDERALL; + + // Solid + if (dtype == 1) + ffloorflags |= FF_SOLID|FF_CUTLEVEL; + // Water + else if (dtype == 2) + ffloorflags |= FF_SWIMMABLE|FF_CUTEXTRA|FF_CUTSPRITES|FF_EXTRA|FF_RIPPLE; + // Intangible + else if (dtype == 3) + ffloorflags |= FF_CUTEXTRA|FF_CUTSPRITES|FF_EXTRA; + } + + // Non-opaque + if (dopacity < 255) + { + // Invisible + if (dopacity == 0) + { + // True invisible + if (ffloorflags & FF_NOSHADE) + ffloorflags &= ~(FF_RENDERALL|FF_CUTEXTRA|FF_CUTSPRITES|FF_EXTRA|FF_BOTHPLANES|FF_ALLSIDES|FF_CUTLEVEL); + // Shadow block + else + { + ffloorflags |= FF_CUTSPRITES; + ffloorflags &= ~(FF_RENDERALL|FF_CUTEXTRA|FF_EXTRA|FF_BOTHPLANES|FF_ALLSIDES|FF_CUTLEVEL); + } + } + else + { + ffloorflags |= FF_TRANSLUCENT|FF_CUTEXTRA|FF_EXTRA; + ffloorflags &= ~FF_CUTLEVEL; + } + } + + P_AddFakeFloorsByLine(i, dopacity, TMB_TRANSLUCENT, ffloorflags, secthinkers); + } + break; + + case 300: // Trigger linedef executor + case 303: // Count rings + case 305: // Character ability + case 314: // Pushable linedef executors (count # of pushables) + case 317: // Condition set trigger + case 319: // Unlockable trigger + case 331: // Player skin + case 334: // Object dye + case 337: // Emerald check + if (lines[i].args[0] > TMT_EACHTIMEMASK) + P_AddEachTimeThinker(&lines[i], lines[i].args[0] == TMT_EACHTIMEENTERANDEXIT); break; case 308: // Race-only linedef executor. Triggers once. - if (!(gametyperules & GTR_CIRCUIT)) + if (!P_CheckGametypeRules(lines[i].args[2], (UINT32)lines[i].args[1])) + { lines[i].special = 0; + break; + } + if (lines[i].args[0] > TMT_EACHTIMEMASK) + P_AddEachTimeThinker(&lines[i], lines[i].args[0] == TMT_EACHTIMEENTERANDEXIT); break; // Linedef executor triggers for CTF teams. case 309: - case 311: if (!(gametyperules & GTR_TEAMS)) + { lines[i].special = 0; - break; - - // Each time executors - case 306: - case 301: - case 310: - case 312: - case 332: - case 335: - P_AddEachTimeThinker(&lines[i]); + break; + } + if (lines[i].args[0] > TMT_EACHTIMEMASK) + P_AddEachTimeThinker(&lines[i], lines[i].args[0] == TMT_EACHTIMEENTERANDEXIT); break; // No More Enemies Linedef Exec @@ -6731,100 +6554,24 @@ void P_SpawnSpecials(boolean fromnetsave) P_AddNoEnemiesThinker(&lines[i]); break; - // Pushable linedef executors (count # of pushables) - case 314: - case 315: - break; - - // Unlock trigger executors - case 317: - case 318: - break; - case 319: - case 320: - break; - // Trigger on X calls case 321: - case 322: - if (lines[i].flags & ML_NOCLIMB && sides[lines[i].sidenum[0]].rowoffset > 0) // optional "starting" count - lines[i].callcount = sides[lines[i].sidenum[0]].rowoffset>>FRACBITS; - else - lines[i].callcount = sides[lines[i].sidenum[0]].textureoffset>>FRACBITS; - if (lines[i].special == 322) // Each time - P_AddEachTimeThinker(&lines[i]); - break; - - // Skin trigger executors - case 331: - case 333: - break; - - // Object dye executors - case 334: - case 336: - break; - // Record attack only linedef exec - case 323: - if (!modeattacking) - lines[i].special = 0; - break; - - case 328: // Encore-only linedef execute on map load - if (!encoremode) - lines[i].special = 0; - // This is handled in P_RunLevelLoadExecutors. - break; - - case 399: // Linedef execute on map load - // This is handled in P_RunLevelLoadExecutors. - break; - - case 400: - case 401: - case 402: - case 403: - case 404: - case 405: - case 406: - case 407: - case 408: - case 409: - case 410: - case 411: - case 412: - case 413: - case 414: - case 415: - case 416: - case 417: - case 418: - case 419: - case 420: - case 421: - case 422: - case 423: - case 424: - case 425: - case 426: - case 427: - case 428: - case 429: - case 430: - case 431: + lines[i].callcount = (lines[i].args[2] && lines[i].args[3] > 0) ? lines[i].args[3] : lines[i].args[1]; // optional "starting" count + if (lines[i].args[0] > TMXT_EACHTIMEMASK) // Each time + P_AddEachTimeThinker(&lines[i], lines[i].args[0] == TMXT_EACHTIMEENTERANDEXIT); break; case 449: // Enable bosses with parameter { - INT32 bossid = sides[*lines[i].sidenum].textureoffset>>FRACBITS; + INT32 bossid = lines[i].args[0]; if (bossid & ~15) // if any bits other than first 16 are set { CONS_Alert(CONS_WARNING, - M_GetText("Boss enable linedef (tag %d) has an invalid texture x offset.\nConsider changing it or removing it entirely.\n"), - tag); + M_GetText("Boss enable linedef has an invalid boss ID (%d).\nConsider changing it or removing it entirely.\n"), + bossid); break; } - if (!(lines[i].flags & ML_NOCLIMB)) + if (!(lines[i].args[1])) { bossdisabled |= (1<>FRACBITS); + TAG_ITER_SECTORS(lines[i].args[0], s) + P_SpawnAdjustableGlowingLight(§ors[s], lines[i].args[2], + lines[i].args[3] ? sectors[s].lightlevel : lines[i].args[4], lines[i].args[1]); break; case 603: // Adjustable flickering light sec = sides[*lines[i].sidenum].sector - sectors; - TAG_ITER_SECTORS(tag, s) - P_SpawnAdjustableFireFlicker(§ors[sec], §ors[s], - P_AproxDistance(lines[i].dx, lines[i].dy)>>FRACBITS); + TAG_ITER_SECTORS(lines[i].args[0], s) + P_SpawnAdjustableFireFlicker(§ors[s], lines[i].args[2], + lines[i].args[3] ? sectors[s].lightlevel : lines[i].args[4], lines[i].args[1]); break; - case 604: // Adjustable Blinking Light (unsynchronized) + case 604: // Adjustable Blinking Light sec = sides[*lines[i].sidenum].sector - sectors; - TAG_ITER_SECTORS(tag, s) - P_SpawnAdjustableStrobeFlash(§ors[sec], §ors[s], - abs(lines[i].dx)>>FRACBITS, abs(lines[i].dy)>>FRACBITS, false); - break; - - case 605: // Adjustable Blinking Light (synchronized) - sec = sides[*lines[i].sidenum].sector - sectors; - TAG_ITER_SECTORS(tag, s) - P_SpawnAdjustableStrobeFlash(§ors[sec], §ors[s], - abs(lines[i].dx)>>FRACBITS, abs(lines[i].dy)>>FRACBITS, true); + TAG_ITER_SECTORS(lines[i].args[0], s) + P_SpawnAdjustableStrobeFlash(§ors[s], lines[i].args[3], + (lines[i].args[4] & TMB_USETARGET) ? sectors[s].lightlevel : lines[i].args[5], + lines[i].args[1], lines[i].args[2], lines[i].args[4] & TMB_SYNC); break; case 606: // HACK! Copy colormaps. Just plain colormaps. @@ -6937,22 +6641,128 @@ void P_SpawnSpecials(boolean fromnetsave) } break; - // SRB2Kart - case 2000: // Waypoint Parameters + default: break; + } + } + + // And another round, this time with all FOFs already created + for (i = 0; i < numlines; i++) + { + switch (lines[i].special) + { + INT32 s; + INT32 l; + + case 74: // Make FOF bustable + { + UINT8 busttype = BT_REGULAR; + ffloorbustflags_e bustflags = 0; + + if (!udmf) + break; + + switch (lines[i].args[1]) + { + case TMFB_TOUCH: + busttype = BT_TOUCH; + break; + case TMFB_SPIN: + busttype = BT_SPINBUST; + break; + case TMFB_REGULAR: + busttype = BT_REGULAR; + break; + case TMFB_STRONG: + busttype = BT_STRONG; + break; + } + + if (lines[i].args[2] & TMFB_PUSHABLES) + bustflags |= FB_PUSHABLES; + if (lines[i].args[2] & TMFB_EXECUTOR) + bustflags |= FB_EXECUTOR; + if (lines[i].args[2] & TMFB_ONLYBOTTOM) + bustflags |= FB_ONLYBOTTOM; + + TAG_ITER_LINES(lines[i].args[0], l) + { + if (lines[l].special < 100 || lines[l].special >= 300) + continue; + + TAG_ITER_SECTORS(lines[l].args[0], s) + { + ffloor_t *rover; + + for (rover = sectors[s].ffloors; rover; rover = rover->next) + { + if (rover->master != lines + l) + continue; + + rover->flags |= FF_BUSTUP; + rover->spawnflags |= FF_BUSTUP; + rover->bustflags = bustflags; + rover->busttype = busttype; + rover->busttag = lines[i].args[3]; + CheckForBustableBlocks = true; + break; + } + } + } + break; + } + + case 75: // Make FOF quicksand + { + if (!udmf) + break; + TAG_ITER_LINES(lines[i].args[0], l) + { + if (lines[l].special < 100 || lines[l].special >= 300) + continue; + + TAG_ITER_SECTORS(lines[l].args[0], s) + { + ffloor_t *rover; + + for (rover = sectors[s].ffloors; rover; rover = rover->next) + { + if (rover->master != lines + l) + continue; + + rover->flags |= FF_QUICKSAND; + rover->spawnflags |= FF_QUICKSAND; + rover->sinkspeed = abs(lines[i].args[1]) << (FRACBITS - 1); + rover->friction = abs(lines[i].args[2]) << (FRACBITS - 6); + CheckForQuicksand = true; + break; + } + } + } + break; + } + + case 76: // Make FOF bouncy + { + if (udmf) + { + TAG_ITER_LINES(lines[i].args[0], l) + P_MakeFOFBouncy(lines + i, lines + l); + } + else + { + TAG_ITER_SECTORS(lines[i].args[0], s) + for (j = 0; (unsigned)j < sectors[s].linecount; j++) + P_MakeFOFBouncy(lines + i, sectors[s].lines[j]); + } + break; + } + + // SRB2Kart case 2001: // Finish Line if ((gametyperules & GTR_CIRCUIT)) circuitmap = true; break; - case 2002: // Linedef Trigger: Race Lap - break; - case 2003: // Respawn Line - break; - case 2004: // Bot controller - break; - - case 499: // Linedef Executor: Enable/Disable Waypoints - break; default: break; @@ -7018,20 +6828,22 @@ void P_SpawnSpecialsThatRequireObjects(boolean fromnetsave) /** Adds 3Dfloors as appropriate based on a common control linedef. * * \param line Control linedef to use. + * \param alpha Alpha value (0-255). + * \param blendmode Blending mode. * \param ffloorflags 3Dfloor flags to use. * \param secthkiners Lists of thinkers sorted by sector. May be NULL. * \sa P_SpawnSpecials, P_AddFakeFloor * \author Graue */ -static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinkerlist_t *secthinkers) +static void P_AddFakeFloorsByLine(size_t line, INT32 alpha, UINT8 blendmode, ffloortype_e ffloorflags, thinkerlist_t *secthinkers) { INT32 s; - mtag_t tag = Tag_FGet(&lines[line].tags); + mtag_t tag = lines[line].args[0]; size_t sec = sides[*lines[line].sidenum].sector-sectors; line_t* li = lines + line; TAG_ITER_SECTORS(tag, s) - P_AddFakeFloor(§ors[s], §ors[sec], li, ffloorflags, secthinkers); + P_AddFakeFloor(§ors[s], §ors[sec], li, alpha, blendmode, ffloorflags, secthinkers); } /* @@ -7174,7 +6986,7 @@ void T_Scroll(scroll_t *s) if (!is3dblock) continue; - TAG_ITER_SECTORS(Tag_FGet(&line->tags), sect) + TAG_ITER_SECTORS(line->args[0], sect) { sector_t *psec; psec = sectors + sect; @@ -7249,7 +7061,7 @@ void T_Scroll(scroll_t *s) if (!is3dblock) continue; - TAG_ITER_SECTORS(Tag_FGet(&line->tags), sect) + TAG_ITER_SECTORS(line->args[0], sect) { sector_t *psec; psec = sectors + sect; @@ -7332,9 +7144,12 @@ static void Add_Scroller(INT32 type, fixed_t dx, fixed_t dy, INT32 control, INT3 s->accel = accel; s->exclusive = exclusive; s->vdx = s->vdy = 0; - if ((s->control = control) != -1) + s->control = control; + if (s->control != -1) s->last_height = sectors[control].floorheight + sectors[control].ceilingheight; s->affectee = affectee; + if (type == sc_carry || type == sc_carry_ceiling) + sectors[affectee].specialflags |= SSF_CONVEYOR; P_AddThinker(THINK_MAIN, &s->thinker); // interpolation @@ -7354,6 +7169,24 @@ static void Add_Scroller(INT32 type, fixed_t dx, fixed_t dy, INT32 control, INT3 } } +static void P_SpawnPlaneScroller(line_t *l, fixed_t dx, fixed_t dy, INT32 control, INT32 affectee, INT32 accel, INT32 exclusive) +{ + if (l->args[1] != TMP_CEILING) + { + if (l->args[2] != TMS_SCROLLONLY) + Add_Scroller(sc_carry, FixedMul(dx, CARRYFACTOR), FixedMul(dy, CARRYFACTOR), control, affectee, accel, exclusive); + if (l->args[2] != TMS_CARRYONLY) + Add_Scroller(sc_floor, -dx, dy, control, affectee, accel, exclusive); + } + if (l->args[1] != TMP_FLOOR) + { + if (l->args[2] != TMS_SCROLLONLY) + Add_Scroller(sc_carry_ceiling, FixedMul(dx, CARRYFACTOR), FixedMul(dy, CARRYFACTOR), control, affectee, accel, exclusive); + if (l->args[2] != TMS_CARRYONLY) + Add_Scroller(sc_ceiling, -dx, dy, control, affectee, accel, exclusive); + } +} + /** Initializes the scrollers. * * \todo Get rid of all the magic numbers. @@ -7363,166 +7196,72 @@ static void P_SpawnScrollers(void) { size_t i; line_t *l = lines; - mtag_t tag; for (i = 0; i < numlines; i++, l++) { - fixed_t dx = l->dx >> SCROLL_SHIFT; // direction and speed of scrolling - fixed_t dy = l->dy >> SCROLL_SHIFT; - - fixed_t bx = 0;/* backside variants */ - fixed_t by = 0; - INT32 control = -1, accel = 0; // no control sector or acceleration - INT32 special = l->special; - register INT32 s; - tag = Tag_FGet(&l->tags); - - // These types are same as the ones they get set to except that the - // first side's sector's heights cause scrolling when they change, and - // this linedef controls the direction and speed of the scrolling. The - // most complicated linedef since donuts, but powerful :) - - if (special == 515 || special == 512 || special == 522 || special == 532 || special == 504) // displacement scrollers + if (l->special == 502 || l->special == 510) { - special -= 2; - control = (INT32)(sides[*l->sidenum].sector - sectors); - } - else if (special == 514 || special == 511 || special == 521 || special == 531 || special == 503) // accelerative scrollers - { - special--; - accel = 1; - control = (INT32)(sides[*l->sidenum].sector - sectors); - } - else if (special == 535 || special == 525) // displacement scrollers - { - special -= 2; - control = (INT32)(sides[*l->sidenum].sector - sectors); - } - else if (special == 534 || special == 524) // accelerative scrollers - { - accel = 1; - special--; - control = (INT32)(sides[*l->sidenum].sector - sectors); + if ((l->args[4] & TMST_TYPEMASK) != TMST_REGULAR) + control = (INT32)(sides[*l->sidenum].sector - sectors); + if ((l->args[4] & TMST_TYPEMASK) == TMST_ACCELERATIVE) + accel = 1; } - if (special == 507) // front and back scrollers + // + // FIXME: UDMFify front+back scrollers + // types 507-509 + // + + switch (l->special) { - if (s != 0xffff) + case 510: // plane scroller { - bx = -(sides[s].textureoffset); - by = sides[s].rowoffset; + fixed_t length = R_PointToDist2(l->v2->x, l->v2->y, l->v1->x, l->v1->y); + fixed_t speed = l->args[3] << FRACBITS; + fixed_t dx = FixedMul(FixedDiv(l->dx, length), speed) >> SCROLL_SHIFT; + fixed_t dy = FixedMul(FixedDiv(l->dy, length), speed) >> SCROLL_SHIFT; + + if (l->args[0] == 0) + P_SpawnPlaneScroller(l, dx, dy, control, (INT32)(l->frontsector - sectors), accel, !(l->args[4] & TMST_NONEXCLUSIVE)); + else + { + TAG_ITER_SECTORS(l->args[0], s) + P_SpawnPlaneScroller(l, dx, dy, control, s, accel, !(l->args[4] & TMST_NONEXCLUSIVE)); + } + break; } - } - - switch (special) - { - case 513: // scroll effect ceiling - case 533: // scroll and carry objects on ceiling - TAG_ITER_SECTORS(tag, s) - Add_Scroller(sc_ceiling, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB); - if (special != 533) - break; - /* FALLTHRU */ - - case 523: // carry objects on ceiling - dx = FixedMul(dx, CARRYFACTOR); - dy = FixedMul(dy, CARRYFACTOR); - TAG_ITER_SECTORS(tag, s) - Add_Scroller(sc_carry_ceiling, dx, dy, control, s, accel, l->flags & ML_NOCLIMB); - break; - - case 510: // scroll effect floor - case 530: // scroll and carry objects on floor - TAG_ITER_SECTORS(tag, s) - Add_Scroller(sc_floor, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB); - if (special != 530) - break; - /* FALLTHRU */ - - case 520: // carry objects on floor - dx = FixedMul(dx, CARRYFACTOR); - dy = FixedMul(dy, CARRYFACTOR); - TAG_ITER_SECTORS(tag, s) - Add_Scroller(sc_carry, dx, dy, control, s, accel, l->flags & ML_NOCLIMB); - break; // scroll wall according to linedef // (same direction and speed as scrolling floors) case 502: { - TAG_ITER_LINES(tag, s) + TAG_ITER_LINES(l->args[0], s) if (s != (INT32)i) { - if (l->flags & ML_EFFECT2) // use texture offsets instead - { - dx = sides[l->sidenum[0]].textureoffset; - dy = sides[l->sidenum[0]].rowoffset; - } - if (l->flags & ML_EFFECT3) - { - if (lines[s].sidenum[1] != 0xffff) - Add_Scroller(sc_side, dx, dy, control, lines[s].sidenum[1], accel, 0); - } - else - Add_Scroller(sc_side, dx, dy, control, lines[s].sidenum[0], accel, 0); + if (l->args[1] != TMSD_BACK) + Add_Scroller(sc_side, l->args[2] << (FRACBITS - SCROLL_SHIFT), l->args[3] << (FRACBITS - SCROLL_SHIFT), control, lines[s].sidenum[0], accel, 0); + if (l->args[1] != TMSD_FRONT && lines[s].sidenum[1] != 0xffff) + Add_Scroller(sc_side, l->args[2] << (FRACBITS - SCROLL_SHIFT), l->args[3] << (FRACBITS - SCROLL_SHIFT), control, lines[s].sidenum[1], accel, 0); } break; } - case 505: - s = lines[i].sidenum[0]; - Add_Scroller(sc_side, -sides[s].textureoffset, sides[s].rowoffset, -1, s, accel, 0); - break; - - case 506: - s = lines[i].sidenum[1]; - - if (s != 0xffff) - Add_Scroller(sc_side, -sides[s].textureoffset, sides[s].rowoffset, -1, lines[i].sidenum[0], accel, 0); - else - CONS_Debug(DBG_GAMELOGIC, "Line special 506 (line #%s) missing back side!\n", sizeu1(i)); - break; - - case 507: - s = lines[i].sidenum[0]; - - if (lines[i].sidenum[1] != 0xffff) - Add_Scroller(sc_side, -sides[s].textureoffset, sides[s].rowoffset, -1, lines[i].sidenum[1], accel, 0); - else - CONS_Debug(DBG_GAMELOGIC, "Line special 507 (line #%s) missing back side!\n", sizeu1(i)); - break; - - case 508: - s = lines[i].sidenum[1]; - - if (s != 0xffff) - Add_Scroller(sc_side, -sides[s].textureoffset, sides[s].rowoffset, -1, s, accel, 0); - else - CONS_Debug(DBG_GAMELOGIC, "Line special 508 (line #%s) missing back side!\n", sizeu1(i)); - break; - - case 509: // scroll front and backside of tagged lines - TAG_ITER_LINES(tag, s) + case 500: + { + if (l->args[0] != TMSD_BACK) + Add_Scroller(sc_side, -l->args[1] << FRACBITS, l->args[2] << FRACBITS, -1, l->sidenum[0], accel, 0); + if (l->args[0] != TMSD_FRONT) { - if (s != (INT32)i) - { - Add_Scroller(sc_side, dx, dy, control, lines[s].sidenum[0], accel, 0); - if (lines[s].sidenum[1] != 0xffff) - Add_Scroller(sc_side, bx, by, control, lines[s].sidenum[1], accel, 0); - } + if (l->sidenum[1] != 0xffff) + Add_Scroller(sc_side, -l->args[1] << FRACBITS, l->args[2] << FRACBITS, -1, l->sidenum[1], accel, 0); + else + CONS_Debug(DBG_GAMELOGIC, "Line special 500 (line #%s) missing back side!\n", sizeu1(i)); } break; - - case 500: // scroll first side - Add_Scroller(sc_side, FRACUNIT, 0, -1, lines[i].sidenum[0], accel, 0); - break; - - case 501: // jff 1/30/98 2-way scroll - Add_Scroller(sc_side, -FRACUNIT, 0, -1, lines[i].sidenum[0], accel, 0); - break; + } } } } @@ -7566,7 +7305,7 @@ void T_Disappear(disappear_t *d) { ffloor_t *rover; register INT32 s; - mtag_t afftag = Tag_FGet(&lines[d->affectee].tags); + mtag_t afftag = lines[d->affectee].args[0]; TAG_ITER_SECTORS(afftag, s) { @@ -7581,7 +7320,7 @@ void T_Disappear(disappear_t *d) { rover->flags |= FF_EXISTS; - if (!(lines[d->sourceline].flags & ML_NOCLIMB)) + if (!(lines[d->sourceline].args[5])) { sectors[s].soundorg.z = P_GetFFloorTopZAt(rover, sectors[s].soundorg.x, sectors[s].soundorg.y); S_StartSound(§ors[s].soundorg, sfx_appear); @@ -8064,7 +7803,7 @@ static void P_ResetColormapFader(sector_t *sector) // The thinker is the first member in all the action structs, // so just let the thinker get freed, and that will free the whole // structure. - P_RemoveThinker(&((elevator_t *)sector->fadecolormapdata)->thinker); + P_RemoveThinker(&((thinkerdata_t *)sector->fadecolormapdata)->thinker); sector->fadecolormapdata = NULL; } } @@ -8293,40 +8032,32 @@ void T_Friction(friction_t *f) static void P_SpawnFriction(void) { size_t i; - line_t *l = lines; - mtag_t tag; - register INT32 s; - fixed_t strength; // frontside texture offset controls magnitude + sector_t *s = sectors; + fixed_t friction; // friction value to be applied during movement INT32 movefactor; // applied to each player move to simulate inertia - for (i = 0; i < numlines; i++, l++) - if (l->special == 540) - { - tag = Tag_FGet(&l->tags); - strength = sides[l->sidenum[0]].textureoffset>>FRACBITS; - if (strength > 0) // sludge - strength = strength*2; // otherwise, the maximum sludginess value is +967... + for (i = 0; i < numsectors; i++, s++) + { + if (s->friction == ORIG_FRICTION) + continue; - // The following might seem odd. At the time of movement, - // the move distance is multiplied by 'friction/0x10000', so a - // higher friction value actually means 'less friction'. - friction = ORIG_FRICTION - (0x1EB8*strength)/0x80; // ORIG_FRICTION is 0xE800 + friction = s->friction; - if (friction > FRACUNIT) - friction = FRACUNIT; - if (friction < 0) - friction = 0; + if (friction > FRACUNIT) + friction = FRACUNIT; + if (friction < 0) + friction = 0; - movefactor = FixedDiv(ORIG_FRICTION, friction); - if (movefactor < FRACUNIT) - movefactor = 19*movefactor - 18*FRACUNIT; - else - movefactor = FRACUNIT; + movefactor = FixedDiv(ORIG_FRICTION, friction); + if (movefactor < FRACUNIT) + movefactor = 8*movefactor - 7*FRACUNIT; + else + movefactor = FRACUNIT; - TAG_ITER_SECTORS(tag, s) - Add_Friction(friction, movefactor, s, -1); - } + Add_Friction(friction, movefactor, (INT32)(s-sectors), -1); + + } } /* @@ -8345,20 +8076,20 @@ static void P_SpawnFriction(void) * \param type Type of push/pull effect. * \param x_mag X magnitude. * \param y_mag Y magnitude. - * \param source For a point pusher/puller, the source object. + * \param z_mag Z magnitude. * \param affectee Target sector. * \param referrer What sector set it * \sa T_Pusher, P_GetPushThing, P_SpawnPushers */ -static void Add_Pusher(pushertype_e type, fixed_t x_mag, fixed_t y_mag, mobj_t *source, INT32 affectee, INT32 referrer, INT32 exclusive, INT32 slider) +static void Add_Pusher(pushertype_e type, fixed_t x_mag, fixed_t y_mag, fixed_t z_mag, INT32 affectee, INT32 referrer, INT32 exclusive, INT32 slider) { pusher_t *p = Z_Calloc(sizeof *p, PU_LEVSPEC, NULL); p->thinker.function.acp1 = (actionf_p1)T_Pusher; - p->source = source; p->type = type; - p->x_mag = x_mag>>FRACBITS; - p->y_mag = y_mag>>FRACBITS; + p->x_mag = x_mag; + p->y_mag = y_mag; + p->z_mag = z_mag; p->exclusive = exclusive; p->slider = slider; @@ -8366,140 +8097,18 @@ static void Add_Pusher(pushertype_e type, fixed_t x_mag, fixed_t y_mag, mobj_t * { p->roverpusher = true; p->referrer = referrer; + sectors[referrer].specialflags |= SSF_WINDCURRENT; } else - p->roverpusher = false; - - // "The right triangle of the square of the length of the hypotenuse is equal to the sum of the squares of the lengths of the other two sides." - // "Bah! Stupid brains! Don't you know anything besides the Pythagorean Theorem?" - Earthworm Jim - if (type == p_downcurrent || type == p_upcurrent || type == p_upwind || type == p_downwind) - p->magnitude = P_AproxDistance(p->x_mag,p->y_mag)<<(FRACBITS-PUSH_FACTOR); - else - p->magnitude = P_AproxDistance(p->x_mag,p->y_mag); - if (source) // point source exist? { - // where force goes to zero - if (type == p_push) - p->radius = AngleFixed(source->angle); - else - p->radius = (p->magnitude)<<(FRACBITS+1); - - p->x = p->source->x; - p->y = p->source->y; - p->z = p->source->z; + p->roverpusher = false; + sectors[affectee].specialflags |= SSF_WINDCURRENT; } + p->affectee = affectee; P_AddThinker(THINK_MAIN, &p->thinker); } - -// PIT_PushThing determines the angle and magnitude of the effect. -// The object's x and y momentum values are changed. -static pusher_t *tmpusher; // pusher structure for blockmap searches - -/** Applies a point pusher/puller to a thing. - * - * \param thing Thing to be pushed. - * \return True if the thing was pushed. - * \todo Make a more robust P_BlockThingsIterator() so the hidden parameter - * ::tmpusher won't need to be used. - * \sa T_Pusher - */ -static inline BlockItReturn_t PIT_PushThing(mobj_t *thing) -{ - if (thing->eflags & MFE_PUSHED) - return BMIT_ABORT; - - if (!tmpusher->source) - return BMIT_ABORT; - - // Allow this to affect pushable objects at some point? - if (thing->player && !(thing->flags & (MF_NOGRAVITY | MF_NOCLIP))) - { - INT32 dist; - INT32 speed; - INT32 sx, sy, sz; - - sx = tmpusher->x; - sy = tmpusher->y; - sz = tmpusher->z; - - // don't fade wrt Z if health & 2 (mapthing has multi flag) - if (tmpusher->source->health & 2) - dist = P_AproxDistance(thing->x - sx,thing->y - sy); - else - { - // Make sure the Z is in range - if (thing->z < sz - tmpusher->radius || thing->z > sz + tmpusher->radius) - return BMIT_ABORT; - - dist = P_AproxDistance(P_AproxDistance(thing->x - sx, thing->y - sy), - thing->z - sz); - } - - speed = (tmpusher->magnitude - ((dist>>FRACBITS)>>1))<<(FRACBITS - PUSH_FACTOR - 1); - - // If speed <= 0, you're outside the effective radius. You also have - // to be able to see the push/pull source point. - - // Written with bits and pieces of P_HomingAttack - if ((speed > 0) && (P_CheckSight(thing, tmpusher->source))) - { - // only push wrt Z if health & 1 (mapthing has ambush flag) - if (tmpusher->source->health & 1) - { - fixed_t tmpmomx, tmpmomy, tmpmomz; - - tmpmomx = FixedMul(FixedDiv(sx - thing->x, dist), speed); - tmpmomy = FixedMul(FixedDiv(sy - thing->y, dist), speed); - tmpmomz = FixedMul(FixedDiv(sz - thing->z, dist), speed); - if (tmpusher->source->type == MT_PUSH) // away! - { - tmpmomx *= -1; - tmpmomy *= -1; - tmpmomz *= -1; - } - - thing->momx += tmpmomx; - thing->momy += tmpmomy; - thing->momz += tmpmomz; - - if (thing->player) - { - thing->player->cmomx += tmpmomx; - thing->player->cmomy += tmpmomy; - thing->player->cmomx = FixedMul(thing->player->cmomx, ORIG_FRICTION); - thing->player->cmomy = FixedMul(thing->player->cmomy, ORIG_FRICTION); - } - } - else - { - angle_t pushangle; - - pushangle = R_PointToAngle2(thing->x, thing->y, sx, sy); - if (tmpusher->source->type == MT_PUSH) - pushangle += ANGLE_180; // away - pushangle >>= ANGLETOFINESHIFT; - thing->momx += FixedMul(speed, FINECOSINE(pushangle)); - thing->momy += FixedMul(speed, FINESINE(pushangle)); - - if (thing->player) - { - thing->player->cmomx += FixedMul(speed, FINECOSINE(pushangle)); - thing->player->cmomy += FixedMul(speed, FINESINE(pushangle)); - thing->player->cmomx = FixedMul(thing->player->cmomx, ORIG_FRICTION); - thing->player->cmomy = FixedMul(thing->player->cmomy, ORIG_FRICTION); - } - } - } - } - - if (tmpusher->exclusive) - thing->eflags |= MFE_PUSHED; - - return BMIT_CONTINUE; -} - /** Applies a pusher to all affected objects. * * \param p Thinker for the pusher effect. @@ -8511,30 +8120,19 @@ void T_Pusher(pusher_t *p) sector_t *sec, *referrer = NULL; mobj_t *thing; msecnode_t *node; - INT32 xspeed = 0,yspeed = 0; - INT32 xl, xh, yl, yh, bx, by; - INT32 radius; - //INT32 ht = 0; + fixed_t x_mag, y_mag, z_mag; + fixed_t xspeed = 0, yspeed = 0, zspeed = 0; boolean inFOF; boolean touching; boolean moved; - xspeed = yspeed = 0; + x_mag = p->x_mag >> PUSH_FACTOR; + y_mag = p->y_mag >> PUSH_FACTOR; + z_mag = p->z_mag >> PUSH_FACTOR; sec = sectors + p->affectee; - - // Be sure the special sector type is still turned on. If so, proceed. - // Else, bail out; the sector type has been changed on us. - if (p->roverpusher) - { - referrer = §ors[p->referrer]; - - if (GETSECSPECIAL(referrer->special, 3) != 2) - return; - } - else if (GETSECSPECIAL(sec->special, 3) != 2) - return; + referrer = sectors + p->referrer; // For constant pushers (wind/current) there are 3 situations: // @@ -8554,29 +8152,6 @@ void T_Pusher(pusher_t *p) // // In Phase II, you can apply these effects to Things other than players. - if (p->type == p_push) - { - - // Seek out all pushable things within the force radius of this - // point pusher. Crosses sectors, so use blockmap. - - tmpusher = p; // MT_PUSH/MT_PULL point source - radius = p->radius; // where force goes to zero - tmbbox[BOXTOP] = p->y + radius; - tmbbox[BOXBOTTOM] = p->y - radius; - tmbbox[BOXRIGHT] = p->x + radius; - tmbbox[BOXLEFT] = p->x - radius; - - xl = (unsigned)(tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT; - xh = (unsigned)(tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT; - yl = (unsigned)(tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT; - yh = (unsigned)(tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT; - for (bx = xl; bx <= xh; bx++) - for (by = yl; by <= yh; by++) - P_BlockThingsIterator(bx,by, PIT_PushThing); - return; - } - // constant pushers p_wind and p_current node = sec->touching_thinglist; // things touching this sector for (; node; node = node->m_thinglist_next) @@ -8650,84 +8225,36 @@ void T_Pusher(pusher_t *p) if (!touching && !inFOF) // Object is out of range of effect continue; - if (p->type == p_wind) + if (inFOF || (p->type == p_current && touching)) { - if (touching) // on ground - { - xspeed = (p->x_mag)>>1; // half force - yspeed = (p->y_mag)>>1; - moved = true; - } - else if (inFOF) - { - xspeed = (p->x_mag); // full force - yspeed = (p->y_mag); - moved = true; - } + xspeed = x_mag; // full force + yspeed = y_mag; + zspeed = z_mag; + moved = true; } - else if (p->type == p_upwind) + else if (p->type == p_wind && touching) { - if (touching) // on ground - { - thing->momz += (p->magnitude)>>1; - moved = true; - } - else if (inFOF) - { - thing->momz += p->magnitude; - moved = true; - } - } - else if (p->type == p_downwind) - { - if (touching) // on ground - { - thing->momz -= (p->magnitude)>>1; - moved = true; - } - else if (inFOF) - { - thing->momz -= p->magnitude; - moved = true; - } - } - else // p_current - { - if (!touching && !inFOF) // Not in water at all - xspeed = yspeed = 0; // no force - else // underwater / touching water - { - if (p->type == p_upcurrent) - thing->momz += p->magnitude; - else if (p->type == p_downcurrent) - thing->momz -= p->magnitude; - else - { - xspeed = p->x_mag; // full force - yspeed = p->y_mag; - } - moved = true; - } + xspeed = x_mag>>1; // half force + yspeed = y_mag>>1; + zspeed = z_mag>>1; + moved = true; } - if (p->type != p_downcurrent && p->type != p_upcurrent - && p->type != p_upwind && p->type != p_downwind) + thing->momx += xspeed; + thing->momy += yspeed; + thing->momz += zspeed; + if (thing->player) { - thing->momx += xspeed<<(FRACBITS-PUSH_FACTOR); - thing->momy += yspeed<<(FRACBITS-PUSH_FACTOR); - if (thing->player) - { - thing->player->cmomx += xspeed<<(FRACBITS-PUSH_FACTOR); - thing->player->cmomy += yspeed<<(FRACBITS-PUSH_FACTOR); - thing->player->cmomx = FixedMul(thing->player->cmomx, ORIG_FRICTION); - thing->player->cmomy = FixedMul(thing->player->cmomy, ORIG_FRICTION); - } - - // Tumbleweeds bounce a bit... - if (thing->type == MT_LITTLETUMBLEWEED || thing->type == MT_BIGTUMBLEWEED) - thing->momz += P_AproxDistance(xspeed<<(FRACBITS-PUSH_FACTOR), yspeed<<(FRACBITS-PUSH_FACTOR)) >> 2; + thing->player->cmomx += xspeed; + thing->player->cmomy += yspeed; + thing->player->cmomx = FixedMul(thing->player->cmomx, ORIG_FRICTION); + thing->player->cmomy = FixedMul(thing->player->cmomy, ORIG_FRICTION); } + // Tumbleweeds bounce a bit... + if (thing->type == MT_LITTLETUMBLEWEED || thing->type == MT_BIGTUMBLEWEED) + thing->momz += P_AproxDistance(xspeed, yspeed) >> 2; + if (moved) { if (p->slider && thing->player && !thing->player->carry) @@ -8735,7 +8262,7 @@ void T_Pusher(pusher_t *p) P_ResetPlayer (thing->player); thing->player->carry = CR_SLIDING; - thing->angle = R_PointToAngle2 (0, 0, xspeed<<(FRACBITS-PUSH_FACTOR), yspeed<<(FRACBITS-PUSH_FACTOR)); + thing->angle = R_PointToAngle2(0, 0, xspeed, yspeed); if (!demo.playback) { @@ -8754,86 +8281,33 @@ void T_Pusher(pusher_t *p) } } - -/** Gets a push/pull object. - * - * \param s Sector number to look in. - * \return Pointer to the first ::MT_PUSH or ::MT_PULL object found in the - * sector. - * \sa P_GetTeleportDestThing, P_GetStarpostThing, P_GetAltViewThing - */ -mobj_t *P_GetPushThing(UINT32 s) -{ - mobj_t *thing; - sector_t *sec; - - sec = sectors + s; - thing = sec->thinglist; - while (thing) - { - switch (thing->type) - { - case MT_PUSH: - case MT_PULL: - return thing; - default: - break; - } - thing = thing->snext; - } - return NULL; -} - /** Spawns pushers. * - * \todo Remove magic numbers. * \sa P_SpawnSpecials, Add_Pusher */ static void P_SpawnPushers(void) { size_t i; line_t *l = lines; - mtag_t tag; register INT32 s; - mobj_t *thing; + fixed_t length, hspeed, dx, dy; for (i = 0; i < numlines; i++, l++) { - tag = Tag_FGet(&l->tags); - switch (l->special) + if (l->special != 541) + continue; + + length = R_PointToDist2(l->v2->x, l->v2->y, l->v1->x, l->v1->y); + hspeed = l->args[1] << FRACBITS; + dx = FixedMul(FixedDiv(l->dx, length), hspeed); + dy = FixedMul(FixedDiv(l->dy, length), hspeed); + + if (l->args[0] == 0) + Add_Pusher(l->args[3], dx, dy, l->args[2] << FRACBITS, (INT32)(l->frontsector - sectors), -1, !(l->args[4] & TMPF_NONEXCLUSIVE), !!(l->args[4] & TMPF_SLIDE)); + else { - case 541: // wind - TAG_ITER_SECTORS(tag, s) - Add_Pusher(p_wind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); - break; - case 544: // current - TAG_ITER_SECTORS(tag, s) - Add_Pusher(p_current, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); - break; - case 547: // push/pull - TAG_ITER_SECTORS(tag, s) - { - thing = P_GetPushThing(s); - if (thing) // No MT_P* means no effect - Add_Pusher(p_push, l->dx, l->dy, thing, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); - } - break; - case 545: // current up - TAG_ITER_SECTORS(tag, s) - Add_Pusher(p_upcurrent, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); - break; - case 546: // current down - TAG_ITER_SECTORS(tag, s) - Add_Pusher(p_downcurrent, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); - break; - case 542: // wind up - TAG_ITER_SECTORS(tag, s) - Add_Pusher(p_upwind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); - break; - case 543: // wind down - TAG_ITER_SECTORS(tag, s) - Add_Pusher(p_downwind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); - break; + TAG_ITER_SECTORS(l->args[0], s) + Add_Pusher(l->args[3], dx, dy, l->args[2] << FRACBITS, s, -1, !(l->args[4] & TMPF_NONEXCLUSIVE), !!(l->args[4] & TMPF_SLIDE)); } } } diff --git a/src/p_spec.h b/src/p_spec.h index 40b9d75ff..8578fa8ea 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -20,9 +20,448 @@ extern mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs extern mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs -// 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); +// 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 +{ + 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, +} 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; // GETSECSPECIAL (specialval, section) // @@ -33,6 +472,10 @@ void P_StartQuake(fixed_t intensity, tic_t time); // 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<mo->x; oldy = player->mo->y; - // SRB2Kart TODO: make shatter blocks the default behavior, we don't need the hundreds of other types - P_UnsetThingPosition(player->mo); player->mo->x += player->mo->momx; player->mo->y += player->mo->momy; @@ -1438,90 +1444,86 @@ static void P_CheckBustableBlocks(player_t *player) for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next) { + ffloor_t *rover; + fixed_t topheight, bottomheight; + if (!node->m_sector) break; - if (node->m_sector->ffloors) + if (!node->m_sector->ffloors) + continue; + + for (rover = node->m_sector->ffloors; rover; rover = rover->next) { - ffloor_t *rover; - fixed_t topheight, bottomheight; + if (!P_PlayerCanBust(player, rover)) + continue; - for (rover = node->m_sector->ffloors; rover; rover = rover->next) + topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + + // Height checks + if (rover->bustflags & FB_ONLYBOTTOM) { - if (!(rover->flags & FF_EXISTS)) continue; + if (player->mo->z + player->mo->momz + player->mo->height < bottomheight) + continue; - if ((rover->flags & FF_BUSTUP)/* && rover->master->frontsector->crumblestate == CRUMBLE_NONE*/) + if (player->mo->z + player->mo->height > bottomheight) + continue; + } + else + { + switch (rover->busttype) { - // If it's an FF_SHATTER, you can break it just by touching it. - if (rover->flags & FF_SHATTER) - goto bust; - - if (rover->flags & FF_STRONGBUST) + case BT_TOUCH: + if (player->mo->z + player->mo->momz > topheight) continue; - bust: - topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); - bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + if (player->mo->z + player->mo->momz + player->mo->height < bottomheight) + continue; - // Height checks - if (rover->flags & FF_SHATTERBOTTOM) - { - if (player->mo->z+player->mo->momz + player->mo->height < bottomheight) - continue; + break; + case BT_SPINBUST: + if (player->mo->z + player->mo->momz > topheight) + continue; - if (player->mo->z+player->mo->height > bottomheight) - continue; - } - else if (rover->flags & FF_SPINBUST) - { - if (player->mo->z+player->mo->momz > topheight) - continue; + if (player->mo->z + player->mo->height < bottomheight) + continue; - if (player->mo->z + player->mo->height < bottomheight) - continue; - } - else if (rover->flags & FF_SHATTER) - { - if (player->mo->z + player->mo->momz > topheight) - continue; + break; + default: + if (player->mo->z >= topheight) + continue; - if (player->mo->z+player->mo->momz + player->mo->height < bottomheight) - continue; - } - else - { - if (player->mo->z >= topheight) - continue; + if (player->mo->z + player->mo->height < bottomheight) + continue; - if (player->mo->z + player->mo->height < bottomheight) - continue; - } - - // Impede the player's fall a bit - if (((rover->flags & FF_SPINBUST) || (rover->flags & FF_SHATTER)) && player->mo->z >= topheight) - player->mo->momz >>= 1; - else if (rover->flags & FF_SHATTER) - { - player->mo->momx >>= 1; - player->mo->momy >>= 1; - } - - //if (metalrecording) - // G_RecordBustup(rover); - - EV_CrumbleChain(NULL, rover); // node->m_sector - - // Run a linedef executor?? - if (rover->master->flags & ML_EFFECT5) - P_LinedefExecute((INT16)(P_AproxDistance(rover->master->dx, rover->master->dy)>>FRACBITS), player->mo, node->m_sector); - - goto bustupdone; + break; } } + + // Impede the player's fall a bit + if (((rover->busttype == BT_TOUCH) || (rover->busttype == BT_SPINBUST)) && player->mo->z >= topheight) + player->mo->momz >>= 1; + else if (rover->busttype == BT_TOUCH) + { + player->mo->momx >>= 1; + player->mo->momy >>= 1; + } + + //if (metalrecording) + // G_RecordBustup(rover); + + EV_CrumbleChain(NULL, rover); // node->m_sector + + // Run a linedef executor?? + if (rover->bustflags & FB_EXECUTOR) + P_LinedefExecute(rover->busttag, player->mo, node->m_sector); + + goto bustupdone; } } -bustupdone: +bustupdone: P_UnsetThingPosition(player->mo); player->mo->x = oldx; player->mo->y = oldy; diff --git a/src/r_bsp.c b/src/r_bsp.c index 7253fa930..e051c4387 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -43,6 +43,8 @@ INT32 doorclosed; boolean R_NoEncore(sector_t *sector, boolean ceiling) { + // FIXME: UDMFify + /* boolean invertencore = (GETSECSPECIAL(sector->special, 2) == 15); #if 0 // perfect implementation INT32 val = GETSECSPECIAL(sector->special, 3); @@ -57,14 +59,19 @@ boolean R_NoEncore(sector_t *sector, boolean ceiling) return false; if (ceiling) - return ((boolean)(sector->flags & SF_FLIPSPECIAL_CEILING)); - return ((boolean)(sector->flags & SF_FLIPSPECIAL_FLOOR)); + return ((boolean)(sector->flags & MSF_FLIPSPECIAL_CEILING)); + return ((boolean)(sector->flags & MSF_FLIPSPECIAL_FLOOR)); + */ + + (void)sector; + (void)ceiling; + return false; } boolean R_IsRipplePlane(sector_t *sector, ffloor_t *rover, int ceiling) { - return rover ? rover->flags & FF_RIPPLE : - sector->flags & (SF_RIPPLE_FLOOR << ceiling); + return rover ? (rover->flags & FF_RIPPLE) : + (sector->flags & (MSF_RIPPLE_FLOOR << ceiling)); } // @@ -265,11 +272,11 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, { if (floorlightlevel) *floorlightlevel = sec->floorlightsec == -1 ? - sec->lightlevel : sectors[sec->floorlightsec].lightlevel; + (sec->floorlightabsolute ? sec->floorlightlevel : max(0, min(255, sec->lightlevel + sec->floorlightlevel))) : sectors[sec->floorlightsec].lightlevel; if (ceilinglightlevel) *ceilinglightlevel = sec->ceilinglightsec == -1 ? - sec->lightlevel : sectors[sec->ceilinglightsec].lightlevel; + (sec->ceilinglightabsolute ? sec->ceilinglightlevel : max(0, min(255, sec->lightlevel + sec->ceilinglightlevel))) : sectors[sec->ceilinglightsec].lightlevel; // if (sec->midmap != -1) // mapnum = sec->midmap; @@ -335,11 +342,11 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, tempsec->lightlevel = s->lightlevel; if (floorlightlevel) - *floorlightlevel = s->floorlightsec == -1 ? s->lightlevel + *floorlightlevel = s->floorlightsec == -1 ? (s->floorlightabsolute ? s->floorlightlevel : max(0, min(255, s->lightlevel + s->floorlightlevel))) : sectors[s->floorlightsec].lightlevel; if (ceilinglightlevel) - *ceilinglightlevel = s->ceilinglightsec == -1 ? s->lightlevel + *ceilinglightlevel = s->ceilinglightsec == -1 ? (s->ceilinglightabsolute ? s->ceilinglightlevel : max(0, min(255, s->lightlevel + s->ceilinglightlevel))) : sectors[s->ceilinglightsec].lightlevel; } else if (heightsec != -1 && viewz >= sectors[heightsec].ceilingheight @@ -373,12 +380,12 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, tempsec->lightlevel = s->lightlevel; if (floorlightlevel) - *floorlightlevel = s->floorlightsec == -1 ? s->lightlevel : - sectors[s->floorlightsec].lightlevel; + *floorlightlevel = s->floorlightsec == -1 ? (s->floorlightabsolute ? s->floorlightlevel : max(0, min(255, s->lightlevel + s->floorlightlevel))) + : sectors[s->floorlightsec].lightlevel; if (ceilinglightlevel) - *ceilinglightlevel = s->ceilinglightsec == -1 ? s->lightlevel : - sectors[s->ceilinglightsec].lightlevel; + *ceilinglightlevel = s->ceilinglightsec == -1 ? (s->ceilinglightabsolute ? s->ceilinglightlevel : max(0, min(255, s->lightlevel + s->ceilinglightlevel))) + : sectors[s->ceilinglightsec].lightlevel; } sec = tempsec; } @@ -404,6 +411,10 @@ boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back) && back->ceiling_yoffs == front->ceiling_yoffs && back->ceilingpic_angle == front->ceilingpic_angle // Consider altered lighting. + && back->floorlightlevel == front->floorlightlevel + && back->floorlightabsolute == front->floorlightabsolute + && back->ceilinglightlevel == front->ceilinglightlevel + && back->ceilinglightabsolute == front->ceilinglightabsolute && back->floorlightsec == front->floorlightsec && back->ceilinglightsec == front->ceilinglightsec // Consider colormaps @@ -923,12 +934,12 @@ static void R_Subsector(size_t num) } light = R_GetPlaneLight(frontsector, floorcenterz, false); - if (frontsector->floorlightsec == -1) - floorlightlevel = *frontsector->lightlist[light].lightlevel; + if (frontsector->floorlightsec == -1 && !frontsector->floorlightabsolute) + floorlightlevel = max(0, min(255, *frontsector->lightlist[light].lightlevel + frontsector->floorlightlevel)); floorcolormap = *frontsector->lightlist[light].extra_colormap; light = R_GetPlaneLight(frontsector, ceilingcenterz, false); - if (frontsector->ceilinglightsec == -1) - ceilinglightlevel = *frontsector->lightlist[light].lightlevel; + if (frontsector->ceilinglightsec == -1 && !frontsector->ceilinglightabsolute) + ceilinglightlevel = max(0, min(255, *frontsector->lightlist[light].lightlevel + frontsector->ceilinglightlevel)); ceilingcolormap = *frontsector->lightlist[light].extra_colormap; } diff --git a/src/r_defs.h b/src/r_defs.h index 6a5de4f41..d2432eeb4 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -139,21 +139,34 @@ typedef enum FF_FLOATBOB = 0x40000, ///< Floats on water and bobs if you step on it. FF_NORETURN = 0x80000, ///< Used with ::FF_CRUMBLE. Will not return to its original position after falling. FF_CRUMBLE = 0x100000, ///< Falls 2 seconds after being stepped on, and randomly brings all touching crumbling 3dfloors down with it, providing their master sectors share the same tag (allows crumble platforms above or below, to also exist). - FF_SHATTERBOTTOM = 0x200000, ///< Used with ::FF_BUSTUP. Like FF_SHATTER, but only breaks from the bottom. Good for springing up through rubble. + FF_GOOWATER = 0x200000, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop. FF_MARIO = 0x400000, ///< Acts like a question block when hit from underneath. Goodie spawned at top is determined by master sector. FF_BUSTUP = 0x800000, ///< You can spin through/punch this block and it will crumble! FF_QUICKSAND = 0x1000000, ///< Quicksand! FF_PLATFORM = 0x2000000, ///< You can jump up through this to the top. FF_REVERSEPLATFORM = 0x4000000, ///< A fall-through floor in normal gravity, a platform in reverse gravity. FF_INTANGIBLEFLATS = 0x6000000, ///< Both flats are intangible, but the sides are still solid. - FF_SHATTER = 0x8000000, ///< Used with ::FF_BUSTUP. Bustable on mere touch. - FF_SPINBUST = 0x10000000, ///< Used with ::FF_BUSTUP. Also bustable if you're in your spinning frames. - FF_STRONGBUST = 0x20000000, ///< Used with ::FF_BUSTUP. Only bustable by "strong" characters (Knuckles) and abilities (bouncing, twinspin, melee). - FF_RIPPLE = 0x40000000, ///< Ripple the flats - FF_COLORMAPONLY = (INT32)0x80000000, ///< Only copy the colormap, not the lightlevel - FF_GOOWATER = FF_SHATTERBOTTOM, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop. + FF_RIPPLE = 0x8000000, ///< Ripple the flats + FF_COLORMAPONLY = 0x10000000, ///< Only copy the colormap, not the lightlevel + FF_BOUNCY = 0x20000000, ///< Bounces players + FF_SPLAT = 0x40000000, ///< Use splat flat renderer (treat cyan pixels as invisible) } ffloortype_e; +typedef enum +{ + FB_PUSHABLES = 0x1, // Bustable by pushables + FB_EXECUTOR = 0x2, // Trigger linedef executor + FB_ONLYBOTTOM = 0x4, // Only bustable from below +} ffloorbustflags_e; + +typedef enum +{ + BT_TOUCH, + BT_SPINBUST, + BT_REGULAR, + BT_STRONG, +} busttype_e; + typedef struct ffloor_s { fixed_t *topheight; @@ -187,6 +200,18 @@ typedef struct ffloor_s UINT8 blend; tic_t norender; // for culling + // Only relevant for FF_BUSTUP + ffloorbustflags_e bustflags; + UINT8 busttype; + INT16 busttag; + + // Only relevant for FF_QUICKSAND + fixed_t sinkspeed; + fixed_t friction; + + // Only relevant for FF_BOUNCY + fixed_t bouncestrength; + // these are saved for netgames, so do not let Lua touch these! ffloortype_e spawnflags; // flags the 3D floor spawned with INT32 spawnalpha; // alpha the 3D floor spawned with @@ -262,19 +287,61 @@ typedef struct pslope_s typedef enum { // flipspecial - planes with effect - SF_FLIPSPECIAL_FLOOR = 1, - SF_FLIPSPECIAL_CEILING = 1<<1, - SF_FLIPSPECIAL_BOTH = (SF_FLIPSPECIAL_FLOOR|SF_FLIPSPECIAL_CEILING), + MSF_FLIPSPECIAL_FLOOR = 1, + MSF_FLIPSPECIAL_CEILING = 1<<1, + MSF_FLIPSPECIAL_BOTH = (MSF_FLIPSPECIAL_FLOOR|MSF_FLIPSPECIAL_CEILING), // triggerspecial - conditions under which plane touch causes effect - SF_TRIGGERSPECIAL_TOUCH = 1<<2, - SF_TRIGGERSPECIAL_HEADBUMP = 1<<3, + MSF_TRIGGERSPECIAL_TOUCH = 1<<2, + MSF_TRIGGERSPECIAL_HEADBUMP = 1<<3, + // triggerline - conditions for linedef executor triggering + MSF_TRIGGERLINE_PLANE = 1<<4, // require plane touch + MSF_TRIGGERLINE_MOBJ = 1<<5, // allow non-pushable mobjs to trigger // invertprecip - inverts presence of precipitation - SF_INVERTPRECIP = 1<<4, + MSF_INVERTPRECIP = 1<<6, + MSF_GRAVITYFLIP = 1<<7, + MSF_HEATWAVE = 1<<8, + MSF_NOCLIPCAMERA = 1<<9, // water ripple - SF_RIPPLE_FLOOR = 1<<5, - SF_RIPPLE_CEILING = 1<<6, + MSF_RIPPLE_FLOOR = 1<<10, + MSF_RIPPLE_CEILING = 1<<11, } sectorflags_t; +typedef enum +{ + SSF_NOSTEPUP = 1, + SSF_DOUBLESTEPUP = 1<<1, + SSF_NOSTEPDOWN = 1<<2, + SSF_WINDCURRENT = 1<<3, + SSF_CONVEYOR = 1<<4, + SSF_SPEEDPAD = 1<<5, + SSF_STARPOSTACTIVATOR = 1<<6, + SSF_EXIT = 1<<7, + SSF_DELETEITEMS = 1<<8, + // free: 1<<9, + // free: 1<<10, + // free: 1<<11, + SSF_FAN = 1<<12, + // free: 1<<13, + // free: 1<<14, + SSF_ZOOMTUBESTART = 1<<15, + SSF_ZOOMTUBEEND = 1<<16, +} sectorspecialflags_t; + +typedef enum +{ + SD_NONE = 0, + SD_GENERIC = 1, + SD_LAVA = 2, + SD_DEATHPIT = 3, + SD_INSTAKILL = 4, +} sectordamage_t; + +typedef enum +{ + TO_PLAYER = 0, + TO_ALLPLAYERS = 1, + TO_MOBJ = 2, +} triggerobject_t; typedef enum { @@ -326,7 +393,11 @@ typedef struct sector_s INT32 heightsec; // other sector, or -1 if no other sector INT32 camsec; // used for camera clipping - INT32 floorlightsec, ceilinglightsec; + // floor and ceiling lighting + INT16 floorlightlevel, ceilinglightlevel; + boolean floorlightabsolute, ceilinglightabsolute; // absolute or relative to sector's light level? + INT32 floorlightsec, ceilinglightsec; // take floor/ceiling light level from another sector + INT32 crumblestate; // used for crumbling and bobbing // list of mobjs that are at least partially in the sector @@ -350,10 +421,20 @@ typedef struct sector_s extracolormap_t *extra_colormap; boolean colormap_protected; - // This points to the master's floorheight, so it can be changed in realtime! - fixed_t *gravity; // per-sector gravity - boolean verticalflip; // If gravity < 0, then allow flipped physics + fixed_t gravity; // per-sector gravity factor + fixed_t *gravityptr; // For binary format: Read gravity from floor height of master sector + sectorflags_t flags; + sectorspecialflags_t specialflags; + UINT8 damagetype; + + fixed_t offroad; // Ring Racers + + // Linedef executor triggering + mtag_t triggertag; // tag to call upon triggering + UINT8 triggerer; // who can trigger? + + fixed_t friction; // Sprite culling feature struct line_s *cullheight; @@ -390,7 +471,7 @@ typedef enum #define HORIZONSPECIAL 41 -#define NUMLINEARGS 6 +#define NUMLINEARGS 10 #define NUMLINESTRINGARGS 2 typedef struct line_s @@ -400,6 +481,7 @@ typedef struct line_s vertex_t *v2; fixed_t dx, dy; // Precalculated v2 - v1 for side checking. + angle_t angle; // Precalculated angle between dx and dy // Animation related. INT16 flags; diff --git a/src/r_main.c b/src/r_main.c index 3e79f9871..c23bd725d 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -452,7 +452,7 @@ fixed_t R_ScaleFromGlobalAngle(angle_t visangle) // R_DoCulling // Checks viewz and top/bottom heights of an item against culling planes // Returns true if the item is to be culled, i.e it shouldn't be drawn! -// if ML_NOCLIMB is set, the camera view is required to be in the same area for culling to occur +// if args[1] is set, the camera view is required to be in the same area for culling to occur boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixed_t bottomh, fixed_t toph) { fixed_t cullplane; @@ -461,7 +461,7 @@ boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixe return false; cullplane = cullheight->frontsector->floorheight; - if (cullheight->flags & ML_NOCLIMB) // Group culling + if (cullheight->args[1]) // Group culling { if (!viewcullheight) return false; diff --git a/src/r_plane.c b/src/r_plane.c index 5a97c2dbe..677b4e025 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -888,7 +888,7 @@ void R_DrawSinglePlane(visplane_t *pl) if (pl->ffloor->flags & FF_TRANSLUCENT) { - spanfunctype = (pl->ffloor->master->flags & ML_EFFECT6) ? SPANDRAWFUNC_TRANSSPLAT : SPANDRAWFUNC_TRANS; + spanfunctype = (pl->ffloor->flags & FF_SPLAT) ? SPANDRAWFUNC_TRANSSPLAT : SPANDRAWFUNC_TRANS; // Hacked up support for alpha value in software mode Tails 09-24-2002 // ...unhacked by toaster 04-01-2021 diff --git a/src/r_segs.c b/src/r_segs.c index 68a58ab7e..16c61af43 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -323,7 +323,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) if (ds->curline->sidedef->repeatcnt) repeats = 1 + ds->curline->sidedef->repeatcnt; - else if (ldef->flags & ML_EFFECT5) + else if (ldef->flags & ML_WRAPMIDTEX) { fixed_t high, low; @@ -367,7 +367,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) { dc_texturemid = ds->maskedtextureheight[dc_x]; - if (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3)) + if (curline->linedef->flags & ML_MIDPEG) dc_texturemid += (textureheight[texnum])*times + textureheight[texnum]; else dc_texturemid -= (textureheight[texnum])*times; @@ -810,10 +810,10 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) skewslope = *pfloor->t_slope; // skew using top slope by default if (newline) { - if (newline->flags & ML_DONTPEGTOP) + if (newline->flags & ML_SKEWTD) slopeskew = true; } - else if (pfloor->master->flags & ML_DONTPEGTOP) + else if (pfloor->master->flags & ML_SKEWTD) slopeskew = true; if (slopeskew) @@ -848,7 +848,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (slopeskew) { - angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); + angle_t lineangle = curline->angle; if (skewslope) ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); @@ -1537,9 +1537,9 @@ static void R_RenderSegLoop (void) maskedtexturecol[rw_x] = (INT16)texturecolumn; if (maskedtextureheight != NULL) { - maskedtextureheight[rw_x] = (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3) ? + maskedtextureheight[rw_x] = (curline->linedef->flags & ML_MIDPEG) ? max(rw_midtexturemid, rw_midtextureback) : - min(rw_midtexturemid, rw_midtextureback)); + min(rw_midtexturemid, rw_midtextureback); } } @@ -1826,7 +1826,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) ceilingfrontslide = floorfrontslide = ceilingbackslide = floorbackslide = 0; { - angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); + angle_t lineangle = curline->angle; if (frontsector->f_slope) floorfrontslide = FixedMul(frontsector->f_slope->zdelta, FINECOSINE((lineangle-frontsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); @@ -1850,7 +1850,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) texheight = textureheight[midtexture]; // a single sided line is terminal, so it must mark ends markfloor = markceiling = true; - if (linedef->flags & ML_EFFECT2) { + if (linedef->flags & ML_NOSKEW) { if (linedef->flags & ML_DONTPEGBOTTOM) rw_midtexturemid = frontsector->floorheight + texheight - viewz; else @@ -2006,18 +2006,20 @@ void R_StoreWallRange(INT32 start, INT32 stop) else if (worldlow != worldbottom || worldlowslope != worldbottomslope || backsector->f_slope != frontsector->f_slope - || backsector->floorpic != frontsector->floorpic - || backsector->lightlevel != frontsector->lightlevel - //SoM: 3/22/2000: Check floor x and y offsets. - || backsector->floor_xoffs != frontsector->floor_xoffs - || backsector->floor_yoffs != frontsector->floor_yoffs - || backsector->floorpic_angle != frontsector->floorpic_angle - //SoM: 3/22/2000: Prevents bleeding. - || (frontsector->heightsec != -1 && frontsector->floorpic != skyflatnum) - || backsector->floorlightsec != frontsector->floorlightsec - //SoM: 4/3/2000: Check for colormaps - || frontsector->extra_colormap != backsector->extra_colormap - || (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags))) + || backsector->floorpic != frontsector->floorpic + || backsector->lightlevel != frontsector->lightlevel + //SoM: 3/22/2000: Check floor x and y offsets. + || backsector->floor_xoffs != frontsector->floor_xoffs + || backsector->floor_yoffs != frontsector->floor_yoffs + || backsector->floorpic_angle != frontsector->floorpic_angle + //SoM: 3/22/2000: Prevents bleeding. + || (frontsector->heightsec != -1 && frontsector->floorpic != skyflatnum) + || backsector->floorlightlevel != frontsector->floorlightlevel + || backsector->floorlightabsolute != frontsector->floorlightabsolute + || backsector->floorlightsec != frontsector->floorlightsec + //SoM: 4/3/2000: Check for colormaps + || frontsector->extra_colormap != backsector->extra_colormap + || (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags))) { markfloor = true; } @@ -2037,18 +2039,20 @@ void R_StoreWallRange(INT32 start, INT32 stop) else if (worldhigh != worldtop || worldhighslope != worldtopslope || backsector->c_slope != frontsector->c_slope - || backsector->ceilingpic != frontsector->ceilingpic - || backsector->lightlevel != frontsector->lightlevel - //SoM: 3/22/2000: Check floor x and y offsets. - || backsector->ceiling_xoffs != frontsector->ceiling_xoffs - || backsector->ceiling_yoffs != frontsector->ceiling_yoffs - || backsector->ceilingpic_angle != frontsector->ceilingpic_angle - //SoM: 3/22/2000: Prevents bleeding. - || (frontsector->heightsec != -1 && frontsector->ceilingpic != skyflatnum) - || backsector->ceilinglightsec != frontsector->ceilinglightsec - //SoM: 4/3/2000: Check for colormaps - || frontsector->extra_colormap != backsector->extra_colormap - || (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags))) + || backsector->ceilingpic != frontsector->ceilingpic + || backsector->lightlevel != frontsector->lightlevel + //SoM: 3/22/2000: Check floor x and y offsets. + || backsector->ceiling_xoffs != frontsector->ceiling_xoffs + || backsector->ceiling_yoffs != frontsector->ceiling_yoffs + || backsector->ceilingpic_angle != frontsector->ceilingpic_angle + //SoM: 3/22/2000: Prevents bleeding. + || (frontsector->heightsec != -1 && frontsector->ceilingpic != skyflatnum) + || backsector->ceilinglightlevel != frontsector->ceilinglightlevel + || backsector->ceilinglightabsolute != frontsector->ceilinglightabsolute + || backsector->ceilinglightsec != frontsector->ceilinglightsec + //SoM: 4/3/2000: Check for colormaps + || frontsector->extra_colormap != backsector->extra_colormap + || (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags))) { markceiling = true; } @@ -2074,26 +2078,13 @@ void R_StoreWallRange(INT32 start, INT32 stop) { fixed_t texheight; // top texture - if ((linedef->flags & (ML_DONTPEGTOP) && (linedef->flags & ML_DONTPEGBOTTOM)) - && linedef->sidenum[1] != 0xffff) - { - // Special case... use offsets from 2nd side but only if it has a texture. - side_t *def = &sides[linedef->sidenum[1]]; - toptexture = R_GetTextureNum(def->toptexture); + toptexture = R_GetTextureNum(sidedef->toptexture); + topbrightmap = R_GetTextureBrightmap(toptexture); + texheight = textureheight[toptexture]; - if (!toptexture) //Second side has no texture, use the first side's instead. - toptexture = R_GetTextureNum(sidedef->toptexture); - - topbrightmap = R_GetTextureBrightmap(toptexture); - texheight = textureheight[toptexture]; - } - else + if (!(linedef->flags & ML_SKEWTD)) { - toptexture = R_GetTextureNum(sidedef->toptexture); - topbrightmap = R_GetTextureBrightmap(toptexture); - texheight = textureheight[toptexture]; - } - if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + // Ignore slopes for lower/upper textures unless flag is checked if (linedef->flags & ML_DONTPEGTOP) rw_toptexturemid = frontsector->ceilingheight - viewz; else @@ -2119,7 +2110,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) bottomtexture = R_GetTextureNum(sidedef->bottomtexture); bottombrightmap = R_GetTextureBrightmap(bottomtexture); - if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + if (!(linedef->flags & ML_SKEWTD)) + { + // Ignore slopes for lower/upper textures unless flag is checked if (linedef->flags & ML_DONTPEGBOTTOM) rw_bottomtexturemid = frontsector->floorheight - viewz; else @@ -2350,7 +2343,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (curline->polyseg) { // use REAL front and back floors please, so midtexture rendering isn't mucked up rw_midtextureslide = rw_midtexturebackslide = 0; - if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) + if (linedef->flags & ML_MIDPEG) rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz; else rw_midtexturemid = rw_midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz; @@ -2358,16 +2351,16 @@ void R_StoreWallRange(INT32 start, INT32 stop) else { // Set midtexture starting height - if (linedef->flags & ML_EFFECT2) + if (linedef->flags & ML_NOSKEW) { // Ignore slopes when texturing rw_midtextureslide = rw_midtexturebackslide = 0; - if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) + if (linedef->flags & ML_MIDPEG) rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; else rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz; } - else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) + else if (linedef->flags & ML_MIDPEG) { rw_midtexturemid = worldbottom; rw_midtextureslide = floorfrontslide; diff --git a/src/taglist.c b/src/taglist.c index 2ad2aa7e0..df4b18a50 100644 --- a/src/taglist.c +++ b/src/taglist.c @@ -37,6 +37,25 @@ void Tag_Add (taglist_t* list, const mtag_t tag) list->tags[list->count++] = tag; } +/// Removes a tag from a given element's taglist. +/// \warning This does not rebuild the global taggroups, which are used for iteration. +void Tag_Remove(taglist_t* list, const mtag_t tag) +{ + UINT16 i; + + for (i = 0; i < list->count; i++) + { + if (list->tags[i] != tag) + continue; + + for (; i+1 < list->count; i++) + list->tags[i] = list->tags[i+1]; + + list->tags = Z_Realloc(list->tags, (list->count - 1) * sizeof(mtag_t), PU_LEVEL, NULL); + return; + } +} + /// Sets the first tag entry in a taglist. /// Replicates the old way of accessing element->tag. void Tag_FSet (taglist_t* list, const mtag_t tag) @@ -408,6 +427,22 @@ INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start) // Ingame list manipulation. +/// Adds the tag to the given sector, and updates the global taggroups. +void Tag_SectorAdd (const size_t id, const mtag_t tag) +{ + sector_t* sec = §ors[id]; + Tag_Add(&sec->tags, tag); + Taggroup_Add(tags_sectors, tag, id); +} + +/// Removes the tag from the given sector, and updates the global taggroups. +void Tag_SectorRemove (const size_t id, const mtag_t tag) +{ + sector_t* sec = §ors[id]; + Tag_Remove(&sec->tags, tag); + Taggroup_Remove(tags_sectors, tag, id); +} + /// Changes the first tag for a given sector, and updates the global taggroups. void Tag_SectorFSet (const size_t id, const mtag_t tag) { @@ -420,3 +455,16 @@ void Tag_SectorFSet (const size_t id, const mtag_t tag) Taggroup_Add(tags_sectors, tag, id); Tag_FSet(&sec->tags, tag); } + +mtag_t Tag_NextUnused(mtag_t start) +{ + while ((UINT16)start < MAXTAGS) + { + if (!in_bit_array(tags_available, (UINT16)start)) + return start; + + start++; + } + + return (mtag_t)MAXTAGS; +} diff --git a/src/taglist.h b/src/taglist.h index 66e1e7ddc..a66312425 100644 --- a/src/taglist.h +++ b/src/taglist.h @@ -28,12 +28,15 @@ typedef struct } taglist_t; void Tag_Add (taglist_t* list, const mtag_t tag); +void Tag_Remove (taglist_t* list, const mtag_t tag); void Tag_FSet (taglist_t* list, const mtag_t tag); mtag_t Tag_FGet (const taglist_t* list); boolean Tag_Find (const taglist_t* list, const mtag_t tag); boolean Tag_Share (const taglist_t* list1, const taglist_t* list2); boolean Tag_Compare (const taglist_t* list1, const taglist_t* list2); +void Tag_SectorAdd (const size_t id, const mtag_t tag); +void Tag_SectorRemove (const size_t id, const mtag_t tag); void Tag_SectorFSet (const size_t id, const mtag_t tag); /// Taggroup list. It is essentially just an element id list. @@ -46,6 +49,8 @@ typedef struct extern bitarray_t tags_available[]; +extern mtag_t Tag_NextUnused(mtag_t start); + extern size_t num_tags; extern taggroup_t* tags_sectors[]; From a88d046db439bf418fc14ce8a93dadbd4383142d Mon Sep 17 00:00:00 2001 From: Eidolon Date: Thu, 26 May 2022 23:38:50 -0500 Subject: [PATCH 05/54] Change UDMF wall scroll scale to SCROLL_SHIFT UDMF special 502 now must scale arg 2 and 3 in the same scale space as line length scrolling in binary format. This is to ensure compatibility with the binary format. Fixes STJr/SRB2#862 Co-Authored-By: MascaraSnake --- src/p_setup.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 585e83641..30e711dc0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -5419,13 +5419,13 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[1] = 0; if (lines[i].flags & ML_NOSKEW) { - lines[i].args[2] = lines[i].dx >> (FRACBITS + SCROLL_SHIFT); - lines[i].args[3] = lines[i].dy >> (FRACBITS + SCROLL_SHIFT); + lines[i].args[2] = sides[lines[i].sidenum[0]].textureoffset >> (FRACBITS - SCROLL_SHIFT); + lines[i].args[3] = sides[lines[i].sidenum[0]].rowoffset >> (FRACBITS - SCROLL_SHIFT); } else { - lines[i].args[2] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; - lines[i].args[3] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + lines[i].args[2] = lines[i].dx >> FRACBITS; + lines[i].args[3] = lines[i].dy >> FRACBITS; } lines[i].args[4] = lines[i].special - 502; lines[i].special = 502; From 12717c7a6c5452403fac1942bd3166ea85de08f7 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 4 Jun 2022 17:46:00 +0200 Subject: [PATCH 06/54] Fix copypaste error in P_GetMobjGravity --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 71ba3c581..cdddc0098 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1068,7 +1068,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) if ((rover->flags & (FF_SWIMMABLE|FF_GOOWATER)) == (FF_SWIMMABLE|FF_GOOWATER)) goopgravity = true; - gravfactor = P_GetSectorGravityFactor(mo->subsector->sector); + gravfactor = P_GetSectorGravityFactor(rover->master->frontsector); if (gravfactor == FRACUNIT) continue; From 11d9ba1cec1cc477d6d9fea3cbadb771c1d6dffc Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 4 Jun 2022 11:14:31 +0200 Subject: [PATCH 07/54] UDMF conversion: Fix noclimb flag not being applied to linedef types 66-68 --- src/p_setup.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_setup.c b/src/p_setup.c index 30e711dc0..35352fc89 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -4115,6 +4115,8 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[0] = tag; lines[i].args[1] = lines[i].special - 66; lines[i].args[2] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[2] *= -1; lines[i].special = 66; break; case 76: //Make FOF bouncy From 04630e71f2b752da2b1c59fd27c158f1a027edf1 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 1 May 2022 19:27:10 +0200 Subject: [PATCH 08/54] Fix size_t compiler warnings in P_WriteTextmap --- src/p_setup.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 35352fc89..e09b40abe 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1884,31 +1884,31 @@ static void P_WriteTextmap(void) case 1: TAG_ITER_SECTORS(Tag_FGet(&wlines[i].tags), s) { - CONS_Alert(CONS_WARNING, M_GetText("Linedef %d applies custom gravity to sector %d. Changes to this gravity at runtime will not be reflected in the converted map. Use linedef type 469 for this.\n"), i, s); + CONS_Alert(CONS_WARNING, M_GetText("Linedef %s applies custom gravity to sector %d. Changes to this gravity at runtime will not be reflected in the converted map. Use linedef type 469 for this.\n"), sizeu1(i), s); wsectors[s].gravity = FixedDiv(lines[i].frontsector->floorheight >> FRACBITS, 1000); } break; case 2: - CONS_Alert(CONS_WARNING, M_GetText("Custom exit linedef %d detected. Changes to the next map at runtime will not be reflected in the converted map. Use linedef type 468 for this.\n"), i); + CONS_Alert(CONS_WARNING, M_GetText("Custom exit linedef %s detected. Changes to the next map at runtime will not be reflected in the converted map. Use linedef type 468 for this.\n"), sizeu1(i)); wlines[i].args[0] = lines[i].frontsector->floorheight >> FRACBITS; wlines[i].args[2] = lines[i].frontsector->ceilingheight >> FRACBITS; break; case 5: case 50: case 51: - CONS_Alert(CONS_WARNING, M_GetText("Linedef %d has type %d, which is not supported in UDMF.\n"), i, wlines[i].special); + CONS_Alert(CONS_WARNING, M_GetText("Linedef %s has type %d, which is not supported in UDMF.\n"), sizeu1(i), wlines[i].special); break; case 61: if (wlines[i].flags & ML_MIDSOLID) continue; if (!wlines[i].args[1]) continue; - CONS_Alert(CONS_WARNING, M_GetText("Linedef %d with crusher type 61 rises twice as fast on spawn. This behavior is not supported in UDMF.\n"), i); + CONS_Alert(CONS_WARNING, M_GetText("Linedef %s with crusher type 61 rises twice as fast on spawn. This behavior is not supported in UDMF.\n"), sizeu1(i)); break; case 76: if (freetag == (mtag_t)MAXTAGS) { - CONS_Alert(CONS_WARNING, M_GetText("No unused tag found. Linedef %d with type 76 cannot be converted.\n"), i); + CONS_Alert(CONS_WARNING, M_GetText("No unused tag found. Linedef %s with type 76 cannot be converted.\n"), sizeu1(i)); break; } TAG_ITER_SECTORS(wlines[i].args[0], s) @@ -1924,9 +1924,9 @@ static void P_WriteTextmap(void) break; case 259: if (wlines[i].args[3] & FF_QUICKSAND) - CONS_Alert(CONS_WARNING, M_GetText("Quicksand properties of custom FOF on linedef %d cannot be converted. Use linedef type 75 instead.\n"), i); + CONS_Alert(CONS_WARNING, M_GetText("Quicksand properties of custom FOF on linedef %s cannot be converted. Use linedef type 75 instead.\n"), sizeu1(i)); if (wlines[i].args[3] & FF_BUSTUP) - CONS_Alert(CONS_WARNING, M_GetText("Bustable properties of custom FOF on linedef %d cannot be converted. Use linedef type 74 instead.\n"), i); + CONS_Alert(CONS_WARNING, M_GetText("Bustable properties of custom FOF on linedef %s cannot be converted. Use linedef type 74 instead.\n"), sizeu1(i)); break; case 412: if ((s = Tag_Iterate_Sectors(wlines[i].args[0], 0)) < 0) @@ -1935,7 +1935,7 @@ static void P_WriteTextmap(void) break; if (freetag == (mtag_t)MAXTAGS) { - CONS_Alert(CONS_WARNING, M_GetText("No unused tag found. Linedef %d with type 412 cannot be converted.\n"), i); + CONS_Alert(CONS_WARNING, M_GetText("No unused tag found. Linedef %s with type 412 cannot be converted.\n"), sizeu1(i)); break; } Tag_Add(&specialthings[s].teleport->tags, freetag); @@ -1949,7 +1949,7 @@ static void P_WriteTextmap(void) break; if (freetag == (mtag_t)MAXTAGS) { - CONS_Alert(CONS_WARNING, M_GetText("No unused tag found. Linedef %d with type 422 cannot be converted.\n"), i); + CONS_Alert(CONS_WARNING, M_GetText("No unused tag found. Linedef %s with type 422 cannot be converted.\n"), sizeu1(i)); break; } Tag_Add(&specialthings[s].altview->tags, freetag); @@ -1958,14 +1958,14 @@ static void P_WriteTextmap(void) freetag = Tag_NextUnused(freetag); break; case 447: - CONS_Alert(CONS_WARNING, M_GetText("Linedef %d has change colormap action, which cannot be converted automatically. Tag arg0 to a sector with the desired colormap.\n"), i); + CONS_Alert(CONS_WARNING, M_GetText("Linedef %s has change colormap action, which cannot be converted automatically. Tag arg0 to a sector with the desired colormap.\n"), sizeu1(i)); if (wlines[i].flags & ML_TFERLINE) - CONS_Alert(CONS_WARNING, M_GetText("Linedef %d mixes front and back colormaps, which is not supported in UDMF. Copy one colormap to the target sector first, then mix in the second one.\n"), i); + CONS_Alert(CONS_WARNING, M_GetText("Linedef %s mixes front and back colormaps, which is not supported in UDMF. Copy one colormap to the target sector first, then mix in the second one.\n"), sizeu1(i)); break; case 455: - CONS_Alert(CONS_WARNING, M_GetText("Linedef %d has fade colormap action, which cannot be converted automatically. Tag arg0 to a sector with the desired colormap.\n"), i); + CONS_Alert(CONS_WARNING, M_GetText("Linedef %s has fade colormap action, which cannot be converted automatically. Tag arg0 to a sector with the desired colormap.\n"), sizeu1(i)); if (wlines[i].flags & ML_TFERLINE) - CONS_Alert(CONS_WARNING, M_GetText("Linedef %d specifies starting colormap for the fade, which is not supported in UDMF. Change the colormap with linedef type 447 instead.\n"), i); + CONS_Alert(CONS_WARNING, M_GetText("Linedef %s specifies starting colormap for the fade, which is not supported in UDMF. Change the colormap with linedef type 447 instead.\n"), sizeu1(i)); break; case 457: if ((s = Tag_Iterate_Sectors(wlines[i].args[0], 0)) < 0) @@ -1974,7 +1974,7 @@ static void P_WriteTextmap(void) break; if (freetag == (mtag_t)MAXTAGS) { - CONS_Alert(CONS_WARNING, M_GetText("No unused tag found. Linedef %d with type 457 cannot be converted.\n"), i); + CONS_Alert(CONS_WARNING, M_GetText("No unused tag found. Linedef %s with type 457 cannot be converted.\n"), sizeu1(i)); break; } Tag_Add(&specialthings[s].angleanchor->tags, freetag); @@ -1997,7 +1997,7 @@ static void P_WriteTextmap(void) wsectors[s].extra_colormap = wsides[wlines[i].sidenum[0]].colormap_data; if (freetag == (mtag_t)MAXTAGS) { - CONS_Alert(CONS_WARNING, M_GetText("No unused tag found. Linedef %d with type 606 cannot be converted.\n"), i); + CONS_Alert(CONS_WARNING, M_GetText("No unused tag found. Linedef %s with type 606 cannot be converted.\n"), sizeu1(i)); break; } Tag_Add(&wsectors[s].tags, freetag); @@ -2012,23 +2012,23 @@ static void P_WriteTextmap(void) } if (wlines[i].special >= 300 && wlines[i].special < 400 && wlines[i].flags & ML_WRAPMIDTEX) - CONS_Alert(CONS_WARNING, M_GetText("Linedef executor trigger linedef %d has disregard order flag, which is not supported in UDMF.\n"), i); + CONS_Alert(CONS_WARNING, M_GetText("Linedef executor trigger linedef %s has disregard order flag, which is not supported in UDMF.\n"), sizeu1(i)); } for (i = 0; i < numsectors; i++) { if (Tag_Find(&wsectors[i].tags, LE_CAPSULE0)) - CONS_Alert(CONS_WARNING, M_GetText("Sector %d has reserved tag %d, which is not supported in UDMF. Use arg3 of the boss mapthing instead.\n"), i, LE_CAPSULE0); + CONS_Alert(CONS_WARNING, M_GetText("Sector %s has reserved tag %d, which is not supported in UDMF. Use arg3 of the boss mapthing instead.\n"), sizeu1(i), LE_CAPSULE0); if (Tag_Find(&wsectors[i].tags, LE_CAPSULE1)) - CONS_Alert(CONS_WARNING, M_GetText("Sector %d has reserved tag %d, which is not supported in UDMF. Use arg3 of the boss mapthing instead.\n"), i, LE_CAPSULE1); + CONS_Alert(CONS_WARNING, M_GetText("Sector %s has reserved tag %d, which is not supported in UDMF. Use arg3 of the boss mapthing instead.\n"), sizeu1(i), LE_CAPSULE1); if (Tag_Find(&wsectors[i].tags, LE_CAPSULE2)) - CONS_Alert(CONS_WARNING, M_GetText("Sector %d has reserved tag %d, which is not supported in UDMF. Use arg3 of the boss mapthing instead.\n"), i, LE_CAPSULE2); + CONS_Alert(CONS_WARNING, M_GetText("Sector %s has reserved tag %d, which is not supported in UDMF. Use arg3 of the boss mapthing instead.\n"), sizeu1(i), LE_CAPSULE2); switch (GETSECSPECIAL(wsectors[i].special, 1)) { case 9: case 10: - CONS_Alert(CONS_WARNING, M_GetText("Sector %d has ring drainer effect, which is not supported in UDMF. Use linedef type 462 instead.\n"), i); + CONS_Alert(CONS_WARNING, M_GetText("Sector %s has ring drainer effect, which is not supported in UDMF. Use linedef type 462 instead.\n"), sizeu1(i)); break; default: break; @@ -2037,13 +2037,13 @@ static void P_WriteTextmap(void) switch (GETSECSPECIAL(wsectors[i].special, 2)) { case 6: - CONS_Alert(CONS_WARNING, M_GetText("Sector %d has emerald check trigger type, which is not supported in UDMF. Use linedef types 337-339 instead.\n"), i); + CONS_Alert(CONS_WARNING, M_GetText("Sector %s has emerald check trigger type, which is not supported in UDMF. Use linedef types 337-339 instead.\n"), sizeu1(i)); break; case 7: - CONS_Alert(CONS_WARNING, M_GetText("Sector %d has NiGHTS mare trigger type, which is not supported in UDMF. Use linedef types 340-342 instead.\n"), i); + CONS_Alert(CONS_WARNING, M_GetText("Sector %s has NiGHTS mare trigger type, which is not supported in UDMF. Use linedef types 340-342 instead.\n"), sizeu1(i)); break; case 9: - CONS_Alert(CONS_WARNING, M_GetText("Sector %d has Egg Capsule type, which is not supported in UDMF. Use linedef type 464 instead.\n"), i); + CONS_Alert(CONS_WARNING, M_GetText("Sector %s has Egg Capsule type, which is not supported in UDMF. Use linedef type 464 instead.\n"), sizeu1(i)); break; default: break; @@ -2166,7 +2166,7 @@ static void P_WriteTextmap(void) } if (wlines[i].executordelay != 0 && wlines[i].backsector) { - CONS_Alert(CONS_WARNING, M_GetText("Linedef %d has an executor delay. Changes to the delay at runtime will not be reflected in the converted map. Use linedef type 465 for this.\n"), i); + CONS_Alert(CONS_WARNING, M_GetText("Linedef %s has an executor delay. Changes to the delay at runtime will not be reflected in the converted map. Use linedef type 465 for this.\n"), sizeu1(i)); fprintf(f, "executordelay = %d;\n", (wlines[i].backsector->ceilingheight >> FRACBITS) + (wlines[i].backsector->floorheight >> FRACBITS)); } if (wlines[i].flags & ML_IMPASSABLE) From 8863cb281bde39152b69971fd22e0d8a90d0cfa7 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 28 May 2022 10:29:35 +0200 Subject: [PATCH 09/54] Fix more size_t mishaps --- src/p_setup.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index e09b40abe..9f87a93b3 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2053,7 +2053,7 @@ static void P_WriteTextmap(void) fprintf(f, "namespace = \"srb2\";\n"); for (i = 0; i < nummapthings; i++) { - fprintf(f, "thing // %d\n", i); + fprintf(f, "thing // %s\n", sizeu1(i)); fprintf(f, "{\n"); firsttag = Tag_FGet(&wmapthings[i].tags); if (firsttag != 0) @@ -2096,7 +2096,7 @@ static void P_WriteTextmap(void) for (i = 0; i < numvertexes; i++) { - fprintf(f, "vertex // %d\n", i); + fprintf(f, "vertex // %s\n", sizeu1(i)); fprintf(f, "{\n"); fprintf(f, "x = %f;\n", FIXED_TO_FLOAT(wvertexes[i].x)); fprintf(f, "y = %f;\n", FIXED_TO_FLOAT(wvertexes[i].y)); @@ -2110,10 +2110,10 @@ static void P_WriteTextmap(void) for (i = 0; i < numlines; i++) { - fprintf(f, "linedef // %d\n", i); + fprintf(f, "linedef // %s\n", sizeu1(i)); fprintf(f, "{\n"); - fprintf(f, "v1 = %d;\n", wlines[i].v1 - vertexes); - fprintf(f, "v2 = %d;\n", wlines[i].v2 - vertexes); + fprintf(f, "v1 = %s;\n", sizeu1(wlines[i].v1 - vertexes)); + fprintf(f, "v2 = %s;\n", sizeu1(wlines[i].v2 - vertexes)); fprintf(f, "sidefront = %d;\n", wlines[i].sidenum[0]); if (wlines[i].sidenum[1] != 0xffff) fprintf(f, "sideback = %d;\n", wlines[i].sidenum[1]); @@ -2205,9 +2205,9 @@ static void P_WriteTextmap(void) for (i = 0; i < numsides; i++) { - fprintf(f, "sidedef // %d\n", i); + fprintf(f, "sidedef // %s\n", sizeu1(i)); fprintf(f, "{\n"); - fprintf(f, "sector = %d;\n", wsides[i].sector - sectors); + fprintf(f, "sector = %s;\n", sizeu1(wsides[i].sector - sectors)); if (wsides[i].textureoffset != 0) fprintf(f, "offsetx = %d;\n", wsides[i].textureoffset >> FRACBITS); if (wsides[i].rowoffset != 0) @@ -2226,7 +2226,7 @@ static void P_WriteTextmap(void) for (i = 0; i < numsectors; i++) { - fprintf(f, "sector // %d\n", i); + fprintf(f, "sector // %s\n", sizeu1(i)); fprintf(f, "{\n"); fprintf(f, "heightfloor = %d;\n", wsectors[i].floorheight >> FRACBITS); fprintf(f, "heightceiling = %d;\n", wsectors[i].ceilingheight >> FRACBITS); From 45dc7541c4b7778caf8ad0e3b9e0ebb663e9c719 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 28 May 2022 14:08:19 +0200 Subject: [PATCH 10/54] Fix even more size_t printfs --- src/p_setup.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 9f87a93b3..b4bf95ec8 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2086,10 +2086,10 @@ static void P_WriteTextmap(void) fprintf(f, "flip = true;\n"); for (j = 0; j < NUMMAPTHINGARGS; j++) if (wmapthings[i].args[j] != 0) - fprintf(f, "arg%d = %d;\n", j, wmapthings[i].args[j]); + fprintf(f, "arg%s = %d;\n", sizeu1(j), wmapthings[i].args[j]); for (j = 0; j < NUMMAPTHINGSTRINGARGS; j++) if (mapthings[i].stringargs[j]) - fprintf(f, "stringarg%d = \"%s\";\n", j, mapthings[i].stringargs[j]); + fprintf(f, "stringarg%s = \"%s\";\n", sizeu1(j), mapthings[i].stringargs[j]); fprintf(f, "}\n"); fprintf(f, "\n"); } @@ -2135,10 +2135,10 @@ static void P_WriteTextmap(void) fprintf(f, "special = %d;\n", wlines[i].special); for (j = 0; j < NUMLINEARGS; j++) if (wlines[i].args[j] != 0) - fprintf(f, "arg%d = %d;\n", j, wlines[i].args[j]); + fprintf(f, "arg%s = %d;\n", sizeu1(j), wlines[i].args[j]); for (j = 0; j < NUMLINESTRINGARGS; j++) if (lines[i].stringargs[j]) - fprintf(f, "stringarg%d = \"%s\";\n", j, lines[i].stringargs[j]); + fprintf(f, "stringarg%s = \"%s\";\n", sizeu1(j), lines[i].stringargs[j]); if (wlines[i].alpha != FRACUNIT) fprintf(f, "alpha = %f;\n", FIXED_TO_FLOAT(wlines[i].alpha)); if (wlines[i].blendmode != AST_COPY) @@ -3130,7 +3130,7 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype linenum = (nodetype == NT_XGL3) ? READUINT32((*data)) : READUINT16((*data)); if (linenum != 0xFFFF && linenum >= numlines) - I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %d has invalid linedef %d!\n", sizeu1(k), i, linenum); + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %s has invalid linedef %d!\n", sizeu1(k), sizeu1(i), linenum); segs[k].glseg = (linenum == 0xFFFF); segs[k].linedef = (linenum == 0xFFFF) ? NULL : &lines[linenum]; segs[k].side = READUINT8((*data)); @@ -3139,7 +3139,7 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype { subsectors[i].firstline++; if (subsectors[i].firstline == k) - I_Error("P_LoadExtendedSubsectorsAndSegs: Subsector %d does not have any valid segs!", i); + I_Error("P_LoadExtendedSubsectorsAndSegs: Subsector %s does not have any valid segs!", sizeu1(i)); } break; @@ -6105,7 +6105,7 @@ static void P_ConvertBinaryThingTypes(void) if (j == -1) { - CONS_Debug(DBG_GAMELOGIC, "Particle generator (mapthing #%d) needs to be tagged to a #15 parameter line (trying to find tag %d).\n", i, mapthings[i].angle); + CONS_Debug(DBG_GAMELOGIC, "Particle generator (mapthing #%s) needs to be tagged to a #15 parameter line (trying to find tag %d).\n", sizeu1(i), mapthings[i].angle); break; } mapthings[i].args[0] = mapthings[i].z; From 4ef4669ea873f968d314d0d0e07b3c4a723feea9 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Sat, 28 May 2022 12:18:09 +0000 Subject: [PATCH 11/54] Apply 1 suggestion(s) to 1 file(s) --- src/p_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index b4bf95ec8..f680fbc03 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3130,7 +3130,7 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype linenum = (nodetype == NT_XGL3) ? READUINT32((*data)) : READUINT16((*data)); if (linenum != 0xFFFF && linenum >= numlines) - I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %s has invalid linedef %d!\n", sizeu1(k), sizeu1(i), linenum); + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %s has invalid linedef %d!\n", sizeu1(k), sizeu2(i), linenum); segs[k].glseg = (linenum == 0xFFFF); segs[k].linedef = (linenum == 0xFFFF) ? NULL : &lines[linenum]; segs[k].side = READUINT8((*data)); From 890b4583fa42705ef82d42cd801a36c60b3f79b9 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 4 Jun 2022 10:59:42 +0200 Subject: [PATCH 12/54] Fix custom FOF flag conversion in binary maps --- src/p_setup.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/r_defs.h | 41 ++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 2 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index f680fbc03..696732e4e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3856,6 +3856,81 @@ static void P_SetBinaryFOFAlpha(line_t *line) } } +static INT32 P_GetFOFFlags(INT32 oldflags) +{ + INT32 result = 0; + if (oldflags & FF_OLD_EXISTS) + result |= FF_EXISTS; + if (oldflags & FF_OLD_BLOCKPLAYER) + result |= FF_BLOCKPLAYER; + if (oldflags & FF_OLD_BLOCKOTHERS) + result |= FF_BLOCKOTHERS; + if (oldflags & FF_OLD_RENDERSIDES) + result |= FF_RENDERSIDES; + if (oldflags & FF_OLD_RENDERPLANES) + result |= FF_RENDERPLANES; + if (oldflags & FF_OLD_SWIMMABLE) + result |= FF_SWIMMABLE; + if (oldflags & FF_OLD_NOSHADE) + result |= FF_NOSHADE; + if (oldflags & FF_OLD_CUTSOLIDS) + result |= FF_CUTSOLIDS; + if (oldflags & FF_OLD_CUTEXTRA) + result |= FF_CUTEXTRA; + if (oldflags & FF_OLD_CUTSPRITES) + result |= FF_CUTSPRITES; + if (oldflags & FF_OLD_BOTHPLANES) + result |= FF_BOTHPLANES; + if (oldflags & FF_OLD_EXTRA) + result |= FF_EXTRA; + if (oldflags & FF_OLD_TRANSLUCENT) + result |= FF_TRANSLUCENT; + if (oldflags & FF_OLD_FOG) + result |= FF_FOG; + if (oldflags & FF_OLD_INVERTPLANES) + result |= FF_INVERTPLANES; + if (oldflags & FF_OLD_ALLSIDES) + result |= FF_ALLSIDES; + if (oldflags & FF_OLD_INVERTSIDES) + result |= FF_INVERTSIDES; + if (oldflags & FF_OLD_DOUBLESHADOW) + result |= FF_DOUBLESHADOW; + if (oldflags & FF_OLD_FLOATBOB) + result |= FF_FLOATBOB; + if (oldflags & FF_OLD_NORETURN) + result |= FF_NORETURN; + if (oldflags & FF_OLD_CRUMBLE) + result |= FF_CRUMBLE; + if (oldflags & FF_OLD_GOOWATER) + result |= FF_GOOWATER; + if (oldflags & FF_OLD_MARIO) + result |= FF_MARIO; + if (oldflags & FF_OLD_BUSTUP) + result |= FF_BUSTUP; + if (oldflags & FF_OLD_QUICKSAND) + result |= FF_QUICKSAND; + if (oldflags & FF_OLD_PLATFORM) + result |= FF_PLATFORM; + if (oldflags & FF_OLD_REVERSEPLATFORM) + result |= FF_REVERSEPLATFORM; + if (oldflags & FF_OLD_RIPPLE) + result |= FF_RIPPLE; + if (oldflags & FF_OLD_COLORMAPONLY) + result |= FF_COLORMAPONLY; + return result; +} + +static INT32 P_GetFOFBustflags(INT32 oldflags) +{ + if (oldflags & FF_OLD_SHATTER) + return TMFB_TOUCH; + if (oldflags & FF_OLD_SPINBUST) + return TMFB_SPIN; + if (oldflags & FF_OLD_STRONGBUST) + return TMFB_STRONG; + return TMFB_REGULAR; +} + static void P_ConvertBinaryLinedefTypes(void) { size_t i; @@ -4504,10 +4579,12 @@ static void P_ConvertBinaryLinedefTypes(void) I_Error("Custom FOF (tag %d) found without a linedef back side!", tag); lines[i].args[0] = tag; - lines[i].args[3] = sides[lines[i].sidenum[1]].toptexture; + lines[i].args[3] = P_GetFOFFlags(sides[lines[i].sidenum[1]].toptexture); if (lines[i].flags & ML_EFFECT6) lines[i].args[3] |= FF_SPLAT; - lines[i].args[4] = sides[lines[i].sidenum[1]].midtexture; + lines[i].args[4] = P_GetFOFBustflags(sides[lines[i].sidenum[1]].toptexture); + if (sides[lines[i].sidenum[1]].toptexture & FF_OLD_SHATTERBOTTOM) + lines[i].args[4] |= TMFB_ONLYBOTTOM; if (lines[i].args[3] & FF_TRANSLUCENT) { P_SetBinaryFOFAlpha(&lines[i]); diff --git a/src/r_defs.h b/src/r_defs.h index d2432eeb4..4ace43014 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -152,6 +152,47 @@ typedef enum FF_SPLAT = 0x40000000, ///< Use splat flat renderer (treat cyan pixels as invisible) } ffloortype_e; +typedef enum +{ + FF_OLD_EXISTS = 0x1, + FF_OLD_BLOCKPLAYER = 0x2, + FF_OLD_BLOCKOTHERS = 0x4, + FF_OLD_SOLID = 0x6, + FF_OLD_RENDERSIDES = 0x8, + FF_OLD_RENDERPLANES = 0x10, + FF_OLD_RENDERALL = 0x18, + FF_OLD_SWIMMABLE = 0x20, + FF_OLD_NOSHADE = 0x40, + FF_OLD_CUTSOLIDS = 0x80, + FF_OLD_CUTEXTRA = 0x100, + FF_OLD_CUTLEVEL = 0x180, + FF_OLD_CUTSPRITES = 0x200, + FF_OLD_BOTHPLANES = 0x400, + FF_OLD_EXTRA = 0x800, + FF_OLD_TRANSLUCENT = 0x1000, + FF_OLD_FOG = 0x2000, + FF_OLD_INVERTPLANES = 0x4000, + FF_OLD_ALLSIDES = 0x8000, + FF_OLD_INVERTSIDES = 0x10000, + FF_OLD_DOUBLESHADOW = 0x20000, + FF_OLD_FLOATBOB = 0x40000, + FF_OLD_NORETURN = 0x80000, + FF_OLD_CRUMBLE = 0x100000, + FF_OLD_SHATTERBOTTOM = 0x200000, + FF_OLD_GOOWATER = 0x200000, + FF_OLD_MARIO = 0x400000, + FF_OLD_BUSTUP = 0x800000, + FF_OLD_QUICKSAND = 0x1000000, + FF_OLD_PLATFORM = 0x2000000, + FF_OLD_REVERSEPLATFORM = 0x4000000, + FF_OLD_INTANGIBLEFLATS = 0x6000000, + FF_OLD_SHATTER = 0x8000000, + FF_OLD_SPINBUST = 0x10000000, + FF_OLD_STRONGBUST = 0x20000000, + FF_OLD_RIPPLE = 0x40000000, + FF_OLD_COLORMAPONLY = 0x80000000, +} oldffloortype_e; + typedef enum { FB_PUSHABLES = 0x1, // Bustable by pushables From 3b971835eea4f4787d0c040ae78080d10c1672c2 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 31 Jul 2022 12:04:42 +0200 Subject: [PATCH 13/54] Add Lua backwards compatibility for FOF flags --- src/deh_tables.c | 111 ++++++--- src/hardware/hw_main.c | 74 +++--- src/k_bot.c | 2 +- src/k_botsearch.c | 4 +- src/k_kart.c | 16 +- src/lua_maplib.c | 178 ++++++++++++++- src/objects/orbinaut.c | 2 +- src/p_enemy.c | 2 +- src/p_floor.c | 28 +-- src/p_map.c | 50 ++--- src/p_maputl.c | 24 +- src/p_mobj.c | 86 +++---- src/p_saveg.c | 8 +- src/p_setup.c | 72 +++--- src/p_sight.c | 18 +- src/p_spec.c | 500 ++++++++++++++++++++--------------------- src/p_spec.h | 4 +- src/p_user.c | 182 +++++++-------- src/r_bsp.c | 32 +-- src/r_defs.h | 82 +++---- src/r_draw8.c | 2 +- src/r_plane.c | 12 +- src/r_segs.c | 98 ++++---- src/r_things.c | 6 +- 24 files changed, 890 insertions(+), 703 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index 06842cf28..6a799d277 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -6447,42 +6447,81 @@ struct int_const_s const INT_CONST[] = { {"SKSKPOWR",SKSKPOWR}, // Power item taunt // 3D Floor/Fake Floor/FOF/whatever flags - {"FF_EXISTS",FF_EXISTS}, ///< Always set, to check for validity. - {"FF_BLOCKPLAYER",FF_BLOCKPLAYER}, ///< Solid to player, but nothing else - {"FF_BLOCKOTHERS",FF_BLOCKOTHERS}, ///< Solid to everything but player - {"FF_SOLID",FF_SOLID}, ///< Clips things. - {"FF_RENDERSIDES",FF_RENDERSIDES}, ///< Renders the sides. - {"FF_RENDERPLANES",FF_RENDERPLANES}, ///< Renders the floor/ceiling. - {"FF_RENDERALL",FF_RENDERALL}, ///< Renders everything. - {"FF_SWIMMABLE",FF_SWIMMABLE}, ///< Is a water block. - {"FF_NOSHADE",FF_NOSHADE}, ///< Messes with the lighting? - {"FF_CUTSOLIDS",FF_CUTSOLIDS}, ///< Cuts out hidden solid pixels. - {"FF_CUTEXTRA",FF_CUTEXTRA}, ///< Cuts out hidden translucent pixels. - {"FF_CUTLEVEL",FF_CUTLEVEL}, ///< Cuts out all hidden pixels. - {"FF_CUTSPRITES",FF_CUTSPRITES}, ///< Final step in making 3D water. - {"FF_BOTHPLANES",FF_BOTHPLANES}, ///< Render inside and outside planes. - {"FF_EXTRA",FF_EXTRA}, ///< Gets cut by ::FF_CUTEXTRA. - {"FF_TRANSLUCENT",FF_TRANSLUCENT}, ///< See through! - {"FF_FOG",FF_FOG}, ///< Fog "brush." - {"FF_INVERTPLANES",FF_INVERTPLANES}, ///< Only render inside planes. - {"FF_ALLSIDES",FF_ALLSIDES}, ///< Render inside and outside sides. - {"FF_INVERTSIDES",FF_INVERTSIDES}, ///< Only render inside sides. - {"FF_DOUBLESHADOW",FF_DOUBLESHADOW}, ///< Make two lightlist entries to reset light? - {"FF_FLOATBOB",FF_FLOATBOB}, ///< Floats on water and bobs if you step on it. - {"FF_NORETURN",FF_NORETURN}, ///< Used with ::FF_CRUMBLE. Will not return to its original position after falling. - {"FF_CRUMBLE",FF_CRUMBLE}, ///< Falls 2 seconds after being stepped on, and randomly brings all touching crumbling 3dfloors down with it, providing their master sectors share the same tag (allows crumble platforms above or below, to also exist). - {"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop. - {"FF_MARIO",FF_MARIO}, ///< Acts like a question block when hit from underneath. Goodie spawned at top is determined by master sector. - {"FF_BUSTUP",FF_BUSTUP}, ///< You can spin through/punch this block and it will crumble! - {"FF_QUICKSAND",FF_QUICKSAND}, ///< Quicksand! - {"FF_PLATFORM",FF_PLATFORM}, ///< You can jump up through this to the top. - {"FF_REVERSEPLATFORM",FF_REVERSEPLATFORM}, ///< A fall-through floor in normal gravity, a platform in reverse gravity. - {"FF_INTANGIBLEFLATS",FF_INTANGIBLEFLATS}, ///< Both flats are intangible, but the sides are still solid. - {"FF_INTANGABLEFLATS",FF_INTANGIBLEFLATS}, ///< Both flats are intangable, but the sides are still solid. - {"FF_RIPPLE",FF_RIPPLE}, ///< Ripple the flats - {"FF_COLORMAPONLY",FF_COLORMAPONLY}, ///< Only copy the colormap, not the lightlevel - {"FF_BOUNCY",FF_BOUNCY}, ///< Bounces players - {"FF_SPLAT",FF_SPLAT}, ///< Use splat flat renderer (treat cyan pixels as invisible) + {"FOF_EXISTS",FOF_EXISTS}, ///< Always set, to check for validity. + {"FOF_BLOCKPLAYER",FOF_BLOCKPLAYER}, ///< Solid to player, but nothing else + {"FOF_BLOCKOTHERS",FOF_BLOCKOTHERS}, ///< Solid to everything but player + {"FOF_SOLID",FOF_SOLID}, ///< Clips things. + {"FOF_RENDERSIDES",FOF_RENDERSIDES}, ///< Renders the sides. + {"FOF_RENDERPLANES",FOF_RENDERPLANES}, ///< Renders the floor/ceiling. + {"FOF_RENDERALL",FOF_RENDERALL}, ///< Renders everything. + {"FOF_SWIMMABLE",FOF_SWIMMABLE}, ///< Is a water block. + {"FOF_NOSHADE",FOF_NOSHADE}, ///< Messes with the lighting? + {"FOF_CUTSOLIDS",FOF_CUTSOLIDS}, ///< Cuts out hidden solid pixels. + {"FOF_CUTEXTRA",FOF_CUTEXTRA}, ///< Cuts out hidden translucent pixels. + {"FOF_CUTLEVEL",FOF_CUTLEVEL}, ///< Cuts out all hidden pixels. + {"FOF_CUTSPRITES",FOF_CUTSPRITES}, ///< Final step in making 3D water. + {"FOF_BOTHPLANES",FOF_BOTHPLANES}, ///< Render inside and outside planes. + {"FOF_EXTRA",FOF_EXTRA}, ///< Gets cut by ::FOF_CUTEXTRA. + {"FOF_TRANSLUCENT",FOF_TRANSLUCENT}, ///< See through! + {"FOF_FOG",FOF_FOG}, ///< Fog "brush." + {"FOF_INVERTPLANES",FOF_INVERTPLANES}, ///< Only render inside planes. + {"FOF_ALLSIDES",FOF_ALLSIDES}, ///< Render inside and outside sides. + {"FOF_INVERTSIDES",FOF_INVERTSIDES}, ///< Only render inside sides. + {"FOF_DOUBLESHADOW",FOF_DOUBLESHADOW}, ///< Make two lightlist entries to reset light? + {"FOF_FLOATBOB",FOF_FLOATBOB}, ///< Floats on water and bobs if you step on it. + {"FOF_NORETURN",FOF_NORETURN}, ///< Used with ::FOF_CRUMBLE. Will not return to its original position after falling. + {"FOF_CRUMBLE",FOF_CRUMBLE}, ///< Falls 2 seconds after being stepped on, and randomly brings all touching crumbling 3dfloors down with it, providing their master sectors share the same tag (allows crumble platforms above or below, to also exist). + {"FOF_GOOWATER",FOF_GOOWATER}, ///< Used with ::FOF_SWIMMABLE. Makes thick bouncey goop. + {"FOF_MARIO",FOF_MARIO}, ///< Acts like a question block when hit from underneath. Goodie spawned at top is determined by master sector. + {"FOF_BUSTUP",FOF_BUSTUP}, ///< You can spin through/punch this block and it will crumble! + {"FOF_QUICKSAND",FOF_QUICKSAND}, ///< Quicksand! + {"FOF_PLATFORM",FOF_PLATFORM}, ///< You can jump up through this to the top. + {"FOF_REVERSEPLATFORM",FOF_REVERSEPLATFORM}, ///< A fall-through floor in normal gravity, a platform in reverse gravity. + {"FOF_INTANGIBLEFLATS",FOF_INTANGIBLEFLATS}, ///< Both flats are intangible, but the sides are still solid. + {"FOF_RIPPLE",FOF_RIPPLE}, ///< Ripple the flats + {"FOF_COLORMAPONLY",FOF_COLORMAPONLY}, ///< Only copy the colormap, not the lightlevel + {"FOF_BOUNCY",FOF_BOUNCY}, ///< Bounces players + {"FOF_SPLAT",FOF_SPLAT}, ///< Use splat flat renderer (treat cyan pixels as invisible) + + // Old FOF flags for backwards compatibility + {"FF_EXISTS",FF_OLD_EXISTS}, + {"FF_BLOCKPLAYER",FF_OLD_BLOCKPLAYER}, + {"FF_BLOCKOTHERS",FF_OLD_BLOCKOTHERS}, + {"FF_SOLID",FF_OLD_SOLID}, + {"FF_RENDERSIDES",FF_OLD_RENDERSIDES}, + {"FF_RENDERPLANES",FF_OLD_RENDERPLANES}, + {"FF_RENDERALL",FF_OLD_RENDERALL}, + {"FF_SWIMMABLE",FF_OLD_SWIMMABLE}, + {"FF_NOSHADE",FF_OLD_NOSHADE}, + {"FF_CUTSOLIDS",FF_OLD_CUTSOLIDS}, + {"FF_CUTEXTRA",FF_OLD_CUTEXTRA}, + {"FF_CUTLEVEL",FF_OLD_CUTLEVEL}, + {"FF_CUTSPRITES",FF_OLD_CUTSPRITES}, + {"FF_BOTHPLANES",FF_OLD_BOTHPLANES}, + {"FF_EXTRA",FF_OLD_EXTRA}, + {"FF_TRANSLUCENT",FF_OLD_TRANSLUCENT}, + {"FF_FOG",FF_OLD_FOG}, + {"FF_INVERTPLANES",FF_OLD_INVERTPLANES}, + {"FF_ALLSIDES",FF_OLD_ALLSIDES}, + {"FF_INVERTSIDES",FF_OLD_INVERTSIDES}, + {"FF_DOUBLESHADOW",FF_OLD_DOUBLESHADOW}, + {"FF_FLOATBOB",FF_OLD_FLOATBOB}, + {"FF_NORETURN",FF_OLD_NORETURN}, + {"FF_CRUMBLE",FF_OLD_CRUMBLE}, + {"FF_SHATTERBOTTOM",FF_OLD_SHATTERBOTTOM}, + {"FF_GOOWATER",FF_OLD_GOOWATER}, + {"FF_MARIO",FF_OLD_MARIO}, + {"FF_BUSTUP",FF_OLD_BUSTUP}, + {"FF_QUICKSAND",FF_OLD_QUICKSAND}, + {"FF_PLATFORM",FF_OLD_PLATFORM}, + {"FF_REVERSEPLATFORM",FF_OLD_REVERSEPLATFORM}, + {"FF_INTANGIBLEFLATS",FF_OLD_INTANGIBLEFLATS}, + {"FF_INTANGABLEFLATS",FF_OLD_INTANGIBLEFLATS}, + {"FF_SHATTER",FF_OLD_SHATTER}, + {"FF_SPINBUST",FF_OLD_SPINBUST}, + {"FF_STRONGBUST",FF_OLD_STRONGBUST}, + {"FF_RIPPLE",FF_OLD_RIPPLE}, + {"FF_COLORMAPONLY",FF_OLD_COLORMAPONLY}, // FOF bustable flags {"FB_PUSHABLES",FB_PUSHABLES}, diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index e1fd97cd1..c86635319 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -839,9 +839,9 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, if (endtop < endrealbot && top < realbot) return; - if (!(list[i].flags & FF_NOSHADE)) + if (!(list[i].flags & FOF_NOSHADE)) { - if (pfloor && (pfloor->flags & FF_FOG)) + if (pfloor && (pfloor->fofflags & FOF_FOG)) { lightnum = pfloor->master->frontsector->lightlevel; colormap = pfloor->master->frontsector->extra_colormap; @@ -855,13 +855,13 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, solid = false; - if ((sector->lightlist[i].flags & FF_CUTSOLIDS) && !(cutflag & FF_EXTRA)) + if ((sector->lightlist[i].flags & FOF_CUTSOLIDS) && !(cutflag & FOF_EXTRA)) solid = true; - else if ((sector->lightlist[i].flags & FF_CUTEXTRA) && (cutflag & FF_EXTRA)) + else if ((sector->lightlist[i].flags & FOF_CUTEXTRA) && (cutflag & FOF_EXTRA)) { - if (sector->lightlist[i].flags & FF_EXTRA) + if (sector->lightlist[i].flags & FOF_EXTRA) { - if ((sector->lightlist[i].flags & (FF_FOG|FF_SWIMMABLE)) == (cutflag & (FF_FOG|FF_SWIMMABLE))) // Only merge with your own types + if ((sector->lightlist[i].flags & (FOF_FOG|FOF_SWIMMABLE)) == (cutflag & (FOF_FOG|FOF_SWIMMABLE))) // Only merge with your own types solid = true; } else @@ -1150,7 +1150,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom polyflags = PF_Environment; if (gl_frontsector->numlights) - HWR_SplitWall(gl_frontsector, wallVerts, gl_toptexture, &Surf, FF_CUTLEVEL, NULL, polyflags); + HWR_SplitWall(gl_frontsector, wallVerts, gl_toptexture, &Surf, FOF_CUTLEVEL, NULL, polyflags); else if (grTex->mipmap.flags & TF_TRANSPARENT) HWR_AddTransparentWall(wallVerts, &Surf, gl_toptexture, polyflags, false, lightnum, colormap); else @@ -1223,7 +1223,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom polyflags = PF_Environment; if (gl_frontsector->numlights) - HWR_SplitWall(gl_frontsector, wallVerts, gl_bottomtexture, &Surf, FF_CUTLEVEL, NULL, polyflags); + HWR_SplitWall(gl_frontsector, wallVerts, gl_bottomtexture, &Surf, FOF_CUTLEVEL, NULL, polyflags); else if (grTex->mipmap.flags & TF_TRANSPARENT) HWR_AddTransparentWall(wallVerts, &Surf, gl_bottomtexture, polyflags, false, lightnum, colormap); else @@ -1430,10 +1430,10 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if (gl_frontsector->numlights) { if (!(blendmode & PF_Masked)) - HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_TRANSLUCENT, NULL, blendmode); // vanilla just uses PF_Masked here - if we run into any issues, maybe change to that + HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FOF_TRANSLUCENT, NULL, blendmode); // vanilla just uses PF_Masked here - if we run into any issues, maybe change to that else { - HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_CUTLEVEL, NULL, blendmode); // vanilla just uses PF_Masked here - if we run into any issues, maybe change to that + HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FOF_CUTLEVEL, NULL, blendmode); // vanilla just uses PF_Masked here - if we run into any issues, maybe change to that } } else if (!(blendmode & PF_Masked)) @@ -1514,6 +1514,10 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[2].y = FIXED_TO_FLOAT(worldtopslope); wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope); + // I don't think that solid walls can use translucent linedef types... + if (gl_frontsector->numlights) + HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FOF_CUTLEVEL, NULL, 0); + else { FBITFIELD blendmode = PF_Masked; if (grTex->mipmap.flags & TF_TRANSPARENT) @@ -1521,7 +1525,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // I don't think that solid walls can use translucent linedef types... if (gl_frontsector->numlights) - HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_CUTLEVEL, NULL, blendmode); + HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FOF_CUTLEVEL, NULL, blendmode); else { if (grTex->mipmap.flags & TF_TRANSPARENT) @@ -1586,9 +1590,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if (bothsides) continue; - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERSIDES)) + if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERSIDES)) continue; - if (!(rover->flags & FF_ALLSIDES) && rover->flags & FF_INVERTSIDES) + if (!(rover->fofflags & FOF_ALLSIDES) && rover->fofflags & FOF_INVERTSIDES) continue; SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) @@ -1629,7 +1633,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[2].y = FIXED_TO_FLOAT(hS); wallVerts[0].y = FIXED_TO_FLOAT(l); wallVerts[1].y = FIXED_TO_FLOAT(lS); - if (rover->flags & FF_FOG) + if (rover->fofflags & FOF_FOG) { wallVerts[3].t = wallVerts[2].t = 0; wallVerts[0].t = wallVerts[1].t = 0; @@ -1688,7 +1692,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; } - if (rover->flags & FF_FOG) + if (rover->fofflags & FOF_FOG) { FBITFIELD blendmode; @@ -1700,7 +1704,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap); if (gl_frontsector->numlights) - HWR_SplitWall(gl_frontsector, wallVerts, 0, &Surf, rover->flags, rover, blendmode); + HWR_SplitWall(gl_frontsector, wallVerts, 0, &Surf, rover->fofflags, rover, blendmode); else HWR_AddTransparentWall(wallVerts, &Surf, 0, blendmode, true, lightnum, colormap); } @@ -1708,7 +1712,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom { FBITFIELD blendmode = PF_Masked; - if (rover->flags & FF_TRANSLUCENT) + if (rover->fofflags & FOF_TRANSLUCENT) { if (rover->alpha < 256 || rover->blend) { @@ -1718,7 +1722,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } if (gl_frontsector->numlights) - HWR_SplitWall(gl_frontsector, wallVerts, texnum, &Surf, rover->flags, rover, blendmode); + HWR_SplitWall(gl_frontsector, wallVerts, texnum, &Surf, rover->fofflags, rover, blendmode); else { if (blendmode != PF_Masked) @@ -1746,9 +1750,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if (bothsides) continue; - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERSIDES)) + if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERSIDES)) continue; - if (!(rover->flags & FF_ALLSIDES || rover->flags & FF_INVERTSIDES)) + if (!(rover->fofflags & FOF_ALLSIDES || rover->fofflags & FOF_INVERTSIDES)) continue; SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) @@ -1788,7 +1792,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[2].y = FIXED_TO_FLOAT(hS); wallVerts[0].y = FIXED_TO_FLOAT(l); wallVerts[1].y = FIXED_TO_FLOAT(lS); - if (rover->flags & FF_FOG) + if (rover->fofflags & FOF_FOG) { wallVerts[3].t = wallVerts[2].t = 0; wallVerts[0].t = wallVerts[1].t = 0; @@ -1814,7 +1818,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; } - if (rover->flags & FF_FOG) + if (rover->fofflags & FOF_FOG) { FBITFIELD blendmode; @@ -1826,7 +1830,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap); if (gl_backsector->numlights) - HWR_SplitWall(gl_backsector, wallVerts, 0, &Surf, rover->flags, rover, blendmode); + HWR_SplitWall(gl_backsector, wallVerts, 0, &Surf, rover->fofflags, rover, blendmode); else HWR_AddTransparentWall(wallVerts, &Surf, 0, blendmode, true, lightnum, colormap); } @@ -1834,7 +1838,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom { FBITFIELD blendmode = PF_Masked; - if (rover->flags & FF_TRANSLUCENT) + if (rover->fofflags & FOF_TRANSLUCENT) { if (rover->alpha < 256 || rover->blend) { @@ -1844,7 +1848,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } if (gl_backsector->numlights) - HWR_SplitWall(gl_backsector, wallVerts, texnum, &Surf, rover->flags, rover, blendmode); + HWR_SplitWall(gl_backsector, wallVerts, texnum, &Surf, rover->fofflags, rover, blendmode); else { if (blendmode != PF_Masked) @@ -3086,17 +3090,17 @@ static void HWR_Subsector(size_t num) cullHeight = P_GetFFloorBottomZAt(rover, viewx, viewy); centerHeight = P_GetFFloorBottomZAt(rover, gl_frontsector->soundorg.x, gl_frontsector->soundorg.y); - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) + if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERPLANES)) continue; if (sub->validcount == validcount) continue; if (centerHeight <= locCeilingHeight && centerHeight >= locFloorHeight && - ((dup_viewz < cullHeight && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || - (dup_viewz > cullHeight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) + ((dup_viewz < cullHeight && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES))) || + (dup_viewz > cullHeight && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES)))) { - if (rover->flags & FF_FOG) + if (rover->fofflags & FOF_FOG) { UINT8 alpha; @@ -3111,7 +3115,7 @@ static void HWR_Subsector(size_t num) alpha, rover->master->frontsector, PF_Fog|PF_NoTexture, true, rover->master->frontsector->extra_colormap); } - else if (rover->flags & FF_TRANSLUCENT + else if (rover->fofflags & FOF_TRANSLUCENT && (rover->alpha < 256 || rover->blend)) // SoM: Flags are more efficient { FBITFIELD blendmode = HWR_GetBlendModeFlag(rover->blend) | HWR_RippleBlend(gl_frontsector, rover, false); @@ -3141,10 +3145,10 @@ static void HWR_Subsector(size_t num) if (centerHeight >= locFloorHeight && centerHeight <= locCeilingHeight && - ((dup_viewz > cullHeight && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || - (dup_viewz < cullHeight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) + ((dup_viewz > cullHeight && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES))) || + (dup_viewz < cullHeight && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES)))) { - if (rover->flags & FF_FOG) + if (rover->fofflags & FOF_FOG) { UINT8 alpha; @@ -3159,7 +3163,7 @@ static void HWR_Subsector(size_t num) alpha, rover->master->frontsector, PF_Fog|PF_NoTexture, true, rover->master->frontsector->extra_colormap); } - else if (rover->flags & FF_TRANSLUCENT + else if (rover->fofflags & FOF_TRANSLUCENT && (rover->alpha < 256 || rover->blend)) // SoM: Flags are more efficient { FBITFIELD blendmode = HWR_GetBlendModeFlag(rover->blend) | HWR_RippleBlend(gl_frontsector, rover, false); @@ -3922,7 +3926,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) return; // even if we aren't changing colormap or lightlevel, we still need to continue drawing down the sprite - if (!(list[i].flags & FF_NOSHADE) && (list[i].flags & FF_CUTSPRITES)) + if (!(list[i].flags & FOF_NOSHADE) && (list[i].flags & FOF_CUTSPRITES)) { if (!lightset) { diff --git a/src/k_bot.c b/src/k_bot.c index 1c2ab4b80..30c661704 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -402,7 +402,7 @@ static line_t *K_FindBotController(mobj_t *mo) { sector_t *rs = NULL; - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) { continue; } diff --git a/src/k_botsearch.c b/src/k_botsearch.c index 52fbc19e0..2d9c9774d 100644 --- a/src/k_botsearch.c +++ b/src/k_botsearch.c @@ -189,7 +189,7 @@ boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t fixed_t top = INT32_MAX; fixed_t bottom = INT32_MAX; - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) { continue; } @@ -197,7 +197,7 @@ boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t top = P_GetZAt(*rover->t_slope, x, y, *rover->topheight); bottom = P_GetZAt(*rover->b_slope, x, y, *rover->bottomheight); - if (!(rover->flags & FF_BLOCKPLAYER)) + if (!(rover->fofflags & FOF_BLOCKPLAYER)) { if ((top >= player->mo->z) && (bottom <= player->mo->z + player->mo->height) && K_BotHatesThisSectorsSpecial(player, rover->master->frontsector)) diff --git a/src/k_kart.c b/src/k_kart.c index ecd04957c..f57720ed3 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1882,7 +1882,7 @@ static fixed_t K_CheckOffroadCollide(mobj_t *mo) // 2: If we're here, we haven't found anything. So let's try looking for FOFs in the sectors using the same logic. for (rover = s->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS)) // This FOF doesn't exist anymore. + if (!(rover->fofflags & FOF_EXISTS)) // This FOF doesn't exist anymore. continue; s2 = §ors[rover->secnum]; // makes things easier for us @@ -7133,13 +7133,13 @@ void K_CalculateBananaSlope(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed fixed_t top, bottom; fixed_t d1, d2; - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; - if ((!(((rover->flags & FF_BLOCKPLAYER && player) - || (rover->flags & FF_BLOCKOTHERS && !player)) - || (rover->flags & FF_QUICKSAND)) - || (rover->flags & FF_SWIMMABLE))) + if ((!(((rover->fofflags & FOF_BLOCKPLAYER && player) + || (rover->fofflags & FOF_BLOCKOTHERS && !player)) + || (rover->fofflags & FOF_QUICKSAND)) + || (rover->fofflags & FOF_SWIMMABLE))) continue; top = K_BananaSlopeZ(*rover->t_slope, x, y, *rover->topheight, radius, false); @@ -7147,7 +7147,7 @@ void K_CalculateBananaSlope(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed if (flip) { - if (rover->flags & FF_QUICKSAND) + if (rover->fofflags & FOF_QUICKSAND) { if (z < top && (z + height) > bottom) { @@ -7171,7 +7171,7 @@ void K_CalculateBananaSlope(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed } else { - if (rover->flags & FF_QUICKSAND) + if (rover->fofflags & FOF_QUICKSAND) { if (z < top && (z + height) > bottom) { diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 925483ea3..a8baf558f 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -214,6 +214,7 @@ enum ffloor_e { ffloor_tslope, ffloor_bslope, ffloor_sector, + ffloor_fofflags, ffloor_flags, ffloor_master, ffloor_target, @@ -1841,6 +1842,80 @@ static int lib_numnodes(lua_State *L) // ffloor_t // ////////////// +static INT32 P_GetOldFOFFlags(ffloor_t *fflr) +{ + INT32 result = 0; + if (fflr->fofflags & FOF_EXISTS) + result |= FF_OLD_EXISTS; + if (fflr->fofflags & FOF_BLOCKPLAYER) + result |= FF_OLD_BLOCKPLAYER; + if (fflr->fofflags & FOF_BLOCKOTHERS) + result |= FF_OLD_BLOCKOTHERS; + if (fflr->fofflags & FOF_RENDERSIDES) + result |= FF_OLD_RENDERSIDES; + if (fflr->fofflags & FOF_RENDERPLANES) + result |= FF_OLD_RENDERPLANES; + if (fflr->fofflags & FOF_SWIMMABLE) + result |= FF_OLD_SWIMMABLE; + if (fflr->fofflags & FOF_NOSHADE) + result |= FF_OLD_NOSHADE; + if (fflr->fofflags & FOF_CUTSOLIDS) + result |= FF_OLD_CUTSOLIDS; + if (fflr->fofflags & FOF_CUTEXTRA) + result |= FF_OLD_CUTEXTRA; + if (fflr->fofflags & FOF_CUTSPRITES) + result |= FF_OLD_CUTSPRITES; + if (fflr->fofflags & FOF_BOTHPLANES) + result |= FF_OLD_BOTHPLANES; + if (fflr->fofflags & FOF_EXTRA) + result |= FF_OLD_EXTRA; + if (fflr->fofflags & FOF_TRANSLUCENT) + result |= FF_OLD_TRANSLUCENT; + if (fflr->fofflags & FOF_FOG) + result |= FF_OLD_FOG; + if (fflr->fofflags & FOF_INVERTPLANES) + result |= FF_OLD_INVERTPLANES; + if (fflr->fofflags & FOF_ALLSIDES) + result |= FF_OLD_ALLSIDES; + if (fflr->fofflags & FOF_INVERTSIDES) + result |= FF_OLD_INVERTSIDES; + if (fflr->fofflags & FOF_DOUBLESHADOW) + result |= FF_OLD_DOUBLESHADOW; + if (fflr->fofflags & FOF_FLOATBOB) + result |= FF_OLD_FLOATBOB; + if (fflr->fofflags & FOF_NORETURN) + result |= FF_OLD_NORETURN; + if (fflr->fofflags & FOF_CRUMBLE) + result |= FF_OLD_CRUMBLE; + if (fflr->bustflags & TMFB_ONLYBOTTOM) + result |= FF_OLD_SHATTERBOTTOM; + if (fflr->fofflags & FOF_GOOWATER) + result |= FF_OLD_GOOWATER; + if (fflr->fofflags & FOF_MARIO) + result |= FF_OLD_MARIO; + if (fflr->fofflags & FOF_BUSTUP) + result |= FF_OLD_BUSTUP; + if (fflr->fofflags & FOF_QUICKSAND) + result |= FF_OLD_QUICKSAND; + if (fflr->fofflags & FOF_PLATFORM) + result |= FF_OLD_PLATFORM; + if (fflr->fofflags & FOF_REVERSEPLATFORM) + result |= FF_OLD_REVERSEPLATFORM; + if (fflr->fofflags & FOF_INTANGIBLEFLATS) + result |= FF_OLD_INTANGIBLEFLATS; + if (fflr->busttype == BT_TOUCH) + result |= FF_OLD_SHATTER; + if (fflr->busttype == BT_SPINBUST) + result |= FF_OLD_SPINBUST; + if (fflr->busttype == BT_STRONG) + result |= FF_OLD_STRONGBUST; + if (fflr->fofflags & FF_OLD_RIPPLE) + result |= FOF_RIPPLE; + if (fflr->fofflags & FF_OLD_COLORMAPONLY) + result |= FOF_COLORMAPONLY; + return result; +} + static int ffloor_get(lua_State *L) { ffloor_t *ffloor = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR)); @@ -1895,8 +1970,11 @@ static int ffloor_get(lua_State *L) case ffloor_sector: LUA_PushUserdata(L, §ors[ffloor->secnum], META_SECTOR); return 1; + case ffloor_fofflags: + lua_pushinteger(L, ffloor->fofflags); + return 1; case ffloor_flags: - lua_pushinteger(L, ffloor->flags); + lua_pushinteger(L, P_GetOldFOFFlags(ffloor)); return 1; case ffloor_master: LUA_PushUserdata(L, ffloor->master, META_LINE); @@ -1938,6 +2016,88 @@ static int ffloor_get(lua_State *L) return 0; } +static void P_SetOldFOFFlags(ffloor_t *fflr, oldffloortype_e oldflags) +{ + ffloortype_e originalflags = fflr->fofflags; + fflr->fofflags = 0; + if (oldflags & FF_OLD_EXISTS) + fflr->fofflags |= FOF_EXISTS; + if (oldflags & FF_OLD_BLOCKPLAYER) + fflr->fofflags |= FOF_BLOCKPLAYER; + if (oldflags & FF_OLD_BLOCKOTHERS) + fflr->fofflags |= FOF_BLOCKOTHERS; + if (oldflags & FF_OLD_RENDERSIDES) + fflr->fofflags |= FOF_RENDERSIDES; + if (oldflags & FF_OLD_RENDERPLANES) + fflr->fofflags |= FOF_RENDERPLANES; + if (oldflags & FF_OLD_SWIMMABLE) + fflr->fofflags |= FOF_SWIMMABLE; + if (oldflags & FF_OLD_NOSHADE) + fflr->fofflags |= FOF_NOSHADE; + if (oldflags & FF_OLD_CUTSOLIDS) + fflr->fofflags |= FOF_CUTSOLIDS; + if (oldflags & FF_OLD_CUTEXTRA) + fflr->fofflags |= FOF_CUTEXTRA; + if (oldflags & FF_OLD_CUTSPRITES) + fflr->fofflags |= FOF_CUTSPRITES; + if (oldflags & FF_OLD_BOTHPLANES) + fflr->fofflags |= FOF_BOTHPLANES; + if (oldflags & FF_OLD_EXTRA) + fflr->fofflags |= FOF_EXTRA; + if (oldflags & FF_OLD_TRANSLUCENT) + fflr->fofflags |= FOF_TRANSLUCENT; + if (oldflags & FF_OLD_FOG) + fflr->fofflags |= FOF_FOG; + if (oldflags & FF_OLD_INVERTPLANES) + fflr->fofflags |= FOF_INVERTPLANES; + if (oldflags & FF_OLD_ALLSIDES) + fflr->fofflags |= FOF_ALLSIDES; + if (oldflags & FF_OLD_INVERTSIDES) + fflr->fofflags |= FOF_INVERTSIDES; + if (oldflags & FF_OLD_DOUBLESHADOW) + fflr->fofflags |= FOF_DOUBLESHADOW; + if (oldflags & FF_OLD_FLOATBOB) + fflr->fofflags |= FOF_FLOATBOB; + if (oldflags & FF_OLD_NORETURN) + fflr->fofflags |= FOF_NORETURN; + if (oldflags & FF_OLD_CRUMBLE) + fflr->fofflags |= FOF_CRUMBLE; + if (oldflags & FF_OLD_GOOWATER) + fflr->fofflags |= FOF_GOOWATER; + if (oldflags & FF_OLD_MARIO) + fflr->fofflags |= FOF_MARIO; + if (oldflags & FF_OLD_BUSTUP) + fflr->fofflags |= FOF_BUSTUP; + if (oldflags & FF_OLD_QUICKSAND) + fflr->fofflags |= FOF_QUICKSAND; + if (oldflags & FF_OLD_PLATFORM) + fflr->fofflags |= FOF_PLATFORM; + if (oldflags & FF_OLD_REVERSEPLATFORM) + fflr->fofflags |= FOF_REVERSEPLATFORM; + if (oldflags & FF_OLD_RIPPLE) + fflr->fofflags |= FOF_RIPPLE; + if (oldflags & FF_OLD_COLORMAPONLY) + fflr->fofflags |= FOF_COLORMAPONLY; + if (originalflags & FOF_BOUNCY) + fflr->fofflags |= FOF_BOUNCY; + if (originalflags & FOF_SPLAT) + fflr->fofflags |= FOF_SPLAT; + + if (oldflags & FF_OLD_SHATTER) + fflr->busttype = BT_TOUCH; + else if (oldflags & FF_OLD_SPINBUST) + fflr->busttype = BT_SPINBUST; + else if (oldflags & FF_OLD_STRONGBUST) + fflr->busttype = BT_STRONG; + else + fflr->busttype = BT_REGULAR; + + if (oldflags & FF_OLD_SHATTERBOTTOM) + fflr->bustflags |= TMFB_ONLYBOTTOM; + else + fflr->bustflags &= ~TMFB_ONLYBOTTOM; +} + static int ffloor_set(lua_State *L) { ffloor_t *ffloor = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR)); @@ -2002,10 +2162,20 @@ static int ffloor_set(lua_State *L) case ffloor_bottompic: *ffloor->bottompic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3)); break; + case ffloor_fofflags: { + ffloortype_e oldflags = ffloor->fofflags; // store FOF's old flags + ffloor->fofflags = luaL_checkinteger(L, 3); + if (ffloor->fofflags != oldflags) + ffloor->target->moved = true; // reset target sector's lightlist + break; + } case ffloor_flags: { - ffloortype_e oldflags = ffloor->flags; // store FOF's old flags - ffloor->flags = luaL_checkinteger(L, 3); - if (ffloor->flags != oldflags) + ffloortype_e oldflags = ffloor->fofflags; // store FOF's old flags + busttype_e oldbusttype = ffloor->busttype; + ffloorbustflags_e oldbustflags = ffloor->bustflags; + oldffloortype_e newflags = luaL_checkinteger(L, 3); + P_SetOldFOFFlags(ffloor, newflags); + if (ffloor->fofflags != oldflags || ffloor->busttype != oldbusttype || ffloor->bustflags != oldbustflags) ffloor->target->moved = true; // reset target sector's lightlist break; } diff --git a/src/objects/orbinaut.c b/src/objects/orbinaut.c index 4f5d5ede6..4d5738e00 100644 --- a/src/objects/orbinaut.c +++ b/src/objects/orbinaut.c @@ -125,7 +125,7 @@ void Obj_OrbinautThink(mobj_t *th) } /* todo: UDMFify - if (P_MobjTouchingSectorSpecialFlag(th, SS)) + if (P_MobjTouchingSectorSpecialFlag(th, ?)) { K_DoPogoSpring(th, 0, 1); } diff --git a/src/p_enemy.c b/src/p_enemy.c index 3859d9335..c877528ad 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -506,7 +506,7 @@ static boolean P_WaterInSector(mobj_t *mobj, fixed_t x, fixed_t y) for (rover = sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE)) + if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_SWIMMABLE)) continue; if (*rover->topheight >= mobj->floorz && *rover->topheight <= mobj->z) diff --git a/src/p_floor.c b/src/p_floor.c index be62c5786..b394ab811 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -554,7 +554,7 @@ static fixed_t P_SectorCheckWater(sector_t *analyzesector, for (rover = analyzesector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_SOLID) + if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_SWIMMABLE) || rover->fofflags & FOF_SOLID) continue; // If the sector is below the water, don't bother. @@ -760,10 +760,10 @@ void T_StartCrumble(crumble_t *crumble) for (rover = sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_CRUMBLE)) + if (!(rover->fofflags & FOF_CRUMBLE)) continue; - if (!(rover->flags & FF_FLOATBOB)) + if (!(rover->fofflags & FOF_FLOATBOB)) continue; if (rover->master != crumble->sourceline) @@ -772,7 +772,7 @@ void T_StartCrumble(crumble_t *crumble) rover->alpha = crumble->origalpha; if (rover->alpha == 0xff) - rover->flags &= ~FF_TRANSLUCENT; + rover->fofflags &= ~FOF_TRANSLUCENT; } } @@ -796,13 +796,13 @@ void T_StartCrumble(crumble_t *crumble) for (rover = sector->ffloors; rover; rover = rover->next) { - if (rover->flags & FF_NORETURN) + if (rover->fofflags & FOF_NORETURN) continue; - if (!(rover->flags & FF_CRUMBLE)) + if (!(rover->fofflags & FOF_CRUMBLE)) continue; - if (!(rover->flags & FF_FLOATBOB)) + if (!(rover->fofflags & FOF_FLOATBOB)) continue; if (rover->master != crumble->sourceline) @@ -810,7 +810,7 @@ void T_StartCrumble(crumble_t *crumble) if (rover->alpha == crumble->origalpha) { - rover->flags |= FF_TRANSLUCENT; + rover->fofflags |= FOF_TRANSLUCENT; rover->alpha = 0x00; } else @@ -818,7 +818,7 @@ void T_StartCrumble(crumble_t *crumble) rover->alpha = crumble->origalpha; if (rover->alpha == 0xff) - rover->flags &= ~FF_TRANSLUCENT; + rover->fofflags &= ~FOF_TRANSLUCENT; } } } @@ -1063,7 +1063,7 @@ void T_ThwompSector(thwomp_t *thwomp) // I could of used rowoffset, but the FOF actually // modifies the textures's Y offset. It doesn't with // textureoffset, so Effect 4 can be ignored as usual. - if ((thwomp->sourceline->flags & ML_SKEWTD) // FIXME: UDMF-ify + if ((thwomp->sourceline->flags & ML_SKEWTD) // FIXME: UDMFify && leveltime < (unsigned)(sides[thwomp->sourceline->sidenum[0]].textureoffset>>FRACBITS)) thwomp->direction = 0; @@ -1167,7 +1167,7 @@ void T_ThwompSector(thwomp_t *thwomp) if (res == pastdest) { - if (rover->flags & FF_EXISTS) + if (rover->fofflags & FOF_EXISTS) S_StartSound((void *)&actionsector->soundorg, thwomp->sound); thwomp->direction = 1; // start heading back up @@ -1904,7 +1904,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) } // no longer exists (can't collide with again) - rover->flags &= ~FF_EXISTS; + rover->fofflags &= ~FOF_EXISTS; rover->master->frontsector->moved = true; P_RecalcPrecipInSector(sec); } @@ -2042,8 +2042,8 @@ void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher) if (roversec->floordata || roversec->ceilingdata) return; - if (!(rover->flags & FF_SOLID)) - rover->flags |= (FF_SOLID|FF_RENDERALL|FF_CUTLEVEL); + if (!(rover->fofflags & FOF_SOLID)) + rover->fofflags |= (FOF_SOLID|FOF_RENDERALL|FOF_CUTLEVEL); // Find an item to pop out! thing = SearchMarioNode(roversec->touching_thinglist); diff --git a/src/p_map.c b/src/p_map.c index 879a6650e..96e8747b0 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1876,13 +1876,13 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) { fixed_t topheight, bottomheight; - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; topheight = P_GetFOFTopZ(thing, newsubsec->sector, rover, x, y, NULL); bottomheight = P_GetFOFBottomZ(thing, newsubsec->sector, rover, x, y, NULL); - if ((rover->flags & (FF_SWIMMABLE|FF_GOOWATER)) == (FF_SWIMMABLE|FF_GOOWATER) && !(thing->flags & MF_NOGRAVITY)) + if ((rover->fofflags & (FOF_SWIMMABLE|FOF_GOOWATER)) == (FOF_SWIMMABLE|FOF_GOOWATER) && !(thing->flags & MF_NOGRAVITY)) { // If you're inside goowater and slowing down fixed_t sinklevel = FixedMul(thing->info->height/6, thing->scale); @@ -1923,14 +1923,14 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) if (P_CheckSolidFFloorSurface(thing, rover)) ; - else if (thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE)) + else if (thing->type == MT_SKIM && (rover->fofflags & FOF_SWIMMABLE)) ; - else if (!((rover->flags & FF_BLOCKPLAYER && thing->player) - || (rover->flags & FF_BLOCKOTHERS && !thing->player) - || rover->flags & FF_QUICKSAND)) + else if (!((rover->fofflags & FOF_BLOCKPLAYER && thing->player) + || (rover->fofflags & FOF_BLOCKOTHERS && !thing->player) + || rover->fofflags & FOF_QUICKSAND)) continue; - if (rover->flags & FF_QUICKSAND) + if (rover->fofflags & FOF_QUICKSAND) { if (thing->z < topheight && bottomheight < thingtop) { @@ -1951,7 +1951,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) + ((topheight - bottomheight)/2)); if (topheight > tmfloorz && abs(delta1) < abs(delta2) - && !(rover->flags & FF_REVERSEPLATFORM)) + && !(rover->fofflags & FOF_REVERSEPLATFORM)) { tmfloorz = tmdropoffz = topheight; tmfloorrover = rover; @@ -1959,8 +1959,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) tmfloorpic = *rover->toppic; } if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2) - && !(rover->flags & FF_PLATFORM) - && !(thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE))) + && !(rover->fofflags & FOF_PLATFORM) + && !(thing->type == MT_SKIM && (rover->fofflags & FOF_SWIMMABLE))) { tmceilingz = tmdrpoffceilz = bottomheight; tmceilingrover = rover; @@ -2183,7 +2183,7 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) for (rover = newsubsec->sector->ffloors; rover; rover = rover->next) { fixed_t topheight, bottomheight; - if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA)) + if (!(rover->fofflags & FOF_BLOCKOTHERS) || !(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERALL) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA)) continue; topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, x, y, NULL); @@ -2495,7 +2495,7 @@ BlockItReturn_t PIT_PushableMoved(mobj_t *thing) static boolean P_WaterRunning(mobj_t *thing) { ffloor_t *rover = thing->floorrover; - return rover && (rover->flags & FF_SWIMMABLE) && + return rover && (rover->fofflags & FOF_SWIMMABLE) && P_IsObjectOnGround(thing); } @@ -3076,9 +3076,9 @@ static boolean P_ThingHeightClip(mobj_t *thing) { rover = (thing->eflags & MFE_VERTICALFLIP) ? oldceilingrover : oldfloorrover; - // Match the Thing's old floorz to an FOF and check for FF_EXISTS - // If ~FF_EXISTS, don't set mobj Z. - if (!rover || ((rover->flags & FF_EXISTS) && (rover->flags & FF_SOLID))) + // Match the Thing's old floorz to an FOF and check for FOF_EXISTS + // If ~FOF_EXISTS, don't set mobj Z. + if (!rover || ((rover->fofflags & FOF_EXISTS) && (rover->fofflags & FOF_SOLID))) { hitfloor = false; if (thing->eflags & MFE_VERTICALFLIP) @@ -3511,10 +3511,10 @@ static void P_CheckLavaWall(mobj_t *mo, sector_t *sec) for (rover = sec->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; - if (!(rover->flags & FF_SWIMMABLE)) + if (!(rover->fofflags & FOF_SWIMMABLE)) continue; if (rover->master->frontsector->damagetype != SD_LAVA) @@ -4217,8 +4217,8 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) for (rover = thing->subsector->sector->ffloors; rover; rover = rover->next) { - if (!(((rover->flags & FF_BLOCKPLAYER) && thing->player) - || ((rover->flags & FF_BLOCKOTHERS) && !thing->player)) || !(rover->flags & FF_EXISTS)) + if (!(((rover->fofflags & FOF_BLOCKPLAYER) && thing->player) + || ((rover->fofflags & FOF_BLOCKOTHERS) && !thing->player)) || !(rover->fofflags & FOF_EXISTS)) continue; topheight = *rover->topheight; @@ -5012,16 +5012,16 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) for (rover = sec->ffloors; rover; rover = rover->next) { fixed_t topheight, bottomheight; - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; - if (!((rover->flags & FF_SOLID) || (rover->flags & FF_QUICKSAND)) || (rover->flags & FF_SWIMMABLE)) + if (!((rover->fofflags & FOF_SOLID) || (rover->fofflags & FOF_QUICKSAND)) || (rover->fofflags & FOF_SWIMMABLE)) continue; topheight = P_GetFFloorTopZAt (rover, x, y); bottomheight = P_GetFFloorBottomZAt(rover, x, y); - if (rover->flags & FF_QUICKSAND) + if (rover->fofflags & FOF_QUICKSAND) { if (z < topheight && bottomheight < thingtop) { @@ -5056,16 +5056,16 @@ fixed_t P_CeilingzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) for (rover = sec->ffloors; rover; rover = rover->next) { fixed_t topheight, bottomheight; - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; - if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE))) + if ((!(rover->fofflags & FOF_SOLID || rover->fofflags & FOF_QUICKSAND) || (rover->fofflags & FOF_SWIMMABLE))) continue; topheight = P_GetFFloorTopZAt (rover, x, y); bottomheight = P_GetFFloorBottomZAt(rover, x, y); - if (rover->flags & FF_QUICKSAND) + if (rover->fofflags & FOF_QUICKSAND) { if (thingtop > bottomheight && topheight > z) { diff --git a/src/p_maputl.c b/src/p_maputl.c index d05e2fad3..5f547773b 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -437,7 +437,7 @@ void P_CameraLineOpening(line_t *linedef) for (rover = front->ffloors; rover; rover = rover->next) { fixed_t topheight, bottomheight; - if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA)) + if (!(rover->fofflags & FOF_BLOCKOTHERS) || !(rover->fofflags & FOF_RENDERALL) || !(rover->fofflags & FOF_EXISTS) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA)) continue; topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tmx, tmy, linedef); @@ -461,7 +461,7 @@ void P_CameraLineOpening(line_t *linedef) for (rover = back->ffloors; rover; rover = rover->next) { fixed_t topheight, bottomheight; - if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA)) + if (!(rover->fofflags & FOF_BLOCKOTHERS) || !(rover->fofflags & FOF_RENDERALL) || !(rover->fofflags & FOF_EXISTS) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA)) continue; topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tmx, tmy, linedef); @@ -802,13 +802,13 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) for (rover = front->ffloors; rover; rover = rover->next) { fixed_t topheight, bottomheight; - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; if (P_CheckSolidFFloorSurface(mobj, rover)) ; - else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player) - || (rover->flags & FF_BLOCKOTHERS && !mobj->player))) + else if (!((rover->fofflags & FOF_BLOCKPLAYER && mobj->player) + || (rover->fofflags & FOF_BLOCKOTHERS && !mobj->player))) continue; topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef); @@ -817,7 +817,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2))); delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); - if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF + if (delta1 >= delta2 && (rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM) // thing is below FOF { if (bottomheight < open[FRONT].top) { open[FRONT].top = bottomheight; @@ -829,7 +829,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) highceiling = bottomheight; } - if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF + if (delta1 < delta2 && (rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM) // thing is above FOF { if (topheight > open[FRONT].bottom) { open[FRONT].bottom = topheight; @@ -846,13 +846,13 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) for (rover = back->ffloors; rover; rover = rover->next) { fixed_t topheight, bottomheight; - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; if (P_CheckSolidFFloorSurface(mobj, rover)) ; - else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player) - || (rover->flags & FF_BLOCKOTHERS && !mobj->player))) + else if (!((rover->fofflags & FOF_BLOCKPLAYER && mobj->player) + || (rover->fofflags & FOF_BLOCKOTHERS && !mobj->player))) continue; topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef); @@ -861,7 +861,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2))); delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); - if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF + if (delta1 >= delta2 && (rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM) // thing is below FOF { if (bottomheight < open[BACK].top) { open[BACK].top = bottomheight; @@ -873,7 +873,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) highceiling = bottomheight; } - if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF + if (delta1 < delta2 && (rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM) // thing is above FOF { if (topheight > open[BACK].bottom) { open[BACK].bottom = topheight; diff --git a/src/p_mobj.c b/src/p_mobj.c index cdddc0098..078b93fdb 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -594,11 +594,11 @@ void P_ExplodeMissile(mobj_t *mo) boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover) { fixed_t topheight, bottomheight; - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) return false; - if ((((rover->flags & FF_BLOCKPLAYER) && mobj->player) - || ((rover->flags & FF_BLOCKOTHERS) && !mobj->player))) + if ((((rover->fofflags & FOF_BLOCKPLAYER) && mobj->player) + || ((rover->fofflags & FOF_BLOCKOTHERS) && !mobj->player))) return false; topheight = P_GetFFloorTopZAt (rover, mobj->x, mobj->y); @@ -1062,10 +1062,10 @@ fixed_t P_GetMobjGravity(mobj_t *mo) for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS) || !P_InsideANonSolidFFloor(mo, rover)) // P_InsideANonSolidFFloor checks for FF_EXISTS itself, but let's not always call this function + if (!(rover->fofflags & FOF_EXISTS) || !P_InsideANonSolidFFloor(mo, rover)) // P_InsideANonSolidFFloor checks for FOF_EXISTS itself, but let's not always call this function continue; - if ((rover->flags & (FF_SWIMMABLE|FF_GOOWATER)) == (FF_SWIMMABLE|FF_GOOWATER)) + if ((rover->fofflags & (FOF_SWIMMABLE|FOF_GOOWATER)) == (FOF_SWIMMABLE|FOF_GOOWATER)) goopgravity = true; gravfactor = P_GetSectorGravityFactor(rover->master->frontsector); @@ -1408,10 +1408,10 @@ static void P_PushableCheckBustables(mobj_t *mo) for (rover = node->m_sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; - if (!(rover->flags & FF_BUSTUP)) + if (!(rover->fofflags & FOF_BUSTUP)) continue; if (!(rover->bustflags & FB_PUSHABLES)) @@ -1947,7 +1947,7 @@ void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype) for (rover = sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL); @@ -1955,16 +1955,16 @@ void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype) if (P_CheckSolidFFloorSurface(mo, rover)) // only the player should stand on lava or run on water ; - else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only + else if (motype != 0 && rover->fofflags & FOF_SWIMMABLE) // "scenery" only continue; - else if (rover->flags & FF_QUICKSAND) // quicksand + else if (rover->fofflags & FOF_QUICKSAND) // quicksand ; else if (!( // if it's not either of the following... - (rover->flags & (FF_BLOCKPLAYER|FF_MARIO) && mo->player) // ...solid to players? (mario blocks are always solid from beneath to players) - || (rover->flags & FF_BLOCKOTHERS && !mo->player) // ...solid to others? + (rover->fofflags & (FOF_BLOCKPLAYER|FOF_MARIO) && mo->player) // ...solid to players? (mario blocks are always solid from beneath to players) + || (rover->fofflags & FOF_BLOCKOTHERS && !mo->player) // ...solid to others? )) // ...don't take it into account. continue; - if (rover->flags & FF_QUICKSAND) + if (rover->fofflags & FOF_QUICKSAND) { switch (motype) { @@ -1989,15 +1989,15 @@ void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype) delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2)); if (topheight > mo->floorz && abs(delta1) < abs(delta2) - && (rover->flags & FF_SOLID) // Non-FF_SOLID Mario blocks are only solid from bottom - && !(rover->flags & FF_REVERSEPLATFORM) - && ((P_MobjFlip(mo)*mo->momz >= 0) || (!(rover->flags & FF_PLATFORM)))) // In reverse gravity, only clip for FOFs that are intangible from their bottom (the "top" you're falling through) if you're coming from above ("below" in your frame of reference) + && (rover->fofflags & FOF_SOLID) // Non-FOF_SOLID Mario blocks are only solid from bottom + && !(rover->fofflags & FOF_REVERSEPLATFORM) + && ((P_MobjFlip(mo)*mo->momz >= 0) || (!(rover->fofflags & FOF_PLATFORM)))) // In reverse gravity, only clip for FOFs that are intangible from their bottom (the "top" you're falling through) if you're coming from above ("below" in your frame of reference) { mo->floorz = topheight; } if (bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2) - && !(rover->flags & FF_PLATFORM) - && ((P_MobjFlip(mo)*mo->momz >= 0) || ((rover->flags & FF_SOLID) && !(rover->flags & FF_REVERSEPLATFORM)))) // In normal gravity, only clip for FOFs that are intangible from the top if you're coming from below + && !(rover->fofflags & FOF_PLATFORM) + && ((P_MobjFlip(mo)*mo->momz >= 0) || ((rover->fofflags & FOF_SOLID) && !(rover->fofflags & FOF_REVERSEPLATFORM)))) // In normal gravity, only clip for FOFs that are intangible from the top if you're coming from below { mo->ceilingz = bottomheight; } @@ -2125,7 +2125,7 @@ boolean P_CheckSolidLava(mobj_t *mobj, ffloor_t *rover) return false; } - if ((rover->flags & FF_SWIMMABLE) && (rover->master->frontsector->damagetype == SD_LAVA)) + if ((rover->fofflags & FOF_SWIMMABLE) && (rover->master->frontsector->damagetype == SD_LAVA)) { return true; } @@ -2688,10 +2688,10 @@ static void P_CheckMarioBlocks(mobj_t *mo) for (rover = node->m_sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; - if (!(rover->flags & FF_MARIO)) + if (!(rover->fofflags & FOF_MARIO)) continue; if (mo->eflags & MFE_VERTICALFLIP) @@ -2700,7 +2700,7 @@ static void P_CheckMarioBlocks(mobj_t *mo) if (*rover->bottomheight != mo->ceilingz) continue; - if (rover->flags & FF_GOOWATER) // Brick block! + if (rover->fofflags & FOF_GOOWATER) // Brick block! EV_CrumbleChain(node->m_sector, rover); else // Question block! EV_MarioBlock(rover, node->m_sector, mo); @@ -3136,7 +3136,7 @@ boolean P_CanRunOnWater(mobj_t *mobj, ffloor_t *rover) return false; } - if (!(rover->flags & FF_SWIMMABLE)) + if (!(rover->fofflags & FOF_SWIMMABLE)) { // It's not even a water FOF. return false; @@ -3252,9 +3252,9 @@ void P_MobjCheckWater(mobj_t *mobj) topheight = P_GetSpecialTopZ(mobj, sectors + rover->secnum, sector); bottomheight = P_GetSpecialBottomZ(mobj, sectors + rover->secnum, sector); - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) - || (((rover->flags & FF_BLOCKPLAYER) && mobj->player) - || ((rover->flags & FF_BLOCKOTHERS) && !mobj->player))) + if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_SWIMMABLE) + || (((rover->fofflags & FOF_BLOCKPLAYER) && mobj->player) + || ((rover->fofflags & FOF_BLOCKOTHERS) && !mobj->player))) { if (topheight < top2 && topheight > thingtop) top2 = topheight; @@ -3298,7 +3298,7 @@ void P_MobjCheckWater(mobj_t *mobj) if (rover->master->frontsector->damagetype == SD_LAVA) mobj->eflags |= MFE_TOUCHLAVA; - if (rover->flags & FF_GOOWATER && !(mobj->flags & MF_NOGRAVITY)) + if (rover->fofflags & FOF_GOOWATER && !(mobj->flags & MF_NOGRAVITY)) mobj->eflags |= MFE_GOOWATER; } } @@ -3567,7 +3567,7 @@ static void P_SceneryCheckWater(mobj_t *mobj) for (rover = sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS) + if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_SWIMMABLE) || rover->fofflags & FOF_BLOCKOTHERS) continue; topheight = P_GetFFloorTopZAt (rover, mobj->x, mobj->y); @@ -3613,7 +3613,7 @@ static boolean P_CameraCheckHeat(camera_t *thiscam) for (rover = sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; if (halfheight >= P_GetFFloorTopZAt(rover, thiscam->x, thiscam->y)) @@ -3643,7 +3643,7 @@ static boolean P_CameraCheckWater(camera_t *thiscam) for (rover = sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS) + if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_SWIMMABLE) || rover->fofflags & FOF_BLOCKOTHERS) continue; if (halfheight >= P_GetFFloorTopZAt(rover, thiscam->x, thiscam->y)) @@ -3807,10 +3807,10 @@ static void P_CheckCrumblingPlatforms(mobj_t *mobj) for (rover = node->m_sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; - if (!(rover->flags & FF_CRUMBLE)) + if (!(rover->fofflags & FOF_CRUMBLE)) continue; if (mobj->eflags & MFE_VERTICALFLIP) @@ -3824,7 +3824,7 @@ static void P_CheckCrumblingPlatforms(mobj_t *mobj) continue; } - EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), mobj->player, rover->alpha, !(rover->flags & FF_NORETURN)); + EV_StartCrumble(rover->master->frontsector, rover, (rover->fofflags & FOF_FLOATBOB), mobj->player, rover->alpha, !(rover->fofflags & FOF_NORETURN)); } } } @@ -3842,10 +3842,10 @@ static boolean P_MobjTouchesSectorWithWater(mobj_t *mobj) for (rover = node->m_sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; - if (!(rover->flags & FF_SWIMMABLE)) + if (!(rover->fofflags & FOF_SWIMMABLE)) continue; return true; @@ -3876,10 +3876,10 @@ static void P_CheckFloatbobPlatforms(mobj_t *mobj) for (rover = node->m_sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; - if (!(rover->flags & FF_FLOATBOB)) + if (!(rover->fofflags & FOF_FLOATBOB)) continue; @@ -4006,12 +4006,12 @@ void P_CalculatePrecipFloor(precipmobj_t *mobj) for (rover = mobjsecsubsec->ffloors; rover; rover = rover->next) { // If it exists, it'll get rained on. - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; if (precipprops[curWeather].effects & PRECIPFX_WATERPARTICLES) { - if (!(rover->flags & FF_SWIMMABLE)) + if (!(rover->fofflags & FOF_SWIMMABLE)) continue; if (setWater == false) @@ -4033,7 +4033,7 @@ void P_CalculatePrecipFloor(precipmobj_t *mobj) } else { - if (!(rover->flags & FF_BLOCKOTHERS) && !(rover->flags & FF_SWIMMABLE)) + if (!(rover->fofflags & FOF_BLOCKOTHERS) && !(rover->fofflags & FOF_SWIMMABLE)) continue; height = P_GetFFloorTopZAt(rover, mobj->x, mobj->y); @@ -10874,10 +10874,10 @@ static void P_SpawnPrecipitationAt(fixed_t basex, fixed_t basey) for (rover = precipsector->sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; - if (!(rover->flags & FF_SWIMMABLE)) + if (!(rover->fofflags & FOF_SWIMMABLE)) continue; condition = true; @@ -12756,7 +12756,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean ffloor_t *rover; for (rover = sec->ffloors; rover; rover = rover->next) { - if ((rover->flags & FF_EXISTS) && (rover->flags & FF_BLOCKOTHERS)) + if ((rover->fofflags & FOF_EXISTS) && (rover->fofflags & FOF_BLOCKOTHERS)) { if (mthing->options & MTF_OBJECTFLIP) { diff --git a/src/p_saveg.c b/src/p_saveg.c index 559deb186..91960e4d2 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1064,7 +1064,7 @@ static boolean CheckFFloorDiff(const sector_t *ss) for (rover = ss->ffloors; rover; rover = rover->next) { - if (rover->flags != rover->spawnflags + if (rover->fofflags != rover->spawnflags || rover->alpha != rover->spawnalpha) { return true; // we found an FOF that changed! @@ -1084,7 +1084,7 @@ static void ArchiveFFloors(const sector_t *ss) for (rover = ss->ffloors; rover; rover = rover->next) { fflr_diff = 0; // reset diff flags - if (rover->flags != rover->spawnflags) + if (rover->fofflags != rover->spawnflags) fflr_diff |= FD_FLAGS; if (rover->alpha != rover->spawnalpha) fflr_diff |= FD_ALPHA; @@ -1094,7 +1094,7 @@ static void ArchiveFFloors(const sector_t *ss) WRITEUINT16(save_p, j); // save ffloor "number" WRITEUINT8(save_p, fflr_diff); if (fflr_diff & FD_FLAGS) - WRITEUINT32(save_p, rover->flags); + WRITEUINT32(save_p, rover->fofflags); if (fflr_diff & FD_ALPHA) WRITEINT16(save_p, rover->alpha); } @@ -1132,7 +1132,7 @@ static void UnArchiveFFloors(const sector_t *ss) fflr_diff = READUINT8(save_p); if (fflr_diff & FD_FLAGS) - rover->flags = READUINT32(save_p); + rover->fofflags = READUINT32(save_p); if (fflr_diff & FD_ALPHA) rover->alpha = READINT16(save_p); diff --git a/src/p_setup.c b/src/p_setup.c index 696732e4e..c16751322 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1923,9 +1923,9 @@ static void P_WriteTextmap(void) freetag = Tag_NextUnused(freetag); break; case 259: - if (wlines[i].args[3] & FF_QUICKSAND) + if (wlines[i].args[3] & FOF_QUICKSAND) CONS_Alert(CONS_WARNING, M_GetText("Quicksand properties of custom FOF on linedef %s cannot be converted. Use linedef type 75 instead.\n"), sizeu1(i)); - if (wlines[i].args[3] & FF_BUSTUP) + if (wlines[i].args[3] & FOF_BUSTUP) CONS_Alert(CONS_WARNING, M_GetText("Bustable properties of custom FOF on linedef %s cannot be converted. Use linedef type 74 instead.\n"), sizeu1(i)); break; case 412: @@ -3860,67 +3860,67 @@ static INT32 P_GetFOFFlags(INT32 oldflags) { INT32 result = 0; if (oldflags & FF_OLD_EXISTS) - result |= FF_EXISTS; + result |= FOF_EXISTS; if (oldflags & FF_OLD_BLOCKPLAYER) - result |= FF_BLOCKPLAYER; + result |= FOF_BLOCKPLAYER; if (oldflags & FF_OLD_BLOCKOTHERS) - result |= FF_BLOCKOTHERS; + result |= FOF_BLOCKOTHERS; if (oldflags & FF_OLD_RENDERSIDES) - result |= FF_RENDERSIDES; + result |= FOF_RENDERSIDES; if (oldflags & FF_OLD_RENDERPLANES) - result |= FF_RENDERPLANES; + result |= FOF_RENDERPLANES; if (oldflags & FF_OLD_SWIMMABLE) - result |= FF_SWIMMABLE; + result |= FOF_SWIMMABLE; if (oldflags & FF_OLD_NOSHADE) - result |= FF_NOSHADE; + result |= FOF_NOSHADE; if (oldflags & FF_OLD_CUTSOLIDS) - result |= FF_CUTSOLIDS; + result |= FOF_CUTSOLIDS; if (oldflags & FF_OLD_CUTEXTRA) - result |= FF_CUTEXTRA; + result |= FOF_CUTEXTRA; if (oldflags & FF_OLD_CUTSPRITES) - result |= FF_CUTSPRITES; + result |= FOF_CUTSPRITES; if (oldflags & FF_OLD_BOTHPLANES) - result |= FF_BOTHPLANES; + result |= FOF_BOTHPLANES; if (oldflags & FF_OLD_EXTRA) - result |= FF_EXTRA; + result |= FOF_EXTRA; if (oldflags & FF_OLD_TRANSLUCENT) - result |= FF_TRANSLUCENT; + result |= FOF_TRANSLUCENT; if (oldflags & FF_OLD_FOG) - result |= FF_FOG; + result |= FOF_FOG; if (oldflags & FF_OLD_INVERTPLANES) - result |= FF_INVERTPLANES; + result |= FOF_INVERTPLANES; if (oldflags & FF_OLD_ALLSIDES) - result |= FF_ALLSIDES; + result |= FOF_ALLSIDES; if (oldflags & FF_OLD_INVERTSIDES) - result |= FF_INVERTSIDES; + result |= FOF_INVERTSIDES; if (oldflags & FF_OLD_DOUBLESHADOW) - result |= FF_DOUBLESHADOW; + result |= FOF_DOUBLESHADOW; if (oldflags & FF_OLD_FLOATBOB) - result |= FF_FLOATBOB; + result |= FOF_FLOATBOB; if (oldflags & FF_OLD_NORETURN) - result |= FF_NORETURN; + result |= FOF_NORETURN; if (oldflags & FF_OLD_CRUMBLE) - result |= FF_CRUMBLE; + result |= FOF_CRUMBLE; if (oldflags & FF_OLD_GOOWATER) - result |= FF_GOOWATER; + result |= FOF_GOOWATER; if (oldflags & FF_OLD_MARIO) - result |= FF_MARIO; + result |= FOF_MARIO; if (oldflags & FF_OLD_BUSTUP) - result |= FF_BUSTUP; + result |= FOF_BUSTUP; if (oldflags & FF_OLD_QUICKSAND) - result |= FF_QUICKSAND; + result |= FOF_QUICKSAND; if (oldflags & FF_OLD_PLATFORM) - result |= FF_PLATFORM; + result |= FOF_PLATFORM; if (oldflags & FF_OLD_REVERSEPLATFORM) - result |= FF_REVERSEPLATFORM; + result |= FOF_REVERSEPLATFORM; if (oldflags & FF_OLD_RIPPLE) - result |= FF_RIPPLE; + result |= FOF_RIPPLE; if (oldflags & FF_OLD_COLORMAPONLY) - result |= FF_COLORMAPONLY; + result |= FOF_COLORMAPONLY; return result; } -static INT32 P_GetFOFBustflags(INT32 oldflags) +static INT32 P_GetFOFBusttype(INT32 oldflags) { if (oldflags & FF_OLD_SHATTER) return TMFB_TOUCH; @@ -4581,17 +4581,17 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[0] = tag; lines[i].args[3] = P_GetFOFFlags(sides[lines[i].sidenum[1]].toptexture); if (lines[i].flags & ML_EFFECT6) - lines[i].args[3] |= FF_SPLAT; - lines[i].args[4] = P_GetFOFBustflags(sides[lines[i].sidenum[1]].toptexture); + lines[i].args[3] |= FOF_SPLAT; + lines[i].args[4] = P_GetFOFBusttype(sides[lines[i].sidenum[1]].toptexture); if (sides[lines[i].sidenum[1]].toptexture & FF_OLD_SHATTERBOTTOM) lines[i].args[4] |= TMFB_ONLYBOTTOM; - if (lines[i].args[3] & FF_TRANSLUCENT) + if (lines[i].args[3] & FOF_TRANSLUCENT) { P_SetBinaryFOFAlpha(&lines[i]); //Replicate old hack: Translucent FOFs set to full opacity cut cyan pixels if (lines[i].args[1] == 256) - lines[i].args[3] |= FF_SPLAT; + lines[i].args[3] |= FOF_SPLAT; } else lines[i].args[1] = 255; diff --git a/src/p_sight.c b/src/p_sight.c index aee5798c3..4a8ccab39 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -309,8 +309,8 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) // check front sector's FOFs first for (rover = front->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS) - || !(rover->flags & FF_RENDERSIDES) || rover->flags & FF_TRANSLUCENT) + if (!(rover->fofflags & FOF_EXISTS) + || !(rover->fofflags & FOF_RENDERSIDES) || (rover->fofflags & (FOF_TRANSLUCENT|FOF_FOG))) { continue; } @@ -326,8 +326,8 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) // check back sector's FOFs as well for (rover = back->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS) - || !(rover->flags & FF_RENDERSIDES) || rover->flags & FF_TRANSLUCENT) + if (!(rover->fofflags & FOF_EXISTS) + || !(rover->fofflags & FOF_RENDERSIDES) || (rover->fofflags & (FOF_TRANSLUCENT|FOF_FOG))) { continue; } @@ -456,8 +456,8 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2) // Allow sight through water, fog, etc. /// \todo Improve by checking fog density/translucency /// and setting a sight limit. - if (!(rover->flags & FF_EXISTS) - || !(rover->flags & FF_RENDERPLANES) /*|| (rover->flags & FF_TRANSLUCENT)*/) + if (!(rover->fofflags & FOF_EXISTS) + || !(rover->fofflags & FOF_RENDERPLANES) /*|| (rover->fofflags & (FOF_TRANSLUCENT|FOF_FOG))*/) { continue; } @@ -475,10 +475,10 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2) return false; } - if (rover->flags & FF_SOLID) + if (rover->fofflags & FOF_SOLID) continue; // shortcut since neither mobj can be inside the 3dfloor - if (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES)) + if (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES)) { if (los.sightzstart >= topz1 && t2->z + t2->height < topz2) return false; // blocked by upper outside plane @@ -487,7 +487,7 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2) return false; // blocked by lower outside plane } - if (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES) + if (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES) { if (los.sightzstart < topz1 && t2->z >= topz2) return false; // blocked by upper inside plane diff --git a/src/p_spec.c b/src/p_spec.c index 5e2eb4bc0..a651867ca 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2884,16 +2884,16 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) { foundrover = true; - oldflags = rover->flags; + oldflags = rover->fofflags; // Abracadabra! if (line->args[2]) - rover->flags |= FF_EXISTS; + rover->fofflags |= FOF_EXISTS; else - rover->flags &= ~FF_EXISTS; + rover->fofflags &= ~FOF_EXISTS; // if flags changed, reset sector's light list - if (rover->flags != oldflags) + if (rover->fofflags != oldflags) { sec->moved = true; P_RecalcPrecipInSector(sec); @@ -2910,7 +2910,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } break; - case 446: // Make block fall remotely (acts like FF_CRUMBLE) + case 446: // Make block fall remotely (acts like FOF_CRUMBLE) { INT16 sectag = (INT16)(line->args[0]); INT16 foftag = (INT16)(line->args[1]); @@ -2943,9 +2943,9 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) foundrover = true; if (line->args[2] & TMFR_CHECKFLAG) // FOF flags determine respawn ability instead? - respawn = !(rover->flags & FF_NORETURN) ^ !!(line->args[2] & TMFR_NORETURN); // TMFR_NORETURN inverts + respawn = !(rover->fofflags & FOF_NORETURN) ^ !!(line->args[2] & TMFR_NORETURN); // TMFR_NORETURN inverts - EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), player, rover->alpha, respawn); + EV_StartCrumble(rover->master->frontsector, rover, (rover->fofflags & FOF_FLOATBOB), player, rover->alpha, respawn); } } @@ -3143,10 +3143,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) // initialize its alpha to 1 // for relative alpha calc if (!(line->args[3] & TMST_DONTDOTRANSLUCENT) && // do translucent - (rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE - !(rover->spawnflags & FF_RENDERSIDES) && - !(rover->spawnflags & FF_RENDERPLANES) && - !(rover->flags & FF_RENDERALL)) + (rover->spawnflags & FOF_NOSHADE) && // do not include light blocks, which don't set FOF_NOSHADE + !(rover->spawnflags & FOF_RENDERSIDES) && + !(rover->spawnflags & FOF_RENDERPLANES) && + !(rover->fofflags & FOF_RENDERALL)) rover->alpha = 1; P_RemoveFakeFloorFader(rover); @@ -3155,8 +3155,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) max(1, min(256, (line->args[3] & TMST_RELATIVE) ? rover->alpha + destvalue : destvalue)), 0, // set alpha immediately false, NULL, // tic-based logic - false, // do not handle FF_EXISTS - !(line->args[3] & TMST_DONTDOTRANSLUCENT), // handle FF_TRANSLUCENT + false, // do not handle FOF_EXISTS + !(line->args[3] & TMST_DONTDOTRANSLUCENT), // handle FOF_TRANSLUCENT false, // do not handle lighting false, // do not handle colormap false, // do not handle collision @@ -3216,8 +3216,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) speed, (line->args[4] & TMFT_TICBASED), // tic-based logic (line->args[4] & TMFT_RELATIVE), // Relative destvalue - !(line->args[4] & TMFT_DONTDOEXISTS), // do not handle FF_EXISTS - !(line->args[4] & TMFT_DONTDOTRANSLUCENT), // do not handle FF_TRANSLUCENT + !(line->args[4] & TMFT_DONTDOEXISTS), // do not handle FOF_EXISTS + !(line->args[4] & TMFT_DONTDOTRANSLUCENT), // do not handle FOF_TRANSLUCENT !(line->args[4] & TMFT_DONTDOLIGHTING), // do not handle lighting !(line->args[4] & TMFT_DONTDOCOLORMAP), // do not handle colormap !(line->args[4] & TMFT_IGNORECOLLISION), // do not handle collision @@ -3229,10 +3229,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) // initialize its alpha to 1 // for relative alpha calc if (!(line->args[4] & TMFT_DONTDOTRANSLUCENT) && // do translucent - (rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE - !(rover->spawnflags & FF_RENDERSIDES) && - !(rover->spawnflags & FF_RENDERPLANES) && - !(rover->flags & FF_RENDERALL)) + (rover->spawnflags & FOF_NOSHADE) && // do not include light blocks, which don't set FOF_NOSHADE + !(rover->spawnflags & FOF_RENDERSIDES) && + !(rover->spawnflags & FOF_RENDERPLANES) && + !(rover->fofflags & FOF_RENDERALL)) rover->alpha = 1; P_RemoveFakeFloorFader(rover); @@ -3241,8 +3241,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) max(1, min(256, (line->args[4] & TMFT_RELATIVE) ? rover->alpha + destvalue : destvalue)), 0, // set alpha immediately false, NULL, // tic-based logic - !(line->args[4] & TMFT_DONTDOEXISTS), // do not handle FF_EXISTS - !(line->args[4] & TMFT_DONTDOTRANSLUCENT), // do not handle FF_TRANSLUCENT + !(line->args[4] & TMFT_DONTDOEXISTS), // do not handle FOF_EXISTS + !(line->args[4] & TMFT_DONTDOTRANSLUCENT), // do not handle FOF_TRANSLUCENT !(line->args[4] & TMFT_DONTDOLIGHTING), // do not handle lighting !(line->args[4] & TMFT_DONTDOCOLORMAP), // do not handle colormap !(line->args[4] & TMFT_IGNORECOLLISION), // do not handle collision @@ -3912,8 +3912,8 @@ boolean P_IsMobjTouching3DFloor(mobj_t *mo, ffloor_t *ffloor, sector_t *sec) fixed_t topheight = P_GetSpecialTopZ(mo, sectors + ffloor->secnum, sec); fixed_t bottomheight = P_GetSpecialBottomZ(mo, sectors + ffloor->secnum, sec); - if (((ffloor->flags & FF_BLOCKPLAYER) && mo->player) - || ((ffloor->flags & FF_BLOCKOTHERS) && !mo->player)) + if (((ffloor->fofflags & FOF_BLOCKPLAYER) && mo->player) + || ((ffloor->fofflags & FOF_BLOCKOTHERS) && !mo->player)) { // Solid 3D floor: Mobj must touch the top or bottom return P_IsMobjTouchingPlane(mo, ffloor->master->frontsector, topheight, bottomheight); @@ -3951,7 +3951,7 @@ static sector_t *P_MobjTouching3DFloorSpecial(mobj_t *mo, sector_t *sector, INT3 if (GETSECSPECIAL(rover->master->frontsector->special, section) != number) continue; - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; if (!P_IsMobjTouching3DFloor(mo, rover, sector)) @@ -3975,7 +3975,7 @@ static sector_t *P_MobjTouching3DFloorSpecialFlag(mobj_t *mo, sector_t *sector, if (!(rover->master->frontsector->specialflags & flag)) continue; - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; if (!P_IsMobjTouching3DFloor(mo, rover, sector)) @@ -4163,7 +4163,7 @@ static sector_t *P_CheckPlayer3DFloorTrigger(player_t *player, sector_t *sector, if (rover->master->frontsector->triggerer == TO_MOBJ) continue; - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; if (!Tag_Find(&sourceline->tags, rover->master->frontsector->triggertag)) @@ -4723,7 +4723,7 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector) if (!P_SectorHasSpecial(rover->master->frontsector)) continue; - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; if (!P_IsMobjTouching3DFloor(player->mo, rover, sector)) @@ -4831,7 +4831,7 @@ static void P_CheckMobj3DFloorTrigger(mobj_t *mo, sector_t *sec) if (rover->master->frontsector->triggerer != TO_MOBJ) continue; - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; if (!P_IsMobjTouching3DFloor(mo, rover, sec)) @@ -5097,7 +5097,7 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, I sec2->attachedsolid = Z_Malloc(sizeof (*sec2->attachedsolid) * sec2->maxattached, PU_STATIC, NULL); sec2->attached[0] = sec - sectors; sec2->numattached = 1; - sec2->attachedsolid[0] = (flags & FF_SOLID); + sec2->attachedsolid[0] = (flags & FOF_SOLID); } else { @@ -5112,7 +5112,7 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, I sec2->attachedsolid = Z_Realloc(sec2->attachedsolid, sizeof (*sec2->attachedsolid) * sec2->maxattached, PU_STATIC, NULL); } sec2->attached[sec2->numattached] = sec - sectors; - sec2->attachedsolid[sec2->numattached] = (flags & FF_SOLID); + sec2->attachedsolid[sec2->numattached] = (flags & FOF_SOLID); sec2->numattached++; } @@ -5142,7 +5142,7 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, I if (sec2->hasslope) sec->hasslope = true; - fflr->spawnflags = fflr->flags = flags; + fflr->spawnflags = fflr->fofflags = flags; fflr->master = master; fflr->norender = INFTICS; fflr->fadingdata = NULL; @@ -5190,10 +5190,10 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, I } fflr->alpha = max(0, min(0xff, alpha)); - if (fflr->alpha < 0xff || flags & FF_SPLAT) + if (fflr->alpha < 0xff || flags & FOF_SPLAT) { - fflr->flags |= FF_TRANSLUCENT; - fflr->spawnflags = fflr->flags; + fflr->fofflags |= FOF_TRANSLUCENT; + fflr->spawnflags = fflr->fofflags; } fflr->spawnalpha = fflr->alpha; // save for netgames @@ -5217,23 +5217,23 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, I break; } - if (flags & FF_QUICKSAND) + if (flags & FOF_QUICKSAND) CheckForQuicksand = true; - if (flags & FF_BUSTUP) + if (flags & FOF_BUSTUP) CheckForBustableBlocks = true; - if ((flags & FF_MARIO)) + if ((flags & FOF_MARIO)) { - if (!(flags & FF_GOOWATER)) // Don't change the textures of a brick block, just a question block + if (!(flags & FOF_GOOWATER)) // Don't change the textures of a brick block, just a question block P_AddBlockThinker(sec2, master); CheckForMarioBlocks = true; } - if ((flags & FF_CRUMBLE)) + if ((flags & FOF_CRUMBLE)) sec2->crumblestate = CRUMBLE_WAIT; - if ((flags & FF_FLOATBOB)) + if ((flags & FOF_FLOATBOB)) { P_AddFloatThinker(sec2, master->args[0], master); CheckForFloatBob = true; @@ -5577,14 +5577,14 @@ void T_LaserFlash(laserthink_t *flash) if (fflr->master != flash->sourceline) continue; - if (!(fflr->flags & FF_EXISTS)) + if (!(fflr->fofflags & FOF_EXISTS)) break; if (leveltime & 2) - //fflr->flags |= FF_RENDERALL; + //fflr->flags |= FOF_RENDERALL; fflr->alpha = 0xB0; else - //fflr->flags &= ~FF_RENDERALL; + //fflr->flags &= ~FOF_RENDERALL; fflr->alpha = 0x90; top = P_GetFFloorTopZAt (fflr, sector->soundorg.x, sector->soundorg.y); @@ -5730,8 +5730,8 @@ static void P_MakeFOFBouncy(line_t *paramline, line_t *masterline) if (rover->master != masterline) continue; - rover->flags |= FF_BOUNCY; - rover->spawnflags |= FF_BOUNCY; + rover->fofflags |= FOF_BOUNCY; + rover->spawnflags |= FOF_BOUNCY; rover->bouncestrength = (paramline->args[1]<< FRACBITS)/100; CheckForBouncySector = true; break; @@ -6093,117 +6093,117 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 100: // FOF (solid) - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL; + ffloorflags = FOF_EXISTS|FOF_SOLID|FOF_RENDERALL; //Appearance settings if (lines[i].args[3] & TMFA_NOPLANES) - ffloorflags &= ~FF_RENDERPLANES; + ffloorflags &= ~FOF_RENDERPLANES; if (lines[i].args[3] & TMFA_NOSIDES) - ffloorflags &= ~FF_RENDERSIDES; + ffloorflags &= ~FOF_RENDERSIDES; if (lines[i].args[3] & TMFA_INSIDES) { - if (ffloorflags & FF_RENDERPLANES) - ffloorflags |= FF_BOTHPLANES; - if (ffloorflags & FF_RENDERSIDES) - ffloorflags |= FF_ALLSIDES; + if (ffloorflags & FOF_RENDERPLANES) + ffloorflags |= FOF_BOTHPLANES; + if (ffloorflags & FOF_RENDERSIDES) + ffloorflags |= FOF_ALLSIDES; } if (lines[i].args[3] & TMFA_ONLYINSIDES) { - if (ffloorflags & FF_RENDERPLANES) - ffloorflags |= FF_INVERTPLANES; - if (ffloorflags & FF_RENDERSIDES) - ffloorflags |= FF_INVERTSIDES; + if (ffloorflags & FOF_RENDERPLANES) + ffloorflags |= FOF_INVERTPLANES; + if (ffloorflags & FOF_RENDERSIDES) + ffloorflags |= FOF_INVERTSIDES; } if (lines[i].args[3] & TMFA_NOSHADE) - ffloorflags |= FF_NOSHADE; + ffloorflags |= FOF_NOSHADE; if (lines[i].args[3] & TMFA_SPLAT) - ffloorflags |= FF_SPLAT; + ffloorflags |= FOF_SPLAT; //Tangibility settings if (lines[i].args[4] & TMFT_INTANGIBLETOP) - ffloorflags |= FF_REVERSEPLATFORM; + ffloorflags |= FOF_REVERSEPLATFORM; if (lines[i].args[4] & TMFT_INTANGIBLEBOTTOM) - ffloorflags |= FF_PLATFORM; + ffloorflags |= FOF_PLATFORM; if (lines[i].args[4] & TMFT_DONTBLOCKPLAYER) - ffloorflags &= ~FF_BLOCKPLAYER; + ffloorflags &= ~FOF_BLOCKPLAYER; if (lines[i].args[4] & TMFT_DONTBLOCKOTHERS) - ffloorflags &= ~FF_BLOCKOTHERS; + ffloorflags &= ~FOF_BLOCKOTHERS; //Cutting options - if (ffloorflags & FF_RENDERALL) + if (ffloorflags & FOF_RENDERALL) { //If translucent or player can enter it, cut inner walls if ((lines[i].args[1] < 255) || (lines[i].args[4] & TMFT_VISIBLEFROMINSIDE)) - ffloorflags |= FF_CUTEXTRA|FF_EXTRA; + ffloorflags |= FOF_CUTEXTRA|FOF_EXTRA; else - ffloorflags |= FF_CUTLEVEL; + ffloorflags |= FOF_CUTLEVEL; } P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); break; case 120: // FOF (water) - ffloorflags = FF_EXISTS|FF_RENDERPLANES|FF_SWIMMABLE|FF_BOTHPLANES|FF_CUTEXTRA|FF_EXTRA|FF_CUTSPRITES; + ffloorflags = FOF_EXISTS|FOF_RENDERPLANES|FOF_SWIMMABLE|FOF_BOTHPLANES|FOF_CUTEXTRA|FOF_EXTRA|FOF_CUTSPRITES; if (!(lines[i].args[3] & TMFW_NOSIDES)) - ffloorflags |= FF_RENDERSIDES|FF_ALLSIDES; + ffloorflags |= FOF_RENDERSIDES|FOF_ALLSIDES; if (lines[i].args[3] & TMFW_DOUBLESHADOW) - ffloorflags |= FF_DOUBLESHADOW; + ffloorflags |= FOF_DOUBLESHADOW; if (lines[i].args[3] & TMFW_COLORMAPONLY) - ffloorflags |= FF_COLORMAPONLY; + ffloorflags |= FOF_COLORMAPONLY; if (!(lines[i].args[3] & TMFW_NORIPPLE)) - ffloorflags |= FF_RIPPLE; + ffloorflags |= FOF_RIPPLE; if (lines[i].args[3] & TMFW_GOOWATER) - ffloorflags |= FF_GOOWATER; + ffloorflags |= FOF_GOOWATER; if (lines[i].args[3] & TMFW_SPLAT) - ffloorflags |= FF_SPLAT; + ffloorflags |= FOF_SPLAT; P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); break; case 150: // FOF (Air bobbing) - P_AddFakeFloorsByLine(i, 0xff, TMB_TRANSLUCENT, FF_EXISTS|FF_SOLID|FF_RENDERALL, secthinkers); + P_AddFakeFloorsByLine(i, 0xff, TMB_TRANSLUCENT, FOF_EXISTS|FOF_SOLID|FOF_RENDERALL, secthinkers); P_AddAirbob(lines[i].frontsector, lines[i].args[0], lines[i].args[1] << FRACBITS, !!(lines[i].args[2] & TMFB_REVERSE), !!(lines[i].args[2] & TMFB_SPINDASH), !!(lines[i].args[2] & TMFB_DYNAMIC)); break; case 160: // FOF (Water bobbing) - P_AddFakeFloorsByLine(i, 0xff, TMB_TRANSLUCENT, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_FLOATBOB, secthinkers); + P_AddFakeFloorsByLine(i, 0xff, TMB_TRANSLUCENT, FOF_EXISTS|FOF_SOLID|FOF_RENDERALL|FOF_FLOATBOB, secthinkers); break; case 170: // FOF (Crumbling) - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CRUMBLE; + ffloorflags = FOF_EXISTS|FOF_SOLID|FOF_RENDERALL|FOF_CRUMBLE; //Tangibility settings if (lines[i].args[3] & TMFT_INTANGIBLETOP) - ffloorflags |= FF_REVERSEPLATFORM; + ffloorflags |= FOF_REVERSEPLATFORM; if (lines[i].args[3] & TMFT_INTANGIBLEBOTTOM) - ffloorflags |= FF_PLATFORM; + ffloorflags |= FOF_PLATFORM; if (lines[i].args[3] & TMFT_DONTBLOCKPLAYER) - ffloorflags &= ~FF_BLOCKPLAYER; + ffloorflags &= ~FOF_BLOCKPLAYER; if (lines[i].args[3] & TMFT_DONTBLOCKOTHERS) - ffloorflags &= ~FF_BLOCKOTHERS; + ffloorflags &= ~FOF_BLOCKOTHERS; //Flags if (lines[i].args[4] & TMFC_NOSHADE) - ffloorflags |= FF_NOSHADE; + ffloorflags |= FOF_NOSHADE; if (lines[i].args[4] & TMFC_NORETURN) - ffloorflags |= FF_NORETURN; + ffloorflags |= FOF_NORETURN; if (lines[i].args[4] & TMFC_FLOATBOB) - ffloorflags |= FF_FLOATBOB; + ffloorflags |= FOF_FLOATBOB; if (lines[i].args[4] & TMFC_SPLAT) - ffloorflags |= FF_SPLAT; + ffloorflags |= FOF_SPLAT; //If translucent or player can enter it, cut inner walls if (lines[i].args[1] < 0xff || (lines[i].args[3] & TMFT_VISIBLEFROMINSIDE)) - ffloorflags |= FF_CUTEXTRA|FF_EXTRA; + ffloorflags |= FOF_CUTEXTRA|FOF_EXTRA; else - ffloorflags |= FF_CUTLEVEL; + ffloorflags |= FOF_CUTLEVEL; //If player can enter it, render insides if (lines[i].args[3] & TMFT_VISIBLEFROMINSIDE) { - if (ffloorflags & FF_RENDERPLANES) - ffloorflags |= FF_BOTHPLANES; - if (ffloorflags & FF_RENDERSIDES) - ffloorflags |= FF_ALLSIDES; + if (ffloorflags & FOF_RENDERPLANES) + ffloorflags |= FOF_BOTHPLANES; + if (ffloorflags & FOF_RENDERSIDES) + ffloorflags |= FOF_ALLSIDES; } P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); @@ -6216,50 +6216,50 @@ void P_SpawnSpecials(boolean fromnetsave) fixed_t ceilingtop = P_FindHighestCeilingSurrounding(lines[i].frontsector); fixed_t ceilingbottom = P_FindLowestCeilingSurrounding(lines[i].frontsector); - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL; + ffloorflags = FOF_EXISTS|FOF_SOLID|FOF_RENDERALL; //Appearance settings if (lines[i].args[3] & TMFA_NOPLANES) - ffloorflags &= ~FF_RENDERPLANES; + ffloorflags &= ~FOF_RENDERPLANES; if (lines[i].args[3] & TMFA_NOSIDES) - ffloorflags &= ~FF_RENDERSIDES; + ffloorflags &= ~FOF_RENDERSIDES; if (lines[i].args[3] & TMFA_INSIDES) { - if (ffloorflags & FF_RENDERPLANES) - ffloorflags |= FF_BOTHPLANES; - if (ffloorflags & FF_RENDERSIDES) - ffloorflags |= FF_ALLSIDES; + if (ffloorflags & FOF_RENDERPLANES) + ffloorflags |= FOF_BOTHPLANES; + if (ffloorflags & FOF_RENDERSIDES) + ffloorflags |= FOF_ALLSIDES; } if (lines[i].args[3] & TMFA_ONLYINSIDES) { - if (ffloorflags & FF_RENDERPLANES) - ffloorflags |= FF_INVERTPLANES; - if (ffloorflags & FF_RENDERSIDES) - ffloorflags |= FF_INVERTSIDES; + if (ffloorflags & FOF_RENDERPLANES) + ffloorflags |= FOF_INVERTPLANES; + if (ffloorflags & FOF_RENDERSIDES) + ffloorflags |= FOF_INVERTSIDES; } if (lines[i].args[3] & TMFA_NOSHADE) - ffloorflags |= FF_NOSHADE; + ffloorflags |= FOF_NOSHADE; if (lines[i].args[3] & TMFA_SPLAT) - ffloorflags |= FF_SPLAT; + ffloorflags |= FOF_SPLAT; //Tangibility settings if (lines[i].args[4] & TMFT_INTANGIBLETOP) - ffloorflags |= FF_REVERSEPLATFORM; + ffloorflags |= FOF_REVERSEPLATFORM; if (lines[i].args[4] & TMFT_INTANGIBLEBOTTOM) - ffloorflags |= FF_PLATFORM; + ffloorflags |= FOF_PLATFORM; if (lines[i].args[4] & TMFT_DONTBLOCKPLAYER) - ffloorflags &= ~FF_BLOCKPLAYER; + ffloorflags &= ~FOF_BLOCKPLAYER; if (lines[i].args[4] & TMFT_DONTBLOCKOTHERS) - ffloorflags &= ~FF_BLOCKOTHERS; + ffloorflags &= ~FOF_BLOCKOTHERS; //Cutting options - if (ffloorflags & FF_RENDERALL) + if (ffloorflags & FOF_RENDERALL) { //If translucent or player can enter it, cut inner walls if ((lines[i].args[1] < 255) || (lines[i].args[4] & TMFT_VISIBLEFROMINSIDE)) - ffloorflags |= FF_CUTEXTRA|FF_EXTRA; + ffloorflags |= FOF_CUTEXTRA|FOF_EXTRA; else - ffloorflags |= FF_CUTLEVEL; + ffloorflags |= FOF_CUTLEVEL; } P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); @@ -6267,14 +6267,14 @@ void P_SpawnSpecials(boolean fromnetsave) break; } case 200: // Light block - ffloorflags = FF_EXISTS|FF_CUTSPRITES; + ffloorflags = FOF_EXISTS|FOF_CUTSPRITES; if (!lines[i].args[1]) - ffloorflags |= FF_DOUBLESHADOW; + ffloorflags |= FOF_DOUBLESHADOW; P_AddFakeFloorsByLine(i, 0xff, TMB_TRANSLUCENT, ffloorflags, secthinkers); break; case 202: // Fog - ffloorflags = FF_EXISTS|FF_RENDERALL|FF_FOG|FF_INVERTPLANES|FF_INVERTSIDES|FF_CUTEXTRA|FF_EXTRA|FF_DOUBLESHADOW|FF_CUTSPRITES; + ffloorflags = FOF_EXISTS|FOF_RENDERALL|FOF_FOG|FOF_INVERTPLANES|FOF_INVERTSIDES|FOF_CUTEXTRA|FOF_EXTRA|FOF_DOUBLESHADOW|FOF_CUTSPRITES; sec = sides[*lines[i].sidenum].sector - sectors; // SoM: Because it's fog, check for an extra colormap and set the fog flag... if (sectors[sec].extra_colormap) @@ -6283,45 +6283,45 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 220: //Intangible - ffloorflags = FF_EXISTS|FF_RENDERALL|FF_CUTEXTRA|FF_EXTRA|FF_CUTSPRITES; + ffloorflags = FOF_EXISTS|FOF_RENDERALL|FOF_CUTEXTRA|FOF_EXTRA|FOF_CUTSPRITES; //Appearance settings if (lines[i].args[3] & TMFA_NOPLANES) - ffloorflags &= ~FF_RENDERPLANES; + ffloorflags &= ~FOF_RENDERPLANES; if (lines[i].args[3] & TMFA_NOSIDES) - ffloorflags &= ~FF_RENDERSIDES; + ffloorflags &= ~FOF_RENDERSIDES; if (!(lines[i].args[3] & TMFA_INSIDES)) { - if (ffloorflags & FF_RENDERPLANES) - ffloorflags |= FF_BOTHPLANES; - if (ffloorflags & FF_RENDERSIDES) - ffloorflags |= FF_ALLSIDES; + if (ffloorflags & FOF_RENDERPLANES) + ffloorflags |= FOF_BOTHPLANES; + if (ffloorflags & FOF_RENDERSIDES) + ffloorflags |= FOF_ALLSIDES; } if (lines[i].args[3] & TMFA_ONLYINSIDES) { - if (ffloorflags & FF_RENDERPLANES) - ffloorflags |= FF_INVERTPLANES; - if (ffloorflags & FF_RENDERSIDES) - ffloorflags |= FF_INVERTSIDES; + if (ffloorflags & FOF_RENDERPLANES) + ffloorflags |= FOF_INVERTPLANES; + if (ffloorflags & FOF_RENDERSIDES) + ffloorflags |= FOF_INVERTSIDES; } if (lines[i].args[3] & TMFA_NOSHADE) - ffloorflags |= FF_NOSHADE; + ffloorflags |= FOF_NOSHADE; if (lines[i].args[3] & TMFA_SPLAT) - ffloorflags |= FF_SPLAT; + ffloorflags |= FOF_SPLAT; P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); break; case 223: // FOF (intangible, invisible) - for combining specials in a sector - P_AddFakeFloorsByLine(i, 0xff, TMB_TRANSLUCENT, FF_EXISTS|FF_NOSHADE, secthinkers); + P_AddFakeFloorsByLine(i, 0xff, TMB_TRANSLUCENT, FOF_EXISTS|FOF_NOSHADE, secthinkers); break; case 250: // Mario Block - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_MARIO; + ffloorflags = FOF_EXISTS|FOF_SOLID|FOF_RENDERALL|FOF_CUTLEVEL|FOF_MARIO; if (lines[i].args[1] & TMFM_BRICK) - ffloorflags |= FF_GOOWATER; + ffloorflags |= FOF_GOOWATER; if (lines[i].args[1] & TMFM_INVISIBLE) - ffloorflags &= ~(FF_SOLID|FF_RENDERALL|FF_CUTLEVEL); + ffloorflags &= ~(FOF_SOLID|FOF_RENDERALL|FOF_CUTLEVEL); P_AddFakeFloorsByLine(i, 0xff, TMB_TRANSLUCENT, ffloorflags, secthinkers); break; @@ -6330,7 +6330,7 @@ void P_SpawnSpecials(boolean fromnetsave) { UINT16 sound = (lines[i].stringargs[0]) ? get_number(lines[i].stringargs[0]) : sfx_thwomp; P_AddThwompThinker(lines[i].frontsector, &lines[i], lines[i].args[1] << (FRACBITS - 3), lines[i].args[2] << (FRACBITS - 3), sound); - P_AddFakeFloorsByLine(i, 0xff, TMB_TRANSLUCENT, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); + P_AddFakeFloorsByLine(i, 0xff, TMB_TRANSLUCENT, FOF_EXISTS|FOF_SOLID|FOF_RENDERALL|FOF_CUTLEVEL, secthinkers); break; } @@ -6339,7 +6339,7 @@ void P_SpawnSpecials(boolean fromnetsave) UINT8 busttype = BT_REGULAR; ffloorbustflags_e bustflags = 0; - ffloorflags = FF_EXISTS|FF_BLOCKOTHERS|FF_RENDERALL|FF_BUSTUP; + ffloorflags = FOF_EXISTS|FOF_BLOCKOTHERS|FOF_RENDERALL|FOF_BUSTUP; //Bustable type switch (lines[i].args[3]) @@ -6366,10 +6366,10 @@ void P_SpawnSpecials(boolean fromnetsave) if (lines[i].args[4] & TMFB_ONLYBOTTOM) bustflags |= FB_ONLYBOTTOM; if (lines[i].args[4] & TMFB_SPLAT) - ffloorflags |= FF_SPLAT; + ffloorflags |= FOF_SPLAT; if (busttype != BT_TOUCH || bustflags & FB_ONLYBOTTOM) - ffloorflags |= FF_BLOCKPLAYER; + ffloorflags |= FOF_BLOCKPLAYER; TAG_ITER_SECTORS(lines[i].args[0], s) { @@ -6383,9 +6383,9 @@ void P_SpawnSpecials(boolean fromnetsave) break; } case 257: // Quicksand - ffloorflags = FF_EXISTS|FF_QUICKSAND|FF_RENDERALL|FF_ALLSIDES|FF_CUTSPRITES; + ffloorflags = FOF_EXISTS|FOF_QUICKSAND|FOF_RENDERALL|FOF_ALLSIDES|FOF_CUTSPRITES; if (!(lines[i].args[1])) - ffloorflags |= FF_RIPPLE; + ffloorflags |= FOF_RIPPLE; TAG_ITER_SECTORS(lines[i].args[0], s) { @@ -6398,10 +6398,10 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 258: // Laser block - ffloorflags = FF_EXISTS|FF_RENDERALL|FF_NOSHADE|FF_EXTRA|FF_CUTEXTRA|FF_TRANSLUCENT; + ffloorflags = FOF_EXISTS|FOF_RENDERALL|FOF_NOSHADE|FOF_EXTRA|FOF_CUTEXTRA|FOF_TRANSLUCENT; P_AddLaserThinker(lines[i].args[0], lines + i, !!(lines[i].args[3] & TMFL_NOBOSSES)); if (lines[i].args[3] & TMFL_SPLAT) - ffloorflags |= FF_SPLAT; + ffloorflags |= FOF_SPLAT; P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); break; @@ -6413,12 +6413,12 @@ void P_SpawnSpecials(boolean fromnetsave) continue; if (!udmf) // Ugly backwards compatibility stuff { - if (lines[i].args[3] & FF_QUICKSAND) + if (lines[i].args[3] & FOF_QUICKSAND) { fflr->sinkspeed = abs(lines[i].dx) >> 1; fflr->friction = abs(lines[i].dy) >> 6; } - if (lines[i].args[3] & FF_BUSTUP) + if (lines[i].args[3] & FOF_BUSTUP) { switch (lines[i].args[4] % TMFB_ONLYBOTTOM) { @@ -6461,31 +6461,31 @@ void P_SpawnSpecials(boolean fromnetsave) if (dtype == 0) dtype = 1; - ffloorflags = FF_EXISTS; + ffloorflags = FOF_EXISTS; - if (dflags2 & 1) ffloorflags |= FF_NOSHADE; // Disable light effects (Means no shadowcast) - if (dflags2 & 2) ffloorflags |= FF_DOUBLESHADOW; // Restrict light inside (Means doubleshadow) + if (dflags2 & 1) ffloorflags |= FOF_NOSHADE; // Disable light effects (Means no shadowcast) + if (dflags2 & 2) ffloorflags |= FOF_DOUBLESHADOW; // Restrict light inside (Means doubleshadow) if (dflags2 & 4) isfog = true; // Fog effect (Explicitly render like a fog block) - if (dflags1 & 4) ffloorflags |= FF_BOTHPLANES|FF_ALLSIDES; // Render-inside - if (dflags1 & 16) ffloorflags |= FF_INVERTSIDES|FF_INVERTPLANES; // Invert visibility rules + if (dflags1 & 4) ffloorflags |= FOF_BOTHPLANES|FOF_ALLSIDES; // Render-inside + if (dflags1 & 16) ffloorflags |= FOF_INVERTSIDES|FOF_INVERTPLANES; // Invert visibility rules // Fog block if (isfog) - ffloorflags |= FF_RENDERALL|FF_CUTEXTRA|FF_CUTSPRITES|FF_BOTHPLANES|FF_EXTRA|FF_FOG|FF_INVERTPLANES|FF_ALLSIDES|FF_INVERTSIDES; + ffloorflags |= FOF_RENDERALL|FOF_CUTEXTRA|FOF_CUTSPRITES|FOF_BOTHPLANES|FOF_EXTRA|FOF_FOG|FOF_INVERTPLANES|FOF_ALLSIDES|FOF_INVERTSIDES; else { - ffloorflags |= FF_RENDERALL; + ffloorflags |= FOF_RENDERALL; // Solid if (dtype == 1) - ffloorflags |= FF_SOLID|FF_CUTLEVEL; + ffloorflags |= FOF_SOLID|FOF_CUTLEVEL; // Water else if (dtype == 2) - ffloorflags |= FF_SWIMMABLE|FF_CUTEXTRA|FF_CUTSPRITES|FF_EXTRA|FF_RIPPLE; + ffloorflags |= FOF_SWIMMABLE|FOF_CUTEXTRA|FOF_CUTSPRITES|FOF_EXTRA|FOF_RIPPLE; // Intangible else if (dtype == 3) - ffloorflags |= FF_CUTEXTRA|FF_CUTSPRITES|FF_EXTRA; + ffloorflags |= FOF_CUTEXTRA|FOF_CUTSPRITES|FOF_EXTRA; } // Non-opaque @@ -6495,19 +6495,19 @@ void P_SpawnSpecials(boolean fromnetsave) if (dopacity == 0) { // True invisible - if (ffloorflags & FF_NOSHADE) - ffloorflags &= ~(FF_RENDERALL|FF_CUTEXTRA|FF_CUTSPRITES|FF_EXTRA|FF_BOTHPLANES|FF_ALLSIDES|FF_CUTLEVEL); + if (ffloorflags & FOF_NOSHADE) + ffloorflags &= ~(FOF_RENDERALL|FOF_CUTEXTRA|FOF_CUTSPRITES|FOF_EXTRA|FOF_BOTHPLANES|FOF_ALLSIDES|FOF_CUTLEVEL); // Shadow block else { - ffloorflags |= FF_CUTSPRITES; - ffloorflags &= ~(FF_RENDERALL|FF_CUTEXTRA|FF_EXTRA|FF_BOTHPLANES|FF_ALLSIDES|FF_CUTLEVEL); + ffloorflags |= FOF_CUTSPRITES; + ffloorflags &= ~(FOF_RENDERALL|FOF_CUTEXTRA|FOF_EXTRA|FOF_BOTHPLANES|FOF_ALLSIDES|FOF_CUTLEVEL); } } else { - ffloorflags |= FF_TRANSLUCENT|FF_CUTEXTRA|FF_EXTRA; - ffloorflags &= ~FF_CUTLEVEL; + ffloorflags |= FOF_TRANSLUCENT|FOF_CUTEXTRA|FOF_EXTRA; + ffloorflags &= ~FOF_CUTLEVEL; } } @@ -6699,8 +6699,8 @@ void P_SpawnSpecials(boolean fromnetsave) if (rover->master != lines + l) continue; - rover->flags |= FF_BUSTUP; - rover->spawnflags |= FF_BUSTUP; + rover->fofflags |= FOF_BUSTUP; + rover->spawnflags |= FOF_BUSTUP; rover->bustflags = bustflags; rover->busttype = busttype; rover->busttag = lines[i].args[3]; @@ -6730,8 +6730,8 @@ void P_SpawnSpecials(boolean fromnetsave) if (rover->master != lines + l) continue; - rover->flags |= FF_QUICKSAND; - rover->spawnflags |= FF_QUICKSAND; + rover->fofflags |= FOF_QUICKSAND; + rover->spawnflags |= FOF_QUICKSAND; rover->sinkspeed = abs(lines[i].args[1]) << (FRACBITS - 1); rover->friction = abs(lines[i].args[2]) << (FRACBITS - 6); CheckForQuicksand = true; @@ -7001,7 +7001,7 @@ void T_Scroll(scroll_t *s) if (!rover) // This should be impossible, but don't complain if it is the case somehow continue; - if (!(rover->flags & FF_EXISTS)) // If the FOF does not "exist", we pretend that nobody's there + if (!(rover->fofflags & FOF_EXISTS)) // If the FOF does not "exist", we pretend that nobody's there continue; for (node = psec->touching_thinglist; node; node = node->m_thinglist_next) @@ -7076,7 +7076,7 @@ void T_Scroll(scroll_t *s) if (!rover) // This should be impossible, but don't complain if it is the case somehow continue; - if (!(rover->flags & FF_EXISTS)) // If the FOF does not "exist", we pretend that nobody's there + if (!(rover->fofflags & FOF_EXISTS)) // If the FOF does not "exist", we pretend that nobody's there continue; for (node = psec->touching_thinglist; node; node = node->m_thinglist_next) @@ -7315,10 +7315,10 @@ void T_Disappear(disappear_t *d) continue; if (d->exists) - rover->flags &= ~FF_EXISTS; + rover->fofflags &= ~FOF_EXISTS; else { - rover->flags |= FF_EXISTS; + rover->fofflags |= FOF_EXISTS; if (!(lines[d->sourceline].args[5])) { @@ -7403,11 +7403,11 @@ static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 sourcevalue, INT16 destval // If fading an invisible FOF whose render flags we did not yet set, // initialize its alpha to 1 if (dotranslucent && - (rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE - !(rover->flags & FF_FOG) && // do not include fog - !(rover->spawnflags & FF_RENDERSIDES) && - !(rover->spawnflags & FF_RENDERPLANES) && - !(rover->flags & FF_RENDERALL)) + (rover->spawnflags & FOF_NOSHADE) && // do not include light blocks, which don't set FOF_NOSHADE + !(rover->fofflags & FOF_FOG) && // do not include fog + !(rover->spawnflags & FOF_RENDERSIDES) && + !(rover->spawnflags & FOF_RENDERPLANES) && + !(rover->fofflags & FOF_RENDERALL)) rover->alpha = 1; if (fadingdata) @@ -7428,16 +7428,16 @@ static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 sourcevalue, INT16 destval if (docollision) { - if (rover->spawnflags & FF_SOLID) - rover->flags &= ~FF_SOLID; - if (rover->spawnflags & FF_SWIMMABLE) - rover->flags &= ~FF_SWIMMABLE; - if (rover->spawnflags & FF_QUICKSAND) - rover->flags &= ~FF_QUICKSAND; - if (rover->spawnflags & FF_BUSTUP) - rover->flags &= ~FF_BUSTUP; - if (rover->spawnflags & FF_MARIO) - rover->flags &= ~FF_MARIO; + if (rover->spawnflags & FOF_SOLID) + rover->fofflags &= ~FOF_SOLID; + if (rover->spawnflags & FOF_SWIMMABLE) + rover->fofflags &= ~FOF_SWIMMABLE; + if (rover->spawnflags & FOF_QUICKSAND) + rover->fofflags &= ~FOF_QUICKSAND; + if (rover->spawnflags & FOF_BUSTUP) + rover->fofflags &= ~FOF_BUSTUP; + if (rover->spawnflags & FOF_MARIO) + rover->fofflags &= ~FOF_MARIO; } } else // continue fading out @@ -7463,16 +7463,16 @@ static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 sourcevalue, INT16 destval if (docollision) { - if (rover->spawnflags & FF_SOLID) - rover->flags |= FF_SOLID; - if (rover->spawnflags & FF_SWIMMABLE) - rover->flags |= FF_SWIMMABLE; - if (rover->spawnflags & FF_QUICKSAND) - rover->flags |= FF_QUICKSAND; - if (rover->spawnflags & FF_BUSTUP) - rover->flags |= FF_BUSTUP; - if (rover->spawnflags & FF_MARIO) - rover->flags |= FF_MARIO; + if (rover->spawnflags & FOF_SOLID) + rover->fofflags |= FOF_SOLID; + if (rover->spawnflags & FOF_SWIMMABLE) + rover->fofflags |= FOF_SWIMMABLE; + if (rover->spawnflags & FOF_QUICKSAND) + rover->fofflags |= FOF_QUICKSAND; + if (rover->spawnflags & FOF_BUSTUP) + rover->fofflags |= FOF_BUSTUP; + if (rover->spawnflags & FOF_MARIO) + rover->fofflags |= FOF_MARIO; } } else // continue fading in @@ -7492,114 +7492,114 @@ static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 sourcevalue, INT16 destval // routines common to both fade in and fade out if (!stillfading) { - if (doexists && !(rover->spawnflags & FF_BUSTUP)) + if (doexists && !(rover->spawnflags & FOF_BUSTUP)) { if (alpha <= 1) - rover->flags &= ~FF_EXISTS; + rover->fofflags &= ~FOF_EXISTS; else - rover->flags |= FF_EXISTS; + rover->fofflags |= FOF_EXISTS; // Re-render lighting at end of fade - if (dolighting && !(rover->spawnflags & FF_NOSHADE) && !(rover->flags & FF_EXISTS)) + if (dolighting && !(rover->spawnflags & FOF_NOSHADE) && !(rover->fofflags & FOF_EXISTS)) rover->target->moved = true; } - if (dotranslucent && !(rover->flags & FF_FOG)) + if (dotranslucent && !(rover->fofflags & FOF_FOG)) { if (alpha >= 256) { - if (!(rover->flags & FF_CUTSOLIDS) && - (rover->spawnflags & FF_CUTSOLIDS)) + if (!(rover->fofflags & FOF_CUTSOLIDS) && + (rover->spawnflags & FOF_CUTSOLIDS)) { - rover->flags |= FF_CUTSOLIDS; + rover->fofflags |= FOF_CUTSOLIDS; rover->target->moved = true; } - rover->flags &= ~FF_TRANSLUCENT; + rover->fofflags &= ~FOF_TRANSLUCENT; } else { - rover->flags |= FF_TRANSLUCENT; + rover->fofflags |= FOF_TRANSLUCENT; - if ((rover->flags & FF_CUTSOLIDS) && - (rover->spawnflags & FF_CUTSOLIDS)) + if ((rover->fofflags & FOF_CUTSOLIDS) && + (rover->spawnflags & FOF_CUTSOLIDS)) { - rover->flags &= ~FF_CUTSOLIDS; + rover->fofflags &= ~FOF_CUTSOLIDS; rover->target->moved = true; } } - if ((rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE - !(rover->spawnflags & FF_RENDERSIDES) && - !(rover->spawnflags & FF_RENDERPLANES)) + if ((rover->spawnflags & FOF_NOSHADE) && // do not include light blocks, which don't set FOF_NOSHADE + !(rover->spawnflags & FOF_RENDERSIDES) && + !(rover->spawnflags & FOF_RENDERPLANES)) { if (rover->alpha > 1) - rover->flags |= FF_RENDERALL; + rover->fofflags |= FOF_RENDERALL; else - rover->flags &= ~FF_RENDERALL; + rover->fofflags &= ~FOF_RENDERALL; } } } else { - if (doexists && !(rover->spawnflags & FF_BUSTUP)) + if (doexists && !(rover->spawnflags & FOF_BUSTUP)) { - // Re-render lighting if we haven't yet set FF_EXISTS (beginning of fade) - if (dolighting && !(rover->spawnflags & FF_NOSHADE) && !(rover->flags & FF_EXISTS)) + // Re-render lighting if we haven't yet set FOF_EXISTS (beginning of fade) + if (dolighting && !(rover->spawnflags & FOF_NOSHADE) && !(rover->fofflags & FOF_EXISTS)) rover->target->moved = true; - rover->flags |= FF_EXISTS; + rover->fofflags |= FOF_EXISTS; } - if (dotranslucent && !(rover->flags & FF_FOG)) + if (dotranslucent && !(rover->fofflags & FOF_FOG)) { - rover->flags |= FF_TRANSLUCENT; + rover->fofflags |= FOF_TRANSLUCENT; - if ((rover->flags & FF_CUTSOLIDS) && - (rover->spawnflags & FF_CUTSOLIDS)) + if ((rover->fofflags & FOF_CUTSOLIDS) && + (rover->spawnflags & FOF_CUTSOLIDS)) { - rover->flags &= ~FF_CUTSOLIDS; + rover->fofflags &= ~FOF_CUTSOLIDS; rover->target->moved = true; } - if ((rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE - !(rover->spawnflags & FF_RENDERSIDES) && - !(rover->spawnflags & FF_RENDERPLANES)) - rover->flags |= FF_RENDERALL; + if ((rover->spawnflags & FOF_NOSHADE) && // do not include light blocks, which don't set FOF_NOSHADE + !(rover->spawnflags & FOF_RENDERSIDES) && + !(rover->spawnflags & FOF_RENDERPLANES)) + rover->fofflags |= FOF_RENDERALL; } if (docollision) { if (doghostfade) // remove collision flags during fade { - if (rover->spawnflags & FF_SOLID) - rover->flags &= ~FF_SOLID; - if (rover->spawnflags & FF_SWIMMABLE) - rover->flags &= ~FF_SWIMMABLE; - if (rover->spawnflags & FF_QUICKSAND) - rover->flags &= ~FF_QUICKSAND; - if (rover->spawnflags & FF_BUSTUP) - rover->flags &= ~FF_BUSTUP; - if (rover->spawnflags & FF_MARIO) - rover->flags &= ~FF_MARIO; + if (rover->spawnflags & FOF_SOLID) + rover->fofflags &= ~FOF_SOLID; + if (rover->spawnflags & FOF_SWIMMABLE) + rover->fofflags &= ~FOF_SWIMMABLE; + if (rover->spawnflags & FOF_QUICKSAND) + rover->fofflags &= ~FOF_QUICKSAND; + if (rover->spawnflags & FOF_BUSTUP) + rover->fofflags &= ~FOF_BUSTUP; + if (rover->spawnflags & FOF_MARIO) + rover->fofflags &= ~FOF_MARIO; } else // keep collision during fade { - if (rover->spawnflags & FF_SOLID) - rover->flags |= FF_SOLID; - if (rover->spawnflags & FF_SWIMMABLE) - rover->flags |= FF_SWIMMABLE; - if (rover->spawnflags & FF_QUICKSAND) - rover->flags |= FF_QUICKSAND; - if (rover->spawnflags & FF_BUSTUP) - rover->flags |= FF_BUSTUP; - if (rover->spawnflags & FF_MARIO) - rover->flags |= FF_MARIO; + if (rover->spawnflags & FOF_SOLID) + rover->fofflags |= FOF_SOLID; + if (rover->spawnflags & FOF_SWIMMABLE) + rover->fofflags |= FOF_SWIMMABLE; + if (rover->spawnflags & FOF_QUICKSAND) + rover->fofflags |= FOF_QUICKSAND; + if (rover->spawnflags & FOF_BUSTUP) + rover->fofflags |= FOF_BUSTUP; + if (rover->spawnflags & FOF_MARIO) + rover->fofflags |= FOF_MARIO; } } } - if (!(rover->flags & FF_FOG)) // don't set FOG alpha + if (!(rover->fofflags & FOF_FOG)) // don't set FOG alpha { if (!stillfading || exactalpha) rover->alpha = alpha; @@ -7642,8 +7642,8 @@ static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 sourcevalue, INT16 destval * \param speed speed to fade by * \param ticbased tic-based logic, speed = duration * \param relative Destvalue is relative to rover->alpha - * \param doexists handle FF_EXISTS - * \param dotranslucent handle FF_TRANSLUCENT + * \param doexists handle FOF_EXISTS + * \param dotranslucent handle FOF_TRANSLUCENT * \param dolighting fade FOF light * \param docollision handle interactive flags * \param doghostfade no interactive flags during fading @@ -7659,10 +7659,10 @@ static void P_AddFakeFloorFader(ffloor_t *rover, size_t sectornum, size_t ffloor // If fading an invisible FOF whose render flags we did not yet set, // initialize its alpha to 1 if (dotranslucent && - (rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE - !(rover->spawnflags & FF_RENDERSIDES) && - !(rover->spawnflags & FF_RENDERPLANES) && - !(rover->flags & FF_RENDERALL)) + (rover->spawnflags & FOF_NOSHADE) && // do not include light blocks, which don't set FOF_NOSHADE + !(rover->spawnflags & FOF_RENDERSIDES) && + !(rover->spawnflags & FOF_RENDERPLANES) && + !(rover->fofflags & FOF_RENDERALL)) rover->alpha = 1; // already equal, nothing to do @@ -7703,7 +7703,7 @@ static void P_AddFakeFloorFader(ffloor_t *rover, size_t sectornum, size_t ffloor P_ResetFakeFloorFader(rover, d, false); // Set a separate thinker for shadow fading - if (dolighting && !(rover->flags & FF_NOSHADE)) + if (dolighting && !(rover->fofflags & FOF_NOSHADE)) { UINT16 lightdelta = abs(sectors[rover->secnum].spawn_lightlevel - rover->target->lightlevel); fixed_t alphapercent = min(FixedDiv(d->destvalue, rover->spawnalpha), 1*FRACUNIT); // don't make darker than spawn_lightlevel @@ -7724,7 +7724,7 @@ static void P_AddFakeFloorFader(ffloor_t *rover, size_t sectornum, size_t ffloor d->destlightlevel = -1; // Set a separate thinker for colormap fading - if (docolormap && !(rover->flags & FF_NOSHADE) && sectors[rover->secnum].spawn_extra_colormap && !sectors[rover->secnum].colormap_protected) + if (docolormap && !(rover->fofflags & FOF_NOSHADE) && sectors[rover->secnum].spawn_extra_colormap && !sectors[rover->secnum].colormap_protected) { extracolormap_t *dest_exc, *source_exc = sectors[rover->secnum].extra_colormap ? sectors[rover->secnum].extra_colormap : R_GetDefaultColormap(); @@ -7785,11 +7785,11 @@ void T_Fade(fade_t *d) d->doexists, d->dotranslucent, d->dolighting, d->docolormap, d->docollision, d->doghostfade, d->exactalpha)) { // Finalize lighting, copypasta from P_AddFakeFloorFader - if (d->dolighting && !(d->rover->flags & FF_NOSHADE) && d->destlightlevel > -1) + if (d->dolighting && !(d->rover->fofflags & FOF_NOSHADE) && d->destlightlevel > -1) sectors[d->rover->secnum].lightlevel = d->destlightlevel; // Finalize colormap - if (d->docolormap && !(d->rover->flags & FF_NOSHADE) && sectors[d->rover->secnum].spawn_extra_colormap) + if (d->docolormap && !(d->rover->fofflags & FOF_NOSHADE) && sectors[d->rover->secnum].spawn_extra_colormap) sectors[d->rover->secnum].extra_colormap = d->dest_exc; P_RemoveFakeFloorFader(d->rover); diff --git a/src/p_spec.h b/src/p_spec.h index 8578fa8ea..08aa6016b 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -1032,8 +1032,8 @@ typedef struct INT16 speed; ///< Speed to fade by boolean ticbased; ///< Tic-based logic toggle INT32 timer; ///< Timer for tic-based logic - boolean doexists; ///< Handle FF_EXISTS - boolean dotranslucent; ///< Handle FF_TRANSLUCENT + 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 diff --git a/src/p_user.c b/src/p_user.c index e8f84d744..32ebe3098 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -979,20 +979,20 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec) for (rover = sec->ffloors; rover; rover = rover->next) { // If the FOF doesn't exist, continue. - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; // If the FOF is configured to let the object through, continue. - if (!((rover->flags & FF_BLOCKPLAYER && mo->player) - || (rover->flags & FF_BLOCKOTHERS && !mo->player))) + if (!((rover->fofflags & FOF_BLOCKPLAYER && mo->player) + || (rover->fofflags & FOF_BLOCKOTHERS && !mo->player))) continue; // If the the platform is intangible from below, continue. - if (rover->flags & FF_PLATFORM) + if (rover->fofflags & FOF_PLATFORM) continue; // If the FOF is a water block, continue. (Unnecessary check?) - if (rover->flags & FF_SWIMMABLE) + if (rover->fofflags & FOF_SWIMMABLE) continue; // Actually check if the player is on the suitable FOF. @@ -1013,20 +1013,20 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec) for (rover = sec->ffloors; rover; rover = rover->next) { // If the FOF doesn't exist, continue. - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; // If the FOF is configured to let the object through, continue. - if (!((rover->flags & FF_BLOCKPLAYER && mo->player) - || (rover->flags & FF_BLOCKOTHERS && !mo->player))) + if (!((rover->fofflags & FOF_BLOCKPLAYER && mo->player) + || (rover->fofflags & FOF_BLOCKOTHERS && !mo->player))) continue; // If the the platform is intangible from above, continue. - if (rover->flags & FF_REVERSEPLATFORM) + if (rover->fofflags & FOF_REVERSEPLATFORM) continue; // If the FOF is a water block, continue. (Unnecessary check?) - if (rover->flags & FF_SWIMMABLE) + if (rover->fofflags & FOF_SWIMMABLE) continue; // Actually check if the player is on the suitable FOF. @@ -1395,10 +1395,10 @@ boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand for (rover = sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; - if (!(rover->flags & FF_QUICKSAND)) + if (!(rover->fofflags & FOF_QUICKSAND)) continue; topheight = P_GetFFloorTopZAt (rover, mo->x, mo->y); @@ -1550,104 +1550,78 @@ static void P_CheckBouncySectors(player_t *player) for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next) { + ffloor_t *rover; + if (!node->m_sector) break; - if (node->m_sector->ffloors) + if (!node->m_sector->ffloors) + continue; + + for (rover = node->m_sector->ffloors; rover; rover = rover->next) { - ffloor_t *rover; - boolean top = true; fixed_t topheight, bottomheight; - for (rover = node->m_sector->ffloors; rover; rover = rover->next) + if (!(rover->fofflags & FOF_EXISTS)) + continue; // FOFs should not be bouncy if they don't even "exist" + + // Handle deprecated bouncy FOF sector type + if (!udmf && GETSECSPECIAL(rover->master->frontsector->special, 1) == 15) { - if (!(rover->flags & FF_EXISTS)) - continue; // FOFs should not be bouncy if they don't even "exist" - - if (GETSECSPECIAL(rover->master->frontsector->special, 1) != 15) - continue; // this sector type is required for FOFs to be bouncy - - topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); - bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); - - if (player->mo->z > topheight) - continue; - - if (player->mo->z + player->mo->height < bottomheight) - continue; - - if (oldz < P_GetFOFTopZ(player->mo, node->m_sector, rover, oldx, oldy, NULL) - && oldz + player->mo->height > P_GetFOFBottomZ(player->mo, node->m_sector, rover, oldx, oldy, NULL)) - top = false; - - { - fixed_t linedist; - - linedist = P_AproxDistance(rover->master->v1->x-rover->master->v2->x, rover->master->v1->y-rover->master->v2->y); - - linedist = FixedDiv(linedist,100*FRACUNIT); - - if (top) - { - fixed_t newmom; - - pslope_t *slope; - if (abs(oldz - topheight) < abs(oldz + player->mo->height - bottomheight)) { // Hit top - slope = *rover->t_slope; - } else { // Hit bottom - slope = *rover->b_slope; - } - - momentum.x = player->mo->momx; - momentum.y = player->mo->momy; - momentum.z = player->mo->momz*2; - - if (slope) - P_ReverseQuantizeMomentumToSlope(&momentum, slope); - - newmom = momentum.z = -FixedMul(momentum.z,linedist)/2; - - if (abs(newmom) < (linedist*2)) - { - goto bouncydone; - } - - if (!(rover->master->flags & ML_NOTBOUNCY)) - { - if (newmom > 0) - { - if (newmom < 8*FRACUNIT) - newmom = 8*FRACUNIT; - } - else if (newmom > -8*FRACUNIT && newmom != 0) - newmom = -8*FRACUNIT; - } - - if (newmom > player->mo->height/2) - newmom = player->mo->height/2; - else if (newmom < -player->mo->height/2) - newmom = -player->mo->height/2; - - momentum.z = newmom*2; - - if (slope) - P_QuantizeMomentumToSlope(&momentum, slope); - - player->mo->momx = momentum.x; - player->mo->momy = momentum.y; - player->mo->momz = momentum.z/2; - } - else - { - player->mo->momx = -FixedMul(player->mo->momx,linedist); - player->mo->momy = -FixedMul(player->mo->momy,linedist); - } - - goto bouncydone; - } + rover->fofflags |= FOF_BOUNCY; + rover->bouncestrength = P_AproxDistance(rover->master->dx, rover->master->dy)/100; } + + if (!(rover->fofflags & FOF_BOUNCY)) + continue; + + topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + + if (player->mo->z > topheight) + continue; + + if (player->mo->z + player->mo->height < bottomheight) + continue; + + if (oldz < P_GetFOFTopZ(player->mo, node->m_sector, rover, oldx, oldy, NULL) + && oldz + player->mo->height > P_GetFOFBottomZ(player->mo, node->m_sector, rover, oldx, oldy, NULL)) + { + player->mo->momx = -FixedMul(player->mo->momx,rover->bouncestrength); + player->mo->momy = -FixedMul(player->mo->momy,rover->bouncestrength); + } + else + { + pslope_t *slope = (abs(oldz - topheight) < abs(oldz + player->mo->height - bottomheight)) ? *rover->t_slope : *rover->b_slope; + + momentum.x = player->mo->momx; + momentum.y = player->mo->momy; + momentum.z = player->mo->momz*2; + + if (slope) + P_ReverseQuantizeMomentumToSlope(&momentum, slope); + + momentum.z = -FixedMul(momentum.z,rover->bouncestrength)/2; + + if (abs(momentum.z) < (rover->bouncestrength*2)) + goto bouncydone; + + if (momentum.z > FixedMul(24*FRACUNIT, player->mo->scale)) //half of the default player height + momentum.z = FixedMul(24*FRACUNIT, player->mo->scale); + else if (momentum.z < -FixedMul(24*FRACUNIT, player->mo->scale)) + momentum.z = -FixedMul(24*FRACUNIT, player->mo->scale); + + if (slope) + P_QuantizeMomentumToSlope(&momentum, slope); + + player->mo->momx = momentum.x; + player->mo->momy = momentum.y; + player->mo->momz = momentum.z; + } + goto bouncydone; } } + bouncydone: P_UnsetThingPosition(player->mo); player->mo->x = oldx; @@ -1667,9 +1641,9 @@ static void P_CheckQuicksand(player_t *player) for (rover = player->mo->subsector->sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS)) continue; + if (!(rover->fofflags & FOF_EXISTS)) continue; - if (!(rover->flags & FF_QUICKSAND)) + if (!(rover->fofflags & FOF_QUICKSAND)) continue; topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y); @@ -3540,7 +3514,7 @@ static void P_CalcPostImg(player_t *player) { size_t j; - if (!(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_EXISTS)) continue; topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y); @@ -3573,7 +3547,7 @@ static void P_CalcPostImg(player_t *player) for (rover = sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKPLAYER) + if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_SWIMMABLE) || rover->fofflags & FOF_BLOCKPLAYER) continue; topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y); diff --git a/src/r_bsp.c b/src/r_bsp.c index e051c4387..5bed2eb0d 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -70,7 +70,7 @@ boolean R_NoEncore(sector_t *sector, boolean ceiling) boolean R_IsRipplePlane(sector_t *sector, ffloor_t *rover, int ceiling) { - return rover ? (rover->flags & FF_RIPPLE) : + return rover ? (rover->fofflags & FOF_RIPPLE) : (sector->flags & (MSF_RIPPLE_FLOOR << ceiling)); } @@ -987,7 +987,7 @@ static void R_Subsector(size_t num) for (rover = frontsector->ffloors; rover && numffloors < MAXFFLOORS; rover = rover->next) { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) + if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERPLANES)) continue; if (frontsector->cullheight) @@ -1007,8 +1007,8 @@ static void R_Subsector(size_t num) planecenterz = P_GetFFloorBottomZAt(rover, frontsector->soundorg.x, frontsector->soundorg.y); if (planecenterz <= ceilingcenterz && planecenterz >= floorcenterz - && ((viewz < heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) - || (viewz > heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) + && ((viewz < heightcheck && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES))) + || (viewz > heightcheck && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES)))) { light = R_GetPlaneLight(frontsector, planecenterz, viewz < heightcheck); @@ -1042,8 +1042,8 @@ static void R_Subsector(size_t num) planecenterz = P_GetFFloorTopZAt(rover, frontsector->soundorg.x, frontsector->soundorg.y); if (planecenterz >= floorcenterz && planecenterz <= ceilingcenterz - && ((viewz > heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) - || (viewz < heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) + && ((viewz > heightcheck && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES))) + || (viewz < heightcheck && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES)))) { light = R_GetPlaneLight(frontsector, planecenterz, viewz < heightcheck); @@ -1196,11 +1196,11 @@ void R_Prep3DFloors(sector_t *sector) count = 1; for (rover = sector->ffloors; rover; rover = rover->next) { - if ((rover->flags & FF_EXISTS) && (!(rover->flags & FF_NOSHADE) - || (rover->flags & FF_CUTLEVEL) || (rover->flags & FF_CUTSPRITES))) + if ((rover->fofflags & FOF_EXISTS) && (!(rover->fofflags & FOF_NOSHADE) + || (rover->fofflags & FOF_CUTLEVEL) || (rover->fofflags & FOF_CUTSPRITES))) { count++; - if (rover->flags & FF_DOUBLESHADOW) + if (rover->fofflags & FOF_DOUBLESHADOW) count++; } } @@ -1231,8 +1231,8 @@ void R_Prep3DFloors(sector_t *sector) for (rover = sector->ffloors; rover; rover = rover->next) { rover->lastlight = 0; - if (!(rover->flags & FF_EXISTS) || (rover->flags & FF_NOSHADE - && !(rover->flags & FF_CUTLEVEL) && !(rover->flags & FF_CUTSPRITES))) + if (!(rover->fofflags & FOF_EXISTS) || (rover->fofflags & FOF_NOSHADE + && !(rover->fofflags & FOF_CUTLEVEL) && !(rover->fofflags & FOF_CUTSPRITES))) continue; heighttest = P_GetFFloorTopZAt(rover, sector->soundorg.x, sector->soundorg.y); @@ -1244,7 +1244,7 @@ void R_Prep3DFloors(sector_t *sector) bestslope = *rover->t_slope; continue; } - if (rover->flags & FF_DOUBLESHADOW) { + if (rover->fofflags & FOF_DOUBLESHADOW) { heighttest = P_GetFFloorBottomZAt(rover, sector->soundorg.x, sector->soundorg.y); if (heighttest > bestheight @@ -1265,16 +1265,16 @@ void R_Prep3DFloors(sector_t *sector) sector->lightlist[i].height = maxheight = bestheight; sector->lightlist[i].caster = best; - sector->lightlist[i].flags = best->flags; + sector->lightlist[i].flags = best->fofflags; sector->lightlist[i].slope = bestslope; sec = §ors[best->secnum]; - if (best->flags & FF_NOSHADE) + if (best->fofflags & FOF_NOSHADE) { sector->lightlist[i].lightlevel = sector->lightlist[i-1].lightlevel; sector->lightlist[i].extra_colormap = sector->lightlist[i-1].extra_colormap; } - else if (best->flags & FF_COLORMAPONLY) + else if (best->fofflags & FOF_COLORMAPONLY) { sector->lightlist[i].lightlevel = sector->lightlist[i-1].lightlevel; sector->lightlist[i].extra_colormap = &sec->extra_colormap; @@ -1285,7 +1285,7 @@ void R_Prep3DFloors(sector_t *sector) sector->lightlist[i].extra_colormap = &sec->extra_colormap; } - if (best->flags & FF_DOUBLESHADOW) + if (best->fofflags & FOF_DOUBLESHADOW) { heighttest = P_GetFFloorBottomZAt(best, sector->soundorg.x, sector->soundorg.y); if (bestheight == heighttest) ///TODO: do this in a more efficient way -Red diff --git a/src/r_defs.h b/src/r_defs.h index 4ace43014..58ba6ee9d 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -115,41 +115,41 @@ typedef struct */ typedef enum { - FF_EXISTS = 0x1, ///< Always set, to check for validity. - FF_BLOCKPLAYER = 0x2, ///< Solid to player, but nothing else - FF_BLOCKOTHERS = 0x4, ///< Solid to everything but player - FF_SOLID = 0x6, ///< Clips things. - FF_RENDERSIDES = 0x8, ///< Renders the sides. - FF_RENDERPLANES = 0x10, ///< Renders the floor/ceiling. - FF_RENDERALL = 0x18, ///< Renders everything. - FF_SWIMMABLE = 0x20, ///< Is a water block. - FF_NOSHADE = 0x40, ///< Messes with the lighting? - FF_CUTSOLIDS = 0x80, ///< Cuts out hidden solid pixels. - FF_CUTEXTRA = 0x100, ///< Cuts out hidden translucent pixels. - FF_CUTLEVEL = 0x180, ///< Cuts out all hidden pixels. - FF_CUTSPRITES = 0x200, ///< Final step in making 3D water. - FF_BOTHPLANES = 0x400, ///< Render inside and outside planes. - FF_EXTRA = 0x800, ///< Gets cut by ::FF_CUTEXTRA. - FF_TRANSLUCENT = 0x1000, ///< See through! - FF_FOG = 0x2000, ///< Fog "brush." - FF_INVERTPLANES = 0x4000, ///< Only render inside planes. - FF_ALLSIDES = 0x8000, ///< Render inside and outside sides. - FF_INVERTSIDES = 0x10000, ///< Only render inside sides. - FF_DOUBLESHADOW = 0x20000, ///< Make two lightlist entries to reset light? - FF_FLOATBOB = 0x40000, ///< Floats on water and bobs if you step on it. - FF_NORETURN = 0x80000, ///< Used with ::FF_CRUMBLE. Will not return to its original position after falling. - FF_CRUMBLE = 0x100000, ///< Falls 2 seconds after being stepped on, and randomly brings all touching crumbling 3dfloors down with it, providing their master sectors share the same tag (allows crumble platforms above or below, to also exist). - FF_GOOWATER = 0x200000, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop. - FF_MARIO = 0x400000, ///< Acts like a question block when hit from underneath. Goodie spawned at top is determined by master sector. - FF_BUSTUP = 0x800000, ///< You can spin through/punch this block and it will crumble! - FF_QUICKSAND = 0x1000000, ///< Quicksand! - FF_PLATFORM = 0x2000000, ///< You can jump up through this to the top. - FF_REVERSEPLATFORM = 0x4000000, ///< A fall-through floor in normal gravity, a platform in reverse gravity. - FF_INTANGIBLEFLATS = 0x6000000, ///< Both flats are intangible, but the sides are still solid. - FF_RIPPLE = 0x8000000, ///< Ripple the flats - FF_COLORMAPONLY = 0x10000000, ///< Only copy the colormap, not the lightlevel - FF_BOUNCY = 0x20000000, ///< Bounces players - FF_SPLAT = 0x40000000, ///< Use splat flat renderer (treat cyan pixels as invisible) + FOF_EXISTS = 0x1, ///< Always set, to check for validity. + FOF_BLOCKPLAYER = 0x2, ///< Solid to player, but nothing else + FOF_BLOCKOTHERS = 0x4, ///< Solid to everything but player + FOF_SOLID = 0x6, ///< Clips things. + FOF_RENDERSIDES = 0x8, ///< Renders the sides. + FOF_RENDERPLANES = 0x10, ///< Renders the floor/ceiling. + FOF_RENDERALL = 0x18, ///< Renders everything. + FOF_SWIMMABLE = 0x20, ///< Is a water block. + FOF_NOSHADE = 0x40, ///< Messes with the lighting? + FOF_CUTSOLIDS = 0x80, ///< Cuts out hidden solid pixels. + FOF_CUTEXTRA = 0x100, ///< Cuts out hidden translucent pixels. + FOF_CUTLEVEL = 0x180, ///< Cuts out all hidden pixels. + FOF_CUTSPRITES = 0x200, ///< Final step in making 3D water. + FOF_BOTHPLANES = 0x400, ///< Render inside and outside planes. + FOF_EXTRA = 0x800, ///< Gets cut by ::FOF_CUTEXTRA. + FOF_TRANSLUCENT = 0x1000, ///< See through! + FOF_FOG = 0x2000, ///< Fog "brush." + FOF_INVERTPLANES = 0x4000, ///< Only render inside planes. + FOF_ALLSIDES = 0x8000, ///< Render inside and outside sides. + FOF_INVERTSIDES = 0x10000, ///< Only render inside sides. + FOF_DOUBLESHADOW = 0x20000, ///< Make two lightlist entries to reset light? + FOF_FLOATBOB = 0x40000, ///< Floats on water and bobs if you step on it. + FOF_NORETURN = 0x80000, ///< Used with ::FOF_CRUMBLE. Will not return to its original position after falling. + FOF_CRUMBLE = 0x100000, ///< Falls 2 seconds after being stepped on, and randomly brings all touching crumbling 3dfloors down with it, providing their master sectors share the same tag (allows crumble platforms above or below, to also exist). + FOF_GOOWATER = 0x200000, ///< Used with ::FOF_SWIMMABLE. Makes thick bouncey goop. + FOF_MARIO = 0x400000, ///< Acts like a question block when hit from underneath. Goodie spawned at top is determined by master sector. + FOF_BUSTUP = 0x800000, ///< You can spin through/punch this block and it will crumble! + FOF_QUICKSAND = 0x1000000, ///< Quicksand! + FOF_PLATFORM = 0x2000000, ///< You can jump up through this to the top. + FOF_REVERSEPLATFORM = 0x4000000, ///< A fall-through floor in normal gravity, a platform in reverse gravity. + FOF_INTANGIBLEFLATS = 0x6000000, ///< Both flats are intangible, but the sides are still solid. + FOF_RIPPLE = 0x8000000, ///< Ripple the flats + FOF_COLORMAPONLY = 0x10000000, ///< Only copy the colormap, not the lightlevel + FOF_BOUNCY = 0x20000000, ///< Bounces players + FOF_SPLAT = 0x40000000, ///< Use splat flat renderer (treat cyan pixels as invisible) } ffloortype_e; typedef enum @@ -190,7 +190,7 @@ typedef enum FF_OLD_SPINBUST = 0x10000000, FF_OLD_STRONGBUST = 0x20000000, FF_OLD_RIPPLE = 0x40000000, - FF_OLD_COLORMAPONLY = 0x80000000, + FF_OLD_COLORMAPONLY = (INT32)0x80000000, } oldffloortype_e; typedef enum @@ -228,7 +228,7 @@ typedef struct ffloor_s struct pslope_s **b_slope; size_t secnum; - ffloortype_e flags; + ffloortype_e fofflags; struct line_s *master; struct sector_s *target; @@ -241,16 +241,16 @@ typedef struct ffloor_s UINT8 blend; tic_t norender; // for culling - // Only relevant for FF_BUSTUP + // Only relevant for FOF_BUSTUP ffloorbustflags_e bustflags; UINT8 busttype; INT16 busttag; - // Only relevant for FF_QUICKSAND + // Only relevant for FOF_QUICKSAND fixed_t sinkspeed; fixed_t friction; - // Only relevant for FF_BOUNCY + // Only relevant for FOF_BOUNCY fixed_t bouncestrength; // these are saved for netgames, so do not let Lua touch these! @@ -271,7 +271,7 @@ typedef struct lightlist_s extracolormap_t **extra_colormap; // pointer-to-a-pointer, so we can react to colormap changes INT32 flags; ffloor_t *caster; - struct pslope_s *slope; // FF_DOUBLESHADOW makes me have to store this pointer here. Bluh bluh. + struct pslope_s *slope; // FOF_DOUBLESHADOW makes me have to store this pointer here. Bluh bluh. } lightlist_t; diff --git a/src/r_draw8.c b/src/r_draw8.c index 8c65cf94a..8f623286f 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -2485,7 +2485,7 @@ void R_DrawColumnShadowed_8(void) { // If the height of the light is above the column, get the colormap // anyway because the lighting of the top should be affected. - solid = dc_lightlist[i].flags & FF_CUTSOLIDS; + solid = dc_lightlist[i].flags & FOF_CUTSOLIDS; height = dc_lightlist[i].height >> LIGHTSCALESHIFT; if (solid) diff --git a/src/r_plane.c b/src/r_plane.c index 677b4e025..4472c9fc3 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -872,13 +872,13 @@ void R_DrawSinglePlane(visplane_t *pl) // Don't draw planes that shouldn't be drawn. for (rover = pl->ffloor->target->ffloors; rover; rover = rover->next) { - if ((pl->ffloor->flags & FF_CUTEXTRA) && (rover->flags & FF_EXTRA)) + if ((pl->ffloor->fofflags & FOF_CUTEXTRA) && (rover->fofflags & FOF_EXTRA)) { - if (pl->ffloor->flags & FF_EXTRA) + if (pl->ffloor->fofflags & FOF_EXTRA) { // The plane is from an extra 3D floor... Check the flags so // there are no undesired cuts. - if (((pl->ffloor->flags & (FF_FOG|FF_SWIMMABLE)) == (rover->flags & (FF_FOG|FF_SWIMMABLE))) + if (((pl->ffloor->fofflags & (FOF_FOG|FOF_SWIMMABLE)) == (rover->fofflags & (FOF_FOG|FOF_SWIMMABLE))) && pl->height < *rover->topheight && pl->height > *rover->bottomheight) return; @@ -886,9 +886,9 @@ void R_DrawSinglePlane(visplane_t *pl) } } - if (pl->ffloor->flags & FF_TRANSLUCENT) + if (pl->ffloor->fofflags & FOF_TRANSLUCENT) { - spanfunctype = (pl->ffloor->flags & FF_SPLAT) ? SPANDRAWFUNC_TRANSSPLAT : SPANDRAWFUNC_TRANS; + spanfunctype = (pl->ffloor->fofflags & FOF_SPLAT) ? SPANDRAWFUNC_TRANSSPLAT : SPANDRAWFUNC_TRANS; // Hacked up support for alpha value in software mode Tails 09-24-2002 // ...unhacked by toaster 04-01-2021 @@ -905,7 +905,7 @@ void R_DrawSinglePlane(visplane_t *pl) else light = LIGHTLEVELS-1; } - else if (pl->ffloor->flags & FF_FOG) + else if (pl->ffloor->fofflags & FOF_FOG) { spanfunctype = SPANDRAWFUNC_FOG; light = (pl->lightlevel >> LIGHTSEGSHIFT); diff --git a/src/r_segs.c b/src/r_segs.c index 16c61af43..c00330a4d 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -270,7 +270,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) rlight->flags = light->flags; if ((R_CheckColumnFunc(COLDRAWFUNC_FUZZY) == false) - || (rlight->flags & FF_FOG) + || (rlight->flags & FOF_FOG) || (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG))) lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); else @@ -410,7 +410,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) { rlight = &dc_lightlist[i]; - if ((rlight->flags & FF_NOSHADE)) + if ((rlight->flags & FOF_NOSHADE)) continue; if (rlight->lightnum < 0) @@ -591,7 +591,7 @@ static boolean R_IsFFloorTranslucent(visffloor_t *pfloor) // Polyobjects have no ffloors, and they're handled in the conditional above. if (pfloor->ffloor != NULL) - return (pfloor->ffloor->flags & (FF_TRANSLUCENT|FF_FOG)); + return (pfloor->ffloor->fofflags & (FOF_TRANSLUCENT|FOF_FOG)); return false; } @@ -648,7 +648,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) bmnum = R_GetTextureBrightmap(texnum); } - if (pfloor->flags & FF_TRANSLUCENT) + if (pfloor->fofflags & FOF_TRANSLUCENT) { boolean fuzzy = true; @@ -667,7 +667,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) R_SetColumnFunc(COLDRAWFUNC_FUZZY, bmnum != 0); } } - else if (pfloor->flags & FF_FOG) + else if (pfloor->fofflags & FOF_FOG) { R_SetColumnFunc(COLDRAWFUNC_FOG, bmnum != 0); } @@ -732,7 +732,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) else rlight->heightstep = CLAMPMIN; rlight->heightstep = (rlight->heightstep-rlight->height)/(range); rlight->flags = light->flags; - if (light->flags & FF_CUTLEVEL) + if (light->flags & FOF_CUTLEVEL) { SLOPEPARAMS(*light->caster->b_slope, leftheight, rightheight, *light->caster->bottomheight) #undef SLOPEPARAMS @@ -756,12 +756,12 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) rlight->extra_colormap = *light->extra_colormap; // Check if the current light effects the colormap/lightlevel - if (pfloor->flags & FF_FOG) + if (pfloor->fofflags & FOF_FOG) rlight->lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT); else rlight->lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); - if (pfloor->flags & FF_FOG || rlight->flags & FF_FOG || (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG))) + if (pfloor->fofflags & FOF_FOG || rlight->flags & FOF_FOG || (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG))) ; else if (P_ApplyLightOffset(rlight->lightnum)) rlight->lightnum += curline->lightOffset; @@ -776,7 +776,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) // Get correct light level! if ((frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG))) lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); - else if (pfloor->flags & FF_FOG) + else if (pfloor->fofflags & FOF_FOG) lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT); else if (R_CheckColumnFunc(COLDRAWFUNC_FUZZY) == true) lightnum = LIGHTLEVELS-1; @@ -784,7 +784,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false) ->lightlevel >> LIGHTSEGSHIFT; - if (pfloor->flags & FF_FOG || (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG))) + if (pfloor->fofflags & FOF_FOG || (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG))) ; else if (P_ApplyLightOffset(lightnum)) lightnum += curline->lightOffset; @@ -932,7 +932,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { rlight = &dc_lightlist[i]; rlight->height += rlight->heightstep; - if (rlight->flags & FF_CUTLEVEL) + if (rlight->flags & FOF_CUTLEVEL) rlight->botheight += rlight->botheightstep; } } @@ -960,7 +960,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { // Check if the current light effects the colormap/lightlevel rlight = &dc_lightlist[i]; - lighteffect = !(dc_lightlist[i].flags & FF_NOSHADE); + lighteffect = !(dc_lightlist[i].flags & FOF_NOSHADE); if (lighteffect) { lightnum = rlight->lightnum; @@ -977,7 +977,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (pindex >= MAXLIGHTSCALE) pindex = MAXLIGHTSCALE-1; - if (pfloor->flags & FF_FOG) + if (pfloor->fofflags & FOF_FOG) { if (pfloor->master->frontsector->extra_colormap) rlight->rcolormap = pfloor->master->frontsector->extra_colormap->colormap + (xwalllights[pindex] - colormaps); @@ -996,15 +996,15 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) solid = 0; // don't carry over solid-cutting flag from the previous light // Check if the current light can cut the current 3D floor. - if (rlight->flags & FF_CUTSOLIDS && !(pfloor->flags & FF_EXTRA)) + if (rlight->flags & FOF_CUTSOLIDS && !(pfloor->fofflags & FOF_EXTRA)) solid = 1; - else if (rlight->flags & FF_CUTEXTRA && pfloor->flags & FF_EXTRA) + else if (rlight->flags & FOF_CUTEXTRA && pfloor->fofflags & FOF_EXTRA) { - if (rlight->flags & FF_EXTRA) + if (rlight->flags & FOF_EXTRA) { // The light is from an extra 3D floor... Check the flags so // there are no undesired cuts. - if ((rlight->flags & (FF_FOG|FF_SWIMMABLE)) == (pfloor->flags & (FF_FOG|FF_SWIMMABLE))) + if ((rlight->flags & (FOF_FOG|FOF_SWIMMABLE)) == (pfloor->fofflags & (FOF_FOG|FOF_SWIMMABLE))) solid = 1; } else @@ -1049,7 +1049,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { rlight = &dc_lightlist[i]; rlight->height += rlight->heightstep; - if (rlight->flags & FF_CUTLEVEL) + if (rlight->flags & FOF_CUTLEVEL) rlight->botheight += rlight->botheightstep; } continue; @@ -1095,7 +1095,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) dc_fullbright += COLORMAP_REMAPOFFSET; } - if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap) + if (pfloor->fofflags & FOF_FOG && pfloor->master->frontsector->extra_colormap) dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); else if (frontsector->extra_colormap) dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); @@ -1548,7 +1548,7 @@ static void R_RenderSegLoop (void) for (i = 0; i < dc_numlights; i++) { dc_lightlist[i].height += dc_lightlist[i].heightstep; - if (dc_lightlist[i].flags & FF_CUTSOLIDS) + if (dc_lightlist[i].flags & FOF_CUTSOLIDS) dc_lightlist[i].botheight += dc_lightlist[i].botheightstep; } } @@ -2161,9 +2161,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) i = 0; for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_RENDERSIDES) || !(rover->fofflags & FOF_EXISTS)) continue; - if (!(rover->flags & FF_ALLSIDES) && rover->flags & FF_INVERTSIDES) + if (!(rover->fofflags & FOF_ALLSIDES) && rover->fofflags & FOF_INVERTSIDES) continue; if (rover->norender == leveltime) @@ -2180,23 +2180,23 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (r2->master == rover->master) // Skip if same control line. break; - if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)) + if (!(r2->fofflags & FOF_EXISTS) || !(r2->fofflags & FOF_RENDERSIDES)) continue; if (r2->norender == leveltime) continue; - if (rover->flags & FF_EXTRA) + if (rover->fofflags & FOF_EXTRA) { - if (!(r2->flags & FF_CUTEXTRA)) + if (!(r2->fofflags & FOF_CUTEXTRA)) continue; - if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG))) + if (r2->fofflags & FOF_EXTRA && (r2->fofflags & (FOF_TRANSLUCENT|FOF_FOG)) != (rover->fofflags & (FOF_TRANSLUCENT|FOF_FOG))) continue; } else { - if (!(r2->flags & FF_CUTSOLIDS)) + if (!(r2->fofflags & FOF_CUTSOLIDS)) continue; } @@ -2219,9 +2219,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_RENDERSIDES) || !(rover->fofflags & FOF_EXISTS)) continue; - if (!(rover->flags & FF_ALLSIDES || rover->flags & FF_INVERTSIDES)) + if (!(rover->fofflags & FOF_ALLSIDES || rover->fofflags & FOF_INVERTSIDES)) continue; if (rover->norender == leveltime) @@ -2238,23 +2238,23 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (r2->master == rover->master) // Skip if same control line. break; - if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)) + if (!(r2->fofflags & FOF_EXISTS) || !(r2->fofflags & FOF_RENDERSIDES)) continue; if (r2->norender == leveltime) continue; - if (rover->flags & FF_EXTRA) + if (rover->fofflags & FOF_EXTRA) { - if (!(r2->flags & FF_CUTEXTRA)) + if (!(r2->fofflags & FOF_CUTEXTRA)) continue; - if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG))) + if (r2->fofflags & FOF_EXTRA && (r2->fofflags & (FOF_TRANSLUCENT|FOF_FOG)) != (rover->fofflags & (FOF_TRANSLUCENT|FOF_FOG))) continue; } else { - if (!(r2->flags & FF_CUTSOLIDS)) + if (!(r2->fofflags & FOF_CUTSOLIDS)) continue; } @@ -2279,9 +2279,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) { for (rover = backsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next) { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_RENDERSIDES) || !(rover->fofflags & FOF_EXISTS)) continue; - if (!(rover->flags & FF_ALLSIDES) && rover->flags & FF_INVERTSIDES) + if (!(rover->fofflags & FOF_ALLSIDES) && rover->fofflags & FOF_INVERTSIDES) continue; if (rover->norender == leveltime) continue; @@ -2301,9 +2301,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) { for (rover = frontsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next) { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) + if (!(rover->fofflags & FOF_RENDERSIDES) || !(rover->fofflags & FOF_EXISTS)) continue; - if (!(rover->flags & FF_ALLSIDES || rover->flags & FF_INVERTSIDES)) + if (!(rover->fofflags & FOF_ALLSIDES || rover->fofflags & FOF_INVERTSIDES)) continue; if (rover->norender == leveltime) continue; @@ -2523,7 +2523,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) rlight->heightstep = (rlight->heightstep-rlight->height)/(range); rlight->flags = light->flags; - if (light->caster && light->caster->flags & FF_CUTSOLIDS) + if (light->caster && light->caster->fofflags & FOF_CUTSOLIDS) { leftheight = P_GetFFloorBottomZAt(light->caster, segleft.x, segleft.y); rightheight = P_GetFFloorBottomZAt(light->caster, segright.x, segright.y); @@ -2610,7 +2610,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) { for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) + if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERPLANES)) continue; if (rover->norender == leveltime) continue; @@ -2625,8 +2625,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz < planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || - (viewz > planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) + ((viewz < planevistest && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES))) || + (viewz > planevistest && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES)))) { //ffloor[i].slope = *rover->b_slope; ffloor[i].b_pos = roverleft; @@ -2648,8 +2648,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz > planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || - (viewz < planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) + ((viewz > planevistest && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES))) || + (viewz < planevistest && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES)))) { //ffloor[i].slope = *rover->t_slope; ffloor[i].b_pos = roverleft; @@ -2667,7 +2667,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) { for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) + if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERPLANES)) continue; if (rover->norender == leveltime) continue; @@ -2682,8 +2682,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz < planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || - (viewz > planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) + ((viewz < planevistest && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES))) || + (viewz > planevistest && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES)))) { //ffloor[i].slope = *rover->b_slope; ffloor[i].b_pos = roverleft; @@ -2705,8 +2705,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz > planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || - (viewz < planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) + ((viewz > planevistest && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES))) || + (viewz < planevistest && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES)))) { //ffloor[i].slope = *rover->t_slope; ffloor[i].b_pos = roverleft; diff --git a/src/r_things.c b/src/r_things.c index b30a9139f..5b43beed2 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1160,7 +1160,7 @@ static void R_SplitSprite(vissprite_t *sprite) { fixed_t testheight; - if (!(sector->lightlist[i].caster->flags & FF_CUTSPRITES)) + if (!(sector->lightlist[i].caster->fofflags & FOF_CUTSPRITES)) continue; testheight = P_GetLightZAt(§or->lightlist[i], sprite->gx, sprite->gy); @@ -1193,7 +1193,7 @@ static void R_SplitSprite(vissprite_t *sprite) newsprite->szt -= 8; newsprite->cut |= SC_TOP; - if (!(sector->lightlist[i].caster->flags & FF_NOSHADE)) + if (!(sector->lightlist[i].caster->fofflags & FOF_NOSHADE)) { lightnum = (*sector->lightlist[i].lightlevel >> LIGHTSEGSHIFT); @@ -1280,7 +1280,7 @@ fixed_t R_GetShadowZ( if (sector->ffloors) for (rover = sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES) || (rover->alpha < 90 && !(rover->flags & FF_SWIMMABLE))) + if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERPLANES) || (rover->alpha < 90 && !(rover->fofflags & FOF_SWIMMABLE))) continue; z = isflipped ? P_GetFFloorBottomZAt(rover, interp.x, interp.y) : P_GetFFloorTopZAt(rover, interp.x, interp.y); From de9d9c19e454fb438713f4ad08be25cddbbb2a72 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 31 Jul 2022 13:01:45 +0200 Subject: [PATCH 14/54] Forgot to add fofflags to ffloor_opt --- src/lua_maplib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index a8baf558f..5f0806769 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -240,6 +240,7 @@ static const char *const ffloor_opt[] = { "t_slope", "b_slope", "sector", // secnum pushed as control sector userdata + "fofflags", "flags", "master", // control linedef "target", // target sector From 8afba6c7a1cda676bce97139e329bd1db1415ca4 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 31 Jul 2022 13:24:45 +0200 Subject: [PATCH 15/54] Use the correct bustflags constant --- src/lua_maplib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 5f0806769..f89059402 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -1888,7 +1888,7 @@ static INT32 P_GetOldFOFFlags(ffloor_t *fflr) result |= FF_OLD_NORETURN; if (fflr->fofflags & FOF_CRUMBLE) result |= FF_OLD_CRUMBLE; - if (fflr->bustflags & TMFB_ONLYBOTTOM) + if (fflr->bustflags & FB_ONLYBOTTOM) result |= FF_OLD_SHATTERBOTTOM; if (fflr->fofflags & FOF_GOOWATER) result |= FF_OLD_GOOWATER; @@ -2094,9 +2094,9 @@ static void P_SetOldFOFFlags(ffloor_t *fflr, oldffloortype_e oldflags) fflr->busttype = BT_REGULAR; if (oldflags & FF_OLD_SHATTERBOTTOM) - fflr->bustflags |= TMFB_ONLYBOTTOM; + fflr->bustflags |= FB_ONLYBOTTOM; else - fflr->bustflags &= ~TMFB_ONLYBOTTOM; + fflr->bustflags &= ~FB_ONLYBOTTOM; } static int ffloor_set(lua_State *L) From 05e44c01861ed47f6729a7d56397b1084c44587f Mon Sep 17 00:00:00 2001 From: spherallic Date: Sun, 18 Sep 2022 12:55:17 +0200 Subject: [PATCH 16/54] Fix action 457 reading the failure tag from the wrong offset field --- src/p_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index c16751322..294a79220 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -5303,7 +5303,7 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[0] = tag; lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; lines[i].args[2] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; - lines[i].args[3] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].rowoffset >> FRACBITS : 0; + lines[i].args[3] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : 0; lines[i].args[4] = !!(lines[i].flags & ML_NOSKEW); break; case 459: //Control text prompt From f2a815ddcaebfdce227309dc96c8d31527403e31 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 9 Oct 2022 03:14:59 -0400 Subject: [PATCH 17/54] It's actually just one type --- src/p_spec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index a651867ca..b0c9584bb 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -7212,7 +7212,7 @@ static void P_SpawnScrollers(void) // // FIXME: UDMFify front+back scrollers - // types 507-509 + // type 507 // switch (l->special) From babd0d59810dda64432dd88785ef560244d1814f Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 00:44:27 -0400 Subject: [PATCH 18/54] Fix TERRAIN reading --- src/k_terrain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_terrain.c b/src/k_terrain.c index 6204db63f..2d8f14d87 100644 --- a/src/k_terrain.c +++ b/src/k_terrain.c @@ -1570,7 +1570,7 @@ static boolean K_DoTERRAINLumpParse(size_t num, void (*parser)(size_t, const cha break; } - val = M_TokenizerRead(0); + val = M_TokenizerRead(1); parser(num, param, val); } From df3c077bf14c65e08c0ff8822f901a474468c640 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 01:51:42 -0400 Subject: [PATCH 19/54] Block Monsters is a flag again --- extras/conf/udb/Includes/Kart2_misc.cfg | 11 ++-- src/deh_tables.c | 2 +- src/doomdata.h | 71 ++++++++++++++----------- src/p_map.c | 31 ++++++++--- src/p_saveg.c | 4 +- src/p_setup.c | 36 +++++++------ src/r_defs.h | 2 +- src/slope_anchors.c | 4 +- 8 files changed, 96 insertions(+), 65 deletions(-) diff --git a/extras/conf/udb/Includes/Kart2_misc.cfg b/extras/conf/udb/Includes/Kart2_misc.cfg index 8de7cc3ba..9291ba62f 100644 --- a/extras/conf/udb/Includes/Kart2_misc.cfg +++ b/extras/conf/udb/Includes/Kart2_misc.cfg @@ -25,7 +25,7 @@ linedefflags linedefflagstranslation { 1 = "blocking"; - 2 = "blockmonsters"; + 2 = "blockplayers"; 4 = "twosided"; 8 = "dontpegtop"; 16 = "dontpegbottom"; @@ -37,8 +37,8 @@ linedefflagstranslation 1024 = "wrapmidtex"; 2048 = "netonly"; 4096 = "nonet"; - 8192 = "effect6"; - 16384 = "bouncy"; + 8192 = "blockmonsters"; + 16384 = "notbouncy"; 32768 = "transfer"; } @@ -46,7 +46,7 @@ linedefflagstranslation linedefflags_udmf { blocking = "Impassable"; - blockmonsters = "Block Enemies"; + blockplayers = "Block Players"; twosided = "Double-Sided"; dontpegtop = "Upper Unpegged"; dontpegbottom = "Lower Unpegged"; @@ -58,7 +58,8 @@ linedefflags_udmf wrapmidtex = "Repeat Midtexture"; netonly = "Netgame Only"; nonet = "No Netgame"; - bouncy = "Bouncy Wall"; + blockmonsters = "Block Enemies"; + bouncy = "Not Bouncy"; transfer = "Transfer Line"; } diff --git a/src/deh_tables.c b/src/deh_tables.c index 6a799d277..ec35ff611 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5812,7 +5812,7 @@ const char *const ML_LIST[] = { "WRAPMIDTEX", "NETONLY", "NONET", - "EFFECT6", + "BLOCKMONSTERS", "NOTBOUNCY", "TFERLINE", NULL diff --git a/src/doomdata.h b/src/doomdata.h index 3bd5b522d..6d3a6386c 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -99,48 +99,57 @@ typedef struct // LineDef attributes. // -// Solid, is an obstacle. -#define ML_IMPASSABLE 1 +enum +{ + // Solid, is an obstacle. + ML_IMPASSABLE = 0x00000001, -// SRB2Kart: Blocks players only; items can be thrown through these. -#define ML_BLOCKPLAYERS 2 + // SRB2Kart: Blocks players only; items can be thrown through these. + ML_BLOCKPLAYERS = 0x00000002, -// Backside will not be present at all if not two sided. -#define ML_TWOSIDED 4 + // Backside will not be present at all if not two sided. + ML_TWOSIDED = 0x00000004, -// If a texture is pegged, the texture will have -// the end exposed to air held constant at the -// top or bottom of the texture (stairs or pulled -// down things) and will move with a height change -// of one of the neighbor sectors. -// Unpegged textures allways have the first row of -// the texture at the top pixel of the line for both -// top and bottom textures (use next to windows). + // If a texture is pegged, the texture will have + // the end exposed to air held constant at the + // top or bottom of the texture (stairs or pulled + // down things) and will move with a height change + // of one of the neighbor sectors. + // Unpegged textures allways have the first row of + // the texture at the top pixel of the line for both + // top and bottom textures (use next to windows). -// upper texture unpegged -#define ML_DONTPEGTOP 8 + // upper texture unpegged + ML_DONTPEGTOP = 0x00000008, -// lower texture unpegged -#define ML_DONTPEGBOTTOM 16 + // lower texture unpegged + ML_DONTPEGBOTTOM = 0x00000010, -#define ML_SKEWTD 32 + ML_SKEWTD = 0x00000020, -// Don't let Knuckles climb on this line -#define ML_NOCLIMB 64 + // Don't let Knuckles climb on this line + ML_NOCLIMB = 0x00000040, -#define ML_NOSKEW 128 -#define ML_MIDPEG 256 -#define ML_MIDSOLID 512 -#define ML_WRAPMIDTEX 1024 + ML_NOSKEW = 0x00000080, + ML_MIDPEG = 0x00000100, + ML_MIDSOLID = 0x00000200, + ML_WRAPMIDTEX = 0x00000400, -#define ML_NETONLY 2048 // Apply effect only in netgames -#define ML_NONET 4096 // Apply effect only in single player games -#define ML_EFFECT6 8192 + // Apply effect only in netgames + ML_NETONLY = 0x00000800, -// Don't bounce off this wall! -#define ML_NOTBOUNCY 16384 + // Apply effect only in single player games + ML_NONET = 0x00001000, -#define ML_TFERLINE 32768 + // Blocks enemies only + ML_BLOCKMONSTERS = 0x00002000, + + // Don't bounce off this wall! + ML_NOTBOUNCY = 0x00004000, + + // Transfers FOF properties. + ML_TFERLINE = 0x00008000, +}; // Sector definition, from editing. typedef struct diff --git a/src/p_map.c b/src/p_map.c index 96e8747b0..ef3d30ef1 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1620,17 +1620,34 @@ boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing) { // missiles can cross uncrossable lines if ((thing->flags & MF_MISSILE)) + { return false; + } else { - return - ( - (ld->flags & ML_IMPASSABLE) || // block objects from moving through this linedef. - (thing->player && !thing->player->spectator && - ld->flags & ML_BLOCKPLAYERS) || // SRB2Kart: Only block players, not items - ((thing->flags & (MF_ENEMY|MF_BOSS)) && ld->special == 81) // case 81: block monsters only - ); + if (thing->player && thing->player->spectator) + { + // Allow spectators thru blocking lines. + return false; + } + + if (ld->flags & ML_IMPASSABLE) + { + // block objects from moving through this linedef. + return true; + } + + if (thing->player) + { + return (ld->flags & ML_BLOCKPLAYERS); + } + else if (thing->flags & (MF_ENEMY|MF_BOSS)) + { + return (ld->flags & ML_BLOCKMONSTERS); + } } + + return false; } boolean P_IsLineTripWire(const line_t *ld) diff --git a/src/p_saveg.c b/src/p_saveg.c index 91960e4d2..105ab1a74 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1480,7 +1480,7 @@ static void ArchiveLines(void) if (diff & LD_DIFF2) WRITEUINT8(save_p, diff2); if (diff & LD_FLAG) - WRITEINT16(save_p, li->flags); + WRITEUINT32(save_p, li->flags); if (diff & LD_SPECIAL) WRITEINT16(save_p, li->special); if (diff & LD_CLLCOUNT) @@ -1562,7 +1562,7 @@ static void UnArchiveLines(void) diff2 = 0; if (diff & LD_FLAG) - li->flags = READINT16(save_p); + li->flags = READUINT32(save_p); if (diff & LD_SPECIAL) li->special = READINT16(save_p); if (diff & LD_CLLCOUNT) diff --git a/src/p_setup.c b/src/p_setup.c index 294a79220..ea2a574e9 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1631,8 +1631,8 @@ static void ParseTextmapLinedefParameter(UINT32 i, const char *param, const char lines[i].flags |= ML_MIDSOLID; else if (fastcmp(param, "wrapmidtex") && fastcmp("true", val)) lines[i].flags |= ML_WRAPMIDTEX; - /*else if (fastcmp(param, "effect6") && fastcmp("true", val)) - lines[i].flags |= ML_EFFECT6;*/ + else if (fastcmp(param, "blockmonsters") && fastcmp("true", val)) + lines[i].flags |= ML_BLOCKMONSTERS; else if (fastcmp(param, "nonet") && fastcmp("true", val)) lines[i].flags |= ML_NONET; else if (fastcmp(param, "netonly") && fastcmp("true", val)) @@ -3714,7 +3714,7 @@ static void P_LinkMapData(void) static void P_AddBinaryMapTagsFromLine(sector_t *sector, line_t *line) { Tag_Add(§or->tags, Tag_FGet(&line->tags)); - if (line->flags & ML_EFFECT6) { + if (line->flags & ML_BLOCKMONSTERS) { if (sides[line->sidenum[0]].textureoffset) Tag_Add(§or->tags, (INT32)sides[line->sidenum[0]].textureoffset / FRACUNIT); if (sides[line->sidenum[0]].rowoffset) @@ -3756,7 +3756,7 @@ static void P_AddBinaryMapTags(void) tag = Tag_FGet(&lines[i].frontsector->tags); target_tag = Tag_FGet(&lines[i].tags); memset(offset_tags, 0, sizeof(mtag_t)*4); - if (lines[i].flags & ML_EFFECT6) { + if (lines[i].flags & ML_BLOCKMONSTERS) { offset_tags[0] = (INT32)sides[lines[i].sidenum[0]].textureoffset / FRACUNIT; offset_tags[1] = (INT32)sides[lines[i].sidenum[0]].rowoffset / FRACUNIT; } @@ -3975,7 +3975,7 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[1] = TMP_BOTH; lines[i].flags &= ~(ML_NETONLY|ML_NONET); - if (lines[i].flags & ML_EFFECT6) // Set offset through x and y texture offsets + if (lines[i].flags & ML_BLOCKMONSTERS) // Set offset through x and y texture offsets { angle_t flatangle = InvAngle(R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y)); fixed_t xoffs = sides[lines[i].sidenum[0]].textureoffset; @@ -4093,7 +4093,7 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[3] &= ~TMPF_INVISIBLEPLANES; /*if (lines[paramline].flags & ML_WRAPMIDTEX) lines[i].args[3] |= TMPF_DONTCLIPPLANES;*/ - if (lines[paramline].flags & ML_EFFECT6) + if (lines[paramline].flags & ML_BLOCKMONSTERS) lines[i].args[3] |= TMPF_SPLAT; if (lines[paramline].flags & ML_NOCLIMB) lines[i].args[3] |= TMPF_EXECUTOR; @@ -4198,6 +4198,10 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[0] = tag; lines[i].args[1] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; break; + case 81: //Block enemies + lines[i].flags |= ML_BLOCKMONSTERS; + lines[i].special = 0; + break; case 100: //FOF: solid, opaque, shadowcasting case 101: //FOF: solid, opaque, non-shadowcasting case 102: //FOF: solid, translucent @@ -4229,7 +4233,7 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[3] |= TMFA_NOPLANES; if (lines[i].special != 100 && (lines[i].special != 104 || !(lines[i].flags & ML_NOCLIMB))) lines[i].args[3] |= TMFA_NOSHADE; - if (lines[i].flags & ML_EFFECT6) + if (lines[i].flags & ML_BLOCKMONSTERS) lines[i].args[3] |= TMFA_SPLAT; //Tangibility @@ -4277,7 +4281,7 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[3] |= TMFW_GOOWATER; //Splat rendering? - if (lines[i].flags & ML_EFFECT6) + if (lines[i].flags & ML_BLOCKMONSTERS) lines[i].args[3] |= TMFW_SPLAT; lines[i].special = 120; @@ -4312,7 +4316,7 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[3] |= TMFA_NOPLANES; if (lines[i].special != 146 && (lines[i].flags & ML_NOCLIMB)) lines[i].args[3] |= TMFA_NOSHADE; - if (lines[i].flags & ML_EFFECT6) + if (lines[i].flags & ML_BLOCKMONSTERS) lines[i].args[3] |= TMFA_SPLAT; //Tangibility @@ -4388,7 +4392,7 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[4] |= TMFC_AIRBOB; if (lines[i].special >= 176 && lines[i].special <= 179) lines[i].args[4] |= TMFC_FLOATBOB; - if (lines[i].flags & ML_EFFECT6) + if (lines[i].flags & ML_BLOCKMONSTERS) lines[i].args[4] |= TMFC_SPLAT; if (lines[i].flags & ML_SKEWTD) @@ -4425,7 +4429,7 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[3] |= TMFA_INSIDES; if (lines[i].special != 190 && (lines[i].special <= 193 || lines[i].flags & ML_NOCLIMB)) lines[i].args[3] |= TMFA_NOSHADE; - if (lines[i].flags & ML_EFFECT6) + if (lines[i].flags & ML_BLOCKMONSTERS) lines[i].args[3] |= TMFA_SPLAT; //Tangibility @@ -4482,7 +4486,7 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[3] |= TMFA_INSIDES; if (lines[i].special != 220 && !(lines[i].flags & ML_NOCLIMB)) lines[i].args[3] |= TMFA_NOSHADE; - if (lines[i].flags & ML_EFFECT6) + if (lines[i].flags & ML_BLOCKMONSTERS) lines[i].args[3] |= TMFA_SPLAT; lines[i].special = 220; @@ -4548,7 +4552,7 @@ static void P_ConvertBinaryLinedefTypes(void) } if (lines[i].special == 252 && lines[i].flags & ML_NOCLIMB) lines[i].args[4] |= TMFB_ONLYBOTTOM; - if (lines[i].flags & ML_EFFECT6) + if (lines[i].flags & ML_BLOCKMONSTERS) lines[i].args[4] |= TMFB_SPLAT; lines[i].special = 254; @@ -4570,7 +4574,7 @@ static void P_ConvertBinaryLinedefTypes(void) if (lines[i].flags & ML_SKEWTD) lines[i].args[3] |= TMFL_NOBOSSES; //Replicate old hack: Translucent FOFs set to full opacity cut cyan pixels - if (lines[i].flags & ML_EFFECT6 || lines[i].args[1] == 256) + if (lines[i].flags & ML_BLOCKMONSTERS || lines[i].args[1] == 256) lines[i].args[3] |= TMFL_SPLAT; break; @@ -4580,7 +4584,7 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[0] = tag; lines[i].args[3] = P_GetFOFFlags(sides[lines[i].sidenum[1]].toptexture); - if (lines[i].flags & ML_EFFECT6) + if (lines[i].flags & ML_BLOCKMONSTERS) lines[i].args[3] |= FOF_SPLAT; lines[i].args[4] = P_GetFOFBusttype(sides[lines[i].sidenum[1]].toptexture); if (sides[lines[i].sidenum[1]].toptexture & FF_OLD_SHATTERBOTTOM) @@ -5656,7 +5660,7 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[1] = tag; - if (lines[i].flags & ML_EFFECT6) + if (lines[i].flags & ML_BLOCKMONSTERS) { UINT8 side = lines[i].special >= 714; diff --git a/src/r_defs.h b/src/r_defs.h index 58ba6ee9d..3f801c197 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -525,7 +525,7 @@ typedef struct line_s angle_t angle; // Precalculated angle between dx and dy // Animation related. - INT16 flags; + UINT32 flags; INT16 special; taglist_t tags; INT32 args[NUMLINEARGS]; diff --git a/src/slope_anchors.c b/src/slope_anchors.c index 071dfe7c2..2c8f4959d 100644 --- a/src/slope_anchors.c +++ b/src/slope_anchors.c @@ -411,7 +411,7 @@ slope_sector (*slope) = new_vertex_slope(anchors, flags); /* Effect 6 - invert slope to opposite side */ - if (flags & ML_EFFECT6) + if (flags & ML_BLOCKMONSTERS) { (*alt) = new_vertex_slope(flip_slope(anchors, sector), flags); } @@ -446,7 +446,7 @@ make_anchored_slope if (plane == (FLOOR|CEILING)) { - flags &= ~ML_EFFECT6; + flags &= ~ML_BLOCKMONSTERS; } if (plane & FLOOR) From f72379e5576b3b078aa7dc3626c4684a647b5a79 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 01:57:24 -0400 Subject: [PATCH 20/54] Fix invisible tripwire --- src/p_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index ea2a574e9..2d3d4d471 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2644,7 +2644,7 @@ static void P_ProcessLinedefsAfterSidedefs(void) if (ld->tripwire) { ld->blendmode = AST_ADD; - ld->alpha = 0; + ld->alpha = 0xff; } if (udmf) From 3fd8c53c4a4cd88602d26c67dc3f32038a9e507a Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 04:55:58 -0400 Subject: [PATCH 21/54] Add ripple planes to binary convert + loading --- src/p_setup.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/p_setup.c b/src/p_setup.c index 2d3d4d471..dec8ce107 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1490,6 +1490,10 @@ static void ParseTextmapSectorParameter(UINT32 i, const char *param, const char sectors[i].flags |= MSF_HEATWAVE; else if (fastcmp(param, "noclipcamera") && fastcmp("true", val)) sectors[i].flags |= MSF_NOCLIPCAMERA; + else if (fastcmp(param, "ripple_floor") && fastcmp("true", val)) + sectors[i].flags |= MSF_RIPPLE_FLOOR; + else if (fastcmp(param, "ripple_ceiling") && fastcmp("true", val)) + sectors[i].flags |= MSF_RIPPLE_CEILING; else if (fastcmp(param, "nostepup") && fastcmp("true", val)) sectors[i].specialflags |= SSF_NOSTEPUP; else if (fastcmp(param, "doublestepup") && fastcmp("true", val)) @@ -2317,6 +2321,10 @@ static void P_WriteTextmap(void) fprintf(f, "heatwave = true;\n"); if (wsectors[i].flags & MSF_NOCLIPCAMERA) fprintf(f, "noclipcamera = true;\n"); + if (wsectors[i].flags & MSF_RIPPLE_FLOOR) + fprintf(f, "ripple_floor = true;\n"); + if (wsectors[i].flags & MSF_RIPPLE_CEILING) + fprintf(f, "ripple_ceiling = true;\n"); if (wsectors[i].specialflags & SSF_NOSTEPUP) fprintf(f, "nostepup = true;\n"); if (wsectors[i].specialflags & SSF_DOUBLESTEPUP) @@ -4015,6 +4023,12 @@ static void P_ConvertBinaryLinedefTypes(void) if (lines[i].flags & ML_SKEWTD) sectors[s].flags |= MSF_INVERTPRECIP; + + if (lines[i].flags & ML_DONTPEGTOP) + sectors[s].flags |= MSF_RIPPLE_FLOOR; + + if (lines[i].flags & ML_DONTPEGBOTTOM) + sectors[s].flags |= MSF_RIPPLE_CEILING; } if (GETSECSPECIAL(lines[i].frontsector->special, 4) != 12) From 21dd68d3922491c4b85f43143812c21564574c77 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 06:08:25 -0400 Subject: [PATCH 22/54] Reimplement Invert Encore Also add removal warnings for sector Sneaker Panels, Trick Panels, and fast-approaching deprecation warnings for sector Offroad. --- extras/conf/udb/Includes/Kart2_misc.cfg | 3 ++ src/hardware/hw_main.c | 16 ++++----- src/k_terrain.c | 2 +- src/k_terrain.h | 2 +- src/p_setup.c | 34 ++++++++++++++----- src/p_spec.c | 15 +++------ src/r_bsp.c | 45 ++++++++++++------------- src/r_bsp.h | 2 +- src/r_defs.h | 2 ++ 9 files changed, 68 insertions(+), 53 deletions(-) diff --git a/extras/conf/udb/Includes/Kart2_misc.cfg b/extras/conf/udb/Includes/Kart2_misc.cfg index 9291ba62f..cae1127b3 100644 --- a/extras/conf/udb/Includes/Kart2_misc.cfg +++ b/extras/conf/udb/Includes/Kart2_misc.cfg @@ -94,6 +94,9 @@ sectorflags gravityflip = "Flip Objects in Reverse Gravity"; heatwave = "Heat Wave"; noclipcamera = "Intangible to the Camera"; + ripple_floor = "Ripply Floor"; + ripple_ceiling = "Ripply Ceiling"; + invertencore = "Invert Encore Remap"; outerspace = "Space Countdown"; doublestepup = "Ramp Sector (double step-up/down)"; nostepdown = "Non-Ramp Sector (No step-down)"; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c86635319..21dc54e7d 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2871,7 +2871,7 @@ static void HWR_AddPolyObjectPlanes(void) } else { - HWR_GetLevelFlat(&levelflats[polyobjsector->floorpic], R_NoEncore(polyobjsector, false)); + HWR_GetLevelFlat(&levelflats[polyobjsector->floorpic], R_NoEncore(polyobjsector, &levelflats[polyobjsector->floorpic], false)); HWR_RenderPolyObjectPlane(po_ptrs[i], false, polyobjsector->floorheight, PF_Occlude, (light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), &levelflats[polyobjsector->floorpic], polyobjsector, 255, (light == -1 ? gl_frontsector->extra_colormap : *gl_frontsector->lightlist[light].extra_colormap)); @@ -2894,7 +2894,7 @@ static void HWR_AddPolyObjectPlanes(void) } else { - HWR_GetLevelFlat(&levelflats[polyobjsector->ceilingpic], R_NoEncore(polyobjsector, true)); + HWR_GetLevelFlat(&levelflats[polyobjsector->ceilingpic], R_NoEncore(polyobjsector, &levelflats[polyobjsector->ceilingpic], true)); HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude, (light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), &levelflats[polyobjsector->ceilingpic], polyobjsector, 255, (light == -1 ? gl_frontsector->extra_colormap : *gl_frontsector->lightlist[light].extra_colormap)); @@ -3031,7 +3031,7 @@ static void HWR_Subsector(size_t num) { if (sub->validcount != validcount) { - HWR_GetLevelFlat(&levelflats[gl_frontsector->floorpic], R_NoEncore(gl_frontsector, false)); + HWR_GetLevelFlat(&levelflats[gl_frontsector->floorpic], R_NoEncore(gl_frontsector, &levelflats[gl_frontsector->floorpic], false)); HWR_RenderPlane(sub, &extrasubsectors[num], false, // Hack to make things continue to work around slopes. locFloorHeight == cullFloorHeight ? locFloorHeight : gl_frontsector->floorheight, @@ -3054,7 +3054,7 @@ static void HWR_Subsector(size_t num) { if (sub->validcount != validcount) { - HWR_GetLevelFlat(&levelflats[gl_frontsector->ceilingpic], R_NoEncore(gl_frontsector, true)); + HWR_GetLevelFlat(&levelflats[gl_frontsector->ceilingpic], R_NoEncore(gl_frontsector, &levelflats[gl_frontsector->ceilingpic], true)); HWR_RenderPlane(sub, &extrasubsectors[num], true, // Hack to make things continue to work around slopes. locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gl_frontsector->ceilingheight, @@ -3132,7 +3132,7 @@ static void HWR_Subsector(size_t num) } else { - HWR_GetLevelFlat(&levelflats[*rover->bottompic], R_NoEncore(gl_frontsector, false)); + HWR_GetLevelFlat(&levelflats[*rover->bottompic], R_NoEncore(gl_frontsector, &levelflats[*rover->bottompic], false)); light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); HWR_RenderPlane(sub, &extrasubsectors[num], false, *rover->bottomheight, HWR_RippleBlend(gl_frontsector, rover, false) | PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->bottompic], rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap); @@ -3180,7 +3180,7 @@ static void HWR_Subsector(size_t num) } else { - HWR_GetLevelFlat(&levelflats[*rover->toppic], R_NoEncore(gl_frontsector, true)); + HWR_GetLevelFlat(&levelflats[*rover->toppic], R_NoEncore(gl_frontsector, &levelflats[*rover->toppic], true)); light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); HWR_RenderPlane(sub, &extrasubsectors[num], true, *rover->topheight, HWR_RippleBlend(gl_frontsector, rover, true) | PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->toppic], rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap); @@ -4886,7 +4886,7 @@ static void HWR_CreateDrawNodes(void) gl_frontsector = NULL; if (!(sortnode[sortindex[i]].plane->blend & PF_NoTexture)) - HWR_GetLevelFlat(sortnode[sortindex[i]].plane->levelflat, R_NoEncore(sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->isceiling)); + HWR_GetLevelFlat(sortnode[sortindex[i]].plane->levelflat, R_NoEncore(sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->levelflat, sortnode[sortindex[i]].plane->isceiling)); HWR_RenderPlane(NULL, sortnode[sortindex[i]].plane->xsub, sortnode[sortindex[i]].plane->isceiling, sortnode[sortindex[i]].plane->fixedheight, sortnode[sortindex[i]].plane->blend, sortnode[sortindex[i]].plane->lightlevel, sortnode[sortindex[i]].plane->levelflat, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->planecolormap); } @@ -4896,7 +4896,7 @@ static void HWR_CreateDrawNodes(void) gl_frontsector = NULL; if (!(sortnode[sortindex[i]].polyplane->blend & PF_NoTexture)) - HWR_GetLevelFlat(sortnode[sortindex[i]].polyplane->levelflat, R_NoEncore(sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->isceiling)); + HWR_GetLevelFlat(sortnode[sortindex[i]].polyplane->levelflat, R_NoEncore(sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->levelflat, sortnode[sortindex[i]].polyplane->isceiling)); HWR_RenderPolyObjectPlane(sortnode[sortindex[i]].polyplane->polysector, sortnode[sortindex[i]].polyplane->isceiling, sortnode[sortindex[i]].polyplane->fixedheight, sortnode[sortindex[i]].polyplane->blend, sortnode[sortindex[i]].polyplane->lightlevel, sortnode[sortindex[i]].polyplane->levelflat, sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->alpha, sortnode[sortindex[i]].polyplane->planecolormap); } diff --git a/src/k_terrain.c b/src/k_terrain.c index 2d8f14d87..4f6367b3e 100644 --- a/src/k_terrain.c +++ b/src/k_terrain.c @@ -1486,7 +1486,7 @@ static void K_ParseTerrainParameter(size_t i, const char *param, const char *val } else if (stricmp(param, "offroad") == 0) { - terrain->offroad = (UINT8)get_number(val); // offroad strength enum? + terrain->offroad = FLOAT_TO_FIXED(atof(val)); } else if (stricmp(param, "damageType") == 0) { diff --git a/src/k_terrain.h b/src/k_terrain.h index 29ce0873e..399b6ba1c 100644 --- a/src/k_terrain.h +++ b/src/k_terrain.h @@ -111,7 +111,7 @@ typedef struct terrain_s size_t overlayID; // Overlay defintion ID. fixed_t friction; // The default friction of this texture. - UINT8 offroad; // The default offroad level of this texture. + fixed_t offroad; // The default offroad level of this texture. INT16 damageType; // The default damage type of this texture. (Negative means no damage). UINT8 trickPanel; // Trick panel strength fixed_t floorClip; // Offset for sprites on this ground diff --git a/src/p_setup.c b/src/p_setup.c index dec8ce107..a6642f3eb 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1494,6 +1494,8 @@ static void ParseTextmapSectorParameter(UINT32 i, const char *param, const char sectors[i].flags |= MSF_RIPPLE_FLOOR; else if (fastcmp(param, "ripple_ceiling") && fastcmp("true", val)) sectors[i].flags |= MSF_RIPPLE_CEILING; + else if (fastcmp(param, "invertencore") && fastcmp("true", val)) + sectors[i].flags |= MSF_INVERTENCORE; else if (fastcmp(param, "nostepup") && fastcmp("true", val)) sectors[i].specialflags |= SSF_NOSTEPUP; else if (fastcmp(param, "doublestepup") && fastcmp("true", val)) @@ -2325,6 +2327,8 @@ static void P_WriteTextmap(void) fprintf(f, "ripple_floor = true;\n"); if (wsectors[i].flags & MSF_RIPPLE_CEILING) fprintf(f, "ripple_ceiling = true;\n"); + if (wsectors[i].flags & MSF_INVERTENCORE) + fprintf(f, "invertencore = true;\n"); if (wsectors[i].specialflags & SSF_NOSTEPUP) fprintf(f, "nostepup = true;\n"); if (wsectors[i].specialflags & SSF_DOUBLESTEPUP) @@ -4026,7 +4030,6 @@ static void P_ConvertBinaryLinedefTypes(void) if (lines[i].flags & ML_DONTPEGTOP) sectors[s].flags |= MSF_RIPPLE_FLOOR; - if (lines[i].flags & ML_DONTPEGBOTTOM) sectors[s].flags |= MSF_RIPPLE_CEILING; } @@ -5788,18 +5791,23 @@ static void P_ConvertBinarySectorTypes(void) switch(GETSECSPECIAL(sectors[i].special, 1)) { case 1: //Damage - case 5: //Spikes sectors[i].damagetype = SD_GENERIC; break; case 2: //Offroad (Weak) + CONS_Alert(CONS_WARNING, "Offroad specials will be deprecated soon. Use the TERRAIN effect!\n"); sectors[i].offroad = FRACUNIT; break; case 3: //Offroad + CONS_Alert(CONS_WARNING, "Offroad specials will be deprecated soon. Use the TERRAIN effect!\n"); sectors[i].offroad = 2*FRACUNIT; break; case 4: //Offroad (Strong) + CONS_Alert(CONS_WARNING, "Offroad specials will be deprecated soon. Use the TERRAIN effect!\n"); sectors[i].offroad = 3*FRACUNIT; break; + case 5: //Spikes + sectors[i].damagetype = SD_GENERIC; + break; case 6: //Death pit (camera tilt) case 7: //Death pit (no camera tilt) sectors[i].damagetype = SD_DEATHPIT; @@ -5807,11 +5815,8 @@ static void P_ConvertBinarySectorTypes(void) case 8: //Instakill sectors[i].damagetype = SD_INSTAKILL; break; - case 11: //Special stage damage - //sectors[i].damagetype = SD_SPECIALSTAGE; - break; - case 12: //Space countdown - //sectors[i].specialflags |= SSF_OUTERSPACE; + case 12: //Wall sector + sectors[i].specialflags |= SSF_NOSTEPUP; break; case 13: //Ramp sector sectors[i].specialflags |= SSF_DOUBLESTEPUP; @@ -5853,12 +5858,19 @@ static void P_ConvertBinarySectorTypes(void) case 8: //Check for linedef executor on FOFs sectors[i].flags |= MSF_TRIGGERLINE_MOBJ; break; + case 15: //Invert Encore + sectors[i].flags |= MSF_INVERTENCORE; + break; default: break; } switch(GETSECSPECIAL(sectors[i].special, 3)) { + case 1: //Trick panel + case 3: + CONS_Alert(CONS_WARNING, "Trick Panel special is deprecated. Use the TERRAIN effect!\n"); + break; case 5: //Speed pad sectors[i].specialflags |= SSF_SPEEDPAD; break; @@ -5871,12 +5883,18 @@ static void P_ConvertBinarySectorTypes(void) case 1: //Star post activator sectors[i].specialflags |= SSF_STARPOSTACTIVATOR; break; - case 2: //Exit/Special Stage pit/Return flag + case 2: //Exit sectors[i].specialflags |= SSF_EXIT; break; case 5: //Fan sector sectors[i].specialflags |= SSF_FAN; break; + case 6: //Sneaker panel + CONS_Alert(CONS_WARNING, "Sneaker Panel special is deprecated. Use the TERRAIN effect!\n"); + break; + case 7: //Destroy items + sectors[i].specialflags |= SSF_DESTROYITEMS; + break; case 8: //Zoom tube start sectors[i].specialflags |= SSF_ZOOMTUBESTART; break; diff --git a/src/p_spec.c b/src/p_spec.c index b0c9584bb..7b09e8bb4 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4453,22 +4453,22 @@ static void P_ProcessSpeedPad(player_t *player, sector_t *sector, sector_t *rove static void P_ProcessExitSector(player_t *player, mtag_t sectag) { -#if 1 - (void)player; - (void)sectag; -#else INT32 lineindex; +#if 0 if (!(gametyperules & GTR_ALLOWEXIT)) return; +#endif // Exit (for FOF exits; others are handled in P_PlayerThink in p_user.c) P_DoPlayerFinish(player); P_SetupSignExit(player); +#if 0 if (!G_CoopGametype()) return; +#endif // Custom exit! // important: use sectag on next line instead of player->mo->subsector->tag @@ -4482,15 +4482,10 @@ static void P_ProcessExitSector(player_t *player, mtag_t sectag) return; } - // Special goodies depending on emeralds collected - if ((lines[lineindex].args[1] & TMEF_EMERALDCHECK) && ALLCHAOSEMERALDS(emeralds)) - nextmapoverride = (INT16)(udmf ? lines[lineindex].args[2] : lines[lineindex].frontsector->ceilingheight>>FRACBITS); - else - nextmapoverride = (INT16)(udmf ? lines[lineindex].args[0] : lines[lineindex].frontsector->floorheight>>FRACBITS); + nextmapoverride = (INT16)(udmf ? lines[lineindex].args[0] : lines[lineindex].frontsector->floorheight>>FRACBITS); if (lines[lineindex].args[1] & TMEF_SKIPTALLY) skipstats = 1; -#endif } static void P_ProcessZoomTube(player_t *player, mtag_t sectag, boolean end) diff --git a/src/r_bsp.c b/src/r_bsp.c index 5bed2eb0d..a40acdd08 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -41,31 +41,28 @@ drawseg_t *ds_p = NULL; // indicates doors closed wrt automap bugfix: INT32 doorclosed; -boolean R_NoEncore(sector_t *sector, boolean ceiling) +boolean R_NoEncore(sector_t *sector, levelflat_t *flat, boolean ceiling) { - // FIXME: UDMFify - /* - boolean invertencore = (GETSECSPECIAL(sector->special, 2) == 15); -#if 0 // perfect implementation - INT32 val = GETSECSPECIAL(sector->special, 3); - //if (val != 1 && val != 3 // spring panel -#else // optimised, see #define GETSECSPECIAL(i,j) ((i >> ((j-1)*4))&15) - if ((!(sector->special & (1<<8)) || (sector->special & ((4|8)<<8))) // spring panel -#endif - && GETSECSPECIAL(sector->special, 4) != 6) // sneaker panel - return invertencore; + const boolean invertEncore = (sector->flags & MSF_INVERTENCORE); + const terrain_t *terrain = (flat != NULL ? flat->terrain : NULL); - if (invertencore) + if ((terrain == NULL) + || (terrain->trickPanel <= 0 && !(terrain->flags & TRF_SNEAKERPANEL))) + { + return invertEncore; + } + + if (invertEncore) + { return false; + } if (ceiling) + { return ((boolean)(sector->flags & MSF_FLIPSPECIAL_CEILING)); - return ((boolean)(sector->flags & MSF_FLIPSPECIAL_FLOOR)); - */ + } - (void)sector; - (void)ceiling; - return false; + return ((boolean)(sector->flags & MSF_FLIPSPECIAL_FLOOR)); } boolean R_IsRipplePlane(sector_t *sector, ffloor_t *rover, int ceiling) @@ -953,7 +950,7 @@ static void R_Subsector(size_t num) frontsector->floorheight, frontsector->floorpic, floorlightlevel, frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL, NULL, frontsector->f_slope, - R_NoEncore(frontsector, false), + R_NoEncore(frontsector, &levelflats[frontsector->floorpic], false), R_IsRipplePlane(frontsector, NULL, false), false ); @@ -969,7 +966,7 @@ static void R_Subsector(size_t num) frontsector->ceilingheight, frontsector->ceilingpic, ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle, ceilingcolormap, NULL, NULL, frontsector->c_slope, - R_NoEncore(frontsector, true), + R_NoEncore(frontsector, &levelflats[frontsector->ceilingpic], true), R_IsRipplePlane(frontsector, NULL, true), true ); @@ -1017,7 +1014,7 @@ static void R_Subsector(size_t num) *rover->bottomheight, *rover->bottompic, *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, *rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope, - R_NoEncore(rover->master->frontsector, true), + R_NoEncore(rover->master->frontsector, &levelflats[*rover->bottompic], true), R_IsRipplePlane(rover->master->frontsector, rover, true), true ); @@ -1051,7 +1048,7 @@ static void R_Subsector(size_t num) *rover->topheight, *rover->toppic, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->t_slope, - R_NoEncore(rover->master->frontsector, false), + R_NoEncore(rover->master->frontsector, &levelflats[*rover->toppic], false), R_IsRipplePlane(rover->master->frontsector, rover, false), false ); @@ -1101,7 +1098,7 @@ static void R_Subsector(size_t num) polysec->floorpic_angle-po->angle, (light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po, NULL, // will ffloors be slopable eventually? - R_NoEncore(polysec, false), + R_NoEncore(polysec, &levelflats[polysec->floorpic], false), false, /* TODO: wet polyobjects? */ true ); @@ -1130,7 +1127,7 @@ static void R_Subsector(size_t num) (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->ceiling_xoffs, polysec->ceiling_yoffs, polysec->ceilingpic_angle-po->angle, (light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po, NULL, // will ffloors be slopable eventually? - R_NoEncore(polysec, true), + R_NoEncore(polysec, &levelflats[polysec->ceilingpic], true), false, /* TODO: wet polyobjects? */ false ); diff --git a/src/r_bsp.h b/src/r_bsp.h index 48edd7caa..0c232d67b 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -42,7 +42,7 @@ void R_RenderBSPNode(INT32 bspnum); // determines when a given sector shouldn't abide by the encoremap's palette. // no longer a static since this is used for encore in hw_main.c as well now: -boolean R_NoEncore(sector_t *sector, boolean ceiling); +boolean R_NoEncore(sector_t *sector, levelflat_t *flat, boolean ceiling); boolean R_IsRipplePlane(sector_t *sector, ffloor_t *rover, int ceiling); diff --git a/src/r_defs.h b/src/r_defs.h index 3f801c197..f4aec08f4 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -345,6 +345,8 @@ typedef enum // water ripple MSF_RIPPLE_FLOOR = 1<<10, MSF_RIPPLE_CEILING = 1<<11, + // invert encore color remap status + MSF_INVERTENCORE = 1<<12, } sectorflags_t; typedef enum From 3f94c6def8d9d512a9cfe79897f9dd437d836411 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 06:10:38 -0400 Subject: [PATCH 23/54] Fix wrong names --- src/p_setup.c | 2 +- src/p_spec.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index a6642f3eb..93f079fea 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -5893,7 +5893,7 @@ static void P_ConvertBinarySectorTypes(void) CONS_Alert(CONS_WARNING, "Sneaker Panel special is deprecated. Use the TERRAIN effect!\n"); break; case 7: //Destroy items - sectors[i].specialflags |= SSF_DESTROYITEMS; + sectors[i].specialflags |= SSF_DELETEITEMS; break; case 8: //Zoom tube start sectors[i].specialflags |= SSF_ZOOMTUBESTART; diff --git a/src/p_spec.c b/src/p_spec.c index 7b09e8bb4..835091c07 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4461,7 +4461,7 @@ static void P_ProcessExitSector(player_t *player, mtag_t sectag) #endif // Exit (for FOF exits; others are handled in P_PlayerThink in p_user.c) - P_DoPlayerFinish(player); + P_DoPlayerExit(player); P_SetupSignExit(player); From 7ceab1f10118fb007e70331f6acfe8e97682279e Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 06:44:55 -0400 Subject: [PATCH 24/54] Fix solid midtextures not working IDK which part was the fix, so I'm keeping all of it LOL --- src/p_maputl.c | 17 ++++++++++++----- src/p_setup.c | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/p_maputl.c b/src/p_maputl.c index 5f547773b..ab810e437 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -576,12 +576,20 @@ P_GetMidtextureTopBottom static boolean P_MidtextureIsSolid(line_t *linedef, mobj_t *mobj) { - if (P_IsLineTripWire(linedef) == true) + if (linedef->polyobj) { - return (mobj->player && !K_TripwirePass(mobj->player)); + // don't do anything for polyobjects! ...for now + return false; } - return (linedef->flags & ML_MIDSOLID); + if (P_IsLineTripWire(linedef) == true) + { + // Tripwire behavior. + return (mobj->player != NULL && K_TripwirePass(mobj->player) == false); + } + + // Determined solely by the flag. + return ((linedef->flags & ML_MIDSOLID) == ML_MIDSOLID); } void P_LineOpening(line_t *linedef, mobj_t *mobj) @@ -692,8 +700,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) if (mobj) { // Check for collision with front side's midtexture if Effect 4 is set - if (P_MidtextureIsSolid(linedef, mobj) == true - && !linedef->polyobj) // don't do anything for polyobjects! ...for now + if (P_MidtextureIsSolid(linedef, mobj) == true) { fixed_t textop, texbottom; fixed_t texmid, delta1, delta2; diff --git a/src/p_setup.c b/src/p_setup.c index 93f079fea..49d14d65e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -967,7 +967,7 @@ static void P_LoadLinedefs(UINT8 *data) for (i = 0; i < numlines; i++, mld++, ld++) { - ld->flags = SHORT(mld->flags); + ld->flags = (UINT32)(SHORT(mld->flags)); ld->special = SHORT(mld->special); Tag_FSet(&ld->tags, SHORT(mld->tag)); memset(ld->args, 0, NUMLINEARGS*sizeof(*ld->args)); From a8ac5a992220732b39c85341004168268402914b Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 07:00:08 -0400 Subject: [PATCH 25/54] Make Kart Z FOF Thwomp delay use args --- src/p_floor.c | 16 ++++++++++------ src/p_saveg.c | 1 + src/p_setup.c | 2 ++ src/p_spec.c | 1 + src/p_spec.h | 1 + 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index b394ab811..268c289cc 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1058,14 +1058,18 @@ void T_ThwompSector(thwomp_t *thwomp) INT32 secnum; fixed_t speed; + if (thwompsactive == false) + { + // Ring Racers: Rest until Lap 2 + return; + } + // SRB2kart 170217 - Thwomps are automatic. // Put up a timer before you start falling down. - // I could of used rowoffset, but the FOF actually - // modifies the textures's Y offset. It doesn't with - // textureoffset, so Effect 4 can be ignored as usual. - if ((thwomp->sourceline->flags & ML_SKEWTD) // FIXME: UDMFify - && leveltime < (unsigned)(sides[thwomp->sourceline->sidenum[0]].textureoffset>>FRACBITS)) - thwomp->direction = 0; + if (--thwomp->initDelay > 0) + { + return; + } // If you just crashed down, wait a second before coming back up. if (--thwomp->delay > 0) diff --git a/src/p_saveg.c b/src/p_saveg.c index 105ab1a74..ce9902833 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2259,6 +2259,7 @@ static void SaveThwompThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->delay); WRITEINT16(save_p, ht->tag); WRITEUINT16(save_p, ht->sound); + WRITEINT32(save_p, ht->initDelay); } static void SaveFloatThinker(const thinker_t *th, const UINT8 type) diff --git a/src/p_setup.c b/src/p_setup.c index 49d14d65e..ea406559c 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -4529,6 +4529,8 @@ static void P_ConvertBinaryLinedefTypes(void) } if (lines[i].flags & ML_MIDSOLID) P_WriteConstant(sides[lines[i].sidenum[0]].textureoffset >> FRACBITS, &lines[i].stringargs[0]); + if (lines[i].flags & ML_SKEWTD) // Kart Z delay. Yes, it used the same field as the above. + lines[i].args[3] = (unsigned)(sides[lines[i].sidenum[0]].textureoffset >> FRACBITS); break; case 252: //FOF: Shatter block case 253: //FOF: Shatter block, translucent diff --git a/src/p_spec.c b/src/p_spec.c index 835091c07..0b7eada6b 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5469,6 +5469,7 @@ static inline void P_AddThwompThinker(sector_t *sec, line_t *sourceline, fixed_t thwomp->delay = 1; thwomp->tag = sourceline->args[0]; thwomp->sound = sound; + thwomp->initDelay = sourceline->args[3]; sec->floordata = thwomp; sec->ceilingdata = thwomp; diff --git a/src/p_spec.h b/src/p_spec.h index 08aa6016b..33ecd0b4e 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -848,6 +848,7 @@ typedef struct INT32 delay; INT16 tag; UINT16 sound; + INT32 initDelay; } thwomp_t; typedef struct From 032ffafd399d3052c0c69922a97d2adbda088712 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 07:02:45 -0400 Subject: [PATCH 26/54] Award Player Rings uses args for overload --- src/p_setup.c | 1 + src/p_spec.c | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index ea406559c..3e25096fa 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -5356,6 +5356,7 @@ static void P_ConvertBinaryLinedefTypes(void) case 460: //Award rings lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; + lines[i].args[2] = !!(lines[i].flags & ML_NOCLIMB); break; case 461: //Spawn object lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; diff --git a/src/p_spec.c b/src/p_spec.c index 0b7eada6b..0a80d15f6 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3475,9 +3475,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if (delay <= 0 || !(leveltime % delay)) { - // No Climb: don't cap rings to 20 - K_AwardPlayerRings(mo->player, rings, - (line->flags & ML_NOCLIMB) == ML_NOCLIMB); + // args[2]: don't cap rings to 20 + K_AwardPlayerRings(mo->player, rings, line->args[2]); } } } From 436c763a02f12f45e8819a6a3d7f08fd1303b585 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 07:22:42 -0400 Subject: [PATCH 27/54] Make MT_WAYPOINT fully use args All of its special flags are contained on args[2] now. --- src/p_mobj.c | 8 ++++---- src/p_setup.c | 23 ++++++++++++++++++++++- src/p_spec.h | 8 ++++++++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 078b93fdb..011ba8eec 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12565,7 +12565,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean // extravalue2 is used for indicating the waypoint is the finishline mobj->threshold = mthing->args[0]; mobj->movecount = tag; - if (mthing->options & MTF_EXTRA) + if (mthing->args[2] & TMWPF_DISABLED) { mobj->extravalue1 = 0; // The waypoint is disabled if extra is on } @@ -12573,7 +12573,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean { mobj->extravalue1 = 1; } - if (mthing->options & MTF_OBJECTSPECIAL) + if (mthing->args[2] & TMWPF_SHORTCUT) { mobj->lastlook = 1; // the waypoint is a shortcut if objectspecial is on } @@ -12581,7 +12581,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean { mobj->lastlook = 0; } - if (mthing->options & MTF_AMBUSH) + if (mthing->args[2] & TMWPF_NORESPAWN) { mobj->reactiontime = 0; // Can't respawn at if Ambush is on } @@ -12589,7 +12589,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean { mobj->reactiontime = 1; } - if (mthing->args[2] == 1) + if (mthing->args[2] & TMWPF_FINISHLINE) { mobj->extravalue2 = 1; // args[2] of 1 means the waypoint is at the finish line mobj->reactiontime = 0; // Also don't respawn at finish lines diff --git a/src/p_setup.c b/src/p_setup.c index 3e25096fa..1c2099357 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -6456,8 +6456,8 @@ static void P_ConvertBinaryThingTypes(void) INT32 firstline = Tag_FindLineSpecial(2000, (INT16)mapthings[i].angle); Tag_FSet(&mapthings[i].tags, mapthings[i].angle); + mapthings[i].args[0] = mapthings[i].z; - mapthings[i].args[2] = mapthings[i].extrainfo; mapthings[i].z = 0; if (firstline != -1) @@ -6470,6 +6470,27 @@ static void P_ConvertBinaryThingTypes(void) mapthings[i].z = linez / FRACUNIT; } + + if (mapthings[i].extrainfo == 1) + { + mapthings[i].args[2] |= TMWPF_FINISHLINE; + } + + if (mapthings[i].options & MTF_EXTRA) + { + mapthings[i].args[2] |= TMWPF_DISABLED; + } + + if (mapthings[i].options & MTF_OBJECTSPECIAL) + { + mapthings[i].args[2] |= TMWPF_SHORTCUT; + } + + if (mapthings[i].options & MTF_AMBUSH) + { + mapthings[i].args[2] |= TMWPF_NORESPAWN; + } + break; } case 2004: // MT_BOTHINT diff --git a/src/p_spec.h b/src/p_spec.h index 33ecd0b4e..1d9496690 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -49,6 +49,14 @@ typedef enum 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, From c1581d0f75546e6011b0febd8e8bf9754f8997db Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 07:48:55 -0400 Subject: [PATCH 28/54] Egg Capsules use args + optimized tube waypoints --- src/k_battle.c | 43 +++++++-------------------------- src/p_mobj.c | 64 ++++++-------------------------------------------- src/p_setup.c | 10 ++++++++ src/p_spec.h | 6 +++++ 4 files changed, 32 insertions(+), 91 deletions(-) diff --git a/src/k_battle.c b/src/k_battle.c index c918daec7..e76581839 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -18,6 +18,7 @@ #include "m_random.h" #include "r_sky.h" // skyflatnum #include "k_grandprix.h" // K_CanChangeRules +#include "p_spec.h" // Battle overtime info struct battleovertime battleovertime; @@ -701,44 +702,18 @@ void K_SetupMovingCapsule(mapthing_t *mt, mobj_t *mobj) { UINT8 sequence = mt->args[0] - 1; fixed_t speed = (FRACUNIT >> 3) * mt->args[1]; - boolean backandforth = (mt->options & MTF_AMBUSH); - boolean reverse = (mt->options & MTF_OBJECTSPECIAL); - mobj_t *mo2; + boolean backandforth = (mt->args[2] & TMBCF_BACKANDFORTH); + boolean reverse = (mt->args[2] & TMBCF_REVERSE); mobj_t *target = NULL; - thinker_t *th; - - // TODO: This and the movement stuff in the thinker should both be using - // 2.2's new optimized functions for doing things with tube waypoints // Find the inital target - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + if (reverse) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold == sequence) - { - if (reverse) // Use the highest waypoint number as first - { - if (mo2->health != 0) - { - if (target == NULL) - target = mo2; - else if (mo2->health > target->health) - target = mo2; - } - } - else // Use the lowest waypoint number as first - { - if (mo2->health == 0) - target = mo2; - } - } + target = P_GetLastTubeWaypoint(sequence); + } + else + { + target = P_GetFirstTubeWaypoint(sequence); } if (!target) diff --git a/src/p_mobj.c b/src/p_mobj.c index 011ba8eec..6604efe02 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8857,11 +8857,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) { fixed_t speed = mobj->movefactor; UINT8 sequence = mobj->lastlook; - UINT8 num = mobj->movecount; boolean backandforth = (mobj->flags2 & MF2_AMBUSH); SINT8 direction = mobj->cvmem; mobj_t *next = NULL; - thinker_t *th; fixed_t dist, momx, momy, momz; dist = P_AproxDistance(mobj->target->x - mobj->x, mobj->target->y - mobj->y); @@ -8884,8 +8882,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj) } else { - mobj_t *mo2; - speed -= dist; P_UnsetThingPosition(mobj); @@ -8898,25 +8894,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->ceilingz = mobj->subsector->sector->ceilingheight; // Onto the next waypoint! - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold == sequence) - { - if (mo2->health == num + direction) - { - next = mo2; - break; - } - } - } + next = (direction < 0) ? P_GetPreviousTubeWaypoint(mobj->target, false) : P_GetNextTubeWaypoint(mobj->target, false); // Are we at the end of the waypoint chain? // If so, search again for the first/previous waypoint (depending on settings) @@ -8924,44 +8902,16 @@ static boolean P_MobjRegularThink(mobj_t *mobj) { if (backandforth) { + // Back and forth movement. mobj->cvmem = -mobj->cvmem; direction = mobj->cvmem; + + next = (direction < 0) ? P_GetPreviousTubeWaypoint(mobj->target, false) : P_GetNextTubeWaypoint(mobj->target, false); } - - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + else { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type != MT_TUBEWAYPOINT) - continue; - - if (mo2->threshold == sequence) - { - if (backandforth) - { - if (mo2->health == num + direction) - { - next = mo2; - break; - } - } - else - { - if (direction < 0) - { - if (next == NULL || mo2->health > next->health) - next = mo2; - } - else - { - if (next == NULL || mo2->health < next->health) - next = mo2; - } - } - } + // Looping circular movement. + next = (direction < 0) ? P_GetLastTubeWaypoint(sequence) : P_GetFirstTubeWaypoint(sequence); } } diff --git a/src/p_setup.c b/src/p_setup.c index 1c2099357..ef2072622 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -6500,6 +6500,16 @@ static void P_ConvertBinaryThingTypes(void) case 2333: // MT_BATTLECAPSULE mapthings[i].args[0] = mapthings[i].extrainfo; mapthings[i].args[1] = mapthings[i].angle; + + if (mapthings[i].options & MTF_OBJECTSPECIAL) + { + mapthings[i].args[2] |= TMBCF_REVERSE; + } + + if (mapthings[i].options & MTF_AMBUSH) + { + mapthings[i].args[2] |= TMBCF_BACKANDFORTH; + } break; default: break; diff --git a/src/p_spec.h b/src/p_spec.h index 1d9496690..8daad8575 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -57,6 +57,12 @@ typedef enum TMWPF_FINISHLINE = 1<<3, } textmapwaypointflags_t; +typedef enum +{ + TMBCF_BACKANDFORTH = 1, + TMBCF_REVERSE = 1<<1, +} textmapbattlecapsuleflags_t; + typedef enum { TMFF_AIMLESS = 1, From 77ec64497ca4a92dfcaa47294bf85b11495e0bc3 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 07:58:28 -0400 Subject: [PATCH 29/54] Item Capsules use args --- src/p_mobj.c | 16 ++++++---------- src/p_setup.c | 20 ++++++++++++++++++++ src/p_spec.h | 6 ++++++ 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 6604efe02..d4f8efcf3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11666,7 +11666,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) { case MT_ITEMCAPSULE: { - boolean isRingCapsule = (mthing->angle < 1 || mthing->angle == KITEM_SUPERRING || mthing->angle >= NUMKARTITEMS); + boolean isRingCapsule = (mthing->args[0] < 1 || mthing->args[0] == KITEM_SUPERRING || mthing->args[0] >= NUMKARTITEMS); // don't spawn ring capsules in GTR_SPHERES gametypes if (isRingCapsule && (gametyperules & GTR_SPHERES)) @@ -11675,7 +11675,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) // in record attack, only spawn ring capsules // (behavior can be inverted with the Extra flag, i.e. item capsule spawns and ring capsule does not) if (modeattacking - && (!(mthing->options & MTF_EXTRA) == !isRingCapsule)) + && (!(mthing->args[2] & TMICF_INVERTTIMEATTACK) == !isRingCapsule)) return false; } break; @@ -12624,18 +12624,14 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean mobj->flags |= MF_NOGRAVITY; // Angle = item type - if (mthing->angle > 0 && mthing->angle < NUMKARTITEMS) - mobj->threshold = mthing->angle; + if (mthing->args[0] > 0 && mthing->args[0] < NUMKARTITEMS) + mobj->threshold = mthing->args[0]; // Parameter = extra items (x5 for rings) - mobj->movecount += mthing->extrainfo; - - // Special = +16 items (+80 for rings) - if (mthing->options & MTF_OBJECTSPECIAL) - mobj->movecount += 16; + mobj->movecount += mthing->args[1]; // Ambush = double size (grounded) / half size (aerial) - if (!(mthing->options & MTF_AMBUSH) == !P_IsObjectOnGround(mobj)) + if (!(mthing->args[2] & TMICF_INVERTSIZE) == !P_IsObjectOnGround(mobj)) { mobj->extravalue1 = min(mobj->extravalue1 << 1, FixedDiv(64*FRACUNIT, mobj->info->radius)); // don't make them larger than the blockmap can handle mobj->scalespeed <<= 1; diff --git a/src/p_setup.c b/src/p_setup.c index ef2072622..fecb5bf20 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -6497,6 +6497,26 @@ static void P_ConvertBinaryThingTypes(void) mapthings[i].args[0] = mapthings[i].angle; mapthings[i].args[1] = mapthings[i].extrainfo; break; + case 2010: // MT_ITEMCAPSULE + mapthings[i].args[0] = mapthings[i].angle; + mapthings[i].args[1] = mapthings[i].extrainfo; + + if (mapthings[i].options & MTF_OBJECTSPECIAL) + { + // Special = +16 items (+80 for rings) + mapthings[i].args[1] += 16; + } + + if (mapthings[i].options & MTF_EXTRA) + { + mapthings[i].args[2] |= TMICF_INVERTTIMEATTACK; + } + + if (mapthings[i].options & MTF_AMBUSH) + { + mapthings[i].args[2] |= TMICF_INVERTSIZE; + } + break; case 2333: // MT_BATTLECAPSULE mapthings[i].args[0] = mapthings[i].extrainfo; mapthings[i].args[1] = mapthings[i].angle; diff --git a/src/p_spec.h b/src/p_spec.h index 8daad8575..096690d48 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -63,6 +63,12 @@ typedef enum TMBCF_REVERSE = 1<<1, } textmapbattlecapsuleflags_t; +typedef enum +{ + TMICF_INVERTTIMEATTACK = 1, + TMICF_INVERTSIZE = 1<<1, +} textmapitemcapsuleflags_t; + typedef enum { TMFF_AIMLESS = 1, From aa7e26e40ef1ef49c862f158799ab88ad4bc86f4 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 08:03:41 -0400 Subject: [PATCH 30/54] Fix credit on ChangeMusic, use args --- src/p_setup.c | 2 ++ src/p_spec.c | 6 +++--- src/p_spec.h | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index fecb5bf20..373222a2a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -4944,6 +4944,8 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[0] |= TMM_FORCERESET; if (lines[i].flags & ML_MIDSOLID) lines[i].args[0] |= TMM_NOLOOP; + if (lines[i].flags & ML_MIDPEG) + lines[i].args[0] |= TMM_NOCREDIT; lines[i].args[1] = sides[lines[i].sidenum[0]].midtexture; lines[i].args[2] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; lines[i].args[3] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; diff --git a/src/p_spec.c b/src/p_spec.c index 0a80d15f6..132b113aa 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2451,9 +2451,6 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) else S_FadeMusicFromVolume(fadetarget, fadesource, postfadems); - //if (!(line->flags & ML_EFFECT3)) // FIXME: UDMFify - S_ShowMusicCredit(); - if (position) S_SetMusicPosition(position); } @@ -2479,6 +2476,9 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) !(line->args[0] & TMM_FADE) ? prefadems : 0, !(line->args[0] & TMM_FADE) ? postfadems : 0); + if (!(line->args[0] & TMM_NOCREDIT)) + S_ShowMusicCredit(); + if ((line->args[0] & TMM_FADE) && fadetarget) { if (!postfadems) diff --git a/src/p_spec.h b/src/p_spec.h index 096690d48..c07a65b71 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -343,6 +343,7 @@ typedef enum TMM_NORELOAD = 1<<3, TMM_FORCERESET = 1<<4, TMM_NOLOOP = 1<<5, + TMM_NOCREDIT = 1<<6, } textmapmusicflags_t; typedef enum From 7f755016060490b307b4d23d6224abc6ceb90a32 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 08:55:49 -0400 Subject: [PATCH 31/54] Linedef 80 updated - Uses args instead of texture offsets. - Compares tag lists, instead of thing angle. - Made the arguments accept 0 as a "catch-all" option (args[0] == 0 means don't care what type it is; line tag == 0 means don't care what tags they have) --- src/p_setup.c | 4 ++++ src/p_spec.c | 27 +++++++++++++++++++++------ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 373222a2a..cbd5a9979 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -4215,6 +4215,10 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[0] = tag; lines[i].args[1] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; break; + case 80: //Raise tagged things by type to this FOF + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + // angle will be converted to tags elsewhere, because they aren't ready yet... + break; case 81: //Block enemies lines[i].flags |= ML_BLOCKMONSTERS; lines[i].special = 0; diff --git a/src/p_spec.c b/src/p_spec.c index 132b113aa..0fe83adea 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5241,7 +5241,7 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, I static void P_RaiseTaggedThingsToFakeFloor ( UINT16 type, - INT16 tag, + const taglist_t *tags, sector_t *control ){ sector_t *target; @@ -5261,9 +5261,25 @@ P_RaiseTaggedThingsToFakeFloor ( { mthing = mo->spawnpoint; + if (mthing == NULL) + { + continue; + } + + if (!udmf) + { + // We have to convert these here, as mobjs, let alone + // sector thing lists, don't exist at the time of the rest + // of the binary map conversion. + const mtag_t convertTag = mthing->angle; + + Tag_Add(&mthing->tags, convertTag); + Taggroup_Add(tags_mapthings, convertTag, (size_t)(mthing - mapthings)); + } + if ( - mthing->type == type && - mthing->angle == tag + (type == 0 || mthing->type == type) && + (tags->count == 0 || Tag_Share(&mthing->tags, tags)) ){ if (( mo->flags2 & MF2_OBJECTFLIP )) { @@ -6805,10 +6821,9 @@ void P_SpawnSpecialsThatRequireObjects(boolean fromnetsave) case 80: // Raise tagged things by type to this FOF { - mtag_t tag = Tag_FGet(&lines[i].tags); P_RaiseTaggedThingsToFakeFloor( - ( sides[lines[i].sidenum[0]].textureoffset >> FRACBITS ), - tag, + lines[i].args[0], + &lines[i].tags, lines[i].frontsector ); } From 6fb56cc9407e03d5cf7dbb5b55e200297a10a017 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 09:12:41 -0400 Subject: [PATCH 32/54] Finish line + respawn line use args --- src/p_setup.c | 8 ++++++++ src/p_spec.c | 6 +++--- src/p_spec.h | 10 ++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index cbd5a9979..be1276a42 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -5754,6 +5754,14 @@ static void P_ConvertBinaryLinedefTypes(void) case 909: //Fog wall lines[i].blendmode = AST_FOG; break; + case 2001: //Finish line + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[0] |= TMCFF_FLIP; + break; + case 2004: //Respawn line + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[0] |= TMCRF_FRONTONLY; + break; default: break; } diff --git a/src/p_spec.c b/src/p_spec.c index 0fe83adea..8e525dcab 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2079,8 +2079,8 @@ void P_CrossSpecialLine(line_t *line, INT32 side, mobj_t *thing) { if ((gametyperules & GTR_CIRCUIT) && !(player->exiting) && !(player->pflags & PF_HITFINISHLINE)) { - if (((line->flags & (ML_NOCLIMB)) && (side == 0)) - || (!(line->flags & (ML_NOCLIMB)) && (side == 1))) // crossed from behind to infront + if (((line->args[0] & TMCFF_FLIP) && (side == 0)) + || (!(line->args[0] & TMCFF_FLIP) && (side == 1))) // crossed from behind to infront { K_HandleLapIncrement(player); } @@ -2100,7 +2100,7 @@ void P_CrossSpecialLine(line_t *line, INT32 side, mobj_t *thing) if ( player->respawn.state == RESPAWNST_NONE && - (!(line->flags & ML_NOCLIMB) || side == 0) + (!(line->args[0] & TMCRF_FRONTONLY) || side == 0) ) { P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DEATHPIT); diff --git a/src/p_spec.h b/src/p_spec.h index c07a65b71..e3cae0bfe 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -484,6 +484,16 @@ typedef enum TMB_MODULATE = 4, } textmapblendmodes_t; +typedef enum +{ + TMCFF_FLIP = 1, +} textmapcrossfinishflags_t; + +typedef enum +{ + TMCRF_FRONTONLY = 1, +} textmapcrossrespawnflags_t; + // GETSECSPECIAL (specialval, section) // // Pulls out the special # from a particular section. From 5ef177cc945ec43253a1c15a8a937ef797298782 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 09:13:36 -0400 Subject: [PATCH 33/54] Oops, wrong number... --- src/p_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index be1276a42..d86f9bcea 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -5758,7 +5758,7 @@ static void P_ConvertBinaryLinedefTypes(void) if (lines[i].flags & ML_NOCLIMB) lines[i].args[0] |= TMCFF_FLIP; break; - case 2004: //Respawn line + case 2003: //Respawn line if (lines[i].flags & ML_NOCLIMB) lines[i].args[0] |= TMCRF_FRONTONLY; break; From c2cc84774610e17dc83e587ee5ecdbe6d4401c7a Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 09:42:26 -0400 Subject: [PATCH 34/54] Save waypoint riser / anchor data into spawnpoint Allows -writetextmap to write the changes from these binary-only things. --- src/k_waypoint.c | 10 ++++++++++ src/p_setup.c | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/src/k_waypoint.c b/src/k_waypoint.c index 2c9ebec9a..28ff00d04 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -2238,6 +2238,7 @@ static boolean K_RaiseWaypoint( fixed_t sort; fixed_t z; + fixed_t delta; if ( !( riser->spawnpoint->options & MTF_OBJECTSPECIAL ) || @@ -2282,6 +2283,13 @@ static boolean K_RaiseWaypoint( } } + // Keep changes for -writetextmap + if (descending) + delta = sort - waypointmobj->z; + else + delta = waypointmobj->z - sort; + waypointmobj->spawnpoint->z += delta; + waypointmobj->z = sort; } @@ -2316,6 +2324,8 @@ static boolean K_AnchorWaypointRadius( waypointmobj->x, waypointmobj->y, anchor->x, anchor->y); + // Keep changes for -writetextmap + waypointmobj->spawnpoint->args[0] = waypointmobj->radius >> FRACBITS; return true; } else diff --git a/src/p_setup.c b/src/p_setup.c index d86f9bcea..b268078fc 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -6593,8 +6593,11 @@ static void P_ConvertBinaryMap(void) P_ConvertBinarySectorTypes(); P_ConvertBinaryThingTypes(); P_ConvertBinaryLinedefFlags(); + +#if 0 // Don't do this yet... if (M_CheckParm("-writetextmap")) P_WriteTextmap(); +#endif } /** Compute MD5 message digest for bytes read from memory source @@ -7433,6 +7436,10 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) { // Backwards compatibility for non-UDMF maps K_AdjustWaypointsParameters(); + + // Moved over here... + if (M_CheckParm("-writetextmap")) + P_WriteTextmap(); } if (!fromnetsave) // ugly hack for P_NetUnArchiveMisc (and P_LoadNetGame) From 983304f361085ca8e8aa3f2870ea9a66756a1ae8 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 10:16:40 -0400 Subject: [PATCH 35/54] Update birdslopes to use args --- src/p_mobj.c | 2 +- src/p_setup.c | 27 ++++++++++++++++++++++ src/p_slopes.h | 14 ++++++++++++ src/p_spec.h | 9 +++++--- src/slope_anchors.c | 56 ++++++++++++++++++--------------------------- 5 files changed, 70 insertions(+), 38 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index d4f8efcf3..41f56dcd3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11648,7 +11648,7 @@ static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing) return true; } else if (mthing->type == 750 // Slope vertex point (formerly chaos spawn) - || (mthing->type == 777 || mthing->type == 778) // Slope anchors + || (mthing->type == FLOOR_SLOPE_THING || mthing->type == CEILING_SLOPE_THING) // Slope anchors || (mthing->type >= 600 && mthing->type <= 611) // Special placement patterns || mthing->type == 1713) // Hoops { diff --git a/src/p_setup.c b/src/p_setup.c index b268078fc..8b2cf2127 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -5751,6 +5751,29 @@ static void P_ConvertBinaryLinedefTypes(void) case 799: //Set dynamic slope vertex to front sector height lines[i].args[0] = !!(lines[i].flags & ML_NOCLIMB); break; + case LT_SLOPE_ANCHORS_OLD_FLOOR: //Slope front sector floor by 3 tagged vertices + case LT_SLOPE_ANCHORS_OLD_CEILING: //Slope front sector ceiling by 3 tagged vertices + case LT_SLOPE_ANCHORS_OLD: //Slope back sector floor by 3 tagged vertices + { + if (lines[i].special == LT_SLOPE_ANCHORS_OLD_FLOOR) + lines[i].args[0] = TMSA_FLOOR; + else if (lines[i].special == LT_SLOPE_ANCHORS_OLD_CEILING) + lines[i].args[0] = TMSA_CEILING; + else if (lines[i].special == LT_SLOPE_ANCHORS_OLD) + lines[i].args[0] = (TMSA_FLOOR|TMSA_CEILING); + + if (lines[i].flags & ML_NETONLY) + lines[i].args[1] |= TMSAF_NOPHYSICS; + if (lines[i].flags & ML_NONET) + lines[i].args[1] |= TMSAF_DYNAMIC; + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[1] |= TMSAF_BACKSIDE; + if (lines[i].flags & ML_BLOCKMONSTERS) + lines[i].args[1] |= TMSAF_MIRROR; + + lines[i].special = LT_SLOPE_ANCHORS; + break; + } case 909: //Fog wall lines[i].blendmode = AST_FOG; break; @@ -6545,6 +6568,10 @@ static void P_ConvertBinaryThingTypes(void) mapthings[i].args[2] |= TMBCF_BACKANDFORTH; } break; + case FLOOR_SLOPE_THING: + case CEILING_SLOPE_THING: + Tag_FSet(&mapthings[i].tags, mapthings[i].extrainfo); + break; default: break; } diff --git a/src/p_slopes.h b/src/p_slopes.h index 12d10e020..5543b785f 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -48,6 +48,20 @@ typedef enum TMSL_COPY = 1<<2, } textmapslopeflags_t; +typedef enum +{ + TMSA_FLOOR = 1, + TMSA_CEILING = 1<<1, +} textmapslopeanchor_t; + +typedef enum +{ + TMSAF_NOPHYSICS = 1, + TMSAF_DYNAMIC = 1<<1, + TMSAF_BACKSIDE = 1<<2, + TMSAF_MIRROR = 1<<3, +} textmapslopeanchorflags_t; + void P_LinkSlopeThinkers (void); void P_UpdateSlopeLightOffset(pslope_t *slope); diff --git a/src/p_spec.h b/src/p_spec.h index e3cae0bfe..ac501d056 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -1119,9 +1119,12 @@ void P_CalcHeight(player_t *player); /* line specials */ enum { - LT_SLOPE_ANCHORS_FLOOR = 777, - LT_SLOPE_ANCHORS_CEILING = 778, - LT_SLOPE_ANCHORS = 779, + LT_SLOPE_ANCHORS = 777, + + // binary converter + LT_SLOPE_ANCHORS_OLD_FLOOR = 777, + LT_SLOPE_ANCHORS_OLD_CEILING = 778, + LT_SLOPE_ANCHORS_OLD = 779, }; #endif diff --git a/src/slope_anchors.c b/src/slope_anchors.c index 2c8f4959d..d40fc7318 100644 --- a/src/slope_anchors.c +++ b/src/slope_anchors.c @@ -199,7 +199,7 @@ get_anchor for (i = 0; i < list->count; ++i) { - if (list->points[i] == v && list->anchors[i]->extrainfo == tag) + if (list->points[i] == v && Tag_FGet(&list->anchors[i]->tags) == tag) { for (k = 0; k < 3; ++k) { @@ -347,12 +347,12 @@ new_vertex_slope {anchors[2]->x << FRACBITS, anchors[2]->y << FRACBITS, anchors[2]->z << FRACBITS} }; - if (flags & ML_NETONLY) + if (flags & TMSAF_NOPHYSICS) { slope->flags |= SL_NOPHYSICS; } - if (flags & ML_NONET) + if (flags & TMSAF_DYNAMIC) { slope->flags |= SL_DYNAMIC; } @@ -410,8 +410,8 @@ slope_sector { (*slope) = new_vertex_slope(anchors, flags); - /* Effect 6 - invert slope to opposite side */ - if (flags & ML_BLOCKMONSTERS) + /* invert slope to opposite side */ + if (flags & TMSAF_MIRROR) { (*alt) = new_vertex_slope(flip_slope(anchors, sector), flags); } @@ -426,36 +426,30 @@ make_anchored_slope const line_t * line, const int plane ){ - enum - { - FLOOR = 0x1, - CEILING = 0x2, - }; + INT16 flags = line->args[1]; - INT16 flags = line->flags; - - const int side = ( flags & ML_NOCLIMB ) != 0; + const int side = ( flags & TMSAF_BACKSIDE ) != 0; sector_t * s; mtag_t tag = Tag_FGet(&line->tags); - if (side == 0 || flags & ML_TWOSIDED) + if (side == 0 || (line->flags & ML_TWOSIDED)) { s = sides[line->sidenum[side]].sector; - if (plane == (FLOOR|CEILING)) + if (plane == (TMSA_FLOOR|TMSA_CEILING)) { - flags &= ~ML_BLOCKMONSTERS; + flags &= ~TMSAF_MIRROR; } - if (plane & FLOOR) + if (plane & TMSA_FLOOR) { slope_sector (&s->f_slope, &s->c_slope, s, flags, &floor_anchors, tag); } - if (plane & CEILING) + if (plane & TMSA_CEILING) { slope_sector (&s->c_slope, &s->f_slope, s, flags, &ceiling_anchors, tag); @@ -469,27 +463,21 @@ static void P_BuildSlopeAnchorList (void) { } static void P_SetupAnchoredSlopes (void) { - enum - { - FLOOR = 0x1, - CEILING = 0x2, - }; - size_t i; for (i = 0; i < numlines; ++i) { - if (lines[i].special == LT_SLOPE_ANCHORS_FLOOR) + if (lines[i].special == LT_SLOPE_ANCHORS) { - make_anchored_slope(&lines[i], FLOOR); - } - else if (lines[i].special == LT_SLOPE_ANCHORS_CEILING) - { - make_anchored_slope(&lines[i], CEILING); - } - else if (lines[i].special == LT_SLOPE_ANCHORS) - { - make_anchored_slope(&lines[i], FLOOR|CEILING); + int plane = (lines[i].args[0] & (TMSA_FLOOR|TMSA_CEILING)); + + if (plane == 0) + { + CONS_Alert(CONS_WARNING, "Slope anchor linedef %u has no planes set.\n", i); + continue; + } + + make_anchored_slope(&lines[i], plane); } } } From 1ab2b4a897b6c6c3c05e391672c0fb51bc89dec8 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 10:26:25 -0400 Subject: [PATCH 36/54] Bot Controller uses args --- src/k_bot.c | 12 ++++++------ src/p_setup.c | 11 +++++++++++ src/p_spec.h | 7 +++++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/k_bot.c b/src/k_bot.c index 30c661704..eb94d46be 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -510,8 +510,8 @@ fixed_t K_BotRubberband(player_t *player) if (botController != NULL) { - // No Climb Flag: Disable rubberbanding - if (botController->flags & ML_NOCLIMB) + // Disable rubberbanding + if (botController->args[1] & TMBOT_NORUBBERBAND) { return FRACUNIT; } @@ -931,7 +931,7 @@ static void K_BotTrick(player_t *player, ticcmd_t *cmd, line_t *botController) if (player->trickpanel == 1) { - INT32 type = (sides[botController->sidenum[0]].rowoffset / FRACUNIT); + INT32 type = botController->args[0]; // Y Offset: Trick type switch (type) @@ -1318,7 +1318,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) return; } - if (botController != NULL && (botController->flags & ML_NOSKEW)) // FIXME: UDMF-ify + if (botController != NULL && (botController->args[1] & TMBOT_NOCONTROL)) // FIXME: UDMF-ify { // Disable bot controls entirely. return; @@ -1326,12 +1326,12 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) destangle = player->mo->angle; - if (botController != NULL && (botController->flags & ML_SKEWTD)) // FIXME: UDMF-ify + if (botController != NULL && (botController->args[1] & TMBOT_FORCEDIR)) // FIXME: UDMF-ify { const fixed_t dist = DEFAULT_WAYPOINT_RADIUS * player->mo->scale; // X Offset: Movement direction - destangle = FixedAngle(sides[botController->sidenum[0]].textureoffset); + destangle = FixedAngle(botController->args[2] * FRACUNIT); // Overwritten prediction predict = Z_Calloc(sizeof(botprediction_t), PU_STATIC, NULL); diff --git a/src/p_setup.c b/src/p_setup.c index 8b2cf2127..c4c75582a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -5785,6 +5785,17 @@ static void P_ConvertBinaryLinedefTypes(void) if (lines[i].flags & ML_NOCLIMB) lines[i].args[0] |= TMCRF_FRONTONLY; break; + case 2004: //Bot controller + botController->args[0] = sides[botController->sidenum[0]].rowoffset / FRACUNIT; + + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[1] |= TMBOT_NORUBBERBAND; + if (lines[i].flags & ML_NOSKEW) + lines[i].args[1] |= TMBOT_NOCONTROL; + if (lines[i].flags & ML_SKEWTD) + lines[i].args[1] |= TMBOT_FORCEDIR; + + botController->args[2] = sides[botController->sidenum[0]].textureoffset / FRACUNIT; default: break; } diff --git a/src/p_spec.h b/src/p_spec.h index ac501d056..41b9315b8 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -494,6 +494,13 @@ typedef enum TMCRF_FRONTONLY = 1, } textmapcrossrespawnflags_t; +typedef enum +{ + TMBOT_NORUBBERBAND = 1, + TMBOT_NOCONTROL = 1<<1, + TMBOT_FORCEDIR = 1<<2, +} textmapbotcontroller_t; + // GETSECSPECIAL (specialval, section) // // Pulls out the special # from a particular section. From d30c24d2ebeb45eb97c4180a85b12af34567522b Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 10:35:51 -0400 Subject: [PATCH 37/54] Fix embarrassing copy-paste error --- src/p_setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index c4c75582a..f0e9c4fb6 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -5786,7 +5786,7 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[0] |= TMCRF_FRONTONLY; break; case 2004: //Bot controller - botController->args[0] = sides[botController->sidenum[0]].rowoffset / FRACUNIT; + lines[i].args[0] = sides[lines[i].sidenum[0]].rowoffset / FRACUNIT; if (lines[i].flags & ML_NOCLIMB) lines[i].args[1] |= TMBOT_NORUBBERBAND; @@ -5795,7 +5795,7 @@ static void P_ConvertBinaryLinedefTypes(void) if (lines[i].flags & ML_SKEWTD) lines[i].args[1] |= TMBOT_FORCEDIR; - botController->args[2] = sides[botController->sidenum[0]].textureoffset / FRACUNIT; + lines[i].args[2] = sides[lines[i].sidenum[0]].textureoffset / FRACUNIT; default: break; } From 4896a9c8436d202c6e4cf7e84747040faaadba24 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 10:36:59 -0400 Subject: [PATCH 38/54] MT_MAYONAKAARROW uses args --- src/p_enemy.c | 5 +++-- src/p_setup.c | 6 ++++++ src/p_spec.h | 46 ++++++++++++++++++++++++++-------------------- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index c877528ad..a37b5ad04 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -13374,10 +13374,11 @@ void A_MayonakaArrow(mobj_t *actor) if (LUA_CallAction(A_MAYONAKAARROW, (actor))) return; - iswarning = actor->spawnpoint->options & MTF_OBJECTSPECIAL; // is our object a warning sign? + iswarning = (actor->spawnpoint->args[0] == TMMA_WARN); // is our object a warning sign? + // "animtimer" is replaced by "extravalue1" here. actor->extravalue1 = ((actor->extravalue1) ? (actor->extravalue1+1) : (P_RandomRange(PR_DECORATION, 0, (iswarning) ? (TICRATE/2) : TICRATE*3))); - flip = ((actor->spawnpoint->options & 1) ? (3) : (0)); // flip adds 3 frames, which is the flipped version of the sign. + flip = ((actor->spawnpoint->args[0] == TMMA_FLIP) ? (3) : (0)); // flip adds 3 frames, which is the flipped version of the sign. // special warning behavior: if (iswarning) flip = 6; diff --git a/src/p_setup.c b/src/p_setup.c index f0e9c4fb6..05aafd651 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -6579,6 +6579,12 @@ static void P_ConvertBinaryThingTypes(void) mapthings[i].args[2] |= TMBCF_BACKANDFORTH; } break; + case 3122: // MT_MAYONAKAARROW + if (mapthings[i].options & MTF_OBJECTSPECIAL) + mapthings[i].args[0] = TMMA_WARN; + else if (mapthings[i].options & MTF_EXTRA) + mapthings[i].args[0] = TMMA_FLIP; + break; case FLOOR_SLOPE_THING: case CEILING_SLOPE_THING: Tag_FSet(&mapthings[i].tags, mapthings[i].extrainfo); diff --git a/src/p_spec.h b/src/p_spec.h index 41b9315b8..91bc74150 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -49,26 +49,6 @@ typedef enum 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 -{ - TMBCF_BACKANDFORTH = 1, - TMBCF_REVERSE = 1<<1, -} textmapbattlecapsuleflags_t; - -typedef enum -{ - TMICF_INVERTTIMEATTACK = 1, - TMICF_INVERTSIZE = 1<<1, -} textmapitemcapsuleflags_t; - typedef enum { TMFF_AIMLESS = 1, @@ -141,6 +121,32 @@ typedef enum TMB_BARRIER = 1<<1, } textmapbrakflags_t; +typedef enum +{ + TMWPF_DISABLED = 1, + TMWPF_SHORTCUT = 1<<1, + TMWPF_NORESPAWN = 1<<2, + TMWPF_FINISHLINE = 1<<3, +} textmapwaypointflags_t; + +typedef enum +{ + TMBCF_BACKANDFORTH = 1, + TMBCF_REVERSE = 1<<1, +} textmapbattlecapsuleflags_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, From 7cee4ff32aa4e010bb147af600e9e403e6043f8f Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 10:40:06 -0400 Subject: [PATCH 39/54] MT_STEAM's kart behavior uses args --- src/p_map.c | 2 +- src/p_setup.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index ef3d30ef1..e235cb9a4 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -500,7 +500,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) if (object->eflags & MFE_SPRUNG) break; - if (spring->spawnpoint && spring->spawnpoint->options & MTF_OBJECTSPECIAL) + if (spring->spawnpoint && spring->spawnpoint->args[1]) { if (object->player) { diff --git a/src/p_setup.c b/src/p_setup.c index 05aafd651..5100ac66d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -6172,6 +6172,7 @@ static void P_ConvertBinaryThingTypes(void) break; case 541: //Gas jet mapthings[i].args[0] = !!(mapthings[i].options & MTF_AMBUSH); + mapthings[i].args[1] = !!(mapthings[i].options & MTF_OBJECTSPECIAL); break; case 543: //Balloon if (mapthings[i].angle > 0) From 688b4fb9a9b3a6ab3eea82cfab568df2227fe8b1 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 10:43:30 -0400 Subject: [PATCH 40/54] MT_PETSMOKER uses args --- src/p_mobj.c | 2 +- src/p_setup.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 41f56dcd3..a4651b105 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6345,7 +6345,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) if (!(leveltime % 10)) { mobj_t *smok = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_PETSMOKE); - if (mobj->spawnpoint && mobj->spawnpoint->options & MTF_OBJECTSPECIAL) + if (mobj->spawnpoint && mobj->spawnpoint->args[0]) P_SetMobjStateNF(smok, smok->info->painstate); // same function, diff sprite } break; diff --git a/src/p_setup.c b/src/p_setup.c index 5100ac66d..57070f0e7 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -6586,6 +6586,9 @@ static void P_ConvertBinaryThingTypes(void) else if (mapthings[i].options & MTF_EXTRA) mapthings[i].args[0] = TMMA_FLIP; break; + case 2018: // MT_PETSMOKER + mapthings[i].args[0] = !!(mapthings[i].options & MTF_OBJECTSPECIAL); + break; case FLOOR_SLOPE_THING: case CEILING_SLOPE_THING: Tag_FSet(&mapthings[i].tags, mapthings[i].extrainfo); From 0614a8739ca975d1b486c2947abb2a850be87c72 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 10:48:44 -0400 Subject: [PATCH 41/54] Duel items use args --- src/k_kart.c | 2 +- src/p_mobj.c | 6 ++++++ src/p_setup.c | 7 +++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index f57720ed3..00f93272b 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -70,7 +70,7 @@ boolean K_IsDuelItem(mobjtype_t type) boolean K_DuelItemAlwaysSpawns(mapthing_t *mt) { - return (mt->options & MTF_EXTRA); + return !!(mt->args[0]); } static void K_SpawnDuelOnlyItems(void) diff --git a/src/p_mobj.c b/src/p_mobj.c index a4651b105..aa43a9d93 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12805,6 +12805,12 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean // Duel Bomb needs init to match real map thing's angle mobj->angle = FixedAngle(mthing->angle << FRACBITS); Obj_DuelBombInit(mobj); + + if (mthing->args[1]) + { + Obj_DuelBombReverse(mobj); + } + *doangle = false; break; } diff --git a/src/p_setup.c b/src/p_setup.c index 57070f0e7..877168bdd 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -5997,6 +5997,10 @@ static void P_ConvertBinaryThingTypes(void) else mapthings[i].args[0] = TMP_NORMAL; } + if (K_IsDuelItem(mobjtype) == true) + { + mapthings[i].args[0] = !!(mapthings[i].options & MTF_EXTRA); + } } if (mapthings[i].type >= 1 && mapthings[i].type <= 35) //Player starts @@ -6566,6 +6570,9 @@ static void P_ConvertBinaryThingTypes(void) mapthings[i].args[2] |= TMICF_INVERTSIZE; } break; + case 2050: // MT_DUELBOMB + mapthings[i].args[1] = !!(mapthings[i].options & MTF_AMBUSH); + break; case 2333: // MT_BATTLECAPSULE mapthings[i].args[0] = mapthings[i].extrainfo; mapthings[i].args[1] = mapthings[i].angle; From 779aade139d9afae63338cf4efa063423683de78 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 10:50:14 -0400 Subject: [PATCH 42/54] Bot Hints use args --- src/p_mobj.c | 2 +- src/p_setup.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index aa43a9d93..c4c9b12b3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12569,7 +12569,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean } // Steer away instead of towards - if (mthing->options & MTF_AMBUSH) + if (mthing->args[2]) { mobj->extravalue1 = 0; } diff --git a/src/p_setup.c b/src/p_setup.c index 877168bdd..61120d54d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -6549,6 +6549,7 @@ static void P_ConvertBinaryThingTypes(void) case 2004: // MT_BOTHINT mapthings[i].args[0] = mapthings[i].angle; mapthings[i].args[1] = mapthings[i].extrainfo; + mapthings[i].args[2] = !!(mapthings[i].options & MTF_AMBUSH); break; case 2010: // MT_ITEMCAPSULE mapthings[i].args[0] = mapthings[i].angle; From 6b9f29adc44b536470622a3f0c139897e8ee20fb Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 10:54:29 -0400 Subject: [PATCH 43/54] Fix item capsules not getting to be blue --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index c4c9b12b3..914aedd79 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -4282,7 +4282,7 @@ static void P_RefreshItemCapsuleParts(mobj_t *mobj) color = SKINCOLOR_GOLD; newRenderFlags |= RF_SEMIBRIGHT; } - else if (mobj->spawnpoint && (mobj->spawnpoint->options & MTF_EXTRA)) + else if (mobj->spawnpoint && (mobj->spawnpoint->args[2] & TMICF_INVERTTIMEATTACK)) color = SKINCOLOR_SAPPHIRE; else if (itemType == KITEM_SPB) color = SKINCOLOR_JET; From b2c4fa74f98d699064179ce2cc85d9457036a011 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 22:45:35 -0400 Subject: [PATCH 44/54] Add newer UDMF config --- extras/conf/udb/Includes/Game_Kart2.cfg | 77 - extras/conf/udb/Includes/Game_RingRacers.cfg | 53 + extras/conf/udb/Includes/Kart2_sectors.cfg | 105 - ...Kart2_common.cfg => RingRacers_common.cfg} | 57 +- ...2_linedefs.cfg => RingRacers_linedefs.cfg} | 3334 +++-------- .../{Kart2_misc.cfg => RingRacers_misc.cfg} | 122 +- .../conf/udb/Includes/RingRacers_sectors.cfg | 28 + ...Kart2_things.cfg => RingRacers_things.cfg} | 5245 +++++------------ .../{Kart2_UDMF.cfg => RingRacers_UDMF.cfg} | 18 +- src/p_setup.c | 6 +- 10 files changed, 2645 insertions(+), 6400 deletions(-) delete mode 100644 extras/conf/udb/Includes/Game_Kart2.cfg create mode 100644 extras/conf/udb/Includes/Game_RingRacers.cfg delete mode 100644 extras/conf/udb/Includes/Kart2_sectors.cfg rename extras/conf/udb/Includes/{Kart2_common.cfg => RingRacers_common.cfg} (71%) rename extras/conf/udb/Includes/{Kart2_linedefs.cfg => RingRacers_linedefs.cfg} (57%) rename extras/conf/udb/Includes/{Kart2_misc.cfg => RingRacers_misc.cfg} (90%) create mode 100644 extras/conf/udb/Includes/RingRacers_sectors.cfg rename extras/conf/udb/Includes/{Kart2_things.cfg => RingRacers_things.cfg} (53%) rename extras/conf/udb/{Kart2_UDMF.cfg => RingRacers_UDMF.cfg} (61%) diff --git a/extras/conf/udb/Includes/Game_Kart2.cfg b/extras/conf/udb/Includes/Game_Kart2.cfg deleted file mode 100644 index f43cc51e1..000000000 --- a/extras/conf/udb/Includes/Game_Kart2.cfg +++ /dev/null @@ -1,77 +0,0 @@ -// Default lump name for new map -defaultlumpname = "MAP01"; -//GZDB specific. Don't try to load lumps that don't exist. -basegame = "Doom"; - -//Sky textures for vanilla maps -defaultskytextures -{ - SKY1 = "MAP01,MAP02,MAP03,MAP33,MAP50,MAP60,MAPF0,MAPM0"; - SKY2 = "MAPM7,MAPMB"; - SKY4 = "MAP04,MAP06,MAP61,MAPF6,MAPM1"; - SKY6 = "MAP05,MAP51,MAPMA"; - SKY7 = "MAPM2,MAPM5"; - SKY8 = "MAP07,MAP08,MAP09,MAP52,MAP62,MAPF1"; - SKY10 = "MAP10,MAP12,MAP53,MAP63,MAPM3"; - SKY11 = "MAP11,MAPF7"; - SKY13 = "MAP13,MAP64"; - SKY14 = "MAP14"; - SKY15 = "MAP15,MAP54"; - SKY17 = "MAP70"; - SKY20 = "MAP32,MAP55,MAP65,MAPF2,MAPF5"; - SKY21 = "MAPM4"; - SKY22 = "MAP22,MAP23,MAP25,MAP26,MAP27,MAP56,MAP66,MAPF4,MAPM6"; - SKY30 = "MAP30"; - SKY31 = "MAP31"; - SKY35 = "MAP42"; - SKY40 = "MAP41,MAP71,MAPM9"; - SKY55 = "MAPF3,MAPM8"; - SKY68 = "MAPF8"; - SKY99 = "MAP57,MAPZ0"; - SKY159 = "MAP16"; - SKY172 = "MAP40"; - SKY300 = "MAP72"; - SKY301 = "MAP73"; -} - -// Skill levels -skills -{ - 0 = "Easy"; - 1 = "Normal"; - 2 = "Hard"; - 3 = "Master"; -} - -// Skins -skins -{ - sonic; - tails; - knuckles; - amy; - mighty; - fang; - eggman; - metalsonic; - motobug; -} - -// Gametypes -gametypes -{ - -1 = "Single Player"; - 0 = "Race"; - 1 = "Battle"; -} - -// Texture loading options -defaultwalltexture = "GFZROCK"; -defaultfloortexture = "GFZFLR01"; -defaultceilingtexture = "F_SKY1"; - -// Default texture sets -// (these are not required, but useful for new users) -texturesets -{ -} \ No newline at end of file diff --git a/extras/conf/udb/Includes/Game_RingRacers.cfg b/extras/conf/udb/Includes/Game_RingRacers.cfg new file mode 100644 index 000000000..1bb7c2827 --- /dev/null +++ b/extras/conf/udb/Includes/Game_RingRacers.cfg @@ -0,0 +1,53 @@ +// Default lump name for new map +defaultlumpname = "MAPNAME"; + +//GZDB specific. Don't try to load lumps that don't exist. +basegame = "Doom"; + +//Sky textures for vanilla maps +defaultskytextures +{ + SKY1 = "MAP01"; +} + +// Skill levels +skills +{ + 0 = "Easy"; + 1 = "Normal"; + 2 = "Hard"; + 3 = "Master"; +} + +// Skins +skins +{ + sonic; + tails; + knuckles; + amy; + mighty; + fang; + eggman; + metalsonic; + motobug; +} + +// Gametypes +gametypes +{ + -1 = "Grand Prix"; + 0 = "Race"; + 1 = "Battle"; +} + +// Texture loading options +defaultwalltexture = "DEV_OC3"; +defaultfloortexture = "DEV_GZ2"; +defaultceilingtexture = "F_SKY1"; + +// Default texture sets +// (these are not required, but useful for new users) +texturesets +{ +} diff --git a/extras/conf/udb/Includes/Kart2_sectors.cfg b/extras/conf/udb/Includes/Kart2_sectors.cfg deleted file mode 100644 index f9df297e7..000000000 --- a/extras/conf/udb/Includes/Kart2_sectors.cfg +++ /dev/null @@ -1,105 +0,0 @@ -sectortypes -{ - 0 = "Normal"; - 1 = "Damage"; - 2 = "Damage (Water)"; - 3 = "Damage (Fire)"; - 4 = "Damage (Electrical)"; - 5 = "Spikes"; - 6 = "Death Pit (Camera Tilt)"; - 7 = "Death Pit (No Camera Tilt)"; - 8 = "Instant Kill"; - 9 = "Ring Drainer (Floor Touch)"; - 10 = "Ring Drainer (Anywhere in Sector)"; - 11 = "Special Stage Damage"; - 12 = "Space Countdown"; - 13 = "Ramp Sector (double step-up/down)"; - 14 = "Non-Ramp Sector (no step-down)"; - 15 = "Bouncy FOF "; - 16 = "Trigger Line Ex. (Pushable Objects)"; - 32 = "Trigger Line Ex. (Anywhere, All Players)"; - 48 = "Trigger Line Ex. (Floor Touch, All Players)"; - 64 = "Trigger Line Ex. (Anywhere in Sector)"; - 80 = "Trigger Line Ex. (Floor Touch)"; - 96 = "Trigger Line Ex. (Emerald Check) "; - 112 = "Trigger Line Ex. (NiGHTS Mare) "; - 128 = "Check for Linedef Executor on FOFs"; - 144 = "Egg Capsule"; - 160 = "Special Stage Time/Spheres Parameters "; - 176 = "Custom Global Gravity "; - 1280 = "Speed Pad"; - 4096 = "Star Post Activator"; - 8192 = "Exit/Special Stage Pit/Return Flag"; - 12288 = "CTF Red Team Base"; - 16384 = "CTF Blue Team Base"; - 20480 = "Fan Sector"; - 24576 = "Super Sonic Transform"; - 28672 = "Force Spin"; - 32768 = "Zoom Tube Start"; - 36864 = "Zoom Tube End"; - 40960 = "Circuit Finish Line"; - 45056 = "Rope Hang"; - 49152 = "Intangible to the Camera"; -} - -gen_sectortypes -{ - first - { - 0 = "Normal"; - 1 = "Damage"; - 2 = "Damage (Water)"; - 3 = "Damage (Fire)"; - 4 = "Damage (Electrical)"; - 5 = "Spikes"; - 6 = "Death Pit (Camera Tilt)"; - 7 = "Death Pit (No Camera Tilt)"; - 8 = "Instant Kill"; - 9 = "Ring Drainer (Floor Touch)"; - 10 = "Ring Drainer (Anywhere in Sector)"; - 11 = "Special Stage Damage"; - 12 = "Space Countdown"; - 13 = "Ramp Sector (double step-up/down)"; - 14 = "Non-Ramp Sector (no step-down)"; - 15 = "Bouncy FOF "; - } - - second - { - 0 = "Normal"; - 16 = "Trigger Line Ex. (Pushable Objects)"; - 32 = "Trigger Line Ex. (Anywhere, All Players)"; - 48 = "Trigger Line Ex. (Floor Touch, All Players)"; - 64 = "Trigger Line Ex. (Anywhere in Sector)"; - 80 = "Trigger Line Ex. (Floor Touch)"; - 96 = "Trigger Line Ex. (Emerald Check) "; - 112 = "Trigger Line Ex. (NiGHTS Mare) "; - 128 = "Check for Linedef Executor on FOFs"; - 144 = "Egg Capsule"; - 160 = "Special Stage Time/Spheres Parameters "; - 176 = "Custom Global Gravity "; - } - - third - { - 0 = "Normal"; - 1280 = "Speed Pad"; - } - - fourth - { - 0 = "Normal"; - 4096 = "Star Post Activator"; - 8192 = "Exit/Special Stage Pit/Return Flag"; - 12288 = "CTF Red Team Base"; - 16384 = "CTF Blue Team Base"; - 20480 = "Fan Sector"; - 24576 = "Super Sonic Transform"; - 28672 = "Force Spin"; - 32768 = "Zoom Tube Start"; - 36864 = "Zoom Tube End"; - 40960 = "Circuit Finish Line"; - 45056 = "Rope Hang"; - 49152 = "Intangible to the Camera"; - } -} \ No newline at end of file diff --git a/extras/conf/udb/Includes/Kart2_common.cfg b/extras/conf/udb/Includes/RingRacers_common.cfg similarity index 71% rename from extras/conf/udb/Includes/Kart2_common.cfg rename to extras/conf/udb/Includes/RingRacers_common.cfg index 67071c33c..7e662e55e 100644 --- a/extras/conf/udb/Includes/Kart2_common.cfg +++ b/extras/conf/udb/Includes/RingRacers_common.cfg @@ -6,7 +6,7 @@ common // Enables support for long (> 8 chars) texture names // WARNING: this should only be enabled for UDMF game configurations! // WARNING: enabling this will make maps incompatible with Doom Builder 2 and can lead to problems in Slade 3! - longtexturenames = true; + longtexturenames = false; // These directory names are ignored when loading PK3/PK7/Directory resources ignoreddirectories = ".svn .git"; @@ -16,7 +16,7 @@ common // Default testing parameters testparameters = "-file \"%AP\" \"%F\" -warp %L"; - testshortpaths = true; + testshortpaths = false; // Action special help actionspecialhelp = "https://wiki.srb2.org/wiki/Linedef_type_%K"; @@ -46,26 +46,28 @@ common // Texture sources textures { - include("Kart2_misc.cfg", "textures"); + include("RingRacers_misc.cfg", "textures"); } // Patch sources patches { - include("Kart2_misc.cfg", "patches"); + include("RingRacers_misc.cfg", "patches"); } // Sprite sources sprites { - include("Kart2_misc.cfg", "sprites"); + include("RingRacers_misc.cfg", "sprites"); } // Flat sources + /* flats { - include("Kart2_misc.cfg", "flats"); + include("RingRacers_misc.cfg", "flats"); } + */ } mapformat_udmf @@ -78,25 +80,26 @@ mapformat_udmf defaulttestcompiler = "zdbsp_udmf_fast"; // Determines the textmap namespace - engine = "srb2kart"; + engine = "ringracers"; maplumpnames { include("UDMF_misc.cfg", "udmfmaplumpnames_begin"); - include("Kart2_misc.cfg", "udmfmaplumpnames"); + include("RingRacers_misc.cfg", "udmfmaplumpnames"); + include("RingRacers_misc.cfg", "sharedmaplumpnames"); include("UDMF_misc.cfg", "udmfmaplumpnames_end"); } universalfields { - include("Kart2_misc.cfg", "universalfields"); + include("RingRacers_misc.cfg", "universalfields"); } // When this is set to true, sectors with the same tag will light up when a line is highlighted linetagindicatesectors = false; // Special linedefs - include("Kart2_misc.cfg", "speciallinedefs_udmf"); + include("RingRacers_misc.cfg", "speciallinedefs_udmf"); // Default flags for first new thing defaultthingflags @@ -106,50 +109,38 @@ mapformat_udmf // SECTOR FLAGS sectorflags { - include("Kart2_misc.cfg", "sectorflags"); + include("RingRacers_misc.cfg", "sectorflags"); } // DEFAULT SECTOR BRIGHTNESS LEVELS sectorbrightness { - include("Kart2_misc.cfg", "sectorbrightness"); + include("RingRacers_misc.cfg", "sectorbrightness"); } - damagetypes = "Generic Water Fire Lava Electric Spike DeathPitTilt DeathPitNoTilt Instakill SpecialStage"; - - // SECTOR TYPES - sectortypes - { - include("Kart2_sectors.cfg", "sectortypes"); - } - - // GENERALISED SECTOR TYPES - gen_sectortypes - { - include("Kart2_sectors.cfg", "gen_sectortypes"); - } + damagetypes = "Generic Lava DeathPit Instakill"; // LINEDEF FLAGS linedefflags { - include("Kart2_misc.cfg", "linedefflags_udmf"); + include("RingRacers_misc.cfg", "linedefflags_udmf"); } linedefflagstranslation { - include("Kart2_misc.cfg", "linedefflagstranslation"); + include("RingRacers_misc.cfg", "linedefflagstranslation"); } // LINEDEF RENDERSTYLES linedefrenderstyles { - include("Kart2_misc.cfg", "linedefrenderstyles"); + include("RingRacers_misc.cfg", "linedefrenderstyles"); } // THING FLAGS thingflags { - include("Kart2_misc.cfg", "thingflags_udmf"); + include("RingRacers_misc.cfg", "thingflags_udmf"); } // Thing flags UDMF translation table @@ -157,7 +148,7 @@ mapformat_udmf // When the UDMF field name is prefixed with ! it is inverted thingflagstranslation { - include("Kart2_misc.cfg", "thingflagstranslation"); + include("RingRacers_misc.cfg", "thingflagstranslation"); } // How to compare thing flags (for the stuck things error checker) @@ -169,12 +160,12 @@ mapformat_udmf // THING TYPES thingtypes { - include("Kart2_things.cfg", "udmf"); + include("RingRacers_things.cfg", "udmf"); } // LINEDEF TYPES linedeftypes { - include("Kart2_linedefs.cfg", "udmf"); + include("RingRacers_linedefs.cfg", "udmf"); } -} \ No newline at end of file +} diff --git a/extras/conf/udb/Includes/Kart2_linedefs.cfg b/extras/conf/udb/Includes/RingRacers_linedefs.cfg similarity index 57% rename from extras/conf/udb/Includes/Kart2_linedefs.cfg rename to extras/conf/udb/Includes/RingRacers_linedefs.cfg index b845b2830..2e471cbcb 100644 --- a/extras/conf/udb/Includes/Kart2_linedefs.cfg +++ b/extras/conf/udb/Includes/RingRacers_linedefs.cfg @@ -1,1738 +1,3 @@ -doom -{ - misc - { - title = "Miscellaneous"; - - 0 - { - title = "None"; - prefix = "(0)"; - } - 1 - { - title = "Per-Sector Gravity"; - prefix = "(1)"; - } - 5 - { - title = " Camera Scanner"; - prefix = "(5)"; - } - 7 - { - title = "Sector Flat Alignment"; - prefix = "(7)"; - } - 10 - { - title = "Culling Plane"; - prefix = "(10)"; - } - 13 - { - title = "Heat Wave Effect"; - prefix = "(13)"; - } - 40 - { - title = "Visual Portal Between Tagged Linedefs"; - prefix = "(40)"; - } - 41 - { - title = "Horizon Effect"; - prefix = "(41)"; - } - 50 - { - title = "Instantly Lower Floor on Level Load"; - prefix = "(50)"; - } - 51 - { - title = "Instantly Raise Ceiling on Level Load"; - prefix = "(51)"; - } - 63 - { - title = "Fake Floor/Ceiling Planes"; - prefix = "(63)"; - } - 540 - { - title = "Floor Friction"; - prefix = "(540)"; - } - } - - parameters - { - title = "Parameters"; - - 2 - { - title = "Custom Exit"; - prefix = "(2)"; - } - 3 - { - title = "Zoom Tube Parameters"; - prefix = "(3)"; - } - 4 - { - title = "Speed Pad Parameters"; - prefix = "(4)"; - } - 8 - { - title = "Special Sector Properties"; - prefix = "(8)"; - } - 9 - { - title = "Chain Parameters"; - prefix = "(9)"; - } - 11 - { - title = "Rope Hang Parameters"; - prefix = "(11)"; - } - 12 - { - title = "Rock Spawner Parameters"; - prefix = "(12)"; - } - 14 - { - title = "Bustable Block Parameters"; - prefix = "(14)"; - } - 15 - { - title = "Fan Particle Spawner Parameters"; - prefix = "(15)"; - } - 16 - { - title = "Minecart Parameters"; - prefix = "(16)"; - } - 64 - { - title = "Continuously Appearing/Disappearing FOF"; - prefix = "(64)"; - } - 65 - { - title = " Bridge Thinker"; - prefix = "(65)"; - } - 76 - { - title = "Make FOF Bouncy"; - prefix = "(76)"; - } - } - - polyobject - { - title = "PolyObject"; - - 20 - { - title = "First Line"; - prefix = "(20)"; - } - 21 - { - title = " Explicitly Include Line"; - prefix = "(21)"; - } - 22 - { - title = "Parameters"; - prefix = "(22)"; - } - 30 - { - title = "Waving Flag"; - prefix = "(30)"; - } - 31 - { - title = "Displacement by Front Sector"; - prefix = "(31)"; - } - 32 - { - title = "Angular Displacement by Front Sector"; - prefix = "(32)"; - } - } - - planemove - { - title = "Plane Movement"; - - 52 - { - title = "Continuously Falling Sector"; - prefix = "(52)"; - } - 53 - { - title = "Continuous Floor/Ceiling Mover"; - prefix = "(53)"; - } - 54 - { - title = "Continuous Floor Mover"; - prefix = "(54)"; - } - 55 - { - title = "Continuous Ceiling Mover"; - prefix = "(55)"; - } - 56 - { - title = "Continuous Two-Speed Floor/Ceiling Mover"; - prefix = "(56)"; - } - 57 - { - title = "Continuous Two-Speed Floor Mover"; - prefix = "(57)"; - } - 58 - { - title = "Continuous Two-Speed Ceiling Mover"; - prefix = "(58)"; - } - 59 - { - title = "Activate Moving Platform"; - prefix = "(59)"; - } - 60 - { - title = "Activate Moving Platform (Adjustable Speed)"; - prefix = "(60)"; - } - 61 - { - title = "Crusher (Ceiling to Floor)"; - prefix = "(61)"; - } - 62 - { - title = "Crusher (Floor to Ceiling)"; - prefix = "(62)"; - } - 66 - { - title = "Move Floor by Displacement"; - prefix = "(66)"; - } - 67 - { - title = "Move Ceiling by Displacement"; - prefix = "(67)"; - } - 68 - { - title = "Move Floor and Ceiling by Displacement"; - prefix = "(68)"; - } - } - - fofsolid - { - title = "FOF (solid)"; - - 100 - { - title = "Solid, Opaque"; - prefix = "(100)"; - } - 101 - { - title = "Solid, Opaque, No Shadow"; - prefix = "(101)"; - } - 102 - { - title = "Solid, Translucent"; - prefix = "(102)"; - } - 103 - { - title = "Solid, Sides Only"; - prefix = "(103)"; - } - 104 - { - title = "Solid, No Sides"; - prefix = "(104)"; - } - 105 - { - title = "Solid, Invisible"; - prefix = "(105)"; - } - 140 - { - title = "Intangible from Bottom, Opaque"; - prefix = "(140)"; - } - 141 - { - title = "Intangible from Bottom, Translucent"; - prefix = "(141)"; - } - 142 - { - title = "Intangible from Bottom, Translucent, No Sides"; - prefix = "(142)"; - } - 143 - { - title = "Intangible from Top, Opaque"; - prefix = "(143)"; - } - 144 - { - title = "Intangible from Top, Translucent"; - prefix = "(144)"; - } - 145 - { - title = "Intangible from Top, Translucent, No Sides"; - prefix = "(145)"; - } - 146 - { - title = "Only Tangible from Sides"; - prefix = "(146)"; - } - } - - fofintangible - { - title = "FOF (intangible)"; - - 120 - { - title = "Water, Opaque"; - prefix = "(120)"; - } - 121 - { - title = "Water, Translucent"; - prefix = "(121)"; - } - 122 - { - title = "Water, Opaque, No Sides"; - prefix = "(122)"; - } - 123 - { - title = "Water, Translucent, No Sides"; - prefix = "(123)"; - } - 124 - { - title = "Goo Water, Translucent"; - prefix = "(124)"; - } - 125 - { - title = "Goo Water, Translucent, No Sides"; - prefix = "(125)"; - } - 220 - { - title = "Intangible, Opaque"; - prefix = "(220)"; - } - 221 - { - title = "Intangible, Translucent"; - prefix = "(221)"; - } - 222 - { - title = "Intangible, Sides Only"; - prefix = "(222)"; - } - 223 - { - title = "Intangible, Invisible"; - prefix = "(223)"; - } - } - - fofmoving - { - title = "FOF (moving)"; - - 150 - { - title = "Air Bobbing"; - prefix = "(150)"; - } - 151 - { - title = "Air Bobbing (Adjustable)"; - prefix = "(151)"; - } - 152 - { - title = "Reverse Air Bobbing (Adjustable)"; - prefix = "(152)"; - } - 153 - { - title = "Dynamically Sinking Platform"; - prefix = "(153)"; - } - 160 - { - title = "Water Bobbing"; - prefix = "(160)"; - } - 190 - { - title = "Rising Platform, Solid, Opaque"; - prefix = "(190)"; - } - 191 - { - title = "Rising Platform, Solid, Opaque, No Shadow"; - prefix = "(191)"; - } - 192 - { - title = "Rising Platform, Solid, Translucent"; - prefix = "(192)"; - } - 193 - { - title = "Rising Platform, Solid, Invisible"; - prefix = "(193)"; - } - 194 - { - title = "Rising Platform, Intangible from Bottom, Opaque"; - prefix = "(194)"; - } - 195 - { - title = "Rising Platform, Intangible from Bottom, Translucent"; - prefix = "(195)"; - } - } - - fofcrumbling - { - title = "FOF (crumbling)"; - - 170 - { - title = "Crumbling, Respawn"; - prefix = "(170)"; - } - 171 - { - title = "Crumbling, No Respawn"; - prefix = "(171)"; - } - 172 - { - title = "Crumbling, Respawn, Intangible from Bottom"; - prefix = "(172)"; - } - 173 - { - title = "Crumbling, No Respawn, Intangible from Bottom"; - prefix = "(173)"; - } - 174 - { - title = "Crumbling, Respawn, Int. from Bottom, Translucent"; - prefix = "(174)"; - } - 175 - { - title = "Crumbling, No Respawn, Int. from Bottom, Translucent"; - prefix = "(175)"; - } - 176 - { - title = "Crumbling, Respawn, Floating, Bobbing"; - prefix = "(176)"; - } - 177 - { - title = "Crumbling, No Respawn, Floating, Bobbing"; - prefix = "(177)"; - } - 178 - { - title = "Crumbling, Respawn, Floating"; - prefix = "(178)"; - } - 179 - { - title = "Crumbling, No Respawn, Floating"; - prefix = "(179)"; - } - 180 - { - title = "Crumbling, Respawn, Air Bobbing"; - prefix = "(180)"; - } - } - - fofspecial - { - title = "FOF (special)"; - - 200 - { - title = "Light Block"; - prefix = "(200)"; - } - 201 - { - title = "Half Light Block"; - prefix = "(201)"; - } - 202 - { - title = "Fog Block"; - prefix = "(202)"; - } - 250 - { - title = "Mario Block"; - prefix = "(250)"; - } - 251 - { - title = "Thwomp Block"; - prefix = "(251)"; - } - 252 - { - title = "Shatter Block"; - prefix = "(252)"; - } - 253 - { - title = "Shatter Block, Translucent"; - prefix = "(253)"; - } - 254 - { - title = "Bustable Block"; - prefix = "(254)"; - } - 255 - { - title = "Spin-Bustable Block"; - prefix = "(255)"; - } - 256 - { - title = "Spin-Bustable Block, Translucent"; - prefix = "(256)"; - } - 257 - { - title = "Quicksand"; - prefix = "(257)"; - } - 258 - { - title = "Laser"; - prefix = "(258)"; - } - 259 - { - title = "Custom FOF"; - prefix = "(259)"; - } - } - - linedeftrigger - { - title = "Linedef Executor Trigger"; - - 300 - { - title = "Continuous"; - prefix = "(300)"; - } - 301 - { - title = "Each Time"; - prefix = "(301)"; - } - 302 - { - title = "Once"; - prefix = "(302)"; - } - 303 - { - title = "Ring Count - Continuous"; - prefix = "(303)"; - } - 304 - { - title = "Ring Count - Once"; - prefix = "(304)"; - } - 305 - { - title = "Character Ability - Continuous"; - prefix = "(305)"; - } - 306 - { - title = "Character Ability - Each Time"; - prefix = "(306)"; - } - 307 - { - title = "Character Ability - Once"; - prefix = "(307)"; - } - 308 - { - title = "Race Only - Once"; - prefix = "(308)"; - } - 309 - { - title = "CTF Red Team - Continuous"; - prefix = "(309)"; - } - 310 - { - title = "CTF Red Team - Each Time"; - prefix = "(310)"; - } - 311 - { - title = "CTF Blue Team - Continuous"; - prefix = "(311)"; - } - 312 - { - title = "CTF Blue Team - Each Time"; - prefix = "(312)"; - } - 313 - { - title = "No More Enemies - Once"; - prefix = "(313)"; - } - 314 - { - title = "Number of Pushables - Continuous"; - prefix = "(314)"; - } - 315 - { - title = "Number of Pushables - Once"; - prefix = "(315)"; - } - 317 - { - title = "Condition Set Trigger - Continuous"; - prefix = "(317)"; - } - 318 - { - title = "Condition Set Trigger - Once"; - prefix = "(318)"; - } - 319 - { - title = "Unlockable - Continuous"; - prefix = "(319)"; - } - 320 - { - title = "Unlockable - Once"; - prefix = "(320)"; - } - 321 - { - title = "Trigger After X Calls - Continuous"; - prefix = "(321)"; - } - 322 - { - title = "Trigger After X Calls - Each Time"; - prefix = "(322)"; - } - 323 - { - title = "NiGHTSerize - Each Time"; - prefix = "(323)"; - } - 324 - { - title = "NiGHTSerize - Once"; - prefix = "(324)"; - } - 325 - { - title = "De-NiGHTSerize - Each Time"; - prefix = "(325)"; - } - 326 - { - title = "De-NiGHTSerize - Once"; - prefix = "(326)"; - } - 327 - { - title = "NiGHTS Lap - Each Time"; - prefix = "(327)"; - } - 328 - { - title = "NiGHTS Lap - Once"; - prefix = "(328)"; - } - 329 - { - title = "Ideya Capture Touch - Each Time"; - prefix = "(329)"; - } - 330 - { - title = "Ideya Capture Touch - Once"; - prefix = "(330)"; - } - 331 - { - title = "Player Skin - Continuous"; - flags64text = "[6] Disable for this skin"; - prefix = "(331)"; - } - 332 - { - title = "Player Skin - Each Time"; - prefix = "(332)"; - } - 333 - { - title = "Player Skin - Once"; - prefix = "(333)"; - } - 334 - { - title = "Object Dye - Continuous"; - prefix = "(334)"; - } - 335 - { - title = "Object Dye - Each Time"; - prefix = "(335)"; - } - 336 - { - title = "Object Dye - Once"; - prefix = "(336)"; - } - 337 - { - title = "Emerald Check - Continuous"; - prefix = "(337)"; - } - 338 - { - title = "Emerald Check - Each Time"; - prefix = "(338)"; - } - 339 - { - title = "Emerald Check - Once"; - prefix = "(339)"; - } - 340 - { - title = "NiGHTS Mare - Continuous"; - prefix = "(340)"; - } - 341 - { - title = "NiGHTS Mare - Each Time"; - prefix = "(341)"; - } - 342 - { - title = "NiGHTS Mare - Once"; - prefix = "(342)"; - } - 399 - { - title = "Level Load"; - prefix = "(399)"; - } - } - - linedefexecsector - { - title = "Linedef Executor (sector)"; - - 400 - { - title = "Set Tagged Sector's Floor Height/Texture"; - prefix = "(400)"; - } - 401 - { - title = "Set Tagged Sector's Ceiling Height/Texture"; - prefix = "(401)"; - } - 402 - { - title = "Set Tagged Sector's Light Level"; - prefix = "(402)"; - } - 408 - { - title = "Set Tagged Sector's Flats"; - prefix = "(408)"; - } - 409 - { - title = "Change Tagged Sector's Tag"; - prefix = "(409)"; - } - 410 - { - title = "Change Front Sector's Tag"; - prefix = "(410)"; - } - 416 - { - title = "Start Adjustable Flickering Light"; - prefix = "(416)"; - } - 417 - { - title = "Start Adjustable Pulsating Light"; - prefix = "(417)"; - } - 418 - { - title = "Start Adjustable Blinking Light (unsynchronized)"; - prefix = "(418)"; - } - 419 - { - title = "Start Adjustable Blinking Light (synchronized)"; - prefix = "(419)"; - } - 420 - { - title = "Fade Light Level"; - prefix = "(420)"; - } - 421 - { - title = "Stop Lighting Effect"; - prefix = "(421)"; - } - 435 - { - title = "Change Plane Scroller Direction"; - prefix = "(435)"; - } - 467 - { - title = "Set Tagged Sector's Light Level"; - prefix = "(467)"; - } - } - - linedefexecplane - { - title = "Linedef Executor (plane movement)"; - - 403 - { - title = "Move Tagged Sector's Floor"; - prefix = "(403)"; - } - 404 - { - title = "Move Tagged Sector's Ceiling"; - prefix = "(404)"; - } - 405 - { - title = "Move Floor According to Front Texture Offsets"; - prefix = "(405)"; - } - 407 - { - title = "Move Ceiling According to Front Texture Offsets"; - prefix = "(407)"; - } - 411 - { - title = "Stop Plane Movement"; - prefix = "(411)"; - } - 428 - { - title = "Start Platform Movement"; - prefix = "(428)"; - } - 429 - { - title = "Crush Ceiling Once"; - prefix = "(429)"; - } - 430 - { - title = "Crush Floor Once"; - prefix = "(430)"; - } - 431 - { - title = "Crush Floor and Ceiling Once"; - prefix = "(431)"; - } - } - - linedefexecplayer - { - title = "Linedef Executor (player/object)"; - - 412 - { - title = "Teleporter"; - prefix = "(412)"; - } - 425 - { - title = "Change Object State"; - prefix = "(425)"; - } - 426 - { - title = "Stop Object"; - prefix = "(426)"; - } - 427 - { - title = "Award Score"; - prefix = "(427)"; - } - 432 - { - title = "Enable/Disable 2D Mode"; - prefix = "(432)"; - } - 433 - { - title = "Enable/Disable Gravity Flip"; - prefix = "(433)"; - } - 434 - { - title = "Award Power-Up"; - prefix = "(434)"; - } - 437 - { - title = "Disable Player Control"; - prefix = "(437)"; - } - 438 - { - title = "Change Object Size"; - prefix = "(438)"; - } - 442 - { - title = "Change Object Type State"; - prefix = "(442)"; - } - 457 - { - title = "Track Object's Angle"; - prefix = "(457)"; - } - 458 - { - title = "Stop Tracking Object's Angle"; - prefix = "(458)"; - } - 460 - { - title = "Award Rings"; - prefix = "(460)"; - } - 461 - { - title = "Spawn Object"; - prefix = "(461)"; - } - 462 - { - title = "Stop Timer/Exit Stage in Record Attack"; - prefix = "(462)"; - } - 463 - { - title = "Dye Object"; - prefix = "(463)"; - } - 464 - { - title = "Trigger Egg Capsule"; - prefix = "(464)"; - } - 466 - { - title = "Set Level Failure State"; - prefix = "(466)"; - } - } - - linedefexecmisc - { - title = "Linedef Executor (misc.)"; - - 413 - { - title = "Change Music"; - prefix = "(413)"; - } - 414 - { - title = "Play Sound Effect"; - prefix = "(414)"; - } - 415 - { - title = "Run Script"; - prefix = "(415)"; - } - 422 - { - title = "Switch to Cut-Away View"; - prefix = "(422)"; - } - 423 - { - title = "Change Sky"; - prefix = "(423)"; - } - 424 - { - title = "Change Weather"; - prefix = "(424)"; - } - 436 - { - title = "Shatter FOF"; - prefix = "(436)"; - } - 439 - { - title = "Change Tagged Linedef's Textures"; - prefix = "(439)"; - } - 440 - { - title = "Start Metal Sonic Race"; - prefix = "(440)"; - } - 441 - { - title = "Condition Set Trigger"; - prefix = "(441)"; - } - 443 - { - title = "Call Lua Function"; - prefix = "(443)"; - } - 444 - { - title = "Earthquake"; - prefix = "(444)"; - } - 445 - { - title = "Make FOF Disappear/Reappear"; - prefix = "(445)"; - } - 446 - { - title = "Make FOF Crumble"; - prefix = "(446)"; - } - 447 - { - title = "Change Tagged Sector's Colormap"; - prefix = "(447)"; - } - 448 - { - title = "Change Skybox"; - prefix = "(448)"; - } - 449 - { - title = "Enable Bosses with Parameter"; - prefix = "(449)"; - } - 450 - { - title = "Execute Linedef Executor (specific tag)"; - prefix = "(450)"; - } - 451 - { - title = "Execute Linedef Executor (random tag in range)"; - prefix = "(451)"; - } - 452 - { - title = "Set FOF Translucency"; - prefix = "(452)"; - } - 453 - { - title = "Fade FOF"; - prefix = "(453)"; - } - 454 - { - title = "Stop Fading FOF"; - prefix = "(454)"; - } - 455 - { - title = "Fade Tagged Sector's Colormap"; - prefix = "(455)"; - } - 456 - { - title = "Stop Fading Tagged Sector's Colormap"; - prefix = "(456)"; - } - 459 - { - title = "Control Text Prompt"; - prefix = "(459)"; - } - } - - linedefexecpoly - { - title = "Linedef Executor (polyobject)"; - - 480 - { - title = "Door Slide"; - prefix = "(480)"; - } - 481 - { - title = "Door Swing"; - prefix = "(481)"; - } - 482 - { - title = "Move"; - prefix = "(482)"; - } - 483 - { - title = "Move, Override"; - prefix = "(483)"; - } - 484 - { - title = "Rotate Right"; - prefix = "(484)"; - } - 485 - { - title = "Rotate Right, Override"; - prefix = "(485)"; - } - 486 - { - title = "Rotate Left"; - prefix = "(486)"; - } - 487 - { - title = "Rotate Left, Override"; - prefix = "(487)"; - } - 488 - { - title = "Move by Waypoints"; - prefix = "(488)"; - } - 489 - { - title = "Turn Invisible, Intangible"; - prefix = "(489)"; - } - 490 - { - title = "Turn Visible, Tangible"; - prefix = "(490)"; - } - 491 - { - title = "Set Translucency"; - prefix = "(491)"; - } - 492 - { - title = "Fade Translucency"; - prefix = "(492)"; - } - } - - wallscroll - { - title = "Wall Scrolling"; - - 500 - { - title = "Scroll Wall Front Side Left"; - prefix = "(500)"; - } - 501 - { - title = "Scroll Wall Front Side Right"; - prefix = "(501)"; - } - 502 - { - title = "Scroll Wall According to Linedef"; - prefix = "(502)"; - } - 503 - { - title = "Scroll Wall According to Linedef (Accelerative)"; - prefix = "(503)"; - } - 504 - { - title = "Scroll Wall According to Linedef (Displacement)"; - prefix = "(504)"; - } - 505 - { - title = "Scroll Texture by Front Side Offsets"; - prefix = "(505)"; - } - 506 - { - title = "Scroll Texture by Back Side Offsets"; - prefix = "(506)"; - } - } - - planescroll - { - title = "Plane Scrolling"; - - 510 - { - title = "Scroll Floor Texture"; - prefix = "(510)"; - } - 511 - { - title = "Scroll Floor Texture (Accelerative)"; - prefix = "(511)"; - } - 512 - { - title = "Scroll Floor Texture (Displacement)"; - prefix = "(512)"; - } - 513 - { - title = "Scroll Ceiling Texture"; - prefix = "(513)"; - } - 514 - { - title = "Scroll Ceiling Texture (Accelerative)"; - prefix = "(514)"; - } - 515 - { - title = "Scroll Ceiling Texture (Displacement)"; - prefix = "(515)"; - } - 520 - { - title = "Carry Objects on Floor"; - prefix = "(520)"; - } - 521 - { - title = "Carry Objects on Floor (Accelerative)"; - prefix = "(521)"; - } - 522 - { - title = "Carry Objects on Floor (Displacement)"; - prefix = "(522)"; - } - 523 - { - title = "Carry Objects on Ceiling"; - prefix = "(523)"; - } - 524 - { - title = "Carry Objects on Ceiling (Accelerative)"; - prefix = "(524)"; - } - 525 - { - title = "Carry Objects on Ceiling (Displacement)"; - prefix = "(525)"; - } - 530 - { - title = "Scroll Floor Texture and Carry Objects"; - prefix = "(530)"; - } - 531 - { - title = "Scroll Floor Texture and Carry Objects (Accelerative)"; - prefix = "(531)"; - } - 532 - { - title = "Scroll Floor Texture and Carry Objects (Displacement)"; - prefix = "(532)"; - } - 533 - { - title = "Scroll Ceiling Texture and Carry Objects"; - prefix = "(533)"; - } - 534 - { - title = "Scroll Ceiling Texture and Carry Objects (Accelerative)"; - prefix = "(534)"; - } - 535 - { - title = "Scroll Ceiling Texture and Carry Objects (Displacement)"; - prefix = "(535)"; - } - } - - pusher - { - title = "Pusher"; - - 541 - { - title = "Wind"; - prefix = "(541)"; - } - 542 - { - title = "Upwards Wind"; - prefix = "(542)"; - } - 543 - { - title = "Downwards Wind"; - prefix = "(543)"; - } - 544 - { - title = "Current"; - prefix = "(544)"; - } - 545 - { - title = "Upwards Current"; - prefix = "(545)"; - } - 546 - { - title = "Downwards Current"; - prefix = "(546)"; - } - 547 - { - title = "Push/Pull"; - prefix = "(547)"; - } - } - - light - { - title = "Lighting"; - - 600 - { - title = "Floor Lighting"; - prefix = "(600)"; - } - 601 - { - title = "Ceiling Lighting"; - prefix = "(601)"; - } - 602 - { - title = "Adjustable Pulsating Light"; - prefix = "(602)"; - } - 603 - { - title = "Adjustable Flickering Light"; - prefix = "(603)"; - } - 604 - { - title = "Adjustable Blinking Light (unsynchronized)"; - prefix = "(604)"; - } - 605 - { - title = "Adjustable Blinking Light (synchronized)"; - prefix = "(605)"; - } - 606 - { - title = "Colormap"; - prefix = "(606)"; - } - } - - slope - { - title = "Slope"; - - 700 - { - title = "Slope Frontside Floor"; - prefix = "(700)"; - } - 701 - { - title = "Slope Frontside Ceiling"; - prefix = "(701)"; - } - 702 - { - title = "Slope Frontside Floor and Ceiling"; - prefix = "(702)"; - } - 703 - { - title = "Slope Frontside Floor and Backside Ceiling"; - prefix = "(703)"; - } - 704 - { - title = "Slope Frontside Floor by 3 Tagged Vertex Things"; - prefix = "(704)"; - } - 705 - { - title = "Slope Frontside Ceiling by 3 Tagged Vertex Things"; - prefix = "(705)"; - } - 710 - { - title = "Slope Backside Floor"; - prefix = "(710)"; - } - 711 - { - title = "Slope Backside Ceiling"; - prefix = "(711)"; - } - 712 - { - title = "Slope Backside Floor and Ceiling"; - prefix = "(712)"; - } - 713 - { - title = "Slope Backside Floor and Frontside Ceiling"; - prefix = "(713)"; - } - 714 - { - title = "Slope Backside Floor by 3 Tagged Vertex Things"; - prefix = "(714)"; - } - 715 - { - title = "Slope Backside Ceiling by 3 Tagged Vertex Things"; - prefix = "(715)"; - } - 720 - { - title = "Copy Frontside Floor Slope from Line Tag"; - prefix = "(720)"; - } - 721 - { - title = "Copy Frontside Ceiling Slope from Line Tag"; - prefix = "(721)"; - } - 722 - { - title = "Copy Frontside Floor and Ceiling Slope from Line Tag"; - prefix = "(722)"; - } - 799 - { - title = "Set Tagged Dynamic Slope Vertex to Front Sector Height"; - prefix = "(799)"; - } - } - - transwall - { - title = "Translucent Wall"; - - 900 - { - title = "90% Opaque"; - prefix = "(900)"; - } - 901 - { - title = "80% Opaque"; - prefix = "(901)"; - } - 902 - { - title = "70% Opaque"; - prefix = "(902)"; - } - 903 - { - title = "60% Opaque"; - prefix = "(903)"; - } - 904 - { - title = "50% Opaque"; - prefix = "(904)"; - } - 905 - { - title = "40% Opaque"; - prefix = "(905)"; - } - 906 - { - title = "30% Opaque"; - prefix = "(906)"; - } - 907 - { - title = "20% Opaque"; - prefix = "(907)"; - } - 908 - { - title = "10% Opaque"; - prefix = "(908)"; - } - 909 - { - title = "Fog Wall"; - prefix = "(909)"; - } - 910 - { - title = "100% Additive"; - prefix = "(910)"; - } - 911 - { - title = "90% Additive"; - prefix = "(911)"; - } - 912 - { - title = "80% Additive"; - prefix = "(912)"; - } - 913 - { - title = "70% Additive"; - prefix = "(913)"; - } - 914 - { - title = "60% Additive"; - prefix = "(914)"; - } - 915 - { - title = "50% Additive"; - prefix = "(915)"; - } - 916 - { - title = "40% Additive"; - prefix = "(916)"; - } - 917 - { - title = "30% Additive"; - prefix = "(917)"; - } - 918 - { - title = "20% Additive"; - prefix = "(918)"; - } - 919 - { - title = "10% Additive"; - prefix = "(919)"; - } - 920 - { - title = "100% Subtractive"; - prefix = "(920)"; - } - 921 - { - title = "90% Subtractive"; - prefix = "(921)"; - } - 922 - { - title = "80% Subtractive"; - prefix = "(922)"; - } - 923 - { - title = "70% Subtractive"; - prefix = "(923)"; - } - 924 - { - title = "60% Subtractive"; - prefix = "(924)"; - } - 925 - { - title = "50% Subtractive"; - prefix = "(925)"; - } - 926 - { - title = "40% Subtractive"; - prefix = "(926)"; - } - 927 - { - title = "30% Subtractive"; - prefix = "(927)"; - } - 928 - { - title = "20% Subtractive"; - prefix = "(928)"; - } - 929 - { - title = "10% Subtractive"; - prefix = "(929)"; - } - 930 - { - title = "100% Reverse Subtractive"; - prefix = "(930)"; - } - 931 - { - title = "90% Reverse Subtractive"; - prefix = "(931)"; - } - 932 - { - title = "80% Reverse Subtractive"; - prefix = "(932)"; - } - 933 - { - title = "70% Reverse Subtractive"; - prefix = "(933)"; - } - 934 - { - title = "60% Reverse Subtractive"; - prefix = "(934)"; - } - 935 - { - title = "50% Reverse Subtractive"; - prefix = "(935)"; - } - 936 - { - title = "40% Reverse Subtractive"; - prefix = "(936)"; - } - 937 - { - title = "30% Reverse Subtractive"; - prefix = "(937)"; - } - 938 - { - title = "20% Reverse Subtractive"; - prefix = "(938)"; - } - 939 - { - title = "10% Reverse Subtractive"; - prefix = "(939)"; - } - 940 - { - title = "Modulate"; - prefix = "(940)"; - } - } -} - udmf { misc @@ -1806,6 +71,74 @@ udmf type = 13; } } + + 80 + { + title = "Offset Tagged Things from Frontside FOF"; + prefix = "(80)"; + arg0 + { + title = "Target thing type"; + type = 0; + } + } + + 2001 + { + title = "Finish Line"; + prefix = "(2001)"; + arg0 + { + title = "Flip?"; + type = 3; + } + } + + 2003 + { + title = "Respawn Line"; + prefix = "(2003)"; + arg0 + { + title = "Only from front?"; + type = 3; + } + } + + 2004 + { + title = "Bot Controller"; + prefix = "(2004)"; + arg0 + { + title = "Trick"; + type = 12; + enum + { + 0 = "None"; + 1 = "Left"; + 2 = "Right"; + 3 = "Up"; + 4 = "Down"; + } + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Disable rubberbanding"; + 2 = "Disable controls"; + 4 = "Use forced angle?"; + } + } + arg2 + { + title = "Forced Angle"; + type = 8; + } + } } parameters @@ -1820,20 +153,6 @@ udmf { title = "Next map"; } - arg1 - { - title = "Flags"; - type = 12; - enum - { - 1 = "Skip score tally"; - 2 = "Check emeralds"; - } - } - arg2 - { - title = "Next map (all emeralds)"; - } } 3 @@ -1864,16 +183,6 @@ udmf { title = "Speed"; } - arg1 - { - title = "Flags"; - type = 12; - enum - { - 1 = "No teleport to center"; - 2 = "Force spinning frames"; - } - } stringarg0 { title = "Sound"; @@ -2031,6 +340,242 @@ udmf type = 15; } } + + 30 + { + title = "Waving Flag"; + prefix = "(30)"; + arg0 + { + title = "PolyObject ID"; + type = 14; + } + arg1 + { + title = "Speed"; + } + arg2 + { + title = "Distance"; + } + } + + 31 + { + title = "Displacement by Front Sector"; + prefix = "(31)"; + arg0 + { + title = "PolyObject ID"; + type = 14; + } + arg1 + { + title = "Base speed"; + } + } + + 32 + { + title = "Angular Displacement by Front Sector"; + prefix = "(32)"; + arg0 + { + title = "PolyObject ID"; + type = 14; + } + arg1 + { + title = "Plane factor"; + default = 128; + } + arg2 + { + title = "Rotation factor"; + default = 90; + } + arg3 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Don't turn others"; + 2 = "Turn players"; + } + } + } + } + + planemove + { + title = "Plane Movement"; + + 52 + { + title = "Continuously Falling Sector"; + prefix = "(52)"; + arg0 + { + title = "Speed"; + } + arg1 + { + title = "Direction"; + type = 11; + enum + { + 0 = "Fall"; + 1 = "Rise"; + } + } + } + + 53 + { + title = "Continuous Plane Mover (Slowdown)"; + prefix = "(53)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Affected planes"; + type = 11; + enum = "floorceiling"; + } + arg2 + { + title = "Forward speed"; + } + arg3 + { + title = "Return speed"; + } + arg4 + { + title = "Starting delay"; + } + arg5 + { + title = "Delay before flip"; + } + } + + 56 + { + title = "Continuous Plane Mover (Constant)"; + prefix = "(56)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Affected planes"; + type = 11; + enum = "floorceiling"; + } + arg2 + { + title = "Forward speed"; + } + arg3 + { + title = "Return speed"; + } + arg4 + { + title = "Starting delay"; + } + arg5 + { + title = "Delay before flip"; + } + } + + 60 + { + title = "Activate Moving Platform"; + prefix = "(60)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Speed"; + } + arg2 + { + title = "Starting delay"; + } + arg3 + { + title = "Delay before flip"; + } + arg4 + { + title = "Starting direction"; + type = 11; + enum = "downup"; + } + } + + 61 + { + title = "Ceiling Crusher"; + prefix = "(61)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Starting direction"; + type = 11; + enum + { + 0 = "Crush"; + 1 = "Retract"; + } + } + arg2 + { + title = "Crush speed"; + } + arg3 + { + title = "Retract speed"; + } + } + + 66 + { + title = "Move Planes by Displacement"; + prefix = "(66)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Affected planes"; + type = 11; + enum = "floorceiling"; + } + arg2 + { + title = "Translation factor"; + default = 256; + } + } } fofmodifiers @@ -2222,6 +767,12 @@ udmf default = 255; } arg2 + { + title = "Blending mode"; + type = 11; + enum = "blendmodes"; + } + arg3 { title = "Appearance"; type = 12; @@ -2235,7 +786,7 @@ udmf 32 = "Cut cyan flat pixels"; } } - arg3 + arg4 { title = "Tangibility"; type = 12; @@ -2258,6 +809,12 @@ udmf default = 128; } arg2 + { + title = "Blending mode"; + type = 11; + enum = "blendmodes"; + } + arg3 { title = "Flags"; type = 12; @@ -2325,12 +882,18 @@ udmf default = 255; } arg2 + { + title = "Blending mode"; + type = 11; + enum = "blendmodes"; + } + arg3 { title = "Tangibility"; type = 12; enum = "tangibility"; } - arg3 + arg4 { title = "Flags"; type = 12; @@ -2344,7 +907,7 @@ udmf } } } - + 190 { title = "Rising"; @@ -2360,6 +923,12 @@ udmf default = 255; } arg2 + { + title = "Blending mode"; + type = 11; + enum = "blendmodes"; + } + arg3 { title = "Appearance"; type = 12; @@ -2373,17 +942,17 @@ udmf 32 = "Cut cyan flat pixels"; } } - arg3 + arg4 { title = "Tangibility"; type = 12; enum = "tangibility"; } - arg4 + arg5 { title = "Speed"; } - arg5 + arg6 { title = "Flags"; type = 12; @@ -2438,6 +1007,12 @@ udmf default = 255; } arg2 + { + title = "Blending mode"; + type = 11; + enum = "blendmodes"; + } + arg3 { title = "Appearance"; type = 12; @@ -2502,6 +1077,10 @@ udmf { title = "Rising speed"; } + arg3 + { + title = "Initial delay"; + } stringarg0 { title = "Crushing sound"; @@ -2524,6 +1103,12 @@ udmf default = 255; } arg2 + { + title = "Blending mode"; + type = 11; + enum = "blendmodes"; + } + arg3 { title = "Bustable type"; type = 11; @@ -2535,7 +1120,7 @@ udmf 3 = "Strong"; } } - arg3 + arg4 { title = "Flags"; type = 12; @@ -2547,7 +1132,7 @@ udmf 8 = "Cut cyan flat pixels"; } } - arg4 + arg5 { title = "Linedef executor tag"; type = 15; @@ -2594,6 +1179,12 @@ udmf default = 128; } arg2 + { + title = "Blending mode"; + type = 11; + enum = "blendmodes"; + } + arg3 { title = "Flags"; type = 12; @@ -2620,6 +1211,12 @@ udmf default = 255; } arg2 + { + title = "Blending mode"; + type = 11; + enum = "blendmodes"; + } + arg3 { title = "Flags"; type = 12; @@ -2659,12 +1256,13 @@ udmf 260 { title = "Generalized 3D Floor"; + prefix = "(260)"; id = "Sector_Set3dFloor"; requiresactivation = false; arg0 { - title = "Sector Tag"; + title = "Target sector tag"; type = 13; } arg1 @@ -2680,8 +1278,8 @@ udmf } flags { - 4 = "Render Both Sides"; - 16 = "Invert Sides"; + 4 = "Render insides"; + 16 = "Only render insides"; } } arg2 @@ -2690,14 +1288,14 @@ udmf type = 12; enum { - 1 = "Disable shadowcast"; - 2 = "Double shadowcast"; - 4 = "Fog block"; + 1 = "No shadow"; + 2 = "Double shadow"; + 4 = "Fog"; } } arg3 { - title = "Opacity"; + title = "Alpha"; default = 255; } } @@ -2747,42 +1345,6 @@ udmf } } - 305 - { - title = "Character Ability"; - prefix = "(305)"; - arg0 - { - title = "Trigger type"; - type = 11; - enum = "triggertype"; - } - arg1 - { - title = "Ability"; - type = 11; - enum - { - 0 = "None"; - 1 = "Thok"; - 2 = "Fly"; - 3 = "Glide and climb"; - 4 = "Homing attack"; - 5 = "Swim"; - 6 = "Double jump"; - 7 = "Float"; - 8 = "Float with slow descent"; - 9 = "Telekinesis"; - 10 = "Fall switch"; - 11 = "Jump boost"; - 12 = "Air drill"; - 13 = "Jump-thok"; - 14 = "Pogo bounce"; - 15 = "Twin spin"; - } - } - } - 308 { title = "Gametype"; @@ -2950,279 +1512,6 @@ udmf } } - 323 - { - title = "NiGHTSerize"; - prefix = "(323)"; - arg0 - { - title = "Trigger type"; - type = 11; - enum - { - 0 = "Each time"; - 1 = "Once"; - } - } - arg1 - { - title = "Mare number"; - } - arg2 - { - title = "Lap number"; - } - arg3 - { - title = "Mare comparison"; - type = 11; - enum = "comparison"; - } - arg4 - { - title = "Lap comparison"; - type = 11; - enum = "comparison"; - } - arg5 - { - title = "Compared player"; - type = 11; - enum - { - 0 = "Fastest"; - 1 = "Slowest"; - 2 = "Triggerer"; - } - } - arg6 - { - title = "NiGHTS check"; - type = 11; - enum - { - 0 = "No check"; - 1 = "Trigger if player was not NiGHTS"; - 2 = "Trigger if player was already NiGHTS"; - } - } - arg7 - { - title = "Flags"; - type = 12; - enum - { - 1 = "Only count bonus time laps"; - 2 = "Only trigger if final mare completed"; - } - } - } - 325 - { - title = "De-NiGHTSerize"; - prefix = "(325)"; - arg0 - { - title = "Trigger type"; - type = 11; - enum - { - 0 = "Each time"; - 1 = "Once"; - } - } - arg1 - { - title = "Mare number"; - } - arg2 - { - title = "Lap number"; - } - arg3 - { - title = "Mare comparison"; - type = 11; - enum = "comparison"; - } - arg4 - { - title = "Lap comparison"; - type = 11; - enum = "comparison"; - } - arg5 - { - title = "Compared player"; - type = 11; - enum - { - 0 = "Fastest"; - 1 = "Slowest"; - 2 = "Triggerer"; - } - } - arg6 - { - title = "NiGHTS check"; - type = 11; - enum - { - 0 = "No check"; - 1 = "Trigger if nobody is now NiGHTS"; - 2 = "Trigger if somebody is still NiGHTS"; - } - } - arg7 - { - title = "Only bonus laps?"; - type = 11; - enum = "noyes"; - } - } - 327 - { - title = "NiGHTS Lap"; - prefix = "(327)"; - arg0 - { - title = "Trigger type"; - type = 11; - enum - { - 0 = "Each time"; - 1 = "Once"; - } - } - arg1 - { - title = "Mare number"; - } - arg2 - { - title = "Lap number"; - } - arg3 - { - title = "Mare comparison"; - type = 11; - enum = "comparison"; - } - arg4 - { - title = "Lap comparison"; - type = 11; - enum = "comparison"; - } - arg5 - { - title = "Compared player"; - type = 11; - enum - { - 0 = "Fastest"; - 1 = "Slowest"; - 2 = "Triggerer"; - } - } - arg6 - { - title = "Only bonus laps?"; - type = 11; - enum = "noyes"; - } - } - 329 - { - title = "Ideya Capture Touch"; - prefix = "(329)"; - arg0 - { - title = "Trigger type"; - type = 11; - enum - { - 0 = "Each time"; - 1 = "Once"; - } - } - arg1 - { - title = "Mare number"; - } - arg2 - { - title = "Lap number"; - } - arg3 - { - title = "Mare comparison"; - type = 11; - enum = "comparison"; - } - arg4 - { - title = "Lap comparison"; - type = 11; - enum = "comparison"; - } - arg5 - { - title = "Compared player"; - type = 11; - enum - { - 0 = "Fastest"; - 1 = "Slowest"; - 2 = "Triggerer"; - } - } - arg6 - { - title = "Spheres check"; - type = 11; - enum - { - 0 = "Trigger if enough spheres"; - 1 = "Trigger if not enough spheres"; - 2 = "Trigger regardless of spheres"; - } - } - arg7 - { - title = "Flags"; - type = 12; - enum - { - 1 = "Only count bonus time laps"; - 2 = "Trigger upon entering Ideya Capture"; - } - } - } - - 331 - { - title = "Player Skin"; - prefix = "(331)"; - arg0 - { - title = "Trigger type"; - type = 11; - enum = "triggertype"; - } - arg1 - { - title = "Invert choice?"; - type = 11; - enum = "noyes"; - } - stringarg0 - { - title = "Skin name"; - type = 2; - } - } - 334 { title = "Object Dye"; @@ -3246,66 +1535,37 @@ udmf } } - 337 - { - title = "Emerald Check"; - prefix = "(337)"; - arg0 - { - title = "Trigger type"; - type = 11; - enum = "triggertype"; - } - arg1 - { - title = "Emeralds"; - type = 12; - enum - { - 1 = "Emerald 1"; - 2 = "Emerald 2"; - 4 = "Emerald 3"; - 8 = "Emerald 4"; - 16 = "Emerald 5"; - 32 = "Emerald 6"; - 64 = "Emerald 7"; - } - } - arg2 - { - title = "Check if"; - type = 11; - enum = "flagcheck"; - } - } - - 340 - { - title = "NiGHTS Mare"; - prefix = "(340)"; - arg0 - { - title = "Trigger type"; - type = 11; - enum = "triggertype"; - } - arg1 - { - title = "Mare"; - } - arg2 - { - title = "Comparison"; - type = 11; - enum = "comparison"; - } - } - 399 { title = "Level Load"; prefix = "(399)"; } + + 2002 + { + title = "Race Lap"; + prefix = "(2002)"; + arg0 + { + title = "Lap"; + } + arg1 + { + title = "Trigger"; + type = 11; + enum + { + 0 = "Equal"; + 1 = "Greater than or equal"; + 2 = "Less than or equal"; + } + } + arg2 + { + title = "First place?"; + type = 3; + } + } } linedefexecsector @@ -3397,6 +1657,7 @@ udmf 0 = "Add tag"; 1 = "Remove tag"; 2 = "Replace first tag"; + 3 = "Change trigger tag"; } } } @@ -3419,6 +1680,7 @@ udmf 0 = "Add tag"; 1 = "Remove tag"; 2 = "Replace first tag"; + 3 = "Change trigger tag"; } } } @@ -4107,157 +2369,172 @@ udmf } } - linedefexecplayer + linedefexecmisc { - title = "Linedef Executor (player/object)"; + title = "Linedef Executor (misc.)"; - 412 + 413 { - title = "Teleporter"; - prefix = "(412)"; + title = "Change Music"; + prefix = "(413)"; arg0 - { - title = "Destination tag"; - type = 14; - } - arg1 { title = "Flags"; type = 12; enum { - 1 = "Silent"; - 2 = "Keep angle"; - 4 = "Keep momentum"; - 8 = "Relative silent"; + 1 = "For all players"; + 2 = "Seek offset from current position"; + 4 = "Fade to custom volume"; + 8 = "Don't reload after death"; + 16 = "Force music reload"; + 32 = "Don't loop"; + } + } + arg1 + { + title = "Position"; + } + arg2 + { + title = "Fade out time"; + } + arg3 + { + title = "Fade in time"; + } + arg4 + { + title = "Fade destination volume"; + } + arg5 + { + title = "Fade start volume"; + default = -1; + } + arg6 + { + title = "Track number"; + } + stringarg0 + { + title = "Music name"; + type = 2; + } + } + + 414 + { + title = "Play Sound Effect"; + prefix = "(414)"; + arg0 + { + title = "Source"; + type = 11; + enum + { + 0 = "Triggering object"; + 1 = "Trigger sector"; + 2 = "Nowhere"; + 3 = "Tagged sectors"; + } + } + arg1 + { + title = "Listener"; + type = 11; + enum + { + 0 = "Triggering player"; + 1 = "Everyone"; + 2 = "Everyone touching tagged sectors"; } } arg2 { - title = "X offset"; + title = "Target sector tag"; + type = 13; } - arg3 - { - title = "Y offset"; - } - arg4 - { - title = "Z offset"; - } - } - - 425 - { - title = "Change Object State"; - prefix = "(425)"; stringarg0 { - title = "State"; + title = "Sound name"; type = 2; } } - 426 + 415 { - title = "Stop Object"; - prefix = "(426)"; - arg0 - { - title = "Move to center?"; - type = 11; - enum = "noyes"; - } - } - - 427 - { - title = "Award Score"; - prefix = "(427)"; - arg0 - { - title = "Score"; - } - } - - 432 - { - title = "Enable/Disable 2D Mode"; - prefix = "(432)"; - arg0 - { - title = "Mode"; - type = 11; - enum - { - 0 = "2D"; - 1 = "3D"; - } - } - } - - 433 - { - title = "Enable/Disable Gravity Flip"; - prefix = "(433)"; - arg0 - { - title = "Gravity"; - type = 11; - enum - { - 0 = "Reverse"; - 1 = "Normal"; - } - } - } - - 434 - { - title = "Award Power-Up"; - prefix = "(434)"; + title = "Run Script"; + prefix = "(415)"; stringarg0 { - title = "Power"; - type = 2; - } - stringarg1 - { - title = "Duration/Amount"; + title = "Lump name"; type = 2; } } - 437 + 422 { - title = "Disable Player Control"; - prefix = "(437)"; + title = "Switch to Cut-Away View"; + prefix = "(422)"; arg0 { - title = "Time"; + title = "Viewpoint tag"; + type = 14; } arg1 { - title = "Allow jumping?"; + title = "Time"; + } + } + + 423 + { + title = "Change Sky"; + prefix = "(423)"; + arg0 + { + title = "Sky number"; + } + arg1 + { + title = "For all players?"; type = 11; enum = "noyes"; } } - 438 + 424 { - title = "Change Object Size"; - prefix = "(438)"; + title = "Change Weather"; + prefix = "(424)"; arg0 { - title = "Size (%)"; - default = 100; + title = "Weather"; + type = 11; + enum + { + 0 = "None"; + 1 = "Storm (thunder, lightning and rain)"; + 2 = "Snow"; + 3 = "Rain"; + 4 = "Preloaded"; + 5 = "Storm (no rain)"; + 6 = "Storm (no lightning)"; + } + } + arg1 + { + title = "For all players?"; + type = 11; + enum = "noyes"; } } - 442 + 436 { - title = "Change Object Type State"; - prefix = "(442)"; + title = "Shatter FOF"; + prefix = "(436)"; arg0 { title = "Target sector tag"; @@ -4265,170 +2542,486 @@ udmf } arg1 { - title = "Change to"; - type = 11; - enum - { - 0 = "Specified state"; - 1 = "Next state"; - } + title = "Control sector tag"; + type = 13; } + } + + 439 + { + title = "Change Tagged Linedef's Textures"; + prefix = "(439)"; + arg0 + { + title = "Target linedef tag"; + type = 15; + } + arg1 + { + title = "Affected sides"; + type = 11; + enum = "frontbackboth"; + } + arg2 + { + title = "Change unset textures?"; + type = 11; + enum = "yesno"; + } + arg3 + { + title = "Use backside textures?"; + type = 11; + enum = "noyes"; + } + } + + 440 + { + title = "Start Metal Sonic Race"; + prefix = "(440)"; + } + + 441 + { + title = "Condition Set Trigger"; + prefix = "(441)"; + arg0 + { + title = "Trigger number"; + } + } + + 443 + { + title = "Call Lua Function"; + prefix = "(443)"; stringarg0 { - title = "Object type"; - type = 2; - } - stringarg1 - { - title = "State"; + title = "Function name"; type = 2; } } - 457 + 444 { - title = "Track Object's Angle"; - prefix = "(457)"; + title = "Earthquake"; + prefix = "(444)"; arg0 { - title = "Anchor tag"; - type = 14; + title = "Duration"; } arg1 { - title = "Angle tolerance"; - type = 8; + title = "Intensity"; + } + } + + 445 + { + title = "Make FOF Disappear/Reappear"; + prefix = "(445)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Control sector tag"; + type = 13; } arg2 { - title = "Time tolerance"; + title = "Effect"; + type = 11; + enum + { + 0 = "Disappear"; + 1 = "Reappear"; + } + } + } + + 446 + { + title = "Make FOF Crumble"; + prefix = "(446)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Control sector tag"; + type = 13; + } + arg2 + { + title = "Respawn?"; + type = 11; + enum + { + 0 = "Yes"; + 1 = "No"; + 2 = "Unless FF_NORETURN"; + 3 = "Only if FF_NORETURN"; + } + } + } + + 447 + { + title = "Change Tagged Sector's Colormap"; + prefix = "(447)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Colormap sector tag"; + type = 13; + } + arg2 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Add to existing colormap"; + 2 = "Subtract light R"; + 4 = "Subtract light G"; + 8 = "Subtract light B"; + 16 = "Subtract light A"; + 32 = "Subtract fade R"; + 64 = "Subtract fade G"; + 128 = "Subtract fade B"; + 256 = "Subtract fade A"; + 512 = "Subtract fadestart"; + 1024 = "Subtract fadeend"; + 2048 = "Ignore flags"; + } + } + } + + 448 + { + title = "Change Skybox"; + prefix = "(448)"; + arg0 + { + title = "Viewpoint ID"; + } + arg1 + { + title = "Centerpoint ID"; + } + arg2 + { + title = "Change?"; + type = 11; + enum + { + 0 = "Viewpoint"; + 1 = "Centerpoint"; + 2 = "Both"; + } + } + arg3 + { + title = "For all players?"; + type = 11; + enum = "noyes"; + } + } + + 449 + { + title = "Enable Bosses with Parameter"; + prefix = "(449)"; + arg0 + { + title = "Boss ID"; + } + arg1 + { + title = "Effect"; + type = 11; + enum + { + 0 = "Enable"; + 1 = "Disable"; + } + } + } + + 450 + { + title = "Execute Linedef Executor (specific tag)"; + prefix = "(450)"; + arg0 + { + title = "Trigger linedef tag"; + type = 15; + } + } + + 451 + { + title = "Execute Linedef Executor (random tag in range)"; + prefix = "(451)"; + arg0 + { + title = "Start of tag range"; + type = 15; + } + arg1 + { + title = "End of tag range"; + type = 15; + } + } + + 452 + { + title = "Set FOF Translucency"; + prefix = "(452)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Control sector tag"; + type = 13; + } + arg2 + { + title = "Alpha"; + } + arg3 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Add to current translucency"; + 2 = "Don't handle FF_TRANSLUCENT"; + } + } + } + + 453 + { + title = "Fade FOF"; + prefix = "(453)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Control sector tag"; + type = 13; + } + arg2 + { + title = "Alpha"; + } + arg3 + { + title = "Fading speed"; + } + arg4 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Add to current translucency"; + 2 = "Interrupt ongoing fades"; + 4 = "Speed is duration"; + 8 = "Don't change collision"; + 16 = "No collision during fade"; + 32 = "Don't handle FF_TRANSLUCENT"; + 64 = "Don't handle FF_EXISTS"; + 128 = "Don't fade lighting"; + 256 = "Don't fade colormap"; + 512 = "Use exact alpha in OpenGL"; + } + } + } + + 454 + { + title = "Stop Fading FOF"; + prefix = "(454)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Control sector tag"; + type = 13; + } + arg2 + { + title = "Finalize collision?"; + type = 11; + enum = "yesno"; + } + } + + 455 + { + title = "Fade Tagged Sector's Colormap"; + prefix = "(455)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Colormap sector tag"; + type = 13; + } + arg2 + { + title = "Fade duration"; + } + arg3 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Add to existing colormap"; + 2 = "Subtract light R"; + 4 = "Subtract light G"; + 8 = "Subtract light B"; + 16 = "Subtract light A"; + 32 = "Subtract fade R"; + 64 = "Subtract fade G"; + 128 = "Subtract fade B"; + 256 = "Subtract fade A"; + 512 = "Subtract fadestart"; + 1024 = "Subtract fadeend"; + 2048 = "Ignore flags"; + 4096 = "Fade from invisible black"; + 8192 = "Interrupt ongoing fades"; + } + } + } + + 456 + { + title = "Stop Fading Tagged Sector's Colormap"; + prefix = "(456)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + } + + 459 + { + title = "Control Text Prompt"; + prefix = "(459)"; + arg0 + { + title = "Prompt number"; + } + arg1 + { + title = "Page number"; + } + arg2 + { + title = "Flags"; + type = 11; + enum + { + 1 = "Close current text prompt"; + 2 = "Trigger linedef executor on close"; + 4 = "Find prompt by name"; + 8 = "Don't disable controls"; + } } arg3 { title = "Trigger linedef tag"; type = 15; } - arg4 + stringarg0 { - title = "Track after failure?"; - type = 11; - enum = "noyes"; + title = "Prompt name"; + type = 2; } } - 458 + 465 { - title = "Stop Tracking Object's Angle"; - prefix = "(458)"; - } - - 460 - { - title = "Award Rings"; - prefix = "(460)"; + title = "Set Linedef Executor Delay"; + prefix = "(465)"; arg0 { - title = "Rings"; + title = "Linedef tag"; + type = 15; } arg1 { - title = "Periodicity"; - } - } - - 461 - { - title = "Spawn Object"; - prefix = "(461)"; - arg0 - { - title = "X position"; - } - arg1 - { - title = "Y position"; + title = "Value"; } arg2 { - title = "Z position"; - } - arg3 - { - title = "Angle"; - type = 8; - } - arg4 - { - title = "Randomize position?"; + title = "Set/Add?"; type = 11; - enum = "noyes"; - } - arg5 - { - title = "Max X position"; - } - arg6 - { - title = "Max Y position"; - } - arg7 - { - title = "Max Z position"; - } - stringarg0 - { - title = "Object type"; - type = 2; + enum = "setadd"; } } - 462 + 468 { - title = "Stop Timer/Exit Stage in Record Attack"; - prefix = "(462)"; - } - - 463 - { - title = "Dye Object"; - prefix = "(463)"; - stringarg0 - { - title = "Skin color"; - type = 2; - } - } - - 464 - { - title = "Trigger Egg Capsule"; - prefix = "(464)"; + title = "Change Linedef Argument"; + prefix = "(468)"; arg0 { - title = "Egg Capsule tag"; - type = 14; + title = "Linedef tag"; + type = 15; } arg1 { - title = "End level?"; + title = "Argument"; + } + arg2 + { + title = "Value"; + } + arg3 + { + title = "Set/Add?"; type = 11; - enum = "yesno"; + enum = "setadd"; } } - 466 + 499 { - title = "Set Level Failure State"; - prefix = "(466)"; + title = "Enable/Disable Waypoints"; + prefix = "(499)"; arg0 { - title = "State"; - type = 11; - enum - { - 0 = "Failure"; - 1 = "Success"; - } + title = "Enable?"; + type = 3; } } } @@ -4962,6 +3555,7 @@ udmf { 1 = "No physics"; 2 = "Dynamic"; + 4 = "Copy to other side"; } } } @@ -5047,6 +3641,34 @@ udmf } } + 777 + { + title = "Create Anchor-Based Slope"; + prefix = "(777)"; + arg0 + { + title = "Planes"; + type = 12; + enum + { + 1 = "Floor"; + 2 = "Ceiling"; + } + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "No physics"; + 2 = "Dynamic"; + 4 = "Slope backside"; + 8 = "Mirror plane"; + } + } + } + 799 { title = "Set Tagged Dynamic Slope Vertex to Front Sector Height"; diff --git a/extras/conf/udb/Includes/Kart2_misc.cfg b/extras/conf/udb/Includes/RingRacers_misc.cfg similarity index 90% rename from extras/conf/udb/Includes/Kart2_misc.cfg rename to extras/conf/udb/Includes/RingRacers_misc.cfg index cae1127b3..8b0fbfbbd 100644 --- a/extras/conf/udb/Includes/Kart2_misc.cfg +++ b/extras/conf/udb/Includes/RingRacers_misc.cfg @@ -1,21 +1,21 @@ linedefflags { 1 = "[0] Impassable"; - 2 = "[1] Block Enemies"; + 2 = "[1] Block Players"; 4 = "[2] Double-Sided"; 8 = "[3] Upper Unpegged"; 16 = "[4] Lower Unpegged"; - 32 = "[5] Slope Skew (E1)"; + 32 = "[5] Slope Skew"; 64 = "[6] Not Climbable"; - 128 = "[7] No Midtexture Skew (E2)"; - 256 = "[8] Peg Midtexture (E3)"; - 512 = "[9] Solid Midtexture (E4)"; - 1024 = "[10] Repeat Midtexture (E5)"; + 128 = "[7] No Midtexture Skew"; + 256 = "[8] Peg Midtexture"; + 512 = "[9] Solid Midtexture"; + 1024 = "[10] Repeat Midtexture"; 2048 = "[11] Netgame Only"; 4096 = "[12] No Netgame"; - 8192 = "[13] Effect 6"; - 16384 = "[14] Bouncy Wall"; - 32768 = "[15] Transfer Line"; + 8192 = "[13] Block Enemies"; + 16384 = "[14] Don't Bump"; + 32768 = "[15] FOF Transfer"; } @@ -59,14 +59,8 @@ linedefflags_udmf netonly = "Netgame Only"; nonet = "No Netgame"; blockmonsters = "Block Enemies"; - bouncy = "Not Bouncy"; - transfer = "Transfer Line"; -} - -linedefactivations_udmf -{ - netonly = "Netgame Only"; - nonet = "No Netgame"; + bouncy = "Don't Bump"; + transfer = "FOF Transfer"; } linedefrenderstyles @@ -94,26 +88,19 @@ sectorflags gravityflip = "Flip Objects in Reverse Gravity"; heatwave = "Heat Wave"; noclipcamera = "Intangible to the Camera"; - ripple_floor = "Ripply Floor"; - ripple_ceiling = "Ripply Ceiling"; - invertencore = "Invert Encore Remap"; - outerspace = "Space Countdown"; + ripple_floor = "Water Ripple Floor"; + ripple_ceiling = "Water Ripple Ceiling"; + invertencore = "Encore Remap Invert"; + nostepup = "Wall Sector (no step-up)"; doublestepup = "Ramp Sector (double step-up/down)"; - nostepdown = "Non-Ramp Sector (No step-down)"; + nostepdown = "Non-Ramp Sector (no step-down)"; speedpad = "Speed Pad"; starpostactivator = "Star Post Activator"; exit = "Exit"; - specialstagepit = "Special Stage Pit"; - returnflag = "Return Flag"; - redteambase = "Red Team Base"; - blueteambase = "Blue Team Base"; fan = "Fan Sector"; - supertransform = "Super Sonic Transform"; - forcespin = "Force Spin"; + deleteitems = "Delete Items"; zoomtubestart = "Zoom Tube Start"; zoomtubeend = "Zoom Tube End"; - finishline = "Circuit Finish Line"; - ropehang = "Rope Hang"; } thingflags @@ -136,10 +123,7 @@ thingflags_udmf // When the UDMF field name is prefixed with ! it is inverted thingflagstranslation { - 1 = "extra"; 2 = "flip"; - 4 = "special"; - 8 = "ambush"; } @@ -459,20 +443,6 @@ doommaplumpnames nodebuild = true; allowempty = false; } - - REJECT - { - required = false; - nodebuild = true; - allowempty = false; - } - - BLOCKMAP - { - required = false; - nodebuild = true; - allowempty = true; - } } udmfmaplumpnames @@ -483,7 +453,12 @@ udmfmaplumpnames nodebuild = true; allowempty = false; } +} +// Because Ring Racers has a versatile virtual resource +// system, we can separate these out a bit more. +sharedmaplumpnames +{ REJECT { required = false; @@ -497,6 +472,34 @@ udmfmaplumpnames nodebuild = true; allowempty = true; } + + PICTURE + { + required = false; + blindcopy = true; + nodebuild = false; + } + + MINIMAP + { + required = false; + blindcopy = true; + nodebuild = false; + } + + TWEAKMAP + { + required = false; + blindcopy = true; + nodebuild = false; + } + + ENCORE + { + required = false; + blindcopy = true; + nodebuild = false; + } } // ENUMERATIONS @@ -672,7 +675,6 @@ enums //Default things filters thingsfilters { - filter0 { name = "Player starts"; @@ -680,17 +682,7 @@ thingsfilters type = -1; } - filter1 - { - name = "Enemies"; - category = "enemies"; - type = -1; - - } - - - filter2 { name = "Normal Gravity"; category = ""; @@ -703,8 +695,7 @@ thingsfilters } - - filter3 + filter2 { name = "Reverse Gravity"; category = ""; @@ -717,22 +708,17 @@ thingsfilters } - - filter4 + filter3 { name = "Rings"; category = ""; type = 300; - } - - filter5 + filter4 { name = "Waypoints"; - category = ""; - type = 2001; - + category = "waypoints"; } } diff --git a/extras/conf/udb/Includes/RingRacers_sectors.cfg b/extras/conf/udb/Includes/RingRacers_sectors.cfg new file mode 100644 index 000000000..4cb9fc0f7 --- /dev/null +++ b/extras/conf/udb/Includes/RingRacers_sectors.cfg @@ -0,0 +1,28 @@ +// Don't feel like updating, these are only for Doom format anyway... +sectortypes +{ + 0 = "Normal"; +} + +gen_sectortypes +{ + first + { + 0 = "Normal"; + } + + second + { + 0 = "Normal"; + } + + third + { + 0 = "Normal"; + } + + fourth + { + 0 = "Normal"; + } +} diff --git a/extras/conf/udb/Includes/Kart2_things.cfg b/extras/conf/udb/Includes/RingRacers_things.cfg similarity index 53% rename from extras/conf/udb/Includes/Kart2_things.cfg rename to extras/conf/udb/Includes/RingRacers_things.cfg index d9ac72e14..50a8732d1 100644 --- a/extras/conf/udb/Includes/Kart2_things.cfg +++ b/extras/conf/udb/Includes/RingRacers_things.cfg @@ -3,3161 +3,6 @@ // 8-Dark_Gray 9-Blue 10-Green 11-Cyan 12-Red 13-Magenta // 14-Yellow 15-White 16-Pink 17-Orange 18-Gold 19-Cream -doom -{ - editor - { - color = 15; // White - arrow = 1; - title = ""; - error = -1; - width = 8; - height = 16; - sort = 1; - - 3328 = "3D Mode Start"; - } - - starts - { - color = 1; // Blue - arrow = 1; - title = "Player Starts"; - width = 16; - height = 48; - sprite = "PLAYA0"; - - 1 - { - title = "Player 01 Start"; - sprite = "PLAYA0"; - } - 2 - { - title = "Player 02 Start"; - sprite = "PLAYA0"; - } - 3 - { - title = "Player 03 Start"; - sprite = "PLAYA0"; - } - 4 - { - title = "Player 04 Start"; - sprite = "PLAYA0"; - } - 5 - { - title = "Player 05 Start"; - sprite = "PLAYA0"; - } - 6 - { - title = "Player 06 Start"; - sprite = "PLAYA0"; - } - 7 - { - title = "Player 07 Start"; - sprite = "PLAYA0"; - } - 8 - { - title = "Player 08 Start"; - sprite = "PLAYA0"; - } - 9 - { - title = "Player 09 Start"; - sprite = "PLAYA0"; - } - 10 - { - title = "Player 10 Start"; - sprite = "PLAYA0"; - } - 11 - { - title = "Player 11 Start"; - sprite = "PLAYA0"; - } - 12 - { - title = "Player 12 Start"; - sprite = "PLAYA0"; - } - 13 - { - title = "Player 13 Start"; - sprite = "PLAYA0"; - } - 14 - { - title = "Player 14 Start"; - sprite = "PLAYA0"; - } - 15 - { - title = "Player 15 Start"; - sprite = "PLAYA0"; - } - 16 - { - title = "Player 16 Start"; - sprite = "PLAYA0"; - } - 17 - { - title = "Player 17 Start"; - sprite = "PLAYA0"; - } - 18 - { - title = "Player 18 Start"; - sprite = "PLAYA0"; - } - 19 - { - title = "Player 19 Start"; - sprite = "PLAYA0"; - } - 20 - { - title = "Player 20 Start"; - sprite = "PLAYA0"; - } - 21 - { - title = "Player 21 Start"; - sprite = "PLAYA0"; - } - 22 - { - title = "Player 22 Start"; - sprite = "PLAYA0"; - } - 23 - { - title = "Player 23 Start"; - sprite = "PLAYA0"; - } - 24 - { - title = "Player 24 Start"; - sprite = "PLAYA0"; - } - 25 - { - title = "Player 25 Start"; - sprite = "PLAYA0"; - } - 26 - { - title = "Player 26 Start"; - sprite = "PLAYA0"; - } - 27 - { - title = "Player 27 Start"; - sprite = "PLAYA0"; - } - 28 - { - title = "Player 28 Start"; - sprite = "PLAYA0"; - } - 29 - { - title = "Player 29 Start"; - sprite = "PLAYA0"; - } - 30 - { - title = "Player 30 Start"; - sprite = "PLAYA0"; - } - 31 - { - title = "Player 31 Start"; - sprite = "PLAYA0"; - } - 32 - { - title = "Player 32 Start"; - sprite = "PLAYA0"; - } - 33 - { - title = "Match Start"; - sprite = "NDRNA2A8"; - } - 34 - { - title = "CTF Red Team Start"; - sprite = "SIGNG0"; - } - 35 - { - title = "CTF Blue Team Start"; - sprite = "SIGNE0"; - } - } - - enemies - { - color = 9; // Light_Blue - arrow = 1; - title = "Enemies"; - - 100 - { - title = "Crawla (Blue)"; - sprite = "POSSA1"; - width = 24; - height = 32; - } - 101 - { - title = "Crawla (Red)"; - sprite = "SPOSA1"; - width = 24; - height = 32; - } - 102 - { - title = "Stupid Dumb Unnamed RoboFish"; - sprite = "FISHA0"; - width = 8; - height = 28; - } - 103 - { - title = "Buzz (Gold)"; - sprite = "BUZZA1"; - width = 28; - height = 40; - } - 104 - { - title = "Buzz (Red)"; - sprite = "RBUZA1"; - width = 28; - height = 40; - } - 108 - { - title = "Deton"; - sprite = "DETNA1"; - width = 20; - height = 32; - } - 110 - { - title = "Turret"; - sprite = "TRETA1"; - width = 16; - height = 32; - } - 111 - { - title = "Pop-up Turret"; - sprite = "TURRI1"; - width = 12; - height = 64; - } - 122 - { - title = "Spring Shell (Green)"; - sprite = "SSHLA1"; - width = 24; - height = 40; - } - 125 - { - title = "Spring Shell (Yellow)"; - sprite = "SSHLI1"; - width = 24; - height = 40; - } - 109 - { - title = "Skim"; - sprite = "SKIMA1"; - width = 16; - height = 24; - } - 113 - { - title = "Jet Jaw"; - sprite = "JJAWA3A7"; - width = 12; - height = 20; - } - 126 - { - title = "Crushstacean"; - sprite = "CRABA0"; - width = 24; - height = 32; - } - 138 - { - title = "Banpyura"; - sprite = "CR2BA0"; - width = 24; - height = 32; - } - 117 - { - title = "Robo-Hood"; - sprite = "ARCHA1"; - width = 24; - height = 32; - } - 118 - { - title = "Lance-a-Bot"; - sprite = "CBFSA1"; - width = 32; - height = 72; - } - 1113 - { - title = "Suspicious Lance-a-Bot Statue"; - sprite = "CBBSA1"; - width = 32; - height = 72; - } - 119 - { - title = "Egg Guard"; - sprite = "ESHIA1"; - width = 16; - height = 48; - } - 115 - { - title = "Bird Aircraft Strike Hazard"; - sprite = "VLTRF1"; - width = 12; - height = 24; - } - 120 - { - title = "Green Snapper"; - sprite = "GSNPA1"; - width = 24; - height = 24; - } - 121 - { - title = "Minus"; - sprite = "MNUSA0"; - width = 24; - height = 32; - } - 134 - { - title = "Canarivore"; - sprite = "CANAA0"; - width = 12; - height = 80; - hangs = 1; - } - 123 - { - title = "Unidus"; - sprite = "UNIDA1"; - width = 18; - height = 36; - } - 135 - { - title = "Pterabyte Spawner"; - sprite = "PTERA2A8"; - width = 16; - height = 16; - } - 136 - { - title = "Pyre Fly"; - sprite = "PYREA0"; - width = 24; - height = 34; - } - 137 - { - title = "Dragonbomber"; - sprite = "DRABA1"; - width = 28; - height = 48; - } - 105 - { - title = "Jetty-Syn Bomber"; - sprite = "JETBB1"; - width = 20; - height = 50; - } - 106 - { - title = "Jetty-Syn Gunner"; - sprite = "JETGB1"; - width = 20; - height = 48; - } - 112 - { - title = "Spincushion"; - sprite = "SHRPA1"; - width = 16; - height = 24; - } - 114 - { - title = "Snailer"; - sprite = "SNLRA3A7"; - width = 24; - height = 48; - } - 129 - { - title = "Penguinator"; - sprite = "PENGA1"; - width = 24; - height = 32; - } - 130 - { - title = "Pophat"; - sprite = "POPHA1"; - width = 24; - height = 32; - } - 107 - { - title = "Crawla Commander"; - sprite = "CCOMA1"; - width = 16; - height = 32; - } - 131 - { - title = "Spinbobert"; - sprite = "SBOBB0"; - width = 32; - height = 32; - } - 132 - { - title = "Cacolantern"; - sprite = "CACOA0"; - width = 32; - height = 32; - } - 133 - { - title = "Hangster"; - sprite = "HBATC1"; - width = 24; - height = 24; - hangs = 1; - } - 127 - { - title = "Hive Elemental"; - sprite = "HIVEA0"; - width = 32; - height = 80; - } - 128 - { - title = "Bumblebore"; - sprite = "BUMBA1"; - width = 16; - height = 32; - } - 124 - { - title = "Buggle"; - sprite = "BBUZA1"; - width = 20; - height = 24; - } - 116 - { - title = "Pointy"; - sprite = "PNTYA1"; - width = 8; - height = 16; - } - } - - bosses - { - color = 8; // Dark_Gray - arrow = 1; - title = "Bosses"; - - 200 - { - title = "Egg Mobile"; - sprite = "EGGMA1"; - width = 24; - height = 76; - } - 201 - { - title = "Egg Slimer"; - sprite = "EGGNA1"; - width = 24; - height = 76; - } - 202 - { - title = "Sea Egg"; - sprite = "EGGOA1"; - width = 32; - height = 116; - } - 203 - { - title = "Egg Colosseum"; - sprite = "EGGPA1"; - width = 24; - height = 76; - } - 204 - { - title = "Fang"; - sprite = "FANGA1"; - width = 24; - height = 60; - } - 206 - { - title = "Brak Eggman (Old)"; - sprite = "BRAKB1"; - width = 48; - height = 160; - } - 207 - { - title = "Metal Sonic (Race)"; - sprite = "METLI1"; - width = 16; - height = 48; - } - 208 - { - title = "Metal Sonic (Battle)"; - sprite = "METLC1"; - width = 16; - height = 48; - } - 209 - { - title = "Brak Eggman"; - sprite = "BRAK01"; - width = 48; - height = 160; - } - 290 - { - arrow = 0; - title = "Boss Escape Point"; - width = 8; - height = 16; - sprite = "internal:eggmanend"; - } - 291 - { - arrow = 0; - title = "Egg Capsule Center"; - width = 8; - height = 16; - sprite = "internal:capsule"; - } - 292 - { - arrow = 0; - title = "Boss Waypoint"; - width = 8; - height = 16; - sprite = "internal:eggmanway"; - } - 293 - { - title = "Metal Sonic Gather Point"; - sprite = "internal:metal"; - width = 8; - height = 16; - } - 294 - { - title = "Fang Waypoint"; - sprite = "internal:eggmanway"; - width = 8; - height = 16; - } - } - - rings - { - color = 14; // Yellow - title = "Rings and Weapon Panels"; - width = 24; - height = 24; - sprite = "RINGA0"; - - 300 - { - title = "Ring"; - sprite = "RINGA0"; - width = 16; - } - 301 - { - title = "Bounce Ring"; - sprite = "internal:RNGBA0"; - } - 302 - { - title = "Rail Ring"; - sprite = "internal:RNGRA0"; - } - 303 - { - title = "Infinity Ring"; - sprite = "internal:RNGIA0"; - } - 304 - { - title = "Automatic Ring"; - sprite = "internal:RNGAA0"; - } - 305 - { - title = "Explosion Ring"; - sprite = "internal:RNGEA0"; - } - 306 - { - title = "Scatter Ring"; - sprite = "internal:RNGSA0"; - } - 307 - { - title = "Grenade Ring"; - sprite = "internal:RNGGA0"; - } - 308 - { - title = "CTF Team Ring (Red)"; - sprite = "internal:RRNGA0"; - width = 16; - } - 309 - { - title = "CTF Team Ring (Blue)"; - sprite = "internal:BRNGA0"; - width = 16; - } - 330 - { - title = "Bounce Ring Panel"; - sprite = "internal:PIKBA0"; - } - 331 - { - title = "Rail Ring Panel"; - sprite = "internal:PIKRA0"; - } - 332 - { - title = "Automatic Ring Panel"; - sprite = "internal:PIKAA0"; - } - 333 - { - title = "Explosion Ring Panel"; - sprite = "internal:PIKEA0"; - } - 334 - { - title = "Scatter Ring Panel"; - sprite = "internal:PIKSA0"; - } - 335 - { - title = "Grenade Ring Panel"; - sprite = "internal:PIKGA0"; - } - } - - collectibles - { - color = 10; // Light_Green - title = "Other Collectibles"; - width = 16; - height = 32; - sort = 1; - sprite = "CEMGA0"; - - 310 - { - title = "CTF Red Flag"; - sprite = "RFLGA0"; - width = 24; - height = 64; - } - 311 - { - title = "CTF Blue Flag"; - sprite = "BFLGA0"; - width = 24; - height = 64; - } - 312 - { - title = "Emerald Token"; - sprite = "TOKEA0"; - width = 16; - height = 32; - } - 313 - { - title = "Chaos Emerald 1 (Green)"; - sprite = "CEMGA0"; - } - 314 - { - title = "Chaos Emerald 2 (Purple)"; - sprite = "CEMGB0"; - } - 315 - { - title = "Chaos Emerald 3 (Blue)"; - sprite = "CEMGC0"; - } - 316 - { - title = "Chaos Emerald 4 (Cyan)"; - sprite = "CEMGD0"; - } - 317 - { - title = "Chaos Emerald 5 (Orange)"; - sprite = "CEMGE0"; - } - 318 - { - title = "Chaos Emerald 6 (Red)"; - sprite = "CEMGF0"; - } - 319 - { - title = "Chaos Emerald 7 (Gray)"; - sprite = "CEMGG0"; - } - 320 - { - title = "Emerald Hunt Location"; - sprite = "SHRDA0"; - } - 321 - { - title = "Match Chaos Emerald Spawn"; - sprite = "CEMGA0"; - } - 322 - { - title = "Emblem"; - sprite = "EMBMA0"; - width = 16; - height = 30; - } - } - - boxes - { - color = 7; // Gray - blocking = 2; - title = "Monitors"; - width = 18; - height = 40; - - 400 - { - title = "Super Ring (10 Rings)"; - sprite = "TVRIA0"; - } - 401 - { - title = "Pity Shield"; - sprite = "TVPIA0"; - } - 402 - { - title = "Attraction Shield"; - sprite = "TVATA0"; - } - 403 - { - title = "Force Shield"; - sprite = "TVFOA0"; - } - 404 - { - title = "Armageddon Shield"; - sprite = "TVARA0"; - } - 405 - { - title = "Whirlwind Shield"; - sprite = "TVWWA0"; - } - 406 - { - title = "Elemental Shield"; - sprite = "TVELA0"; - } - 407 - { - title = "Super Sneakers"; - sprite = "TVSSA0"; - } - 408 - { - title = "Invincibility"; - sprite = "TVIVA0"; - } - 409 - { - title = "Extra Life"; - sprite = "TV1UA0"; - } - 410 - { - title = "Eggman"; - sprite = "TVEGA0"; - } - 411 - { - title = "Teleporter"; - sprite = "TVMXA0"; - } - 413 - { - title = "Gravity Boots"; - sprite = "TVGVA0"; - } - 414 - { - title = "CTF Team Ring Monitor (Red)"; - sprite = "TRRIA0"; - } - 415 - { - title = "CTF Team Ring Monitor (Blue)"; - sprite = "TBRIA0"; - } - 416 - { - title = "Recycler"; - sprite = "TVRCA0"; - } - 418 - { - title = "Score (1,000 Points)"; - sprite = "TV1KA0"; - } - 419 - { - title = "Score (10,000 Points)"; - sprite = "TVTKA0"; - } - 420 - { - title = "Flame Shield"; - sprite = "TVFLA0"; - } - 421 - { - title = "Water Shield"; - sprite = "TVBBA0"; - } - 422 - { - title = "Lightning Shield"; - sprite = "TVZPA0"; - } - } - - boxes2 - { - color = 18; // Gold - blocking = 2; - title = "Monitors (Respawning)"; - width = 20; - height = 44; - - 431 - { - title = "Pity Shield (Respawn)"; - sprite = "TVPIB0"; - } - 432 - { - title = "Attraction Shield (Respawn)"; - sprite = "TVATB0"; - } - 433 - { - title = "Force Shield (Respawn)"; - sprite = "TVFOB0"; - } - 434 - { - title = "Armageddon Shield (Respawn)"; - sprite = "TVARB0"; - } - 435 - { - title = "Whirlwind Shield (Respawn)"; - sprite = "TVWWB0"; - } - 436 - { - title = "Elemental Shield (Respawn)"; - sprite = "TVELB0"; - } - 437 - { - title = "Super Sneakers (Respawn)"; - sprite = "TVSSB0"; - } - 438 - { - title = "Invincibility (Respawn)"; - sprite = "TVIVB0"; - } - 440 - { - title = "Eggman (Respawn)"; - sprite = "TVEGB0"; - } - 443 - { - title = "Gravity Boots (Respawn)"; - sprite = "TVGVB0"; - } - 450 - { - title = "Flame Shield (Respawn)"; - sprite = "TVFLB0"; - } - 451 - { - title = "Water Shield (Respawn)"; - sprite = "TVBBB0"; - } - 452 - { - title = "Lightning Shield (Respawn)"; - sprite = "TVZPB0"; - } - } - - generic - { - color = 11; // Light_Cyan - title = "Generic Items & Hazards"; - - 500 - { - title = "Air Bubble Patch"; - sprite = "BUBLE0"; - width = 8; - height = 16; - } - 501 - { - title = "Signpost"; - sprite = "SIGND0"; - width = 8; - height = 32; - } - 502 - { - arrow = 1; - title = "Star Post"; - sprite = "STPTA0M0"; - width = 64; - height = 128; - } - 520 - { - title = "Bomb Sphere"; - sprite = "SPHRD0"; - width = 16; - height = 24; - } - 521 - { - title = "Spikeball"; - sprite = "SPIKA0"; - width = 12; - height = 8; - } - 522 - { - title = "Wall Spike"; - sprite = "WSPKALAR"; - width = 16; - height = 14; - arrow = 1; - } - 523 - { - title = "Spike"; - sprite = "USPKA0"; - width = 8; - height = 32; - } - 1130 - { - title = "Small Mace"; - sprite = "SMCEA0"; - width = 17; - height = 34; - } - 1131 - { - title = "Big Mace"; - sprite = "BMCEA0"; - width = 34; - height = 68; - } - 1136 - { - title = "Small Fireball"; - sprite = "SFBRA0"; - width = 17; - height = 34; - } - 1137 - { - title = "Large Fireball"; - sprite = "BFBRA0"; - width = 34; - height = 68; - } - } - - springs - { - color = 12; // Light_Red - title = "Springs and Fans"; - width = 20; - height = 16; - sprite = "RSPRD2"; - - 540 - { - title = "Fan"; - sprite = "FANSA0D0"; - width = 16; - height = 8; - } - 541 - { - title = "Gas Jet"; - sprite = "STEMD0"; - width = 32; - } - 542 - { - title = "Bumper"; - sprite = "BUMPA0"; - width = 32; - height = 64; - } - 543 - { - title = "Balloon"; - sprite = "BLONA0"; - width = 32; - height = 64; - } - 550 - { - title = "Yellow Spring"; - sprite = "SPRYA0"; - } - 551 - { - title = "Red Spring"; - sprite = "SPRRA0"; - } - 552 - { - title = "Blue Spring"; - sprite = "SPRBA0"; - } - 555 - { - arrow = 1; - title = "Diagonal Yellow Spring"; - sprite = "YSPRD2"; - width = 16; - } - 556 - { - arrow = 1; - title = "Diagonal Red Spring"; - sprite = "RSPRD2"; - width = 16; - } - 557 - { - arrow = 1; - title = "Diagonal Blue Spring"; - sprite = "BSPRD2"; - width = 16; - } - 558 - { - arrow = 1; - title = "Horizontal Yellow Spring"; - sprite = "SSWYD2D8"; - width = 16; - height = 32; - } - 559 - { - arrow = 1; - title = "Horizontal Red Spring"; - sprite = "SSWRD2D8"; - width = 16; - height = 32; - } - 560 - { - arrow = 1; - title = "Horizontal Blue Spring"; - sprite = "SSWBD2D8"; - width = 16; - height = 32; - } - 1134 - { - title = "Yellow Spring Ball"; - sprite = "YSPBA0"; - width = 17; - height = 34; - } - 1135 - { - title = "Red Spring Ball"; - sprite = "RSPBA0"; - width = 17; - height = 34; - } - 544 - { - arrow = 1; - title = "Yellow Boost Panel"; - sprite = "BSTYA0"; - width = 28; - height = 2; - } - 545 - { - arrow = 1; - title = "Red Boost Panel"; - sprite = "BSTRA0"; - width = 28; - height = 2; - } - } - - patterns - { - color = 5; // Magenta - arrow = 1; - title = "Special Placement Patterns"; - width = 16; - height = 384; - sprite = "RINGA0"; - - 600 - { - arrow = 0; - title = "5 Vertical Rings (Yellow Spring)"; - sprite = "RINGA0"; - } - 601 - { - arrow = 0; - title = "5 Vertical Rings (Red Spring)"; - sprite = "RINGA0"; - height = 1024; - } - 602 - { - title = "5 Diagonal Rings (Yellow Spring)"; - sprite = "RINGA0"; - height = 32; - } - 603 - { - title = "10 Diagonal Rings (Red Spring)"; - sprite = "RINGA0"; - height = 32; - } - 604 - { - title = "Circle of Rings"; - sprite = "RINGA0"; - width = 96; - height = 192; - } - 605 - { - title = "Circle of Rings (Big)"; - sprite = "RINGA0"; - width = 192; - } - 606 - { - title = "Circle of Blue Spheres"; - sprite = "SPHRA0"; - width = 96; - height = 192; - } - 607 - { - title = "Circle of Blue Spheres (Big)"; - sprite = "SPHRA0"; - width = 192; - } - 608 - { - title = "Circle of Rings and Spheres"; - sprite = "SPHRA0"; - width = 96; - height = 192; - } - 609 - { - title = "Circle of Rings and Spheres (Big)"; - sprite = "SPHRA0"; - width = 192; - } - } - - invisible - { - color = 15; // White - title = "Misc. Invisible"; - width = 0; - height = 0; - sprite = "UNKNA0"; - sort = 1; - fixedsize = true; - blocking = 0; - - 700 - { - title = "Water Ambience A (Large)"; - sprite = "internal:ambiance"; - } - - 701 - { - title = "Water Ambience B (Large)"; - sprite = "internal:ambiance"; - } - - 702 - { - title = "Water Ambience C (Medium)"; - sprite = "internal:ambiance"; - } - - 703 - { - title = "Water Ambience D (Medium)"; - sprite = "internal:ambiance"; - } - - 704 - { - title = "Water Ambience E (Small)"; - sprite = "internal:ambiance"; - } - - 705 - { - title = "Water Ambience F (Small)"; - sprite = "internal:ambiance"; - } - - 706 - { - title = "Water Ambience G (Extra Large)"; - sprite = "internal:ambiance"; - } - - 707 - { - title = "Water Ambience H (Extra Large)"; - sprite = "internal:ambiance"; - } - - 708 - { - title = "Disco Ambience"; - sprite = "internal:ambiance"; - } - - 709 - { - title = "Volcano Ambience"; - sprite = "internal:ambiance"; - } - - 710 - { - title = "Machine Ambience"; - sprite = "internal:ambiance"; - } - - 750 - { - title = "Slope Vertex"; - sprite = "internal:vertexslope"; - } - - 751 - { - arrow = 1; - title = "Teleport Destination"; - sprite = "internal:tele"; - } - - 752 - { - arrow = 1; - title = "Alternate View Point"; - sprite = "internal:view"; - } - - 753 - { - title = "Zoom Tube Waypoint"; - sprite = "internal:zoom"; - } - - 754 - { - title = "Push Point"; - sprite = "GWLGA0"; - } - 755 - { - title = "Pull Point"; - sprite = "GWLRA0"; - } - 756 - { - title = "Blast Linedef Executor"; - sprite = "TOADA0"; - width = 32; - height = 16; - } - 757 - { - title = "Fan Particle Generator"; - sprite = "PRTLA0"; - width = 8; - height = 16; - } - 758 - { - title = "Object Angle Anchor"; - sprite = "internal:view"; - } - 760 - { - title = "PolyObject Anchor"; - sprite = "internal:polyanchor"; - } - 761 - { - title = "PolyObject Spawn Point"; - sprite = "internal:polycenter"; - } - 762 - { - title = "PolyObject Spawn Point (Crush)"; - sprite = "internal:polycentercrush"; - } - 780 - { - title = "Skybox View Point"; - sprite = "internal:skyb"; - } - } - - greenflower - { - color = 10; // Green - title = "Greenflower"; - - 800 - { - title = "GFZ Flower"; - sprite = "FWR1A0"; - width = 16; - height = 40; - } - 801 - { - title = "Sunflower"; - sprite = "FWR2A0"; - width = 16; - height = 96; - } - 802 - { - title = "Budding Flower"; - sprite = "FWR3A0"; - width = 8; - height = 32; - } - 803 - { - title = "Blueberry Bush"; - sprite = "BUS3A0"; - width = 16; - height = 32; - } - 804 - { - title = "Berry Bush"; - sprite = "BUS1A0"; - width = 16; - height = 32; - } - 805 - { - title = "Bush"; - sprite = "BUS2A0"; - width = 16; - height = 32; - } - 806 - { - title = "GFZ Tree"; - sprite = "TRE1A0"; - width = 20; - height = 128; - } - 807 - { - title = "GFZ Berry Tree"; - sprite = "TRE1B0"; - width = 20; - height = 128; - } - 808 - { - title = "GFZ Cherry Tree"; - sprite = "TRE1C0"; - width = 20; - height = 128; - } - 809 - { - title = "Checkered Tree"; - sprite = "TRE2A0"; - width = 20; - height = 200; - } - 810 - { - title = "Checkered Tree (Sunset)"; - sprite = "TRE2B0"; - width = 20; - height = 200; - } - 811 - { - title = "Polygon Tree"; - sprite = "TRE4A0"; - width = 20; - height = 200; - } - 812 - { - title = "Bush Tree"; - sprite = "TRE5A0"; - width = 20; - height = 200; - } - 813 - { - title = "Red Bush Tree"; - sprite = "TRE5B0"; - width = 20; - height = 200; - } - } - - technohill - { - color = 10; // Green - title = "Techno Hill"; - - 900 - { - title = "THZ Steam Flower"; - sprite = "THZPA0"; - width = 8; - height = 32; - } - 901 - { - title = "Alarm"; - sprite = "ALRMA0"; - width = 8; - height = 16; - hangs = 1; - } - 902 - { - title = "THZ Spin Flower (Red)"; - sprite = "FWR5A0"; - width = 16; - height = 64; - } - 903 - { - title = "THZ Spin Flower (Yellow)"; - sprite = "FWR6A0"; - width = 16; - height = 64; - } - 904 - { - arrow = 1; - title = "Whistlebush"; - sprite = "THZTA0"; - width = 16; - height = 64; - } - } - - deepsea - { - color = 10; // Green - title = "Deep Sea"; - - 1000 - { - arrow = 1; - blocking = 2; - title = "Gargoyle"; - sprite = "GARGA1"; - width = 16; - height = 40; - } - 1009 - { - arrow = 1; - blocking = 2; - title = "Gargoyle (Big)"; - sprite = "GARGB1"; - width = 32; - height = 80; - } - 1001 - { - title = "Seaweed"; - sprite = "SEWEA0"; - width = 24; - height = 56; - } - 1002 - { - title = "Dripping Water"; - sprite = "DRIPD0"; - width = 8; - height = 16; - hangs = 1; - } - 1003 - { - title = "Coral (Green)"; - sprite = "CORLA0"; - width = 29; - height = 40; - } - 1004 - { - title = "Coral (Red)"; - sprite = "CORLB0"; - width = 30; - height = 53; - } - 1005 - { - title = "Coral (Orange)"; - sprite = "CORLC0"; - width = 28; - height = 41; - } - 1006 - { - title = "Blue Crystal"; - sprite = "BCRYA1"; - width = 8; - height = 16; - } - 1007 - { - title = "Kelp"; - sprite = "KELPA0"; - width = 16; - height = 292; - } - 1008 - { - title = "Stalagmite (DSZ1)"; - sprite = "DSTGA0"; - width = 8; - height = 116; - } - 1010 - { - arrow = 1; - title = "Light Beam"; - sprite = "LIBEARAL"; - width = 16; - height = 16; - } - 1011 - { - title = "Stalagmite (DSZ2)"; - sprite = "DSTGA0"; - width = 8; - height = 116; - } - 1012 - { - arrow = 1; - title = "Big Floating Mine"; - width = 28; - height = 56; - sprite = "BMNEA1"; - } - 1013 - { - title = "Animated Kelp"; - sprite = "ALGAA0"; - width = 48; - height = 120; - } - 1014 - { - title = "Large Coral (Brown)"; - sprite = "CORLD0"; - width = 56; - height = 112; - } - 1015 - { - title = "Large Coral (Beige)"; - sprite = "CORLE0"; - width = 56; - height = 112; - } - } - - castleeggman - { - color = 10; // Green - title = "Castle Eggman"; - - 1100 - { - title = "Chain (Decorative)"; - sprite = "CHANA0"; - width = 4; - height = 128; - hangs = 1; - } - 1101 - { - title = "Torch"; - sprite = "FLAMA0E0"; - width = 8; - height = 32; - } - 1102 - { - arrow = 1; - blocking = 2; - title = "Eggman Statue"; - sprite = "ESTAA1"; - width = 32; - height = 240; - } - 1103 - { - title = "CEZ Flower"; - sprite = "FWR4A0"; - width = 16; - height = 40; - } - 1104 - { - title = "Mace Spawnpoint"; - sprite = "SMCEA0"; - width = 17; - height = 34; - } - 1105 - { - title = "Chain with Maces Spawnpoint"; - sprite = "SMCEA0"; - width = 17; - height = 34; - } - 1106 - { - title = "Chained Spring Spawnpoint"; - sprite = "YSPBA0"; - width = 17; - height = 34; - } - 1107 - { - title = "Chain Spawnpoint"; - sprite = "BMCHA0"; - width = 17; - height = 34; - } - 1108 - { - arrow = 1; - title = "Hidden Chain Spawnpoint"; - sprite = "internal:chain3"; - width = 17; - height = 34; - } - 1109 - { - title = "Firebar Spawnpoint"; - sprite = "BFBRA0"; - width = 17; - height = 34; - } - 1110 - { - title = "Custom Mace Spawnpoint"; - sprite = "SMCEA0"; - width = 17; - height = 34; - } - 1111 - { - arrow = 1; - blocking = 2; - title = "Crawla Statue"; - sprite = "CSTAA1"; - width = 16; - height = 40; - } - 1112 - { - arrow = 1; - blocking = 2; - title = "Lance-a-Bot Statue"; - sprite = "CBBSA1"; - width = 32; - height = 72; - } - 1114 - { - title = "Pine Tree"; - sprite = "PINEA0"; - width = 16; - height = 628; - } - 1115 - { - title = "CEZ Shrub (Small)"; - sprite = "CEZBA0"; - width = 16; - height = 24; - } - 1116 - { - title = "CEZ Shrub (Large)"; - sprite = "CEZBB0"; - width = 32; - height = 48; - } - 1117 - { - arrow = 1; - title = "Pole Banner (Red)"; - sprite = "BANRA0"; - width = 40; - height = 224; - } - 1118 - { - arrow = 1; - title = "Pole Banner (Blue)"; - sprite = "BANRA0"; - width = 40; - height = 224; - } - 1119 - { - title = "Candle"; - sprite = "CNDLA0"; - width = 8; - height = 48; - } - 1120 - { - title = "Candle Pricket"; - sprite = "CNDLB0"; - width = 8; - height = 176; - } - 1121 - { - title = "Flame Holder"; - sprite = "FLMHA0"; - width = 24; - height = 80; - } - 1122 - { - title = "Fire Torch"; - sprite = "CTRCA0"; - width = 16; - height = 80; - } - 1123 - { - title = "Cannonball Launcher"; - sprite = "internal:cannonball"; - width = 8; - height = 16; - } - 1124 - { - blocking = 2; - title = "Cannonball"; - sprite = "CBLLA0"; - width = 20; - height = 40; - } - 1125 - { - title = "Brambles"; - sprite = "CABRALAR"; - width = 48; - height = 32; - } - 1126 - { - title = "Invisible Lockon Object"; - sprite = "LCKNC0"; - width = 16; - height = 32; - } - 1127 - { - title = "Spectator Eggrobo"; - sprite = "EGR1A1"; - width = 20; - height = 72; - } - 1128 - { - arrow = 1; - title = "Waving Flag (Red)"; - sprite = "CFLGA0"; - width = 8; - height = 208; - } - 1129 - { - arrow = 1; - title = "Waving Flag (Blue)"; - sprite = "CFLGA0"; - width = 8; - height = 208; - } - } - - aridcanyon - { - color = 10; // Green - title = "Arid Canyon"; - - 1200 - { - title = "Tumbleweed (Big)"; - sprite = "BTBLA0"; - width = 24; - height = 48; - } - 1201 - { - title = "Tumbleweed (Small)"; - sprite = "STBLA0"; - width = 12; - height = 24; - } - 1202 - { - arrow = 1; - title = "Rock Spawner"; - sprite = "ROIAA0"; - width = 8; - height = 16; - } - 1203 - { - title = "Tiny Red Flower Cactus"; - sprite = "CACTA0"; - width = 13; - height = 24; - } - 1204 - { - title = "Small Red Flower Cactus"; - sprite = "CACTB0"; - width = 15; - height = 52; - } - 1205 - { - title = "Tiny Blue Flower Cactus"; - sprite = "CACTC0"; - width = 13; - height = 24; - } - 1206 - { - title = "Small Blue Flower Cactus"; - sprite = "CACTD0"; - width = 15; - height = 52; - } - 1207 - { - title = "Prickly Pear"; - sprite = "CACTE0"; - width = 32; - height = 96; - } - 1208 - { - title = "Barrel Cactus"; - sprite = "CACTF0"; - width = 20; - height = 128; - } - 1209 - { - title = "Tall Barrel Cactus"; - sprite = "CACTG0"; - width = 24; - height = 224; - } - 1210 - { - title = "Armed Cactus"; - sprite = "CACTH0"; - width = 24; - height = 256; - } - 1211 - { - title = "Ball Cactus"; - sprite = "CACTI0"; - width = 48; - height = 96; - } - 1212 - { - title = "Caution Sign"; - sprite = "WWSGAR"; - width = 22; - height = 64; - } - 1213 - { - title = "Cacti Sign"; - sprite = "WWS2AR"; - width = 22; - height = 64; - } - 1214 - { - title = "Sharp Turn Sign"; - sprite = "WWS3ALAR"; - width = 16; - height = 192; - } - 1215 - { - title = "Mine Oil Lamp"; - sprite = "OILLA0"; - width = 22; - height = 64; - hangs = 1; - } - 1216 - { - title = "TNT Barrel"; - sprite = "BARRA1"; - width = 24; - height = 63; - } - 1217 - { - title = "TNT Proximity Shell"; - sprite = "REMTA0"; - width = 64; - height = 40; - } - 1218 - { - title = "Dust Devil"; - sprite = "TAZDCR"; - width = 80; - height = 416; - } - 1219 - { - title = "Minecart Spawner"; - sprite = "MCRTCLFR"; - width = 22; - height = 32; - } - 1220 - { - title = "Minecart Stopper"; - sprite = "MCRTIR"; - width = 32; - height = 32; - } - 1221 - { - title = "Minecart Saloon Door"; - sprite = "SALDARAL"; - width = 96; - height = 160; - } - 1222 - { - title = "Train Cameo Spawner"; - sprite = "TRAEBRBL"; - width = 28; - height = 32; - } - 1223 - { - title = "Train Dust Spawner"; - sprite = "ADSTA0"; - width = 4; - height = 4; - } - 1224 - { - title = "Train Steam Spawner"; - sprite = "STEAA0"; - width = 4; - height = 4; - } - 1229 - { - title = "Minecart Switch Point"; - sprite = "internal:zoom"; - width = 8; - height = 16; - } - 1230 - { - title = "Tiny Cactus"; - sprite = "CACTJ0"; - width = 13; - height = 28; - } - 1231 - { - title = "Small Cactus"; - sprite = "CACTK0"; - width = 15; - height = 60; - } - } - - redvolcano - { - color = 10; // Green - title = "Red Volcano"; - - 1300 - { - arrow = 1; - title = "Flame Jet (Horizontal)"; - sprite = "internal:flameh"; - width = 16; - height = 40; - } - 1301 - { - title = "Flame Jet (Vertical)"; - sprite = "internal:flamev"; - width = 16; - height = 40; - } - 1302 - { - title = "Spinning Flame Jet (Counter-Clockwise)"; - sprite = "internal:flame2"; - width = 16; - height = 24; - } - 1303 - { - title = "Spinning Flame Jet (Clockwise)"; - sprite = "internal:flame1"; - width = 16; - height = 24; - } - 1304 - { - title = "Lavafall"; - sprite = "LFALF0"; - width = 30; - height = 32; - } - 1305 - { - title = "Rollout Rock"; - sprite = "PUMIA1A5"; - width = 30; - height = 60; - } - 1306 - { - title = "Big Fern"; - sprite = "JPLAB0"; - width = 32; - height = 48; - } - 1307 - { - title = "Jungle Palm"; - sprite = "JPLAC0"; - width = 32; - height = 48; - } - 1308 - { - title = "Torch Flower"; - sprite = "TFLOA0"; - width = 14; - height = 110; - } - 1309 - { - title = "RVZ1 Wall Vine (Long)"; - sprite = "WVINALAR"; - width = 1; - height = 288; - } - 1310 - { - title = "RVZ1 Wall Vine (Short)"; - sprite = "WVINBLBR"; - width = 1; - height = 288; - } - } - - botanicserenity - { - color = 10; // Green - title = "Botanic Serenity"; - width = 16; - height = 32; - sprite = "BSZ1A0"; - 1400 - { - title = "Tall Flower (Red)"; - sprite = "BSZ1A0"; - } - 1401 - { - title = "Tall Flower (Purple)"; - sprite = "BSZ1B0"; - } - 1402 - { - title = "Tall Flower (Blue)"; - sprite = "BSZ1C0"; - } - 1403 - { - title = "Tall Flower (Cyan)"; - sprite = "BSZ1D0"; - } - 1404 - { - title = "Tall Flower (Yellow)"; - sprite = "BSZ1E0"; - } - 1405 - { - title = "Tall Flower (Orange)"; - sprite = "BSZ1F0"; - } - 1410 - { - title = "Medium Flower (Red)"; - sprite = "BSZ2A0"; - } - 1411 - { - title = "Medium Flower (Purple)"; - sprite = "BSZ2B0"; - } - 1412 - { - title = "Medium Flower (Blue)"; - sprite = "BSZ2C0"; - } - 1413 - { - title = "Medium Flower (Cyan)"; - sprite = "BSZ2D0"; - } - 1414 - { - title = "Medium Flower (Yellow)"; - sprite = "BSZ2E0"; - } - 1415 - { - title = "Medium Flower (Orange)"; - sprite = "BSZ2F0"; - } - 1420 - { - title = "Short Flower (Red)"; - sprite = "BSZ3A0"; - } - 1421 - { - title = "Short Flower (Purple)"; - sprite = "BSZ3B0"; - } - 1422 - { - title = "Short Flower (Blue)"; - sprite = "BSZ3C0"; - } - 1423 - { - title = "Short Flower (Cyan)"; - sprite = "BSZ3D0"; - } - 1424 - { - title = "Short Flower (Yellow)"; - sprite = "BSZ3E0"; - } - 1425 - { - title = "Short Flower (Orange)"; - sprite = "BSZ3F0"; - } - 1430 - { - title = "Tulip (Red)"; - sprite = "BST1A0"; - } - 1431 - { - title = "Tulip (Purple)"; - sprite = "BST2A0"; - } - 1432 - { - title = "Tulip (Blue)"; - sprite = "BST3A0"; - } - 1433 - { - title = "Tulip (Cyan)"; - sprite = "BST4A0"; - } - 1434 - { - title = "Tulip (Yellow)"; - sprite = "BST5A0"; - } - 1435 - { - title = "Tulip (Orange)"; - sprite = "BST6A0"; - } - 1440 - { - title = "Cluster (Red)"; - sprite = "BSZ5A0"; - } - 1441 - { - title = "Cluster (Purple)"; - sprite = "BSZ5B0"; - } - 1442 - { - title = "Cluster (Blue)"; - sprite = "BSZ5C0"; - } - 1443 - { - title = "Cluster (Cyan)"; - sprite = "BSZ5D0"; - } - 1444 - { - title = "Cluster (Yellow)"; - sprite = "BSZ5E0"; - } - 1445 - { - title = "Cluster (Orange)"; - sprite = "BSZ5F0"; - } - 1450 - { - title = "Bush (Red)"; - sprite = "BSZ6A0"; - } - 1451 - { - title = "Bush (Purple)"; - sprite = "BSZ6B0"; - } - 1452 - { - title = "Bush (Blue)"; - sprite = "BSZ6C0"; - } - 1453 - { - title = "Bush (Cyan)"; - sprite = "BSZ6D0"; - } - 1454 - { - title = "Bush (Yellow)"; - sprite = "BSZ6E0"; - } - 1455 - { - title = "Bush (Orange)"; - sprite = "BSZ6F0"; - } - 1460 - { - title = "Vine (Red)"; - sprite = "BSZ7A0"; - } - 1461 - { - title = "Vine (Purple)"; - sprite = "BSZ7B0"; - } - 1462 - { - title = "Vine (Blue)"; - sprite = "BSZ7C0"; - } - 1463 - { - title = "Vine (Cyan)"; - sprite = "BSZ7D0"; - } - 1464 - { - title = "Vine (Yellow)"; - sprite = "BSZ7E0"; - } - 1465 - { - title = "Vine (Orange)"; - sprite = "BSZ7F0"; - } - 1470 - { - title = "BSZ Shrub"; - sprite = "BSZ8A0"; - } - 1471 - { - title = "BSZ Clover"; - sprite = "BSZ8B0"; - } - 1473 - { - title = "Palm Tree (Big)"; - width = 16; - height = 160; - sprite = "BSZ8D0"; - } - 1475 - { - title = "Palm Tree (Small)"; - width = 16; - height = 80; - sprite = "BSZ8F0"; - } - } - - azuretemple - { - color = 10; // Green - title = "Azure Temple"; - - 1500 - { - arrow = 1; - blocking = 2; - title = "Glaregoyle"; - sprite = "BGARA1"; - width = 16; - height = 40; - } - 1501 - { - arrow = 1; - blocking = 2; - title = "Glaregoyle (Up)"; - sprite = "BGARA1"; - width = 16; - height = 40; - } - 1502 - { - arrow = 1; - blocking = 2; - title = "Glaregoyle (Down)"; - sprite = "BGARA1"; - width = 16; - height = 40; - } - 1503 - { - arrow = 1; - blocking = 2; - title = "Glaregoyle (Long)"; - sprite = "BGARA1"; - width = 16; - height = 40; - } - 1504 - { - title = "ATZ Target"; - sprite = "RCRYB0"; - width = 24; - height = 32; - } - 1505 - { - title = "Green Flame"; - sprite = "CFLMA0E0"; - width = 8; - height = 32; - } - 1506 - { - arrow = 1; - blocking = 2; - title = "Blue Gargoyle"; - sprite = "BGARD1"; - width = 16; - height = 40; - } - } - - dreamhill - { - color = 10; // Green - title = "Dream Hill"; - - 1600 - { - title = "Spring Tree"; - sprite = "TRE6A0"; - width = 16; - height = 32; - } - 1601 - { - title = "Shleep"; - sprite = "SHLPA0"; - width = 24; - height = 32; - } - 1602 - { - title = "Nightopian"; - sprite = "NTPNA1"; - width = 16; - height = 40; - } - } - - nightstrk - { - color = 13; // Pink - title = "NiGHTS Track"; - width = 8; - height = 4096; - sprite = "UNKNA0"; - - 1700 - { - title = "Axis"; - sprite = "internal:axis1"; - circle = 1; - } - 1701 - { - title = "Axis Transfer"; - sprite = "internal:axis2"; - } - 1702 - { - title = "Axis Transfer Line"; - sprite = "internal:axis3"; - } - 1710 - { - title = "Ideya Capture"; - sprite = "CAPSA0"; - width = 72; - height = 144; - } - } - - nights - { - color = 13; // Pink - title = "NiGHTS Items"; - width = 16; - height = 32; - - 1703 - { - title = "Ideya Drone"; - sprite = "NDRNA1"; - width = 16; - height = 56; - } - 1704 - { - arrow = 1; - title = "NiGHTS Bumper"; - sprite = "NBMPG3G7"; - width = 32; - height = 64; - } - 1705 - { - arrow = 1; - title = "Hoop (Generic)"; - sprite = "HOOPA0"; - width = 80; - height = 160; - } - 1706 - { - title = "Blue Sphere"; - sprite = "SPHRA0"; - width = 16; - height = 24; - } - 1707 - { - title = "Super Paraloop"; - sprite = "NPRUA0"; - } - 1708 - { - title = "Drill Refill"; - sprite = "NPRUB0"; - } - 1709 - { - title = "Nightopian Helper"; - sprite = "NPRUC0"; - } - 1711 - { - title = "Extra Time"; - sprite = "NPRUD0"; - } - 1712 - { - title = "Link Freeze"; - sprite = "NPRUE0"; - } - 1713 - { - arrow = 1; - title = "Hoop (Customizable)"; - sprite = "HOOPA0"; - width = 80; - height = 160; - } - 1714 - { - title = "Ideya Anchor Point"; - sprite = "internal:axis1"; - width = 8; - height = 16; - } - } - - mario - { - color = 6; // Brown - title = "Mario"; - - 1800 - { - title = "Coin"; - sprite = "COINA0"; - width = 16; - height = 24; - } - 1801 - { - arrow = 1; - title = "Goomba"; - sprite = "GOOMA0"; - width = 24; - height = 32; - } - 1802 - { - arrow = 1; - title = "Goomba (Blue)"; - sprite = "BGOMA0"; - width = 24; - height = 32; - } - 1803 - { - title = "Fire Flower"; - sprite = "FFWRB0"; - width = 16; - height = 32; - } - 1804 - { - title = "Koopa Shell"; - sprite = "SHLLA1"; - width = 16; - height = 20; - } - 1805 - { - title = "Puma (Jumping Fireball)"; - sprite = "PUMAA0"; - width = 8; - height = 16; - } - 1806 - { - title = "King Bowser"; - sprite = "KOOPA0"; - width = 16; - height = 48; - } - 1807 - { - title = "Axe"; - sprite = "MAXEA0"; - width = 8; - height = 16; - } - 1808 - { - title = "Bush (Short)"; - sprite = "MUS1A0"; - width = 16; - height = 32; - } - 1809 - { - title = "Bush (Tall)"; - sprite = "MUS2A0"; - width = 16; - height = 32; - } - 1810 - { - title = "Toad"; - sprite = "TOADA0"; - width = 8; - height = 32; - } - } - - christmasdisco - { - color = 10; // Green - title = "Christmas & Disco"; - - 1850 - { - title = "Christmas Pole"; - sprite = "XMS1A0"; - width = 16; - height = 40; - } - 1851 - { - title = "Candy Cane"; - sprite = "XMS2A0"; - width = 8; - height = 32; - } - 1852 - { - blocking = 2; - title = "Snowman"; - sprite = "XMS3A0"; - width = 16; - height = 64; - } - 1853 - { - blocking = 2; - title = "Snowman (With Hat)"; - sprite = "XMS3B0"; - width = 16; - height = 80; - } - 1854 - { - title = "Lamp Post"; - sprite = "XMS4A0"; - width = 8; - height = 120; - } - 1855 - { - title = "Lamp Post (Snow)"; - sprite = "XMS4B0"; - width = 8; - height = 120; - } - 1856 - { - title = "Hanging Star"; - sprite = "XMS5A0"; - width = 4; - height = 80; - hangs = 1; - } - 1857 - { - title = "Berry Bush (Snow)"; - sprite = "BUS1B0"; - width = 16; - height = 32; - } - 1858 - { - title = "Bush (Snow)"; - sprite = "BUS2B0"; - width = 16; - height = 32; - } - 1859 - { - title = "Blueberry Bush (Snow)"; - sprite = "BUS3B0"; - width = 16; - height = 32; - } - 1875 - { - title = "Disco Ball"; - sprite = "DBALA0"; - width = 16; - height = 54; - hangs = 1; - } - 1876 - { - arrow = 1; - blocking = 2; - title = "Eggman Disco Statue"; - sprite = "ESTAB1"; - width = 20; - height = 96; - } - } - - stalagmites - { - color = 10; // Green - title = "Stalagmites"; - width = 16; - height = 40; - - 1900 - { - title = "Brown Stalagmite (Tall)"; - sprite = "STLGA0"; - width = 16; - height = 40; - } - 1901 - { - title = "Brown Stalagmite"; - sprite = "STLGB0"; - width = 16; - height = 40; - } - 1902 - { - title = "Orange Stalagmite (Tall)"; - sprite = "STLGC0"; - width = 16; - height = 40; - } - 1903 - { - title = "Orange Stalagmite"; - sprite = "STLGD0"; - width = 16; - height = 40; - } - 1904 - { - title = "Red Stalagmite (Tall)"; - sprite = "STLGE0"; - width = 16; - height = 40; - } - 1905 - { - title = "Red Stalagmite"; - sprite = "STLGF0"; - width = 16; - height = 40; - } - 1906 - { - title = "Gray Stalagmite (Tall)"; - sprite = "STLGG0"; - width = 24; - height = 96; - } - 1907 - { - title = "Gray Stalagmite"; - sprite = "STLGH0"; - width = 16; - height = 40; - } - 1908 - { - title = "Blue Stalagmite (Tall)"; - sprite = "STLGI0"; - width = 16; - height = 40; - } - 1909 - { - title = "Blue Stalagmite"; - sprite = "STLGJ0"; - width = 16; - height = 40; - } - } - - hauntedheights - { - color = 10; // Green - title = "Haunted Heights"; - - 2000 - { - title = "Smashing Spikeball"; - sprite = "FMCEA0"; - width = 18; - height = 28; - } - 2001 - { - title = "HHZ Grass"; - sprite = "HHZMA0"; - width = 16; - height = 40; - } - 2002 - { - title = "HHZ Tentacle 1"; - sprite = "HHZMB0"; - width = 16; - height = 40; - } - 2003 - { - title = "HHZ Tentacle 2"; - sprite = "HHZMC0"; - width = 16; - height = 40; - } - 2004 - { - title = "HHZ Stalagmite (Tall)"; - sprite = "HHZME0"; - width = 16; - height = 40; - } - 2005 - { - title = "HHZ Stalagmite (Short)"; - sprite = "HHZMF0"; - width = 16; - height = 40; - } - 2006 - { - title = "Jack-o'-lantern 1"; - sprite = "PUMKA0"; - width = 16; - height = 40; - } - 2007 - { - title = "Jack-o'-lantern 2"; - sprite = "PUMKB0"; - width = 16; - height = 40; - } - 2008 - { - title = "Jack-o'-lantern 3"; - sprite = "PUMKC0"; - width = 16; - height = 40; - } - 2009 - { - title = "Purple Mushroom"; - sprite = "SHRMD0"; - width = 16; - height = 48; - } - 2010 - { - title = "HHZ Tree"; - sprite = "HHPLC0"; - width = 12; - height = 40; - } - } - - frozenhillside - { - color = 10; // Green - title = "Frozen Hillside"; - - 2100 - { - title = "Ice Shard (Small)"; - sprite = "FHZIA0"; - width = 8; - height = 32; - } - 2101 - { - title = "Ice Shard (Large)"; - sprite = "FHZIB0"; - width = 8; - height = 32; - } - 2102 - { - title = "Crystal Tree (Aqua)"; - sprite = "TRE3A0"; - width = 20; - height = 200; - } - 2103 - { - title = "Crystal Tree (Pink)"; - sprite = "TRE3B0"; - width = 20; - height = 200; - } - 2104 - { - title = "Amy Cameo"; - sprite = "ROSYA1"; - width = 16; - height = 48; - } - 2105 - { - title = "Mistletoe"; - sprite = "XMS6A0"; - width = 52; - height = 106; - } - } - - tutorial - { - color = 10; // Green - title = "Tutorial"; - - 799 - { - title = "Tutorial Plant"; - sprite = "TUPFH0"; - width = 40; - height = 144; - } - } - - flickies - { - color = 10; // Green - title = "Flickies"; - width = 8; - height = 20; - - 2200 - { - title = "Bluebird"; - sprite = "FL01A1"; - } - 2201 - { - title = "Rabbit"; - sprite = "FL02A1"; - } - 2202 - { - title = "Chicken"; - sprite = "FL03A1"; - } - 2203 - { - title = "Seal"; - sprite = "FL04A1"; - } - 2204 - { - title = "Pig"; - sprite = "FL05A1"; - } - 2205 - { - title = "Chipmunk"; - sprite = "FL06A1"; - } - 2206 - { - title = "Penguin"; - sprite = "FL07A1"; - } - 2207 - { - title = "Fish"; - sprite = "FL08A1"; - } - 2208 - { - title = "Ram"; - sprite = "FL09A1"; - } - 2209 - { - title = "Puffin"; - sprite = "FL10A1"; - } - 2210 - { - title = "Cow"; - sprite = "FL11A1"; - } - 2211 - { - title = "Rat"; - sprite = "FL12A1"; - } - 2212 - { - title = "Bear"; - sprite = "FL13A1"; - } - 2213 - { - title = "Dove"; - sprite = "FL14A1"; - } - 2214 - { - title = "Cat"; - sprite = "FL15A1"; - } - 2215 - { - title = "Canary"; - sprite = "FL16A1"; - } - 2216 - { - title = "Spider"; - sprite = "FS01A1"; - } - 2217 - { - title = "Bat"; - sprite = "FS02A0"; - } - } -} - udmf { editor @@ -3358,186 +203,10 @@ udmf enum = "noyes"; } } - 17 - { - title = "Player 17 Start"; - sprite = "PLAYA0"; - arg0 - { - title = "Spawn on ceiling?"; - type = 11; - enum = "noyes"; - } - } - 18 - { - title = "Player 18 Start"; - sprite = "PLAYA0"; - arg0 - { - title = "Spawn on ceiling?"; - type = 11; - enum = "noyes"; - } - } - 19 - { - title = "Player 19 Start"; - sprite = "PLAYA0"; - arg0 - { - title = "Spawn on ceiling?"; - type = 11; - enum = "noyes"; - } - } - 20 - { - title = "Player 20 Start"; - sprite = "PLAYA0"; - arg0 - { - title = "Spawn on ceiling?"; - type = 11; - enum = "noyes"; - } - } - 21 - { - title = "Player 21 Start"; - sprite = "PLAYA0"; - arg0 - { - title = "Spawn on ceiling?"; - type = 11; - enum = "noyes"; - } - } - 22 - { - title = "Player 22 Start"; - sprite = "PLAYA0"; - arg0 - { - title = "Spawn on ceiling?"; - type = 11; - enum = "noyes"; - } - } - 23 - { - title = "Player 23 Start"; - sprite = "PLAYA0"; - arg0 - { - title = "Spawn on ceiling?"; - type = 11; - enum = "noyes"; - } - } - 24 - { - title = "Player 24 Start"; - sprite = "PLAYA0"; - arg0 - { - title = "Spawn on ceiling?"; - type = 11; - enum = "noyes"; - } - } - 25 - { - title = "Player 25 Start"; - sprite = "PLAYA0"; - arg0 - { - title = "Spawn on ceiling?"; - type = 11; - enum = "noyes"; - } - } - 26 - { - title = "Player 26 Start"; - sprite = "PLAYA0"; - arg0 - { - title = "Spawn on ceiling?"; - type = 11; - enum = "noyes"; - } - } - 27 - { - title = "Player 27 Start"; - sprite = "PLAYA0"; - arg0 - { - title = "Spawn on ceiling?"; - type = 11; - enum = "noyes"; - } - } - 28 - { - title = "Player 28 Start"; - sprite = "PLAYA0"; - arg0 - { - title = "Spawn on ceiling?"; - type = 11; - enum = "noyes"; - } - } - 29 - { - title = "Player 29 Start"; - sprite = "PLAYA0"; - arg0 - { - title = "Spawn on ceiling?"; - type = 11; - enum = "noyes"; - } - } - 30 - { - title = "Player 30 Start"; - sprite = "PLAYA0"; - arg0 - { - title = "Spawn on ceiling?"; - type = 11; - enum = "noyes"; - } - } - 31 - { - title = "Player 31 Start"; - sprite = "PLAYA0"; - arg0 - { - title = "Spawn on ceiling?"; - type = 11; - enum = "noyes"; - } - } - 32 - { - title = "Player 32 Start"; - sprite = "PLAYA0"; - arg0 - { - title = "Spawn on ceiling?"; - type = 11; - enum = "noyes"; - } - } 33 { - title = "Match Start"; - sprite = "NDRNA2A8"; + title = "Battle Start"; + sprite = "SUPTG0"; arg0 { title = "Spawn on ceiling?"; @@ -3545,9 +214,10 @@ udmf enum = "noyes"; } } + /* 34 { - title = "CTF Red Team Start"; + title = "Red Team Start"; sprite = "SIGNG0"; arg0 { @@ -3558,7 +228,7 @@ udmf } 35 { - title = "CTF Blue Team Start"; + title = "Blue Team Start"; sprite = "SIGNE0"; arg0 { @@ -3567,31 +237,32 @@ udmf enum = "noyes"; } } + */ } enemies { color = 9; // Light_Blue arrow = 1; - title = "Enemies"; + title = "Enemies "; 100 { - title = "Crawla (Blue)"; + title = "Crawla (Blue) "; sprite = "POSSA1"; width = 24; height = 32; } 101 { - title = "Crawla (Red)"; + title = "Crawla (Red) "; sprite = "SPOSA1"; width = 24; height = 32; } 102 { - title = "Stupid Dumb Unnamed RoboFish"; + title = "Stupid Dumb Unnamed RoboFish "; sprite = "FISHA0"; width = 8; height = 28; @@ -3602,7 +273,7 @@ udmf } 103 { - title = "Buzz (Gold)"; + title = "Buzz (Gold) "; sprite = "BUZZA1"; width = 28; height = 40; @@ -3615,7 +286,7 @@ udmf } 104 { - title = "Buzz (Red)"; + title = "Buzz (Red) "; sprite = "RBUZA1"; width = 28; height = 40; @@ -3628,14 +299,14 @@ udmf } 108 { - title = "Deton"; + title = "Deton "; sprite = "DETNA1"; width = 20; height = 32; } 110 { - title = "Turret"; + title = "Turret "; sprite = "TRETA1"; width = 16; height = 32; @@ -3647,7 +318,7 @@ udmf } 111 { - title = "Pop-up Turret"; + title = "Pop-up Turret "; sprite = "TURRI1"; width = 12; height = 64; @@ -3658,35 +329,35 @@ udmf } 122 { - title = "Spring Shell (Green)"; + title = "Spring Shell (Green) "; sprite = "SSHLA1"; width = 24; height = 40; } 125 { - title = "Spring Shell (Yellow)"; + title = "Spring Shell (Yellow) "; sprite = "SSHLI1"; width = 24; height = 40; } 109 { - title = "Skim"; + title = "Skim "; sprite = "SKIMA1"; width = 16; height = 24; } 113 { - title = "Jet Jaw"; + title = "Jet Jaw "; sprite = "JJAWA3A7"; width = 12; height = 20; } 126 { - title = "Crushstacean"; + title = "Crushstacean "; sprite = "CRABA0"; width = 24; height = 32; @@ -3703,7 +374,7 @@ udmf } 138 { - title = "Banpyura"; + title = "Banpyura "; sprite = "CR2BA0"; width = 24; height = 32; @@ -3720,7 +391,7 @@ udmf } 117 { - title = "Robo-Hood"; + title = "Robo-Hood "; sprite = "ARCHA1"; width = 24; height = 32; @@ -3733,14 +404,14 @@ udmf } 118 { - title = "Lance-a-Bot"; + title = "Lance-a-Bot "; sprite = "CBFSA1"; width = 32; height = 72; } 1113 { - title = "Suspicious Lance-a-Bot Statue"; + title = "Suspicious Lance-a-Bot Statue "; sprite = "CBBSA1"; width = 32; height = 72; @@ -3753,7 +424,7 @@ udmf } 119 { - title = "Egg Guard"; + title = "Egg Guard "; sprite = "ESHIA1"; width = 16; height = 48; @@ -3777,28 +448,28 @@ udmf } 115 { - title = "Bird Aircraft Strike Hazard"; + title = "Bird Aircraft Strike Hazard "; sprite = "VLTRF1"; width = 12; height = 24; } 120 { - title = "Green Snapper"; + title = "Green Snapper "; sprite = "GSNPA1"; width = 24; height = 24; } 121 { - title = "Minus"; + title = "Minus "; sprite = "MNUSA0"; width = 24; height = 32; } 134 { - title = "Canarivore"; + title = "Canarivore "; sprite = "CANAA0"; width = 12; height = 80; @@ -3806,14 +477,14 @@ udmf } 123 { - title = "Unidus"; + title = "Unidus "; sprite = "UNIDA1"; width = 18; height = 36; } 135 { - title = "Pterabyte Spawner"; + title = "Pterabyte Spawner "; sprite = "PTERA2A8"; width = 16; height = 16; @@ -3825,7 +496,7 @@ udmf } 136 { - title = "Pyre Fly"; + title = "Pyre Fly "; sprite = "PYREA0"; width = 24; height = 34; @@ -3838,14 +509,14 @@ udmf } 137 { - title = "Dragonbomber"; + title = "Dragonbomber "; sprite = "DRABA1"; width = 28; height = 48; } 105 { - title = "Jetty-Syn Bomber"; + title = "Jetty-Syn Bomber "; sprite = "JETBB1"; width = 20; height = 50; @@ -3858,7 +529,7 @@ udmf } 106 { - title = "Jetty-Syn Gunner"; + title = "Jetty-Syn Gunner "; sprite = "JETGB1"; width = 20; height = 48; @@ -3871,49 +542,49 @@ udmf } 112 { - title = "Spincushion"; + title = "Spincushion "; sprite = "SHRPA1"; width = 16; height = 24; } 114 { - title = "Snailer"; + title = "Snailer "; sprite = "SNLRA3A7"; width = 24; height = 48; } 129 { - title = "Penguinator"; + title = "Penguinator "; sprite = "PENGA1"; width = 24; height = 32; } 130 { - title = "Pophat"; + title = "Pophat "; sprite = "POPHA1"; width = 24; height = 32; } 107 { - title = "Crawla Commander"; + title = "Crawla Commander "; sprite = "CCOMA1"; width = 16; height = 32; } 131 { - title = "Spinbobert"; + title = "Spinbobert "; sprite = "SBOBB0"; width = 32; height = 32; } 132 { - title = "Cacolantern"; + title = "Cacolantern "; sprite = "CACOA0"; width = 32; height = 32; @@ -3926,7 +597,7 @@ udmf } 133 { - title = "Hangster"; + title = "Hangster "; sprite = "HBATC1"; width = 24; height = 24; @@ -3934,7 +605,7 @@ udmf } 127 { - title = "Hive Elemental"; + title = "Hive Elemental "; sprite = "HIVEA0"; width = 32; height = 80; @@ -3945,7 +616,7 @@ udmf } 128 { - title = "Bumblebore"; + title = "Bumblebore "; sprite = "BUMBA1"; width = 16; height = 32; @@ -3958,14 +629,14 @@ udmf } 124 { - title = "Buggle"; + title = "Buggle "; sprite = "BBUZA1"; width = 20; height = 24; } 116 { - title = "Pointy"; + title = "Pointy "; sprite = "PNTYA1"; width = 8; height = 16; @@ -3976,11 +647,11 @@ udmf { color = 8; // Dark_Gray arrow = 1; - title = "Bosses"; + title = "Bosses "; 200 { - title = "Egg Mobile"; + title = "Egg Mobile "; sprite = "EGGMA1"; width = 24; height = 76; @@ -4012,7 +683,7 @@ udmf } 201 { - title = "Egg Slimer"; + title = "Egg Slimer "; sprite = "EGGNA1"; width = 24; height = 76; @@ -4050,7 +721,7 @@ udmf } 202 { - title = "Sea Egg"; + title = "Sea Egg "; sprite = "EGGOA1"; width = 32; height = 116; @@ -4082,7 +753,7 @@ udmf } 203 { - title = "Egg Colosseum"; + title = "Egg Colosseum "; sprite = "EGGPA1"; width = 24; height = 76; @@ -4119,7 +790,7 @@ udmf } 204 { - title = "Fang"; + title = "Fang "; sprite = "FANGA1"; width = 24; height = 60; @@ -4161,7 +832,7 @@ udmf } 206 { - title = "Brak Eggman (Old)"; + title = "Brak Eggman (Old) "; sprite = "BRAKB1"; width = 48; height = 160; @@ -4198,7 +869,7 @@ udmf } 207 { - title = "Metal Sonic (Race)"; + title = "Metal Sonic (Race) "; sprite = "METLI1"; width = 16; height = 48; @@ -4211,7 +882,7 @@ udmf } 208 { - title = "Metal Sonic (Battle)"; + title = "Metal Sonic (Battle) "; sprite = "METLC1"; width = 16; height = 48; @@ -4249,7 +920,7 @@ udmf } 209 { - title = "Brak Eggman"; + title = "Brak Eggman "; sprite = "BRAK01"; width = 48; height = 160; @@ -4297,7 +968,7 @@ udmf 290 { arrow = 0; - title = "Boss Escape Point"; + title = "Boss Escape Point "; width = 8; height = 16; sprite = "internal:eggmanend"; @@ -4305,7 +976,7 @@ udmf 291 { arrow = 0; - title = "Egg Capsule Center"; + title = "Egg Capsule Center "; width = 8; height = 16; sprite = "internal:capsule"; @@ -4313,7 +984,7 @@ udmf 292 { arrow = 0; - title = "Boss Waypoint"; + title = "Boss Waypoint "; width = 8; height = 16; sprite = "internal:eggmanway"; @@ -4328,14 +999,14 @@ udmf } 293 { - title = "Metal Sonic Gather Point"; + title = "Metal Sonic Gather Point "; sprite = "internal:metal"; width = 8; height = 16; } 294 { - title = "Fang Waypoint"; + title = "Fang Waypoint "; sprite = "internal:eggmanway"; width = 8; height = 16; @@ -4351,7 +1022,7 @@ udmf rings { color = 14; // Yellow - title = "Rings and Weapon Panels"; + title = "Collectibles"; width = 24; height = 24; sprite = "RINGA0"; @@ -4370,109 +1041,68 @@ udmf } 301 { - title = "Bounce Ring"; + title = "Bounce Ring "; sprite = "internal:RNGBA0"; } 302 { - title = "Rail Ring"; + title = "Rail Ring "; sprite = "internal:RNGRA0"; } 303 { - title = "Infinity Ring"; + title = "Infinity Ring "; sprite = "internal:RNGIA0"; } 304 { - title = "Automatic Ring"; + title = "Automatic Ring "; sprite = "internal:RNGAA0"; } 305 { - title = "Explosion Ring"; + title = "Explosion Ring "; sprite = "internal:RNGEA0"; } 306 { - title = "Scatter Ring"; + title = "Scatter Ring "; sprite = "internal:RNGSA0"; } 307 { - title = "Grenade Ring"; + title = "Grenade Ring "; sprite = "internal:RNGGA0"; } 308 { - title = "CTF Team Ring (Red)"; + title = "CTF Team Ring (Red) "; sprite = "internal:RRNGA0"; width = 16; } 309 { - title = "CTF Team Ring (Blue)"; + title = "CTF Team Ring (Blue) "; sprite = "internal:BRNGA0"; width = 16; } - 330 - { - title = "Bounce Ring Panel"; - sprite = "internal:PIKBA0"; - } - 331 - { - title = "Rail Ring Panel"; - sprite = "internal:PIKRA0"; - } - 332 - { - title = "Automatic Ring Panel"; - sprite = "internal:PIKAA0"; - } - 333 - { - title = "Explosion Ring Panel"; - sprite = "internal:PIKEA0"; - } - 334 - { - title = "Scatter Ring Panel"; - sprite = "internal:PIKSA0"; - } - 335 - { - title = "Grenade Ring Panel"; - sprite = "internal:PIKGA0"; - } - } - - collectibles - { - color = 10; // Light_Green - title = "Other Collectibles"; - width = 16; - height = 32; - sort = 1; - sprite = "CEMGA0"; - 310 { - title = "CTF Red Flag"; + title = "CTF Red Flag "; sprite = "RFLGA0"; width = 24; height = 64; } 311 { - title = "CTF Blue Flag"; + title = "CTF Blue Flag "; sprite = "BFLGA0"; width = 24; height = 64; } 312 { - title = "Emerald Token"; + title = "Emerald Token "; sprite = "TOKEA0"; width = 16; height = 32; @@ -4485,42 +1115,42 @@ udmf } 313 { - title = "Chaos Emerald 1 (Green)"; + title = "Chaos Emerald 1 (Green) "; sprite = "CEMGA0"; } 314 { - title = "Chaos Emerald 2 (Purple)"; + title = "Chaos Emerald 2 (Purple) "; sprite = "CEMGB0"; } 315 { - title = "Chaos Emerald 3 (Blue)"; + title = "Chaos Emerald 3 (Blue) "; sprite = "CEMGC0"; } 316 { - title = "Chaos Emerald 4 (Cyan)"; + title = "Chaos Emerald 4 (Cyan) "; sprite = "CEMGD0"; } 317 { - title = "Chaos Emerald 5 (Orange)"; + title = "Chaos Emerald 5 (Orange) "; sprite = "CEMGE0"; } 318 { - title = "Chaos Emerald 6 (Red)"; + title = "Chaos Emerald 6 (Red) "; sprite = "CEMGF0"; } 319 { - title = "Chaos Emerald 7 (Gray)"; + title = "Chaos Emerald 7 (Gray) "; sprite = "CEMGG0"; } 320 { - title = "Emerald Hunt Location"; + title = "Emerald Hunt Location "; sprite = "SHRDA0"; arg0 { @@ -4531,7 +1161,7 @@ udmf } 321 { - title = "Match Chaos Emerald Spawn"; + title = "Match Chaos Emerald Spawn "; sprite = "CEMGA0"; arg0 { @@ -4542,7 +1172,7 @@ udmf } 322 { - title = "Emblem"; + title = "Chaos Coin"; sprite = "EMBMA0"; width = 16; height = 30; @@ -4553,13 +1183,51 @@ udmf enum = "yesno"; } } + 330 + { + title = "Bounce Ring Panel "; + sprite = "internal:PIKBA0"; + } + 331 + { + title = "Rail Ring Panel "; + sprite = "internal:PIKRA0"; + } + 332 + { + title = "Automatic Ring Panel "; + sprite = "internal:PIKAA0"; + } + 333 + { + title = "Explosion Ring Panel "; + sprite = "internal:PIKEA0"; + } + 334 + { + title = "Scatter Ring Panel "; + sprite = "internal:PIKSA0"; + } + 335 + { + title = "Grenade Ring Panel "; + sprite = "internal:PIKGA0"; + } + + 4050 + { + title = "CD SS1 UFO"; + sprite = "FUFOA0"; + width = 70; + height = 70; + } } boxes { color = 7; // Gray blocking = 2; - title = "Monitors"; + title = "Monitors "; width = 18; height = 40; arg0 @@ -4570,7 +1238,7 @@ udmf 400 { - title = "Super Ring (10 Rings)"; + title = "Super Ring (10 Rings) "; sprite = "TVRIA0"; arg1 { @@ -4581,7 +1249,7 @@ udmf } 401 { - title = "Pity Shield"; + title = "Pity Shield "; sprite = "TVPIA0"; arg1 { @@ -4592,7 +1260,7 @@ udmf } 402 { - title = "Attraction Shield"; + title = "Attraction Shield "; sprite = "TVATA0"; arg1 { @@ -4603,7 +1271,7 @@ udmf } 403 { - title = "Force Shield"; + title = "Force Shield "; sprite = "TVFOA0"; arg1 { @@ -4614,7 +1282,7 @@ udmf } 404 { - title = "Armageddon Shield"; + title = "Armageddon Shield "; sprite = "TVARA0"; arg1 { @@ -4625,7 +1293,7 @@ udmf } 405 { - title = "Whirlwind Shield"; + title = "Whirlwind Shield "; sprite = "TVWWA0"; arg1 { @@ -4636,7 +1304,7 @@ udmf } 406 { - title = "Elemental Shield"; + title = "Elemental Shield "; sprite = "TVELA0"; arg1 { @@ -4647,7 +1315,7 @@ udmf } 407 { - title = "Super Sneakers"; + title = "Super Sneakers "; sprite = "TVSSA0"; arg1 { @@ -4658,7 +1326,7 @@ udmf } 408 { - title = "Invincibility"; + title = "Invincibility "; sprite = "TVIVA0"; arg1 { @@ -4669,7 +1337,7 @@ udmf } 409 { - title = "Extra Life"; + title = "Extra Life "; sprite = "TV1UA0"; arg1 { @@ -4690,12 +1358,12 @@ udmf } 410 { - title = "Eggman"; + title = "Eggman "; sprite = "TVEGA0"; } 411 { - title = "Teleporter"; + title = "Teleporter "; sprite = "TVMXA0"; arg1 { @@ -4706,22 +1374,22 @@ udmf } 413 { - title = "Gravity Boots"; + title = "Gravity Boots "; sprite = "TVGVA0"; } 414 { - title = "CTF Team Ring Monitor (Red)"; + title = "CTF Team Ring Monitor (Red) "; sprite = "TRRIA0"; } 415 { - title = "CTF Team Ring Monitor (Blue)"; + title = "CTF Team Ring Monitor (Blue) "; sprite = "TBRIA0"; } 416 { - title = "Recycler"; + title = "Recycler "; sprite = "TVRCA0"; arg1 { @@ -4732,17 +1400,17 @@ udmf } 418 { - title = "Score (1,000 Points)"; + title = "Score (1,000 Points) "; sprite = "TV1KA0"; } 419 { - title = "Score (10,000 Points)"; + title = "Score (10,000 Points) "; sprite = "TVTKA0"; } 420 { - title = "Flame Shield"; + title = "Flame Shield "; sprite = "TVFLA0"; arg1 { @@ -4753,7 +1421,7 @@ udmf } 421 { - title = "Water Shield"; + title = "Water Shield "; sprite = "TVBBA0"; arg1 { @@ -4764,7 +1432,7 @@ udmf } 422 { - title = "Lightning Shield"; + title = "Lightning Shield "; sprite = "TVZPA0"; arg1 { @@ -4779,7 +1447,7 @@ udmf { color = 18; // Gold blocking = 2; - title = "Monitors (Respawning)"; + title = "Monitors (Respawning) "; width = 20; height = 44; arg0 @@ -4790,67 +1458,67 @@ udmf 431 { - title = "Pity Shield (Respawn)"; + title = "Pity Shield (Respawn) "; sprite = "TVPIB0"; } 432 { - title = "Attraction Shield (Respawn)"; + title = "Attraction Shield (Respawn) "; sprite = "TVATB0"; } 433 { - title = "Force Shield (Respawn)"; + title = "Force Shield (Respawn) "; sprite = "TVFOB0"; } 434 { - title = "Armageddon Shield (Respawn)"; + title = "Armageddon Shield (Respawn) "; sprite = "TVARB0"; } 435 { - title = "Whirlwind Shield (Respawn)"; + title = "Whirlwind Shield (Respawn) "; sprite = "TVWWB0"; } 436 { - title = "Elemental Shield (Respawn)"; + title = "Elemental Shield (Respawn) "; sprite = "TVELB0"; } 437 { - title = "Super Sneakers (Respawn)"; + title = "Super Sneakers (Respawn) "; sprite = "TVSSB0"; } 438 { - title = "Invincibility (Respawn)"; + title = "Invincibility (Respawn) "; sprite = "TVIVB0"; } 440 { - title = "Eggman (Respawn)"; + title = "Eggman (Respawn) "; sprite = "TVEGB0"; } 443 { - title = "Gravity Boots (Respawn)"; + title = "Gravity Boots (Respawn) "; sprite = "TVGVB0"; } 450 { - title = "Flame Shield (Respawn)"; + title = "Flame Shield (Respawn) "; sprite = "TVFLB0"; } 451 { - title = "Water Shield (Respawn)"; + title = "Water Shield (Respawn) "; sprite = "TVBBB0"; } 452 { - title = "Lightning Shield (Respawn)"; + title = "Lightning Shield (Respawn) "; sprite = "TVZPB0"; } } @@ -4883,7 +1551,7 @@ udmf 502 { arrow = 1; - title = "Star Post"; + title = "Race Checkpoint"; sprite = "STPTA0M0"; width = 64; height = 128; @@ -5003,19 +1671,52 @@ udmf width = 34; height = 68; } + 1805 + { + title = "Puma (Jumping Fireball)"; + sprite = "PUMAA0"; + width = 8; + height = 16; + arg0 + { + title = "Jump strength"; + } + } + 1488 + { + arrow = 1; + title = "Random Audience Member"; + sprite = "AUDIA2A8"; + width = 8; + height = 20; + } + 2808 + { + title = "Big Ring"; + sprite = "BRNGA0"; + width = 26; + height = 62; + } + 4095 + { + title = "Empty Kart"; + sprite = "KARTA2A8"; + width = 30; + height = 30; + } } springs { color = 12; // Light_Red - title = "Springs and Fans"; + title = "Springs and Dash Rings"; width = 20; height = 16; sprite = "RSPRD2"; 540 { - title = "Fan"; + title = "Fan "; sprite = "FANSA0D0"; width = 16; height = 8; @@ -5045,6 +1746,12 @@ udmf type = 11; enum = "yesno"; } + arg1 + { + title = "Trick Panel?"; + type = 11; + enum = "yesno"; + } } 542 { @@ -5073,23 +1780,45 @@ udmf 550 { title = "Yellow Spring"; - sprite = "SPRYA0"; + sprite = "SPVYA0"; } 551 { title = "Red Spring"; - sprite = "SPRRA0"; + sprite = "SPVRA0"; } 552 { title = "Blue Spring"; - sprite = "SPRBA0"; + sprite = "SPVBA0"; + } + 553 + { + title = "Grey Spring"; + sprite = "SPVGA0"; + } + 554 + { + arrow = 1; + title = "Diagonal Yellow Spring"; + sprite = "SPDYA2A8"; + width = 16; + arg0 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Ignore gravity"; + 2 = "Rotate 22.5ยฐ CCW"; + } + } } 555 { arrow = 1; - title = "Diagonal Yellow Spring"; - sprite = "YSPRD2"; + title = "Diagonal Red Spring"; + sprite = "SPDRA2A8"; width = 16; arg0 { @@ -5105,8 +1834,8 @@ udmf 556 { arrow = 1; - title = "Diagonal Red Spring"; - sprite = "RSPRD2"; + title = "Diagonal Blue Spring"; + sprite = "SPDBA2A8"; width = 16; arg0 { @@ -5122,8 +1851,8 @@ udmf 557 { arrow = 1; - title = "Diagonal Blue Spring"; - sprite = "BSPRD2"; + title = "Diagonal Grey Spring"; + sprite = "SPDGA2A8"; width = 16; arg0 { @@ -5140,7 +1869,7 @@ udmf { arrow = 1; title = "Horizontal Yellow Spring"; - sprite = "SSWYD2D8"; + sprite = "SPHYA2A8"; width = 16; height = 32; arg0 @@ -5154,7 +1883,7 @@ udmf { arrow = 1; title = "Horizontal Red Spring"; - sprite = "SSWRD2D8"; + sprite = "SPHRA2A8"; width = 16; height = 32; arg0 @@ -5168,7 +1897,21 @@ udmf { arrow = 1; title = "Horizontal Blue Spring"; - sprite = "SSWBD2D8"; + sprite = "SPHBA2A8"; + width = 16; + height = 32; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } + } + 561 + { + arrow = 1; + title = "Horizontal Grey Spring"; + sprite = "SPHGA2A8"; width = 16; height = 32; arg0 @@ -5180,14 +1923,14 @@ udmf } 1134 { - title = "Yellow Spring Ball"; + title = "Yellow Spring Ball "; sprite = "YSPBA0"; width = 17; height = 34; } 1135 { - title = "Red Spring Ball"; + title = "Red Spring Ball "; sprite = "RSPBA0"; width = 17; height = 34; @@ -5195,7 +1938,7 @@ udmf 544 { arrow = 1; - title = "Yellow Boost Panel"; + title = "Yellow Boost Panel "; sprite = "BSTYA0"; width = 28; height = 2; @@ -5209,7 +1952,7 @@ udmf 545 { arrow = 1; - title = "Red Boost Panel"; + title = "Red Boost Panel "; sprite = "BSTRA0"; width = 28; height = 2; @@ -5220,6 +1963,20 @@ udmf enum = "noyes"; } } + 3441 + { + title = "Dash Ring"; + sprite = "DASRA1"; + width = 32; + height = 45; + } + 3442 + { + title = "Rainbow Ring"; + sprite = "RAIRA1"; + width = 32; + height = 45; + } } patterns @@ -5495,6 +2252,17 @@ udmf title = "PolyObject Spawn Point (Crush)"; sprite = "internal:polycentercrush"; } + 777 + { + title = "Floor Slope Anchor"; + sprite = "SAFA0"; + } + + 778 + { + title = "Ceiling Slope Anchor"; + sprite = "SACA0"; + } 780 { title = "Skybox View Point"; @@ -5515,102 +2283,102 @@ udmf greenflower { color = 10; // Green - title = "Greenflower"; + title = "Greenflower "; 800 { - title = "GFZ Flower"; + title = "GFZ Flower "; sprite = "FWR1A0"; width = 16; height = 40; } 801 { - title = "Sunflower"; + title = "Sunflower "; sprite = "FWR2A0"; width = 16; height = 96; } 802 { - title = "Budding Flower"; + title = "Budding Flower "; sprite = "FWR3A0"; width = 8; height = 32; } 803 { - title = "Blueberry Bush"; + title = "Blueberry Bush "; sprite = "BUS3A0"; width = 16; height = 32; } 804 { - title = "Berry Bush"; + title = "Berry Bush "; sprite = "BUS1A0"; width = 16; height = 32; } 805 { - title = "Bush"; + title = "Bush "; sprite = "BUS2A0"; width = 16; height = 32; } 806 { - title = "GFZ Tree"; + title = "GFZ Tree "; sprite = "TRE1A0"; width = 20; height = 128; } 807 { - title = "GFZ Berry Tree"; + title = "GFZ Berry Tree "; sprite = "TRE1B0"; width = 20; height = 128; } 808 { - title = "GFZ Cherry Tree"; + title = "GFZ Cherry Tree "; sprite = "TRE1C0"; width = 20; height = 128; } 809 { - title = "Checkered Tree"; + title = "Checkered Tree "; sprite = "TRE2A0"; width = 20; height = 200; } 810 { - title = "Checkered Tree (Sunset)"; + title = "Checkered Tree (Sunset) "; sprite = "TRE2B0"; width = 20; height = 200; } 811 { - title = "Polygon Tree"; + title = "Polygon Tree "; sprite = "TRE4A0"; width = 20; height = 200; } 812 { - title = "Bush Tree"; + title = "Bush Tree "; sprite = "TRE5A0"; width = 20; height = 200; } 813 { - title = "Red Bush Tree"; + title = "Red Bush Tree "; sprite = "TRE5B0"; width = 20; height = 200; @@ -5620,18 +2388,18 @@ udmf technohill { color = 10; // Green - title = "Techno Hill"; + title = "Techno Hill "; 900 { - title = "THZ Steam Flower"; + title = "THZ Steam Flower "; sprite = "THZPA0"; width = 8; height = 32; } 901 { - title = "Alarm"; + title = "Alarm "; sprite = "ALRMA0"; width = 8; height = 16; @@ -5639,14 +2407,14 @@ udmf } 902 { - title = "THZ Spin Flower (Red)"; + title = "THZ Spin Flower (Red) "; sprite = "FWR5A0"; width = 16; height = 64; } 903 { - title = "THZ Spin Flower (Yellow)"; + title = "THZ Spin Flower (Yellow) "; sprite = "FWR6A0"; width = 16; height = 64; @@ -5654,7 +2422,7 @@ udmf 904 { arrow = 1; - title = "Whistlebush"; + title = "Whistlebush "; sprite = "THZTA0"; width = 16; height = 64; @@ -5664,13 +2432,13 @@ udmf deepsea { color = 10; // Green - title = "Deep Sea"; + title = "Deep Sea "; 1000 { arrow = 1; blocking = 2; - title = "Gargoyle"; + title = "Gargoyle "; sprite = "GARGA1"; width = 16; height = 40; @@ -5685,7 +2453,7 @@ udmf { arrow = 1; blocking = 2; - title = "Gargoyle (Big)"; + title = "Gargoyle (Big) "; sprite = "GARGB1"; width = 32; height = 80; @@ -5698,14 +2466,14 @@ udmf } 1001 { - title = "Seaweed"; + title = "Seaweed "; sprite = "SEWEA0"; width = 24; height = 56; } 1002 { - title = "Dripping Water"; + title = "Dripping Water "; sprite = "DRIPD0"; width = 8; height = 16; @@ -5717,35 +2485,35 @@ udmf } 1003 { - title = "Coral (Green)"; + title = "Coral (Green) "; sprite = "CORLA0"; width = 29; height = 40; } 1004 { - title = "Coral (Red)"; + title = "Coral (Red) "; sprite = "CORLB0"; width = 30; height = 53; } 1005 { - title = "Coral (Orange)"; + title = "Coral (Orange) "; sprite = "CORLC0"; width = 28; height = 41; } 1006 { - title = "Blue Crystal"; + title = "Blue Crystal "; sprite = "BCRYA1"; width = 8; height = 16; } 1007 { - title = "Kelp"; + title = "Kelp "; sprite = "KELPA0"; width = 16; height = 292; @@ -5758,7 +2526,7 @@ udmf } 1008 { - title = "Stalagmite (DSZ1)"; + title = "Stalagmite (DSZ1) "; sprite = "DSTGA0"; width = 8; height = 116; @@ -5772,14 +2540,14 @@ udmf 1010 { arrow = 1; - title = "Light Beam"; + title = "Light Beam "; sprite = "LIBEARAL"; width = 16; height = 16; } 1011 { - title = "Stalagmite (DSZ2)"; + title = "Stalagmite (DSZ2) "; sprite = "DSTGA0"; width = 8; height = 116; @@ -5793,28 +2561,28 @@ udmf 1012 { arrow = 1; - title = "Big Floating Mine"; + title = "Big Floating Mine "; width = 28; height = 56; sprite = "BMNEA1"; } 1013 { - title = "Animated Kelp"; + title = "Animated Kelp "; sprite = "ALGAA0"; width = 48; height = 120; } 1014 { - title = "Large Coral (Brown)"; + title = "Large Coral (Brown) "; sprite = "CORLD0"; width = 56; height = 112; } 1015 { - title = "Large Coral (Beige)"; + title = "Large Coral (Beige) "; sprite = "CORLE0"; width = 56; height = 112; @@ -5824,11 +2592,11 @@ udmf castleeggman { color = 10; // Green - title = "Castle Eggman"; + title = "Castle Eggman "; 1100 { - title = "Chain (Decorative)"; + title = "Chain (Decorative) "; sprite = "CHANA0"; width = 4; height = 128; @@ -5836,7 +2604,7 @@ udmf } 1101 { - title = "Torch"; + title = "Torch "; sprite = "FLAMA0E0"; width = 8; height = 32; @@ -5851,7 +2619,7 @@ udmf { arrow = 1; blocking = 2; - title = "Eggman Statue"; + title = "Eggman Statue "; sprite = "ESTAA1"; width = 32; height = 240; @@ -5870,7 +2638,7 @@ udmf } 1103 { - title = "CEZ Flower"; + title = "CEZ Flower "; sprite = "FWR4A0"; width = 16; height = 40; @@ -6200,7 +2968,7 @@ udmf { arrow = 1; blocking = 2; - title = "Crawla Statue"; + title = "Crawla Statue "; sprite = "CSTAA1"; width = 16; height = 40; @@ -6215,7 +2983,7 @@ udmf { arrow = 1; blocking = 2; - title = "Lance-a-Bot Statue"; + title = "Lance-a-Bot Statue "; sprite = "CBBSA1"; width = 32; height = 72; @@ -6228,21 +2996,21 @@ udmf } 1114 { - title = "Pine Tree"; + title = "Pine Tree "; sprite = "PINEA0"; width = 16; height = 628; } 1115 { - title = "CEZ Shrub (Small)"; + title = "CEZ Shrub (Small) "; sprite = "CEZBA0"; width = 16; height = 24; } 1116 { - title = "CEZ Shrub (Large)"; + title = "CEZ Shrub (Large) "; sprite = "CEZBB0"; width = 32; height = 48; @@ -6250,7 +3018,7 @@ udmf 1117 { arrow = 1; - title = "Pole Banner (Red)"; + title = "Pole Banner (Red) "; sprite = "BANRA0"; width = 40; height = 224; @@ -6258,14 +3026,14 @@ udmf 1118 { arrow = 1; - title = "Pole Banner (Blue)"; + title = "Pole Banner (Blue) "; sprite = "BANRA0"; width = 40; height = 224; } 1119 { - title = "Candle"; + title = "Candle "; sprite = "CNDLA0"; width = 8; height = 48; @@ -6278,7 +3046,7 @@ udmf } 1120 { - title = "Candle Pricket"; + title = "Candle Pricket "; sprite = "CNDLB0"; width = 8; height = 176; @@ -6291,7 +3059,7 @@ udmf } 1121 { - title = "Flame Holder"; + title = "Flame Holder "; sprite = "FLMHA0"; width = 24; height = 80; @@ -6308,14 +3076,14 @@ udmf } 1122 { - title = "Fire Torch"; + title = "Fire Torch "; sprite = "CTRCA0"; width = 16; height = 80; } 1123 { - title = "Cannonball Launcher"; + title = "Cannonball Launcher "; sprite = "internal:cannonball"; width = 8; height = 16; @@ -6323,7 +3091,7 @@ udmf 1124 { blocking = 2; - title = "Cannonball"; + title = "Cannonball "; sprite = "CBLLA0"; width = 20; height = 40; @@ -6336,21 +3104,21 @@ udmf } 1125 { - title = "Brambles"; + title = "Brambles "; sprite = "CABRALAR"; width = 48; height = 32; } 1126 { - title = "Invisible Lockon Object"; + title = "Invisible Lockon Object "; sprite = "LCKNC0"; width = 16; height = 32; } 1127 { - title = "Spectator Eggrobo"; + title = "Spectator Eggrobo "; sprite = "EGR1A1"; width = 20; height = 72; @@ -6369,7 +3137,7 @@ udmf 1128 { arrow = 1; - title = "Waving Flag (Red)"; + title = "Waving Flag (Red) "; sprite = "CFLGA0"; width = 8; height = 208; @@ -6377,7 +3145,7 @@ udmf 1129 { arrow = 1; - title = "Waving Flag (Blue)"; + title = "Waving Flag (Blue) "; sprite = "CFLGA0"; width = 8; height = 208; @@ -6387,11 +3155,11 @@ udmf aridcanyon { color = 10; // Green - title = "Arid Canyon"; + title = "Arid Canyon "; 1200 { - title = "Tumbleweed (Big)"; + title = "Tumbleweed (Big) "; sprite = "BTBLA0"; width = 24; height = 48; @@ -6404,7 +3172,7 @@ udmf } 1201 { - title = "Tumbleweed (Small)"; + title = "Tumbleweed (Small) "; sprite = "STBLA0"; width = 12; height = 24; @@ -6418,7 +3186,7 @@ udmf 1202 { arrow = 1; - title = "Rock Spawner"; + title = "Rock Spawner "; sprite = "ROIAA0"; width = 8; height = 16; @@ -6444,91 +3212,91 @@ udmf } 1203 { - title = "Tiny Red Flower Cactus"; + title = "Tiny Red Flower Cactus "; sprite = "CACTA0"; width = 13; height = 24; } 1204 { - title = "Small Red Flower Cactus"; + title = "Small Red Flower Cactus "; sprite = "CACTB0"; width = 15; height = 52; } 1205 { - title = "Tiny Blue Flower Cactus"; + title = "Tiny Blue Flower Cactus "; sprite = "CACTC0"; width = 13; height = 24; } 1206 { - title = "Small Blue Flower Cactus"; + title = "Small Blue Flower Cactus "; sprite = "CACTD0"; width = 15; height = 52; } 1207 { - title = "Prickly Pear"; + title = "Prickly Pear "; sprite = "CACTE0"; width = 32; height = 96; } 1208 { - title = "Barrel Cactus"; + title = "Barrel Cactus "; sprite = "CACTF0"; width = 20; height = 128; } 1209 { - title = "Tall Barrel Cactus"; + title = "Tall Barrel Cactus "; sprite = "CACTG0"; width = 24; height = 224; } 1210 { - title = "Armed Cactus"; + title = "Armed Cactus "; sprite = "CACTH0"; width = 24; height = 256; } 1211 { - title = "Ball Cactus"; + title = "Ball Cactus "; sprite = "CACTI0"; width = 48; height = 96; } 1212 { - title = "Caution Sign"; + title = "Caution Sign "; sprite = "WWSGAR"; width = 22; height = 64; } 1213 { - title = "Cacti Sign"; + title = "Cacti Sign "; sprite = "WWS2AR"; width = 22; height = 64; } 1214 { - title = "Sharp Turn Sign"; + title = "Sharp Turn Sign "; sprite = "WWS3ALAR"; width = 16; height = 192; } 1215 { - title = "Mine Oil Lamp"; + title = "Mine Oil Lamp "; sprite = "OILLA0"; width = 22; height = 64; @@ -6536,7 +3304,7 @@ udmf } 1216 { - title = "TNT Barrel"; + title = "TNT Barrel "; sprite = "BARRA1"; width = 24; height = 63; @@ -6549,35 +3317,35 @@ udmf } 1217 { - title = "TNT Proximity Shell"; + title = "TNT Proximity Shell "; sprite = "REMTA0"; width = 64; height = 40; } 1218 { - title = "Dust Devil"; + title = "Dust Devil "; sprite = "TAZDCR"; width = 80; height = 416; } 1219 { - title = "Minecart Spawner"; + title = "Minecart Spawner "; sprite = "MCRTCLFR"; width = 22; height = 32; } 1220 { - title = "Minecart Stopper"; + title = "Minecart Stopper "; sprite = "MCRTIR"; width = 32; height = 32; } 1221 { - title = "Minecart Saloon Door"; + title = "Minecart Saloon Door "; sprite = "SALDARAL"; width = 96; height = 160; @@ -6590,28 +3358,28 @@ udmf } 1222 { - title = "Train Cameo Spawner"; + title = "Train Cameo Spawner "; sprite = "TRAEBRBL"; width = 28; height = 32; } 1223 { - title = "Train Dust Spawner"; + title = "Train Dust Spawner "; sprite = "ADSTA0"; width = 4; height = 4; } 1224 { - title = "Train Steam Spawner"; + title = "Train Steam Spawner "; sprite = "STEAA0"; width = 4; height = 4; } 1229 { - title = "Minecart Switch Point"; + title = "Minecart Switch Point "; sprite = "internal:zoom"; width = 8; height = 16; @@ -6628,14 +3396,14 @@ udmf } 1230 { - title = "Tiny Cactus"; + title = "Tiny Cactus "; sprite = "CACTJ0"; width = 13; height = 28; } 1231 { - title = "Small Cactus"; + title = "Small Cactus "; sprite = "CACTK0"; width = 15; height = 60; @@ -6722,7 +3490,7 @@ udmf } 1304 { - title = "Lavafall"; + title = "Lavafall "; sprite = "LFALF0"; width = 30; height = 32; @@ -6739,7 +3507,7 @@ udmf } 1305 { - title = "Rollout Rock"; + title = "Rollout Rock "; sprite = "PUMIA1A5"; width = 30; height = 60; @@ -6752,35 +3520,35 @@ udmf } 1306 { - title = "Big Fern"; + title = "Big Fern "; sprite = "JPLAB0"; width = 32; height = 48; } 1307 { - title = "Jungle Palm"; + title = "Jungle Palm "; sprite = "JPLAC0"; width = 32; height = 48; } 1308 { - title = "Torch Flower"; + title = "Torch Flower "; sprite = "TFLOA0"; width = 14; height = 110; } 1309 { - title = "RVZ1 Wall Vine (Long)"; + title = "RVZ1 Wall Vine (Long) "; sprite = "WVINALAR"; width = 1; height = 288; } 1310 { - title = "RVZ1 Wall Vine (Short)"; + title = "RVZ1 Wall Vine (Short) "; sprite = "WVINBLBR"; width = 1; height = 288; @@ -6790,240 +3558,240 @@ udmf botanicserenity { color = 10; // Green - title = "Botanic Serenity"; + title = "Botanic Serenity "; width = 16; height = 32; sprite = "BSZ1A0"; 1400 { - title = "Tall Flower (Red)"; + title = "Tall Flower (Red) "; sprite = "BSZ1A0"; } 1401 { - title = "Tall Flower (Purple)"; + title = "Tall Flower (Purple) "; sprite = "BSZ1B0"; } 1402 { - title = "Tall Flower (Blue)"; + title = "Tall Flower (Blue) "; sprite = "BSZ1C0"; } 1403 { - title = "Tall Flower (Cyan)"; + title = "Tall Flower (Cyan) "; sprite = "BSZ1D0"; } 1404 { - title = "Tall Flower (Yellow)"; + title = "Tall Flower (Yellow) "; sprite = "BSZ1E0"; } 1405 { - title = "Tall Flower (Orange)"; + title = "Tall Flower (Orange) "; sprite = "BSZ1F0"; } 1410 { - title = "Medium Flower (Red)"; + title = "Medium Flower (Red) "; sprite = "BSZ2A0"; } 1411 { - title = "Medium Flower (Purple)"; + title = "Medium Flower (Purple) "; sprite = "BSZ2B0"; } 1412 { - title = "Medium Flower (Blue)"; + title = "Medium Flower (Blue) "; sprite = "BSZ2C0"; } 1413 { - title = "Medium Flower (Cyan)"; + title = "Medium Flower (Cyan) "; sprite = "BSZ2D0"; } 1414 { - title = "Medium Flower (Yellow)"; + title = "Medium Flower (Yellow) "; sprite = "BSZ2E0"; } 1415 { - title = "Medium Flower (Orange)"; + title = "Medium Flower (Orange) "; sprite = "BSZ2F0"; } 1420 { - title = "Short Flower (Red)"; + title = "Short Flower (Red) "; sprite = "BSZ3A0"; } 1421 { - title = "Short Flower (Purple)"; + title = "Short Flower (Purple) "; sprite = "BSZ3B0"; } 1422 { - title = "Short Flower (Blue)"; + title = "Short Flower (Blue) "; sprite = "BSZ3C0"; } 1423 { - title = "Short Flower (Cyan)"; + title = "Short Flower (Cyan) "; sprite = "BSZ3D0"; } 1424 { - title = "Short Flower (Yellow)"; + title = "Short Flower (Yellow) "; sprite = "BSZ3E0"; } 1425 { - title = "Short Flower (Orange)"; + title = "Short Flower (Orange) "; sprite = "BSZ3F0"; } 1430 { - title = "Tulip (Red)"; + title = "Tulip (Red) "; sprite = "BST1A0"; } 1431 { - title = "Tulip (Purple)"; + title = "Tulip (Purple) "; sprite = "BST2A0"; } 1432 { - title = "Tulip (Blue)"; + title = "Tulip (Blue) "; sprite = "BST3A0"; } 1433 { - title = "Tulip (Cyan)"; + title = "Tulip (Cyan) "; sprite = "BST4A0"; } 1434 { - title = "Tulip (Yellow)"; + title = "Tulip (Yellow) "; sprite = "BST5A0"; } 1435 { - title = "Tulip (Orange)"; + title = "Tulip (Orange) "; sprite = "BST6A0"; } 1440 { - title = "Cluster (Red)"; + title = "Cluster (Red) "; sprite = "BSZ5A0"; } 1441 { - title = "Cluster (Purple)"; + title = "Cluster (Purple) "; sprite = "BSZ5B0"; } 1442 { - title = "Cluster (Blue)"; + title = "Cluster (Blue) "; sprite = "BSZ5C0"; } 1443 { - title = "Cluster (Cyan)"; + title = "Cluster (Cyan) "; sprite = "BSZ5D0"; } 1444 { - title = "Cluster (Yellow)"; + title = "Cluster (Yellow) "; sprite = "BSZ5E0"; } 1445 { - title = "Cluster (Orange)"; + title = "Cluster (Orange) "; sprite = "BSZ5F0"; } 1450 { - title = "Bush (Red)"; + title = "Bush (Red) "; sprite = "BSZ6A0"; } 1451 { - title = "Bush (Purple)"; + title = "Bush (Purple) "; sprite = "BSZ6B0"; } 1452 { - title = "Bush (Blue)"; + title = "Bush (Blue) "; sprite = "BSZ6C0"; } 1453 { - title = "Bush (Cyan)"; + title = "Bush (Cyan) "; sprite = "BSZ6D0"; } 1454 { - title = "Bush (Yellow)"; + title = "Bush (Yellow) "; sprite = "BSZ6E0"; } 1455 { - title = "Bush (Orange)"; + title = "Bush (Orange) "; sprite = "BSZ6F0"; } 1460 { - title = "Vine (Red)"; + title = "Vine (Red) "; sprite = "BSZ7A0"; } 1461 { - title = "Vine (Purple)"; + title = "Vine (Purple) "; sprite = "BSZ7B0"; } 1462 { - title = "Vine (Blue)"; + title = "Vine (Blue) "; sprite = "BSZ7C0"; } 1463 { - title = "Vine (Cyan)"; + title = "Vine (Cyan) "; sprite = "BSZ7D0"; } 1464 { - title = "Vine (Yellow)"; + title = "Vine (Yellow) "; sprite = "BSZ7E0"; } 1465 { - title = "Vine (Orange)"; + title = "Vine (Orange) "; sprite = "BSZ7F0"; } 1470 { - title = "BSZ Shrub"; + title = "BSZ Shrub "; sprite = "BSZ8A0"; } 1471 { - title = "BSZ Clover"; + title = "BSZ Clover "; sprite = "BSZ8B0"; } 1473 { - title = "Palm Tree (Big)"; + title = "Palm Tree (Big) "; width = 16; height = 160; sprite = "BSZ8D0"; } 1475 { - title = "Palm Tree (Small)"; + title = "Palm Tree (Small) "; width = 16; height = 80; sprite = "BSZ8F0"; @@ -7033,13 +3801,13 @@ udmf azuretemple { color = 10; // Green - title = "Azure Temple"; + title = "Azure Temple "; 1500 { arrow = 1; blocking = 2; - title = "Glaregoyle"; + title = "Glaregoyle "; sprite = "BGARA1"; width = 16; height = 40; @@ -7058,7 +3826,7 @@ udmf { arrow = 1; blocking = 2; - title = "Glaregoyle (Up)"; + title = "Glaregoyle (Up) "; sprite = "BGARA1"; width = 16; height = 40; @@ -7077,7 +3845,7 @@ udmf { arrow = 1; blocking = 2; - title = "Glaregoyle (Down)"; + title = "Glaregoyle (Down) "; sprite = "BGARA1"; width = 16; height = 40; @@ -7096,7 +3864,7 @@ udmf { arrow = 1; blocking = 2; - title = "Glaregoyle (Long)"; + title = "Glaregoyle (Long) "; sprite = "BGARA1"; width = 16; height = 40; @@ -7113,14 +3881,14 @@ udmf } 1504 { - title = "ATZ Target"; + title = "ATZ Target "; sprite = "RCRYB0"; width = 24; height = 32; } 1505 { - title = "Green Flame"; + title = "Green Flame "; sprite = "CFLMA0E0"; width = 8; height = 32; @@ -7129,7 +3897,7 @@ udmf { arrow = 1; blocking = 2; - title = "Blue Gargoyle"; + title = "Blue Gargoyle "; sprite = "BGARD1"; width = 16; height = 40; @@ -7145,25 +3913,28 @@ udmf dreamhill { color = 10; // Green - title = "Dream Hill"; + title = "Dream Hill "; + /* + // Needs removed, is causing errors. 1600 { - title = "Spring Tree"; + title = "Spring Tree "; sprite = "TRE6A0"; width = 16; height = 32; } 1601 { - title = "Shleep"; + title = "Shleep "; sprite = "SHLPA0"; width = 24; height = 32; } + */ 1602 { - title = "Nightopian"; + title = "Nightopian "; sprite = "NTPNA1"; width = 16; height = 40; @@ -7176,10 +3947,10 @@ udmf } } - nightstrk + axes { color = 13; // Pink - title = "NiGHTS Track"; + title = "Special Axes"; width = 8; height = 4096; sprite = "UNKNA0"; @@ -7240,7 +4011,7 @@ udmf } 1710 { - title = "Ideya Capture"; + title = "Ideya Capture "; sprite = "CAPSA0"; width = 72; height = 144; @@ -7258,13 +4029,13 @@ udmf nights { color = 13; // Pink - title = "NiGHTS Items"; + title = "NiGHTS Items "; width = 16; height = 32; 1703 { - title = "Ideya Drone"; + title = "Ideya Drone "; sprite = "NDRNA1"; width = 16; height = 56; @@ -7302,14 +4073,14 @@ udmf 1704 { arrow = 1; - title = "NiGHTS Bumper"; + title = "NiGHTS Bumper "; sprite = "NBMPG3G7"; width = 32; height = 64; } 1706 { - title = "Blue Sphere"; + title = "Blue Sphere "; sprite = "SPHRA0"; width = 16; height = 24; @@ -7322,7 +4093,7 @@ udmf } 1707 { - title = "Super Paraloop"; + title = "Super Paraloop "; sprite = "NPRUA0"; arg0 { @@ -7337,7 +4108,7 @@ udmf } 1708 { - title = "Drill Refill"; + title = "Drill Refill "; sprite = "NPRUB0"; arg0 { @@ -7352,7 +4123,7 @@ udmf } 1709 { - title = "Nightopian Helper"; + title = "Nightopian Helper "; sprite = "NPRUC0"; arg0 { @@ -7367,7 +4138,7 @@ udmf } 1711 { - title = "Extra Time"; + title = "Extra Time "; sprite = "NPRUD0"; arg0 { @@ -7382,7 +4153,7 @@ udmf } 1712 { - title = "Link Freeze"; + title = "Link Freeze "; sprite = "NPRUE0"; arg0 { @@ -7398,7 +4169,7 @@ udmf 1713 { arrow = 1; - title = "Hoop"; + title = "Hoop "; sprite = "HOOPA0"; width = 80; height = 160; @@ -7409,7 +4180,7 @@ udmf } 1714 { - title = "Ideya Anchor Point"; + title = "Ideya Anchor Point "; sprite = "internal:axis1"; width = 8; height = 16; @@ -7423,11 +4194,11 @@ udmf mario { color = 6; // Brown - title = "Mario"; + title = "Mario "; 1800 { - title = "Coin"; + title = "Coin "; sprite = "COINA0"; width = 16; height = 24; @@ -7441,7 +4212,7 @@ udmf 1801 { arrow = 1; - title = "Goomba"; + title = "Goomba "; sprite = "GOOMA0"; width = 24; height = 32; @@ -7449,39 +4220,28 @@ udmf 1802 { arrow = 1; - title = "Goomba (Blue)"; + title = "Goomba (Blue) "; sprite = "BGOMA0"; width = 24; height = 32; } 1803 { - title = "Fire Flower"; + title = "Fire Flower "; sprite = "FFWRB0"; width = 16; height = 32; } 1804 { - title = "Koopa Shell"; + title = "Koopa Shell "; sprite = "SHLLA1"; width = 16; height = 20; } - 1805 - { - title = "Puma (Jumping Fireball)"; - sprite = "PUMAA0"; - width = 8; - height = 16; - arg0 - { - title = "Jump strength"; - } - } 1806 { - title = "King Bowser"; + title = "King Bowser "; sprite = "KOOPA0"; width = 16; height = 48; @@ -7493,7 +4253,7 @@ udmf } 1807 { - title = "Axe"; + title = "Axe "; sprite = "MAXEA0"; width = 8; height = 16; @@ -7505,21 +4265,21 @@ udmf } 1808 { - title = "Bush (Short)"; + title = "Bush (Short) "; sprite = "MUS1A0"; width = 16; height = 32; } 1809 { - title = "Bush (Tall)"; + title = "Bush (Tall) "; sprite = "MUS2A0"; width = 16; height = 32; } 1810 { - title = "Toad"; + title = "Toad "; sprite = "TOADA0"; width = 8; height = 32; @@ -7529,18 +4289,18 @@ udmf christmasdisco { color = 10; // Green - title = "Christmas & Disco"; + title = "Christmas & Disco "; 1850 { - title = "Christmas Pole"; + title = "Christmas Pole "; sprite = "XMS1A0"; width = 16; height = 40; } 1851 { - title = "Candy Cane"; + title = "Candy Cane "; sprite = "XMS2A0"; width = 8; height = 32; @@ -7548,7 +4308,7 @@ udmf 1852 { blocking = 2; - title = "Snowman"; + title = "Snowman "; sprite = "XMS3A0"; width = 16; height = 64; @@ -7562,7 +4322,7 @@ udmf 1853 { blocking = 2; - title = "Snowman (With Hat)"; + title = "Snowman (With Hat) "; sprite = "XMS3B0"; width = 16; height = 80; @@ -7575,21 +4335,21 @@ udmf } 1854 { - title = "Lamp Post"; + title = "Lamp Post "; sprite = "XMS4A0"; width = 8; height = 120; } 1855 { - title = "Lamp Post (Snow)"; + title = "Lamp Post (Snow) "; sprite = "XMS4B0"; width = 8; height = 120; } 1856 { - title = "Hanging Star"; + title = "Hanging Star "; sprite = "XMS5A0"; width = 4; height = 80; @@ -7597,28 +4357,28 @@ udmf } 1857 { - title = "Berry Bush (Snow)"; + title = "Berry Bush (Snow) "; sprite = "BUS1B0"; width = 16; height = 32; } 1858 { - title = "Bush (Snow)"; + title = "Bush (Snow) "; sprite = "BUS2B0"; width = 16; height = 32; } 1859 { - title = "Blueberry Bush (Snow)"; + title = "Blueberry Bush (Snow) "; sprite = "BUS3B0"; width = 16; height = 32; } 1875 { - title = "Disco Ball"; + title = "Disco Ball "; sprite = "DBALA0"; width = 16; height = 54; @@ -7628,7 +4388,7 @@ udmf { arrow = 1; blocking = 2; - title = "Eggman Disco Statue"; + title = "Eggman Disco Statue "; sprite = "ESTAB1"; width = 20; height = 96; @@ -7644,82 +4404,85 @@ udmf stalagmites { color = 10; // Green - title = "Stalagmites"; + title = "Stalagmites "; width = 16; height = 40; 1900 { - title = "Brown Stalagmite (Tall)"; + title = "Brown Stalagmite (Tall) "; sprite = "STLGA0"; width = 16; height = 40; } 1901 { - title = "Brown Stalagmite"; + title = "Brown Stalagmite "; sprite = "STLGB0"; width = 16; height = 40; } 1902 { - title = "Orange Stalagmite (Tall)"; + title = "Orange Stalagmite (Tall) "; sprite = "STLGC0"; width = 16; height = 40; } 1903 { - title = "Orange Stalagmite"; + title = "Orange Stalagmite "; sprite = "STLGD0"; width = 16; height = 40; } 1904 { - title = "Red Stalagmite (Tall)"; + title = "Red Stalagmite (Tall) "; sprite = "STLGE0"; width = 16; height = 40; } 1905 { - title = "Red Stalagmite"; + title = "Red Stalagmite "; sprite = "STLGF0"; width = 16; height = 40; } 1906 { - title = "Gray Stalagmite (Tall)"; + title = "Gray Stalagmite (Tall) "; sprite = "STLGG0"; width = 24; height = 96; } 1907 { - title = "Gray Stalagmite"; + title = "Gray Stalagmite "; sprite = "STLGH0"; width = 16; height = 40; } 1908 { - title = "Blue Stalagmite (Tall)"; + title = "Blue Stalagmite (Tall) "; sprite = "STLGI0"; width = 16; height = 40; } 1909 { - title = "Blue Stalagmite"; + title = "Blue Stalagmite "; sprite = "STLGJ0"; width = 16; height = 40; } } + /* + // We want these objects, but they went over a billion of + // other Ring Racers objects... hauntedheights { color = 10; // Green @@ -7825,43 +4588,44 @@ udmf height = 40; } } + */ frozenhillside { color = 10; // Green - title = "Frozen Hillside"; + title = "Frozen Hillside "; 2100 { - title = "Ice Shard (Small)"; + title = "Ice Shard (Small) "; sprite = "FHZIA0"; width = 8; height = 32; } 2101 { - title = "Ice Shard (Large)"; + title = "Ice Shard (Large) "; sprite = "FHZIB0"; width = 8; height = 32; } 2102 { - title = "Crystal Tree (Aqua)"; + title = "Crystal Tree (Aqua) "; sprite = "TRE3A0"; width = 20; height = 200; } 2103 { - title = "Crystal Tree (Pink)"; + title = "Crystal Tree (Pink) "; sprite = "TRE3B0"; width = 20; height = 200; } 2104 { - title = "Amy Cameo"; + title = "Amy Cameo "; sprite = "ROSYA1"; width = 16; height = 48; @@ -7874,7 +4638,7 @@ udmf } 2105 { - title = "Mistletoe"; + title = "Mistletoe "; sprite = "XMS6A0"; width = 52; height = 106; @@ -7884,11 +4648,11 @@ udmf tutorial { color = 10; // Green - title = "Tutorial"; + title = "Tutorial "; 799 { - title = "Tutorial Plant"; + title = "Tutorial Plant "; sprite = "TUPFH0"; width = 40; height = 144; @@ -7899,6 +4663,9 @@ udmf } } + /* + // We want these objects, but they went over a billion of + // other Ring Racers objects... flickies { color = 10; // Green @@ -8036,27 +4803,899 @@ udmf sprite = "FS02A0"; } } + */ + + marble + { + color = 10; // Green + title = "Marble"; + + 1969 + { + title = "MZ Torch"; + sprite = "MARBA0"; + width = 12; + height = 45; + } + 1970 + { + title = "MZ Burner"; + sprite = "MARBJ0"; + width = 24; + height = 96; + } + } + + daytona + { + color = 10; // Green + title = "Daytona Speedway"; + + 3204 + { + title = "DSZ Pinetree"; + sprite = "PINEC0"; + width = 32; + height = 192; + } + } + + eggzeppelin + { + color = 10; // Green + title = "Egg Zeppelin"; + + 2311 + { + title = "EZZ Propeller"; + sprite = "PPLRA0"; + width = 32; + height = 48; + } + } + + competition + { + color = 10; // Green + title = "Competition Cup"; + + 3742 + { + title = "DPZ Palmtree"; + sprite = "DPPTA0"; + width = 16; + height = 560; + } + } + + auroraatoll + { + color = 10; // Green + title = "Aurora Atoll"; + + 1950 + { + title = "AAZ Palmtree"; + sprite = "AATRC0"; + width = 160; + height = 256; + } + } + + barrenbadlands + { + color = 10; // Green + title = "Barren Badlands"; + + 2005 + { + title = "BBZ Frogger"; + sprite = "FROGA2A8"; + width = 28; + height = 72; + } + 2006 + { + title = "BBZ Robra"; + sprite = "CBRAA2A8"; + width = 32; + height = 72; + } + 2007 + { + blocking = 2; + title = "BBZ Blue Robra"; + sprite = "BBRAA2A8"; + width = 32; + height = 72; + } + } + + eeriegrove + { + color = 10; // Green + title = "Eerie Grove"; + + 2679 + { + title = "EGZ Fog Generator"; + sprite = "EGFGA0"; + } + } + + hilltop + { + color = 10; // Green + title = "Hill Top"; + + 716 + { + title = "HTZ Pinetree"; + sprite = "HTZAA0"; + width = 5; + height = 204; + } + + 717 + { + title = "HTZ Bush"; + sprite = "HTZBA0"; + width = 24; + height = 38; + } + } + + skysanc + { + color = 10; // Green + title = "Sky Sanctuary"; + + 3456 + { + title = "SSZ Cloud Cluster"; + sprite = "SSCLA0"; + width = 48; + height = 45; + } + } + + frozenproduction + { + color = 10; // Green + title = "Frozen Production"; + + 691 + { + title = "FPZ FrostThrower"; + sprite = "SFTRB0"; + width = 32; + height = 45; + } + 693 + { + title = "FPZ Side-FrostThrower"; + sprite = "SFTRB0"; + width = 32; + height = 45; + } + } + + rustyrig + { + color = 10; // Green + title = "Rusty Rig"; + + 1988 + { + title = "RRZ Lamp"; + sprite = "RUSTA0"; + width = 12; + height = 45; + } + 1989 + { + title = "RRZ Chain"; + sprite = "RUSTB0"; + width = 12; + height = 45; + } + } + + maniass + { + color = 10; // Green + title = "Mania Special Stage"; + + 1960 + { + title = "SM SS3 Pillar"; + sprite = "DPLRA0"; + width = 58; + height = 256; + } + } + + smk + { + color = 4; // Red + title = "Super Mario Kart "; + + 2301 + { + title = "SMK DP Bush 1 "; + sprite = "SNESA0"; + width = 14; + height = 15; + } + 2302 + { + title = "SMK DP Bush 2 "; + sprite = "SNESB0"; + width = 13; + height = 13; + } + 2303 + { + title = "SMK DP Bush 3 "; + sprite = "SNESC0"; + width = 7; + height = 7; + } + 3970 + { + blocking = 2; + title = "SMK Pipe "; + sprite = "SMKPA1A5"; + width = 20; + height = 52; + } + 3971 + { + title = "SMK DP Monty Mole "; + sprite = "MTYMA0"; + width = 28; + height = 32; + } + 3972 + { + blocking = 2; + title = "SMK Thwomp "; + sprite = "THWPA0"; + width = 22; + height = 52; + } + 3745 + { + title = "SMK VL Snowball "; + sprite = "SNOBA0"; + width = 16; + height = 32; + } + 3203 + { + blocking = 2; + title = "SMK VL Ice Block "; + sprite = "ICEBARAL"; + width = 32; + height = 32; + } + } + + kartz + { + color = 4; // Red + title = "Riders / Kart "; + + 1480 + { + blocking = 2; + arrow = 1; + title = "Devil Gargoyle "; + sprite = "DECOA1"; + width = 16; + height = 40; + } + 1481 + { + blocking = 2; + arrow = 1; + title = "Angel Gargoyle "; + sprite = "DECOB1"; + width = 16; + height = 40; + } + 1482 + { + title = "Generic Palmtree "; + sprite = "DECOC0"; + width = 16; + height = 189; + } + 1483 + { + title = "Peach's Castle Flag "; + sprite = "DECOD0"; + width = 16; + height = 40; + } + 1484 + { + title = "Sonic the Hedge (bust) "; + sprite = "DECOE0"; + width = 64; + height = 64; + } + 1485 + { + title = "Tall Bush "; + sprite = "DECOF0"; + width = 16; + height = 32; + } + 1486 + { + title = "Bush Tree "; + sprite = "DECOG0"; + width = 16; + height = 40; + } + 1487 + { + title = "Fire Hydrant "; + sprite = "DECOH0"; + width = 16; + height = 40; + } + 2400 + { + title = "Big Puma "; + sprite = "DECOI0"; + width = 24; + height = 48; + } + 2805 + { + title = "Autumn Bush "; + sprite = "DOODA0"; + width = 16; + height = 24; + } + 2800 + { + title = "Autumn Flower "; + sprite = "DOODB0"; + width = 16; + height = 40; + } + 2801 + { + title = "Autumn Sunflower "; + sprite = "DOODD0"; + width = 16; + height = 96; + } + 2802 + { + title = "Autumn Budding Flower "; + sprite = "DOODF0"; + width = 8; + height = 32; + } + 2809 + { + title = "Decorative MKSC Item "; + sprite = "DOODJ0"; + width = 16; + height = 32; + } + 2807 + { + title = "Decorative DKR Item "; + sprite = "DOODL0"; + width = 91; + height = 166; + } + 2015 + { + title = "Buzz Bomber "; + sprite = "BUZBA2A8"; + width = 24; + height = 24; + } + 2500 + { + title = "Chomper "; + sprite = "CHOMA2A8"; + width = 24; + height = 48; + } + 2016 + { + title = "SCZ Palmtree "; + sprite = "SACOA0"; + width = 16; + height = 96; + } + 3000 + { + title = "SCZ Blue Flower "; + sprite = "SACOB0"; + width = 16; + height = 40; + } + 3001 + { + title = "SCZ Blue Tulips "; + sprite = "SACOC0"; + width = 16; + height = 40; + } + 3002 + { + title = "SCZ Yellow Flower "; + sprite = "SACOD0"; + width = 16; + height = 40; + } + 3003 + { + title = "SCZ Yellow Tulips "; + sprite = "SACOE0"; + width = 16; + height = 40; + } + 4022 // Dupe + { + title = "SCZ Wall Plant "; + sprite = "SACOF0"; + width = 16; + height = 40; + } + 4024 + { + title = "SCZ Plant "; + sprite = "SACOG0"; + width = 16; + height = 40; + } + 4025 + { + title = "SCZ Bush "; + sprite = "SACOH0"; + width = 16; + height = 40; + } + 4026 + { + title = "CAZ Skull "; + sprite = "CRABA1"; + width = 16; + height = 40; + } + 4027 + { + title = "CAZ Phantom Tree "; + sprite = "CRABB0"; + width = 32; + height = 150; + } + 4028 + { + title = "CAZ Flying Gargoyle "; + sprite = "CRABI1"; + width = 20; + height = 170; + } + 4029 + { + title = "CAZ Lamppost "; + sprite = "CRABK0"; + width = 32; + height = 150; + } + 4030 + { + title = "CAZ Dead Tree "; + sprite = "CRABL0"; + width = 32; + height = 150; + } + 715 + { + title = "Sonic the Hedge "; + sprite = "SBUSA0"; + width = 192; + height = 922; + } + 749 + { + title = "Blue Torch "; + sprite = "CNDLA0"; + width = 8; + height = 32; + } + 748 + { + title = "Green Torch "; + sprite = "CNDLE0"; + width = 8; + height = 32; + } + 744 + { + blocking = 2; + title = "CK RR Chest "; + sprite = "CHESA0"; + width = 48; + height = 64; + } + 743 + { + blocking = 2; + title = "CK RR Chimera Statue "; + sprite = "CHIMA0"; + width = 64; + height = 128; + } + 742 + { + blocking = 2; + title = "CK RR Dragon Statue "; + sprite = "DRGNA0"; + width = 64; + height = 128; + } + 741 + { + blocking = 2; + title = "CK RR Lizard Man Statue "; + sprite = "LZMNA0"; + width = 64; + height = 128; + } + 740 + { + blocking = 2; + title = "CK RR Pegasus Statue "; + sprite = "PGSSA0"; + width = 64; + height = 128; + } + 739 + { + title = "Small Purple Torch "; + sprite = "ZTCHA0"; + width = 8; + height = 32; + } + 747 + { + blocking = 2; + title = "KKR GD Thing "; + sprite = "DOCHA0"; + width = 16; + height = 64; + } + 746 + { + blocking = 2; + title = "KKR GD Duck "; + sprite = "DUCKA0"; + width = 16; + height = 64; + } + 745 + { + blocking = 2; + title = "KKR GD Tree "; + sprite = "GTREA0"; + width = 32; + height = 128; + } + 738 + { + title = "THH Monokuma "; + sprite = "MKMAA2"; + width = 16; + height = 64; + } + 737 + { + title = "Small Red Torch "; + sprite = "RTCHA0"; + width = 8; + height = 32; + } + 736 + { + title = "PC Bowling Pin "; + sprite = "BOWLA0"; + width = 16; + height = 64; + } + 733 + { + title = "PC Exploding Barrel "; + sprite = "BRRLA0"; + width = 32; + height = 64; + } + 732 + { + blocking = 2; + title = "PC Merry-Go-Round Horse "; + sprite = "HRSEA0"; + width = 32; + height = 128; + } + 731 + { + blocking = 2; + title = "Chao Fruit (Blue) "; + sprite = "BFRTA0"; + width = 16; + height = 16; + } + 730 + { + blocking = 2; + title = "Chao Fruit (Orange) "; + sprite = "OFRTA0"; + width = 16; + height = 16; + } + 729 + { + blocking = 2; + title = "Chao Fruit (Red) "; + sprite = "RFRTA0"; + width = 16; + height = 16; + } + 728 + { + blocking = 2; + title = "Chao Fruit (Pink) "; + sprite = "OFRTA0"; + width = 16; + height = 16; + } + 727 + { + title = "RBA Spikeball 1 "; + sprite = "ASPKA0"; + width = 64; + height = 32; + } + 726 + { + title = "RBA Spikeball 2 "; + sprite = "ASPKA0"; + width = 64; + height = 32; + } + 725 + { + title = "RBA Spikeball 3 "; + sprite = "ASPKA0"; + width = 64; + height = 32; + } + 724 + { + title = "RBA Boost Prompt "; + sprite = "HBSTA0"; + width = 64; + height = 64; + } + 724 + { + title = "RBA Boost OFF "; + sprite = "HBSFA0"; + width = 64; + height = 64; + } + 724 + { + title = "RBA Boost ON "; + sprite = "HBSOA0"; + width = 64; + height = 64; + } + 2200 + { + title = "AS Toad "; + sprite = "TOAHA0"; + width = 16; + height = 64; + } + 2201 + { + blocking = 2; + title = "FTZ Lizard Man Statue "; + sprite = "WBLZA0"; + width = 32; + height = 92; + } + 2202 + { + blocking = 2; + title = "FTZ Lion Man Statue "; + sprite = "WBLNA0"; + width = 32; + height = 92; + } + 3124 + { + title = "MC Spotlight "; + sprite = "SPTLA0"; + width = 8; + height = 16; + } + 3120 + { + title = "MC Random Shadow "; + sprite = "ENM1B2B8"; + width = 16; + height = 32; + } + 3121 + { + title = "MC Roaming Shadow "; + sprite = "ENM1C2C8"; + width = 16; + height = 32; + } + 3122 + { + title = "MC Sign "; + sprite = "MARRA0"; + width = 64; + height = 128; + flags1text = "[1] Flip Arrow"; + flags4text = "[4] Boost Warning"; + } + 3199 + { + title = "Mementos Reaper Waypoint "; + sprite = "ENM1B5"; + width = 64; + height = 128; + } + 3202 + { + title = "Mementos Reaper "; + sprite = "REAPA0"; + width = 64; + height = 128; + } + 3201 + { + title = "Mementos Teleporter "; + sprite = "GARUA0"; + width = 512; + height = 16; + } + 1601 + { + title = "MCZ Jack in the Box "; + sprite = "JITBA0"; + width = 16; + height = 128; + } + 2499 + { + title = "3CD Moon "; + sprite = "CDMOA0"; + width = 30; + height = 60; + } + 2498 + { + title = "3CD Bush "; + sprite = "CDBUA0"; + width = 16; + height = 16; + } + 2496 + { + title = "3CD Tree 1 "; + sprite = "CDBUB0"; + width = 20; + height = 20; + } + 2497 + { + title = "3CD Tree 2 "; + sprite = "CDBUC0"; + width = 20; + height = 20; + } + 718 + { + title = "MKSC SG Vine 1 "; + sprite = "SGVAA0"; + width = 32; + height = 256; + } + 719 + { + title = "MKSC SG Vine 2 "; + sprite = "SGVBA0"; + width = 17; + height = 48; + } + 720 + { + title = "MKSC SG Vine 3 "; + sprite = "SGVCA0"; + width = 17; + height = 48; + } + 711 + { + title = "MKDS PG Tree "; + sprite = "PGTRA0"; + width = 30; + height = 504; + } + 712 + { + title = "MKDS PG Flower 1 "; + sprite = "PGF1A0"; + width = 17; + height = 48; + } + 713 + { + title = "MKDS PG Flower 2 "; + sprite = "PGF2A0"; + width = 17; + height = 48; + } + 714 + { + title = "MKDS PG Flower 3 "; + sprite = "PGF3A0"; + width = 17; + height = 48; + } + 715 + { + title = "MKDS PG Bush "; + sprite = "PGBHA0"; + width = 384; + height = 922; + } + 2018 + { + title = "PRZ Smoke Generator "; + sprite = "SMOKA0"; + width = 24; + height = 64; + flags4text = "[4] Spawn VVZ smoke"; + } + 1600 + { + title = "VVZ Smoke "; + sprite = "VAPEA0"; + width = 16; + height = 64; + } + } waypoints { color = 4; // Red - arrow = 1; - title = "Waypoints"; - sprite = "KBLNC0"; - width = 16; - height = 32; + title = "Track Waypoints"; 2001 { - title = "Waypoint (height = next waypoint ID)"; - sprite = "EMBMP0"; - angletext = "ID"; - flags1text = "[1] Disable"; - flags4text = "[4] Shortcut"; - flags8text = "[8] No respawn"; + title = "Waypoint"; + sprite = "WAY1A0"; arg0 { - title = "Next Waypoint ID"; + title = "Next Waypoint Tag"; type = 14; } arg1 @@ -8067,9 +5706,117 @@ udmf } arg2 { - title = "Finish Line?"; - type = 0; + title = "Flags"; + type = 12; + enum + { + 1 = "Disabled on spawn"; + 2 = "Shortcut"; + 4 = "No respawn"; + 8 = "Finish line"; + } + } + } + + 2004 + { + title = "Bot Hint"; + sprite = "WAY4A0"; + arg0 + { + title = "Next Waypoint Tag"; + type = 14; + } + arg1 + { + title = "Radius"; + default = 384; + renderstyle = "Circle"; } } } + + duel + { + color = 4; // Red + arrow = 0; + title = "Duel Mode"; + sprite = "SPBMA2A8"; + arg0 + { + title = "All modes?"; + type = 11; + enum = "yesno"; + } + + 2050 + { + title = "Duel Bomb"; + width = 24; + height = 48; + arrow = 1; + arg1 + { + title = "Flip direction?"; + type = 11; + enum = "yesno"; + } + } + + 2051 + { + title = "Banana"; + sprite = "BANAA2A8"; + width = 16; + height = 32; + } + + 2052 + { + title = "Eggman Item"; + sprite = "FITMA0"; + width = 24; + height = 32; + } + + 2053 + { + title = "Proximity Mine"; + sprite = "SSMNA0"; + width = 16; + height = 24; + } + + 2054 + { + title = "Land Mine"; + sprite = "LNDMALAR"; + width = 24; + height = 32; + } + + 2055 + { + title = "Hyudoro"; + sprite = "HYUUA2A8"; + width = 32; + height = 24; + } + + 2056 + { + title = "Drop Target"; + sprite = "DTRGALAR"; + width = 45; + height = 32; + } + + 2057 + { + title = "Pogo Spring"; + sprite = "POGSA0"; + width = 48; + height = 32; + } + } } diff --git a/extras/conf/udb/Kart2_UDMF.cfg b/extras/conf/udb/RingRacers_UDMF.cfg similarity index 61% rename from extras/conf/udb/Kart2_UDMF.cfg rename to extras/conf/udb/RingRacers_UDMF.cfg index fe4fcb113..a84512f8e 100644 --- a/extras/conf/udb/Kart2_UDMF.cfg +++ b/extras/conf/udb/RingRacers_UDMF.cfg @@ -1,34 +1,34 @@ /************************************************************************\ - Ultimate Doom Builder Game Configuration for SRB2Kart + Ultimate Doom Builder Game Configuration for Dr. Robotnik's Ring Racers \************************************************************************/ // This is required to prevent accidental use of a different configuration type = "Doom Builder 2 Game Configuration"; // This is the title to show for this game -game = "SRB2Kart v2.0 (UDMF)"; +game = "Dr. Robotnik's Ring Racers (UDMF)"; // This is the simplified game engine/sourceport name engine = "zdoom"; // Settings common to all games and all map formats -include("Includes\\Kart2_common.cfg", "common"); +include("Includes\\RingRacers_common.cfg", "common"); // Settings common to text map format -include("Includes\\Kart2_common.cfg", "mapformat_udmf"); +include("Includes\\RingRacers_common.cfg", "mapformat_udmf"); -include("Includes\\Game_Kart2.cfg"); +include("Includes\\Game_RingRacers.cfg"); // Script lumps detection scriptlumpnames { - include("Includes\\Kart2_misc.cfg", "scriptlumpnames"); + include("Includes\\RingRacers_misc.cfg", "scriptlumpnames"); } //Default things filters thingsfilters { - include("Includes\\Kart2_misc.cfg", "thingsfilters"); + include("Includes\\RingRacers_misc.cfg", "thingsfilters"); } // ENUMERATIONS @@ -37,5 +37,5 @@ thingsfilters enums { // Basic game enums - include("Includes\\Kart2_misc.cfg", "enums"); -} \ No newline at end of file + include("Includes\\RingRacers_misc.cfg", "enums"); +} diff --git a/src/p_setup.c b/src/p_setup.c index f14e549ca..da13b0f16 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1260,8 +1260,8 @@ static boolean TextmapCount(size_t size) // Check if namespace is valid. tkn = M_TokenizerRead(0); - if (!fastcmp(tkn, "srb2")) - CONS_Alert(CONS_WARNING, "Invalid namespace '%s', only 'srb2' is supported.\n", tkn); + if (!fastcmp(tkn, "ringracers")) + CONS_Alert(CONS_WARNING, "Invalid namespace '%s', only 'ringracers' is supported.\n", tkn); while ((tkn = M_TokenizerRead(0)) && M_TokenizerGetEndPos() < size) { @@ -2056,7 +2056,7 @@ static void P_WriteTextmap(void) } } - fprintf(f, "namespace = \"srb2\";\n"); + fprintf(f, "namespace = \"ringracers\";\n"); for (i = 0; i < nummapthings; i++) { fprintf(f, "thing // %s\n", sizeu1(i)); From 67efbceda92f32c10a0bed99c25260727eac9b24 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 22:53:22 -0400 Subject: [PATCH 45/54] Add missing Item Boxes / Item Capsules --- .../conf/udb/Includes/RingRacers_things.cfg | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/extras/conf/udb/Includes/RingRacers_things.cfg b/extras/conf/udb/Includes/RingRacers_things.cfg index 50a8732d1..a28a166c2 100644 --- a/extras/conf/udb/Includes/RingRacers_things.cfg +++ b/extras/conf/udb/Includes/RingRacers_things.cfg @@ -1214,6 +1214,40 @@ udmf sprite = "internal:PIKGA0"; } + 2000 + { + title = "Random Item"; + sprite = "RNDMA0"; + width = 36; + height = 36; + } + 2010 + { + title = "Item Capsule"; + sprite = "ICAPA0"; + width = 56; + height = 96; + arg0 + { + title = "Item Type"; + type = 11; + enum = "rritems"; + } + arg1 + { + title = "Amount"; + } + arg2 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Invert Time Attack"; + 2 = "Invert Size"; + } + } + } 4050 { title = "CD SS1 UFO"; From 8d6d8fff6bdde17084ec8ff7860b99a9d754d246 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 10 Oct 2022 23:19:34 -0400 Subject: [PATCH 46/54] Add item type enum to config --- extras/conf/udb/Includes/RingRacers_misc.cfg | 27 ++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/extras/conf/udb/Includes/RingRacers_misc.cfg b/extras/conf/udb/Includes/RingRacers_misc.cfg index 8b0fbfbbd..267a21354 100644 --- a/extras/conf/udb/Includes/RingRacers_misc.cfg +++ b/extras/conf/udb/Includes/RingRacers_misc.cfg @@ -670,6 +670,33 @@ enums 3 = "Reverse subtract"; 4 = "Modulate"; } + + rritems + { + 0 = "Rings"; + 1 = "Sneaker"; + 2 = "Rocket Sneaker"; + 3 = "Invincibility"; + 4 = "Banana"; + 5 = "Eggman Mark"; + 6 = "Orbinaut"; + 7 = "Jawz"; + 8 = "Proximity Mine"; + 9 = "Land Mine"; + 10 = "Ballhog"; + 11 = "SPB"; + 12 = "Grow"; + 13 = "Shrink"; + 14 = "Lightning Shield"; + 15 = "Bubble Shield"; + 16 = "Flame Shield"; + 17 = "Hyudoro"; + 18 = "Pogo Spring"; + 19 = "Super Ring"; + 20 = "Kitchen Sink"; + 21 = "Drop Target"; + 22 = "Garden Top"; + } } //Default things filters From 755916914499e2f1c7436a299409fa9a26d18c31 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 11 Oct 2022 01:31:06 -0400 Subject: [PATCH 47/54] Fix Trick Panel TERRAIN not working --- src/doomdef.h | 4 ++ src/k_brightmap.c | 29 +++++++------ src/k_brightmap.h | 4 +- src/k_terrain.c | 105 +++++++++++++++++++++++++++------------------- src/k_terrain.h | 12 +++--- src/m_misc.c | 7 ++++ 6 files changed, 96 insertions(+), 65 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 89812872b..96ef10769 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -503,13 +503,17 @@ extern char liveeventbackup[256]; void M_StartupLocale(void); extern void *(*M_Memcpy)(void* dest, const void* src, size_t n) FUNCNONNULL; char *va(const char *format, ...) FUNCPRINTF; + char *M_GetToken(const char *inputString); void M_UnGetToken(void); +UINT32 M_GetTokenPos(void); + void M_TokenizerOpen(const char *inputString); void M_TokenizerClose(void); const char *M_TokenizerRead(UINT32 i); UINT32 M_TokenizerGetEndPos(void); void M_TokenizerSetEndPos(UINT32 newPos); + char *sizeu1(size_t num); char *sizeu2(size_t num); char *sizeu3(size_t num); diff --git a/src/k_brightmap.c b/src/k_brightmap.c index d5ed88e2a..a70d7a955 100644 --- a/src/k_brightmap.c +++ b/src/k_brightmap.c @@ -86,29 +86,31 @@ static brightmapStorage_t *K_GetBrightmapStorageByTextureName(const char *checkN } /*-------------------------------------------------- - static boolean K_BRIGHTLumpParser(size_t size) + static boolean K_BRIGHTLumpParser(UINT8 *data, size_t size) Parses inputted lump data as a BRIGHT lump. Input Arguments:- + data - Pointer to lump data. size - The length of the lump data. Return:- false if any errors occured, otherwise true. --------------------------------------------------*/ -static boolean K_BRIGHTLumpParser(size_t size) +static boolean K_BRIGHTLumpParser(UINT8 *data, size_t size) { - const char *tkn = M_TokenizerRead(0); + char *tkn = M_GetToken((char *)data); size_t pos = 0; - while (tkn && (pos = M_TokenizerGetEndPos()) < size) + while (tkn && (pos = M_GetTokenPos()) < size) { boolean valid = true; if (stricmp(tkn, "texture") == 0) { - tkn = M_TokenizerRead(0); - pos = M_TokenizerGetEndPos(); + Z_Free(tkn); + tkn = M_GetToken(NULL); + pos = M_GetTokenPos(); if (tkn && pos < size) { @@ -121,8 +123,9 @@ static boolean K_BRIGHTLumpParser(size_t size) bms->textureHash = quickncasehash(tkn, 8); } - tkn = M_TokenizerRead(0); - pos = M_TokenizerGetEndPos(); + Z_Free(tkn); + tkn = M_GetToken(NULL); + pos = M_GetTokenPos(); if (tkn && pos < size) { @@ -148,14 +151,17 @@ static boolean K_BRIGHTLumpParser(size_t size) valid = false; } + Z_Free(tkn); + if (valid == false) { return false; } - tkn = M_TokenizerRead(0); + tkn = M_GetToken(NULL); } + Z_Free(tkn); return true; } @@ -192,10 +198,7 @@ void K_InitBrightmapsPwad(INT32 wadNum) size = W_LumpLengthPwad(wadNum, lumpNum); CONS_Printf(M_GetText("Loading BRIGHT from %s\n"), name); - - M_TokenizerOpen((char *)data); - K_BRIGHTLumpParser(size); - M_TokenizerClose(); + K_BRIGHTLumpParser(data, size); free(name); Z_Free(data); diff --git a/src/k_brightmap.h b/src/k_brightmap.h index 33a1faec2..9ed86b125 100644 --- a/src/k_brightmap.h +++ b/src/k_brightmap.h @@ -23,10 +23,10 @@ typedef struct brightmapStorage_s // Stores data for brightmap definitions, // before putting them into texturebrightmaps. - char textureName[8]; // The texture's name. + char textureName[9]; // The texture's name. UINT32 textureHash; // The texture name's hash. - char brightmapName[8]; // The brightmap's name. + char brightmapName[9]; // The brightmap's name. UINT32 brightmapHash; // The brightmap name's hash. } brightmapStorage_t; diff --git a/src/k_terrain.c b/src/k_terrain.c index 4f6367b3e..cd420e37a 100644 --- a/src/k_terrain.c +++ b/src/k_terrain.c @@ -1087,7 +1087,7 @@ void K_UpdateTerrainOverlay(mobj_t *mo) } /*-------------------------------------------------- - static void K_FlagBoolean(UINT32 *inputFlags, UINT32 newFlag, const char *val) + static void K_FlagBoolean(UINT32 *inputFlags, UINT32 newFlag, char *val) Sets a flag to true or false depending on the string input. @@ -1100,7 +1100,7 @@ void K_UpdateTerrainOverlay(mobj_t *mo) Return:- None --------------------------------------------------*/ -static void K_FlagBoolean(UINT32 *inputFlags, UINT32 newFlag, const char *val) +static void K_FlagBoolean(UINT32 *inputFlags, UINT32 newFlag, char *val) { if (stricmp(val, "true") == 0) { @@ -1158,7 +1158,7 @@ static void K_NewSplashDefs(void) } /*-------------------------------------------------- - static void K_ParseSplashParameter(size_t i, const char *param, const char *val) + static void K_ParseSplashParameter(size_t i, char *param, char *val) Parser function for Splash blocks. @@ -1170,7 +1170,7 @@ static void K_NewSplashDefs(void) Return:- None --------------------------------------------------*/ -static void K_ParseSplashParameter(size_t i, const char *param, const char *val) +static void K_ParseSplashParameter(size_t i, char *param, char *val) { t_splash_t *splash = &splashDefs[i]; @@ -1260,7 +1260,7 @@ static void K_NewFootstepDefs(void) } /*-------------------------------------------------- - static void K_ParseFootstepParameter(size_t i, const char *param, const char *val) + static void K_ParseFootstepParameter(size_t i, char *param, char *val) Parser function for Footstep blocks. @@ -1272,7 +1272,7 @@ static void K_NewFootstepDefs(void) Return:- None --------------------------------------------------*/ -static void K_ParseFootstepParameter(size_t i, const char *param, const char *val) +static void K_ParseFootstepParameter(size_t i, char *param, char *val) { t_footstep_t *footstep = &footstepDefs[i]; @@ -1367,7 +1367,7 @@ static void K_NewOverlayDefs(void) } /*-------------------------------------------------- - static void K_ParseOverlayParameter(size_t i, const char *param, const char *val) + static void K_ParseOverlayParameter(size_t i, char *param, char *val) Parser function for Overlay blocks. @@ -1379,7 +1379,7 @@ static void K_NewOverlayDefs(void) Return:- None --------------------------------------------------*/ -static void K_ParseOverlayParameter(size_t i, const char *param, const char *val) +static void K_ParseOverlayParameter(size_t i, char *param, char *val) { t_overlay_t *overlay = &overlayDefs[i]; @@ -1449,7 +1449,7 @@ static void K_NewTerrainDefs(void) } /*-------------------------------------------------- - static void K_ParseTerrainParameter(size_t i, const char *param, const char *val) + static void K_ParseTerrainParameter(size_t i, char *param, char *val) Parser function for Terrain blocks. @@ -1461,7 +1461,7 @@ static void K_NewTerrainDefs(void) Return:- None --------------------------------------------------*/ -static void K_ParseTerrainParameter(size_t i, const char *param, const char *val) +static void K_ParseTerrainParameter(size_t i, char *param, char *val) { terrain_t *terrain = &terrainDefs[i]; @@ -1486,7 +1486,7 @@ static void K_ParseTerrainParameter(size_t i, const char *param, const char *val } else if (stricmp(param, "offroad") == 0) { - terrain->offroad = FLOAT_TO_FIXED(atof(val)); + terrain->offroad = (UINT8)get_number(val); // offroad strength enum? } else if (stricmp(param, "damageType") == 0) { @@ -1536,7 +1536,7 @@ static void K_NewTerrainFloorDefs(void) } /*-------------------------------------------------- - static boolean K_DoTERRAINLumpParse(size_t num, void (*parser)(size_t, const char *, const char *)) + static boolean K_DoTERRAINLumpParse(size_t num, void (*parser)(UINT32, char *, char *)) Runs another parser function for the TERRAIN lump, handling the nitty-gritty parts of the @@ -1549,53 +1549,61 @@ static void K_NewTerrainFloorDefs(void) Return:- false if any errors occured, otherwise true. --------------------------------------------------*/ -static boolean K_DoTERRAINLumpParse(size_t num, void (*parser)(size_t, const char *, const char *)) +static boolean K_DoTERRAINLumpParse(size_t num, void (*parser)(size_t, char *, char *)) { - const char *param, *val; + char *param, *val; - param = M_TokenizerRead(0); + param = M_GetToken(NULL); if (!fastcmp(param, "{")) { + Z_Free(param); CONS_Alert(CONS_WARNING, "Invalid TERRAIN data capsule!\n"); return false; } + Z_Free(param); + while (true) { - param = M_TokenizerRead(0); + param = M_GetToken(NULL); if (fastcmp(param, "}")) { + Z_Free(param); break; } - val = M_TokenizerRead(1); + val = M_GetToken(NULL); parser(num, param, val); + + Z_Free(param); + Z_Free(val); } return true; } /*-------------------------------------------------- - static boolean K_TERRAINLumpParser(size_t size) + static boolean K_TERRAINLumpParser(UINT8 *data, size_t size) Parses inputted lump data as a TERRAIN lump. Input Arguments:- + data - Pointer to lump data. size - The length of the lump data. Return:- false if any errors occured, otherwise true. --------------------------------------------------*/ -static boolean K_TERRAINLumpParser(size_t size) +static boolean K_TERRAINLumpParser(UINT8 *data, size_t size) { - const char *tkn = M_TokenizerRead(0); + char *tkn = M_GetToken((char *)data); UINT32 tknHash = 0; size_t pos = 0; size_t i; - while (tkn && (pos = M_TokenizerGetEndPos()) < size) + while (tkn && (pos = M_GetTokenPos()) < size) { boolean valid = true; @@ -1608,8 +1616,9 @@ static boolean K_TERRAINLumpParser(size_t size) // Check for valid fields. else if (stricmp(tkn, "splash") == 0) { - tkn = M_TokenizerRead(0); - pos = M_TokenizerGetEndPos(); + Z_Free(tkn); + tkn = M_GetToken(NULL); + pos = M_GetTokenPos(); if (tkn && pos < size) { @@ -1648,8 +1657,9 @@ static boolean K_TERRAINLumpParser(size_t size) } else if (stricmp(tkn, "footstep") == 0) { - tkn = M_TokenizerRead(0); - pos = M_TokenizerGetEndPos(); + Z_Free(tkn); + tkn = M_GetToken(NULL); + pos = M_GetTokenPos(); if (tkn && pos < size) { @@ -1688,8 +1698,9 @@ static boolean K_TERRAINLumpParser(size_t size) } else if (stricmp(tkn, "overlay") == 0) { - tkn = M_TokenizerRead(0); - pos = M_TokenizerGetEndPos(); + Z_Free(tkn); + tkn = M_GetToken(NULL); + pos = M_GetTokenPos(); if (tkn && pos < size) { @@ -1728,8 +1739,9 @@ static boolean K_TERRAINLumpParser(size_t size) } else if (stricmp(tkn, "terrain") == 0) { - tkn = M_TokenizerRead(0); - pos = M_TokenizerGetEndPos(); + Z_Free(tkn); + tkn = M_GetToken(NULL); + pos = M_GetTokenPos(); if (tkn && pos < size) { @@ -1768,8 +1780,9 @@ static boolean K_TERRAINLumpParser(size_t size) } else if (stricmp(tkn, "floor") == 0 || stricmp(tkn, "texture") == 0) { - tkn = M_TokenizerRead(0); - pos = M_TokenizerGetEndPos(); + Z_Free(tkn); + tkn = M_GetToken(NULL); + pos = M_GetTokenPos(); if (tkn && pos < size) { @@ -1777,8 +1790,9 @@ static boolean K_TERRAINLumpParser(size_t size) { // "optional" is ZDoom syntax // We don't use it, but we can ignore it. - tkn = M_TokenizerRead(0); - pos = M_TokenizerGetEndPos(); + Z_Free(tkn); + tkn = M_GetToken(NULL); + pos = M_GetTokenPos(); } if (tkn && pos < size) @@ -1806,8 +1820,9 @@ static boolean K_TERRAINLumpParser(size_t size) f->textureHash = tknHash; } - tkn = M_TokenizerRead(0); - pos = M_TokenizerGetEndPos(); + Z_Free(tkn); + tkn = M_GetToken(NULL); + pos = M_GetTokenPos(); if (tkn && pos < size) { @@ -1844,8 +1859,9 @@ static boolean K_TERRAINLumpParser(size_t size) } else if (stricmp(tkn, "defaultTerrain") == 0) { - tkn = M_TokenizerRead(0); - pos = M_TokenizerGetEndPos(); + Z_Free(tkn); + tkn = M_GetToken(NULL); + pos = M_GetTokenPos(); if (tkn && pos < size) { @@ -1882,8 +1898,9 @@ static boolean K_TERRAINLumpParser(size_t size) } else if (stricmp(tkn, "defaultOffroadFootstep") == 0) { - tkn = M_TokenizerRead(0); - pos = M_TokenizerGetEndPos(); + Z_Free(tkn); + tkn = M_GetToken(NULL); + pos = M_GetTokenPos(); if (tkn && pos < size) { @@ -1924,14 +1941,17 @@ static boolean K_TERRAINLumpParser(size_t size) valid = false; } + Z_Free(tkn); + if (valid == false) { return false; } - tkn = M_TokenizerRead(0); + tkn = M_GetToken(NULL); } + Z_Free(tkn); return true; } @@ -1977,10 +1997,7 @@ void K_InitTerrain(UINT16 wadNum) size = W_LumpLengthPwad(wadNum, lumpNum); CONS_Printf(M_GetText("Loading TERRAIN from %s\n"), name); - - M_TokenizerOpen((char *)data); - K_TERRAINLumpParser(size); - M_TokenizerClose(); + K_TERRAINLumpParser(data, size); free(name); } diff --git a/src/k_terrain.h b/src/k_terrain.h index 399b6ba1c..a119cf8f5 100644 --- a/src/k_terrain.h +++ b/src/k_terrain.h @@ -27,7 +27,7 @@ typedef struct t_splash_s // Splash definition. // These are particles spawned when hitting the floor. - char name[TERRAIN_NAME_LEN]; // Lookup name. + char name[TERRAIN_NAME_LEN+1]; // Lookup name. UINT32 hash; // Lookup name's hash. UINT16 mobjType; // Thing type. MT_NULL to not spawn anything. @@ -48,7 +48,7 @@ typedef struct t_footstep_s // Footstep definition. // These are particles spawned when moving fast enough on a floor. - char name[TERRAIN_NAME_LEN]; // Lookup name. + char name[TERRAIN_NAME_LEN+1]; // Lookup name. UINT32 hash; // Lookup name's hash. UINT16 mobjType; // Thing type. MT_NULL to not spawn anything. @@ -80,7 +80,7 @@ typedef struct t_overlay_s // Overlay definition. // These are sprites displayed on top of the base object. - char name[TERRAIN_NAME_LEN]; // Lookup name. + char name[TERRAIN_NAME_LEN+1]; // Lookup name. UINT32 hash; // Lookup name's hash. UINT16 states[TOV__MAX]; // State to use when the object is still. @@ -103,7 +103,7 @@ typedef struct terrain_s // Terrain definition. // These are all of the properties that the floor gets. - char name[TERRAIN_NAME_LEN]; // Lookup name. + char name[TERRAIN_NAME_LEN+1]; // Lookup name. UINT32 hash; // Lookup name's hash. size_t splashID; // Splash defintion ID. @@ -113,7 +113,7 @@ typedef struct terrain_s fixed_t friction; // The default friction of this texture. fixed_t offroad; // The default offroad level of this texture. INT16 damageType; // The default damage type of this texture. (Negative means no damage). - UINT8 trickPanel; // Trick panel strength + fixed_t trickPanel; // Trick panel strength fixed_t floorClip; // Offset for sprites on this ground UINT32 flags; // Flag values (see: terrain_flags_t) } terrain_t; @@ -123,7 +123,7 @@ typedef struct t_floor_s // Terrain floor definition. // Ties a texture name to a terrain definition. - char textureName[8]; // Floor texture name. + char textureName[9]; // Floor texture name. UINT32 textureHash; // Floor texture hash. size_t terrainID; // Terrain definition ID. } t_floor_t; diff --git a/src/m_misc.c b/src/m_misc.c index 3826b40d8..cf03c5e2d 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -2074,6 +2074,13 @@ void M_UnGetToken(void) endPos = oldendPos; } +/** Returns the current token's position. + */ +UINT32 M_GetTokenPos(void) +{ + return endPos; +} + #define NUMTOKENS 2 static const char *tokenizerInput = NULL; static UINT32 tokenCapacity[NUMTOKENS] = {0}; From 8953cf54bb9e091b529964c30314b69a1701b6cf Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 11 Oct 2022 02:26:54 -0400 Subject: [PATCH 48/54] Speed Pads are now a TERRAIN effect - Use `SpeedPad` to set the strength. Intended to be scaled like Trick Panels, so 1 for yellow, 2 for red, so on. Can use floating point. - Use `SpeedPadAngle` to rotate the thrust direction. This is in the same system as map angles, so east is 0, north is 90, west is 180, and south is 270. Also accepts floating point. - Speed Pad angle accounts for the flat alignment itself, as well. - Like Sneaker and Trick Panels, the sector / line special are now deprecated. --- .../conf/udb/Includes/RingRacers_linedefs.cfg | 15 ---- extras/conf/udb/Includes/RingRacers_misc.cfg | 1 - src/deh_tables.c | 2 +- src/k_terrain.c | 68 +++++++++++++++ src/k_terrain.h | 2 + src/p_setup.c | 26 +----- src/p_spec.c | 87 +------------------ src/r_bsp.c | 4 +- src/r_defs.h | 2 +- 9 files changed, 80 insertions(+), 127 deletions(-) diff --git a/extras/conf/udb/Includes/RingRacers_linedefs.cfg b/extras/conf/udb/Includes/RingRacers_linedefs.cfg index 2e471cbcb..7f6bf5459 100644 --- a/extras/conf/udb/Includes/RingRacers_linedefs.cfg +++ b/extras/conf/udb/Includes/RingRacers_linedefs.cfg @@ -175,21 +175,6 @@ udmf } } - 4 - { - title = "Speed Pad Parameters"; - prefix = "(4)"; - arg0 - { - title = "Speed"; - } - stringarg0 - { - title = "Sound"; - type = 2; - } - } - 8 { title = "Set Camera Collision Planes"; diff --git a/extras/conf/udb/Includes/RingRacers_misc.cfg b/extras/conf/udb/Includes/RingRacers_misc.cfg index 267a21354..f8fb0e87b 100644 --- a/extras/conf/udb/Includes/RingRacers_misc.cfg +++ b/extras/conf/udb/Includes/RingRacers_misc.cfg @@ -94,7 +94,6 @@ sectorflags nostepup = "Wall Sector (no step-up)"; doublestepup = "Ramp Sector (double step-up/down)"; nostepdown = "Non-Ramp Sector (no step-down)"; - speedpad = "Speed Pad"; starpostactivator = "Star Post Activator"; exit = "Exit"; fan = "Fan Sector"; diff --git a/src/deh_tables.c b/src/deh_tables.c index ec35ff611..2f68edf2c 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5838,7 +5838,7 @@ const char *const SSF_LIST[] = { "DOUBLESTEPUP", "WINDCURRENT", "CONVEYOR", - "SPEEDPAD", + "\x01", // free (name un-matchable) "STARPOSTACTIVATOR", "EXIT", "\x01", // free (name un-matchable) diff --git a/src/k_terrain.c b/src/k_terrain.c index cd420e37a..0ec55ee23 100644 --- a/src/k_terrain.c +++ b/src/k_terrain.c @@ -496,6 +496,64 @@ void K_ProcessTerrainEffect(mobj_t *mo) P_InstaThrust(mo, mo->angle, speed); } + // Speed pad + if (terrain->speedPad > 0) + { + if (player->floorboost != 0) + { + player->floorboost = 2; + } + else + { + fixed_t thrustSpeed = terrain->speedPad * 16; + angle_t thrustAngle = terrain->speedPadAngle; + fixed_t playerSpeed = P_AproxDistance(player->mo->momx, player->mo->momy); + + // FIXME: come up with a better way to get the touched + // texture's rotation to this function. At least this + // will work for 90% of scenarios... + + if (player->mo->eflags & MFE_VERTICALFLIP) + { + if (player->mo->ceilingrover != NULL) + { + thrustAngle += *player->mo->ceilingrover->bottomangle; + } + else + { + thrustAngle += player->mo->subsector->sector->ceilingpic_angle; + } + } + else + { + if (player->mo->floorrover != NULL) + { + thrustAngle += *player->mo->floorrover->topangle; + } + else + { + thrustAngle += player->mo->subsector->sector->floorpic_angle; + } + } + + // Map scale for Shrink, object scale for Grow. + thrustSpeed = FixedMul(thrustSpeed, max(mapobjectscale, player->mo->scale)); + + thrustAngle = K_ReflectAngle( + K_MomentumAngle(player->mo), thrustAngle, + playerSpeed, thrustSpeed + ); + + P_InstaThrust(player->mo, thrustAngle, max(thrustSpeed, 2*playerSpeed)); + + player->dashpadcooldown = TICRATE/3; + player->trickpanel = 0; + player->floorboost = 2; + + S_StartSound(player->mo, sfx_cdfm62); + } + } + // Bumpy floor if (terrain->flags & TRF_STAIRJANK) { @@ -1426,6 +1484,8 @@ static void K_TerrainDefaults(terrain_t *terrain) terrain->offroad = 0; terrain->damageType = -1; terrain->trickPanel = 0; + terrain->speedPad = 0; + terrain->speedPadAngle = 0; terrain->flags = 0; } @@ -1496,6 +1556,14 @@ static void K_ParseTerrainParameter(size_t i, char *param, char *val) { terrain->trickPanel = FLOAT_TO_FIXED(atof(val)); } + else if (stricmp(param, "speedPad") == 0) + { + terrain->speedPad = FLOAT_TO_FIXED(atof(val)); + } + else if (stricmp(param, "speedPadAngle") == 0) + { + terrain->speedPadAngle = FixedAngle(FLOAT_TO_FIXED(atof(val))); + } else if (stricmp(param, "floorClip") == 0) { terrain->floorClip = FLOAT_TO_FIXED(atof(val)); diff --git a/src/k_terrain.h b/src/k_terrain.h index a119cf8f5..84bdc6ad8 100644 --- a/src/k_terrain.h +++ b/src/k_terrain.h @@ -114,6 +114,8 @@ typedef struct terrain_s fixed_t offroad; // The default offroad level of this texture. INT16 damageType; // The default damage type of this texture. (Negative means no damage). fixed_t trickPanel; // Trick panel strength + fixed_t speedPad; // Speed pad strength + angle_t speedPadAngle; // Speed pad angle fixed_t floorClip; // Offset for sprites on this ground UINT32 flags; // Flag values (see: terrain_flags_t) } terrain_t; diff --git a/src/p_setup.c b/src/p_setup.c index da13b0f16..2e9c0830d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1089,19 +1089,6 @@ static void P_LoadSidedefs(UINT8 *data) break; } - case 4: // Speed pad parameters - { - sd->toptexture = sd->midtexture = sd->bottomtexture = 0; - if (msd->toptexture[0] != '-' || msd->toptexture[1] != '\0') - { - char process[8+1]; - M_Memcpy(process,msd->toptexture,8); - process[8] = '\0'; - sd->toptexture = get_number(process); - } - break; - } - case 414: // Play SFX { sd->toptexture = sd->midtexture = sd->bottomtexture = 0; @@ -1502,8 +1489,6 @@ static void ParseTextmapSectorParameter(UINT32 i, const char *param, const char sectors[i].specialflags |= SSF_DOUBLESTEPUP; else if (fastcmp(param, "nostepdown") && fastcmp("true", val)) sectors[i].specialflags |= SSF_NOSTEPDOWN; - else if (fastcmp(param, "speedpad") && fastcmp("true", val)) - sectors[i].specialflags |= SSF_SPEEDPAD; else if (fastcmp(param, "starpostactivator") && fastcmp("true", val)) sectors[i].specialflags |= SSF_STARPOSTACTIVATOR; else if (fastcmp(param, "exit") && fastcmp("true", val)) @@ -2335,8 +2320,6 @@ static void P_WriteTextmap(void) fprintf(f, "doublestepup = true;\n"); if (wsectors[i].specialflags & SSF_NOSTEPDOWN) fprintf(f, "nostepdown = true;\n"); - if (wsectors[i].specialflags & SSF_SPEEDPAD) - fprintf(f, "speedpad = true;\n"); if (wsectors[i].specialflags & SSF_STARPOSTACTIVATOR) fprintf(f, "starpostactivator = true;\n"); if (wsectors[i].specialflags & SSF_EXIT) @@ -3965,12 +3948,7 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[2] = !!(lines[i].flags & ML_MIDSOLID); break; case 4: //Speed pad parameters - lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; - if (lines[i].flags & ML_MIDSOLID) - lines[i].args[1] |= TMSP_NOTELEPORT; - if (lines[i].flags & ML_WRAPMIDTEX) - lines[i].args[1] |= TMSP_FORCESPIN; - P_WriteConstant(sides[lines[i].sidenum[0]].toptexture ? sides[lines[i].sidenum[0]].toptexture : sfx_spdpad, &lines[i].stringargs[0]); + CONS_Alert(CONS_WARNING, "Speed Pad linedef is deprecated. Use the TERRAIN effect!\n"); break; case 7: //Sector flat alignment lines[i].args[0] = tag; @@ -5923,7 +5901,7 @@ static void P_ConvertBinarySectorTypes(void) CONS_Alert(CONS_WARNING, "Trick Panel special is deprecated. Use the TERRAIN effect!\n"); break; case 5: //Speed pad - sectors[i].specialflags |= SSF_SPEEDPAD; + CONS_Alert(CONS_WARNING, "Speed Pad special is deprecated. Use the TERRAIN effect!\n"); break; default: break; diff --git a/src/p_spec.c b/src/p_spec.c index 8e525dcab..8db26f249 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4368,88 +4368,6 @@ static void P_ProcessEggCapsule(player_t *player, sector_t *sector) } } -static void P_ProcessSpeedPad(player_t *player, sector_t *sector, sector_t *roversector, mtag_t sectag) -{ - INT32 lineindex = -1; - angle_t lineangle; - fixed_t linespeed; - fixed_t playerspeed; - fixed_t sfxnum; - size_t i; - - (void)roversector; - - // Try for lines facing the sector itself, with tag 0. - for (i = 0; i < sector->linecount; i++) - { - line_t *li = sector->lines[i]; - - if (li->frontsector != sector) - continue; - - if (li->special != 4) - continue; - - if (!Tag_Find(&li->tags, 0)) - continue; - - lineindex = li - lines; - break; - } - - // Nothing found? Look via tag. - if (lineindex == -1) - lineindex = Tag_FindLineSpecial(4, sectag); - - if (lineindex == -1) - { - CONS_Debug(DBG_GAMELOGIC, "ERROR: Speed pad missing line special #4.\n"); - return; - } - - lineangle = lines[lineindex].angle; - linespeed = lines[lineindex].args[0] << FRACBITS; - - if (linespeed == 0) - { - CONS_Debug(DBG_GAMELOGIC, "ERROR: Speed pad (tag %d) at zero speed.\n", sectag); - return; - } - - if (player->floorboost != 0) - { - player->floorboost = 2; - return; - } - - playerspeed = P_AproxDistance(player->mo->momx, player->mo->momy); - - // SRB2Kart: Scale the speed you get from them! - // This is scaled differently from other horizontal speed boosts from stuff like springs, because of how this is used for some ramp jumps. - if (player->mo->scale > mapobjectscale) - { - linespeed = FixedMul(linespeed, mapobjectscale + (player->mo->scale - mapobjectscale)); - } - - lineangle = K_ReflectAngle( - K_MomentumAngle(player->mo), lineangle, - playerspeed, linespeed - ); - - P_InstaThrust(player->mo, lineangle, max(linespeed, 2*playerspeed)); - - player->dashpadcooldown = TICRATE/3; - player->trickpanel = 0; - player->floorboost = 2; - - sfxnum = lines[lineindex].stringargs[0] ? get_number(lines[lineindex].stringargs[0]) : sfx_cdfm62; - - if (!sfxnum) - sfxnum = sfx_cdfm62; - - S_StartSound(player->mo, sfxnum); -} - static void P_ProcessExitSector(player_t *player, mtag_t sectag) { INT32 lineindex; @@ -4566,12 +4484,13 @@ static void P_EvaluateSpecialFlags(player_t *player, sector_t *sector, sector_t { mtag_t sectag = Tag_FGet(§or->tags); + (void)roversector; + (void)isTouching; + if (sector->specialflags & SSF_WINDCURRENT) player->onconveyor = 2; if (sector->specialflags & SSF_CONVEYOR) player->onconveyor = 4; - if ((sector->specialflags & SSF_SPEEDPAD) && isTouching) - P_ProcessSpeedPad(player, sector, roversector, sectag); if (sector->specialflags & SSF_STARPOSTACTIVATOR) { mobj_t *post = P_GetObjectTypeInSectorNum(MT_STARPOST, sector - sectors); diff --git a/src/r_bsp.c b/src/r_bsp.c index a40acdd08..d547d860a 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -47,7 +47,9 @@ boolean R_NoEncore(sector_t *sector, levelflat_t *flat, boolean ceiling) const terrain_t *terrain = (flat != NULL ? flat->terrain : NULL); if ((terrain == NULL) - || (terrain->trickPanel <= 0 && !(terrain->flags & TRF_SNEAKERPANEL))) + || (terrain->trickPanel <= 0 + && terrain->speedPad <= 0 + && !(terrain->flags & TRF_SNEAKERPANEL))) { return invertEncore; } diff --git a/src/r_defs.h b/src/r_defs.h index f4aec08f4..a0c557e94 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -356,7 +356,7 @@ typedef enum SSF_NOSTEPDOWN = 1<<2, SSF_WINDCURRENT = 1<<3, SSF_CONVEYOR = 1<<4, - SSF_SPEEDPAD = 1<<5, + // free: 1<<5, SSF_STARPOSTACTIVATOR = 1<<6, SSF_EXIT = 1<<7, SSF_DELETEITEMS = 1<<8, From b03cb9e1a80e3ee62f991bfc8aa6221bf9df39e1 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 11 Oct 2022 03:10:50 -0400 Subject: [PATCH 49/54] Drastically speed them up --- src/k_terrain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_terrain.c b/src/k_terrain.c index 0ec55ee23..5c51758ed 100644 --- a/src/k_terrain.c +++ b/src/k_terrain.c @@ -505,7 +505,7 @@ void K_ProcessTerrainEffect(mobj_t *mo) } else { - fixed_t thrustSpeed = terrain->speedPad * 16; + fixed_t thrustSpeed = terrain->speedPad * 80; angle_t thrustAngle = terrain->speedPadAngle; fixed_t playerSpeed = P_AproxDistance(player->mo->momx, player->mo->momy); From 8a8126567b396c9088b4ce855ab18c0d85e9606e Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 16 Oct 2022 16:50:13 -0700 Subject: [PATCH 50/54] Fix -Wformat --- src/slope_anchors.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slope_anchors.c b/src/slope_anchors.c index d40fc7318..18a9ac46e 100644 --- a/src/slope_anchors.c +++ b/src/slope_anchors.c @@ -473,7 +473,7 @@ static void P_SetupAnchoredSlopes (void) { if (plane == 0) { - CONS_Alert(CONS_WARNING, "Slope anchor linedef %u has no planes set.\n", i); + CONS_Alert(CONS_WARNING, "Slope anchor linedef %s has no planes set.\n", sizeu1(i)); continue; } From 42f9443de119bf6c2e3160978ba4f9dd7a6c2f43 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 16 Oct 2022 18:06:02 -0700 Subject: [PATCH 51/54] UDMF: Add back #900 and #901 additive, subtractive special alpha values for FOFs Fix fourth digit blend mode being off by one. see ebe38ff518 --- src/p_setup.c | 15 +++++++++++++-- src/p_spec.c | 5 +++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 2e9c0830d..d1433a7a4 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3838,10 +3838,21 @@ static void P_SetBinaryFOFAlpha(line_t *line) if (sides[line->sidenum[0]].toptexture > 0) { line->args[1] = sides[line->sidenum[0]].toptexture; - if (sides[line->sidenum[0]].toptexture >= 1001) + + if (line->args[1] == 901) // additive special + { + line->args[1] = 0xff; + line->args[2] = TMB_ADD; + } + else if (line->args[1] == 902) // subtractive special + { + line->args[1] = 0xff; + line->args[2] = TMB_SUBTRACT; + } + else if (line->args[1] >= 1001) // fourth digit { - line->args[2] = (sides[line->sidenum[0]].toptexture/1000); line->args[1] %= 1000; + line->args[2] = (sides[line->sidenum[0]].toptexture/1000) + 1; // becomes an AST } } else diff --git a/src/p_spec.c b/src/p_spec.c index 8db26f249..25d75f3ff 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5102,8 +5102,9 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, I else th = th->next; } - fflr->alpha = max(0, min(0xff, alpha)); - if (fflr->alpha < 0xff || flags & FOF_SPLAT) + //fflr->alpha = max(0, min(0xff, alpha)); + fflr->alpha = alpha; + if (blendmode != TMB_TRANSLUCENT || fflr->alpha != 0xff || flags & FOF_SPLAT) { fflr->fofflags |= FOF_TRANSLUCENT; fflr->spawnflags = fflr->fofflags; From 7ceef19f74d0e22569b90214dff1271637fb1b94 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 17 Oct 2022 23:50:38 -0700 Subject: [PATCH 52/54] Fix 42f9443de --- src/p_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index d1433a7a4..743902d61 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3852,7 +3852,7 @@ static void P_SetBinaryFOFAlpha(line_t *line) else if (line->args[1] >= 1001) // fourth digit { line->args[1] %= 1000; - line->args[2] = (sides[line->sidenum[0]].toptexture/1000) + 1; // becomes an AST + line->args[2] = (sides[line->sidenum[0]].toptexture/1000); // TMB_TRANSLUCNET, TMB_ADD, etc } } else From 19a6ea84782c876e32befa5ef1f494b3b8c7c2e9 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 18 Oct 2022 18:20:19 -0700 Subject: [PATCH 53/54] Do not multiply TERRAIN speedPad value --- src/k_terrain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_terrain.c b/src/k_terrain.c index 5c51758ed..90451b3ba 100644 --- a/src/k_terrain.c +++ b/src/k_terrain.c @@ -505,7 +505,7 @@ void K_ProcessTerrainEffect(mobj_t *mo) } else { - fixed_t thrustSpeed = terrain->speedPad * 80; + fixed_t thrustSpeed = terrain->speedPad; angle_t thrustAngle = terrain->speedPadAngle; fixed_t playerSpeed = P_AproxDistance(player->mo->momx, player->mo->momy); From 0fba68f4ba44d40c912514a12f453fda1d475201 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 26 Oct 2022 19:59:15 -0700 Subject: [PATCH 54/54] Subtract texture angle from speedpad TERRAIN --- src/k_terrain.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/k_terrain.c b/src/k_terrain.c index 90451b3ba..de1124bcf 100644 --- a/src/k_terrain.c +++ b/src/k_terrain.c @@ -517,22 +517,22 @@ void K_ProcessTerrainEffect(mobj_t *mo) { if (player->mo->ceilingrover != NULL) { - thrustAngle += *player->mo->ceilingrover->bottomangle; + thrustAngle -= *player->mo->ceilingrover->bottomangle; } else { - thrustAngle += player->mo->subsector->sector->ceilingpic_angle; + thrustAngle -= player->mo->subsector->sector->ceilingpic_angle; } } else { if (player->mo->floorrover != NULL) { - thrustAngle += *player->mo->floorrover->topangle; + thrustAngle -= *player->mo->floorrover->topangle; } else { - thrustAngle += player->mo->subsector->sector->floorpic_angle; + thrustAngle -= player->mo->subsector->sector->floorpic_angle; } }