From 1bcbdf9fd1d6be4c67780392f72087a14082ee8b Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 20 Feb 2018 10:51:12 +0200 Subject: [PATCH 01/27] Added CHAN_LOOP to ZScript ESoundFlags enum https://forum.zdoom.org/viewtopic.php?t=59417 --- wadsrc/static/zscript/constants.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/wadsrc/static/zscript/constants.txt b/wadsrc/static/zscript/constants.txt index 47cf4accd..ef20e2310 100644 --- a/wadsrc/static/zscript/constants.txt +++ b/wadsrc/static/zscript/constants.txt @@ -416,6 +416,7 @@ enum ESoundFlags CHAN_MAYBE_LOCAL = 16, CHAN_UI = 32, CHAN_NOPAUSE = 64, + CHAN_LOOP = 256, CHAN_PICKUP = (CHAN_ITEM|CHAN_MAYBE_LOCAL), CHAN_NOSTOP = 4096 From 117b796c6b4333df247b95aa017417d642b6f875 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Tue, 20 Feb 2018 04:44:36 -0500 Subject: [PATCH 02/27] - fixed: Phobia: The Age (or any mod with DEHACKED overriding player bits) overwrote the player's Friendly flag --- src/d_dehacked.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index cd6525304..92d574d69 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -1196,6 +1196,10 @@ static int PatchThing (int thingy) // triggering line effects and can teleport when the missile flag is removed. info->flags2 &= ~MF2_NOTELEPORT; } + if (thingy == 1) // [SP] special handling for players - always be friendly! + { + value[0] |= MF_FRIENDLY; + } info->flags = ActorFlags::FromInt (value[0]); } if (vchanged[1]) From ff897997d6f9a29168000244b37eed76ab6aa855 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 20 Feb 2018 12:20:18 +0200 Subject: [PATCH 03/27] Fixed hang when TiMidity++ executable failed to launch https://forum.zdoom.org/viewtopic.php?t=59539 --- src/sound/mididevices/music_timiditypp_mididevice.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sound/mididevices/music_timiditypp_mididevice.cpp b/src/sound/mididevices/music_timiditypp_mididevice.cpp index 42733ce38..a254776ec 100644 --- a/src/sound/mididevices/music_timiditypp_mididevice.cpp +++ b/src/sound/mididevices/music_timiditypp_mididevice.cpp @@ -692,6 +692,10 @@ bool TimidityPPMIDIDevice::FillStream(SoundStream *stream, void *buff, int len, } break; } + else if (r == 0 && errno != 0) + { + break; + } got += r; } while(got < len); if(got < len) From 420602e15402a56e857f0eff6b1c8bb0ec129664 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Tue, 20 Feb 2018 05:35:18 -0500 Subject: [PATCH 04/27] - check for deathmatch starts before forcing an unfriendly player to use them. --- src/p_setup.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 937f77fa8..4f2a64bde 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -4138,15 +4138,18 @@ void P_SetupLevel (const char *lumpname, int position) // [SP] move unfriendly players around // horribly hacky - yes, this needs rewritten. - for (i = 0; i < MAXPLAYERS; ++i) + if (level.deathmatchstarts.Size () > 0) { - if (playeringame[i] && players[i].mo != NULL) + for (i = 0; i < MAXPLAYERS; ++i) { - if (!(players[i].mo->flags & MF_FRIENDLY)) + if (playeringame[i] && players[i].mo != NULL) { - AActor * oldSpawn = players[i].mo; - G_DeathMatchSpawnPlayer (i); - oldSpawn->Destroy(); + if (!(players[i].mo->flags & MF_FRIENDLY)) + { + AActor * oldSpawn = players[i].mo; + G_DeathMatchSpawnPlayer (i); + oldSpawn->Destroy(); + } } } } From 74357ced0c0ee2e78d6b68af8116c158111c7a27 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 21 Feb 2018 15:17:02 +0200 Subject: [PATCH 05/27] Fixed read of potentially junk values in ZScript parser The following ill-formed ZScript code might crash targets with sizeof(int) != sizeof(void*) like 64-bit Intel class test { void func() { if (true) ( return; ) } } --- src/scripting/zscript/zcc_parser.cpp | 1 + src/scripting/zscript/zcc_parser.h | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/scripting/zscript/zcc_parser.cpp b/src/scripting/zscript/zcc_parser.cpp index cb927bb50..02d78021b 100644 --- a/src/scripting/zscript/zcc_parser.cpp +++ b/src/scripting/zscript/zcc_parser.cpp @@ -267,6 +267,7 @@ static void ParseSingleFile(FScanner *pSC, const char *filename, int lump, void while (sc.GetToken()) { + value.Largest = 0; value.SourceLoc = sc.GetMessageLine(); switch (sc.TokenType) { diff --git a/src/scripting/zscript/zcc_parser.h b/src/scripting/zscript/zcc_parser.h index 3c1e55805..5f0889fd2 100644 --- a/src/scripting/zscript/zcc_parser.h +++ b/src/scripting/zscript/zcc_parser.h @@ -7,11 +7,31 @@ struct ZCCToken { + template + struct TLargest; + + template + struct TLargest + { + using Type = T; + }; + + template + struct TLargest + { + using Type = typename TLargest< + typename std::conditional< + (sizeof(T) > sizeof(U)), T, U + >::type, Ts... + >::Type; + }; + union { int Int; double Float; FString *String; + TLargest::Type Largest; }; int SourceLoc; From 9bf11155eb0b8635dd8489928387d265097316cd Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 22 Feb 2018 08:40:32 +0100 Subject: [PATCH 06/27] Ignore .DS_Store for macOS --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 80c2238ae..85af54469 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,4 @@ .vs /src/gl/unused /mapfiles_release/*.map +.DS_Store From 12eb760ff4905196a54d8b1196760f4e176be797 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Thu, 22 Feb 2018 16:52:45 +0200 Subject: [PATCH 07/27] Do not abort if Korax target destroyed before attack begins https://forum.zdoom.org/viewtopic.php?t=59551 --- wadsrc/static/zscript/hexen/korax.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/wadsrc/static/zscript/hexen/korax.txt b/wadsrc/static/zscript/hexen/korax.txt index 8f313bc19..b94664bea 100644 --- a/wadsrc/static/zscript/hexen/korax.txt +++ b/wadsrc/static/zscript/hexen/korax.txt @@ -244,6 +244,11 @@ class Korax : Actor void A_KoraxMissile() { + if (!target) + { + return; + } + static const class choices[] = { "WraithFX1", "Demon1FX1", "Demon2FX1", "FireDemonMissile", "CentaurFX", "SerpentFX" @@ -282,6 +287,11 @@ class Korax : Actor void KoraxFire (Class type, int arm) { + if (!target) + { + return; + } + static const int extension[] = { KORAX_ARM_EXTENSION_SHORT, From 1679065a5d975f314b96fcde6d2b50274a974cef Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 24 Feb 2018 16:23:55 +0200 Subject: [PATCH 08/27] Exposed Actor.ACS_ScriptCall() function This method can be used with arbitrary actor object like thing.ACS_ScriptCall("script") CallACS() and ACS_NamedExecuteWithResult() intrinsics work only within self actor context --- wadsrc/static/zscript/actor.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index dbea3fd47..7c9140788 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -1177,7 +1177,7 @@ class Actor : Thinker native { return ACS_LockedExecuteDoor(-int(script), mapnum, arg1, arg2, lock); } - int ACS_NamedExecuteWithResult(name script, int arg1=0, int arg2=0, int arg3=0, int arg4=0) + int ACS_ScriptCall(name script, int arg1=0, int arg2=0, int arg3=0, int arg4=0) { return ACS_ExecuteWithResult(-int(script), arg1, arg2, arg3, arg4); } From 76ff1adb282839f3abe9e425ef33826cf6537e08 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 24 Feb 2018 17:44:39 +0200 Subject: [PATCH 09/27] Disabled reverb editor's test environment by default https://forum.zdoom.org/viewtopic.php?t=59583 --- src/s_environment.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/s_environment.cpp b/src/s_environment.cpp index ac268bc5f..0618d72e3 100644 --- a/src/s_environment.cpp +++ b/src/s_environment.cpp @@ -677,7 +677,7 @@ void S_UnloadReverbDef () Environments = &Off; } -CUSTOM_CVAR(Bool, eaxedit_test, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) +CUSTOM_CVAR(Bool, eaxedit_test, false, CVAR_NOINITCALL) { if (self) { From 3436b80232c0f97eaa355b3db1f1305998476835 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 24 Feb 2018 17:50:13 +0200 Subject: [PATCH 10/27] Added SHARE_DIR search path back https://github.com/coelckers/gzdoom/pull/377#issuecomment-368235506 --- src/gameconfigfile.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index 5053fd033..d0a5c22e3 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -149,6 +149,7 @@ FGameConfigFile::FGameConfigFile () SetValueForKey ("Path", "$PROGDIR", true); #else SetValueForKey ("Path", "$HOME/" GAME_DIR, true); + SetValueForKey ("Path", SHARE_DIR, true); SetValueForKey ("Path", "/usr/local/share/doom", true); SetValueForKey ("Path", "/usr/local/share/games/doom", true); SetValueForKey ("Path", "/usr/share/doom", true); From fb1f8a604580727d86dfa6dde3139d8879833a11 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 24 Feb 2018 22:03:23 +0200 Subject: [PATCH 11/27] Restored ACS_NamedExecuteWithResult for DECORATE https://forum.zdoom.org/viewtopic.php?t=59250 --- wadsrc/static/zscript/actor.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 7c9140788..fa0644755 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -1177,7 +1177,7 @@ class Actor : Thinker native { return ACS_LockedExecuteDoor(-int(script), mapnum, arg1, arg2, lock); } - int ACS_ScriptCall(name script, int arg1=0, int arg2=0, int arg3=0, int arg4=0) + int ACS_NamedExecuteWithResult(name script, int arg1=0, int arg2=0, int arg3=0, int arg4=0) { return ACS_ExecuteWithResult(-int(script), arg1, arg2, arg3, arg4); } @@ -1185,6 +1185,10 @@ class Actor : Thinker native { return ACS_ExecuteAlways(-int(script), mapnum, arg1, arg2, arg3); } + int ACS_ScriptCall(name script, int arg1=0, int arg2=0, int arg3=0, int arg4=0) + { + return ACS_ExecuteWithResult(-int(script), arg1, arg2, arg3, arg4); + } States(Actor, Overlay, Weapon, Item) { From 07f168a58bb82c81280eb65fa497742ab6b2ff3a Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Sat, 24 Feb 2018 16:04:20 -0500 Subject: [PATCH 12/27] - additional check for tween-tic particle rendering, prevents jitter with timefreeze powerup --- src/gl/scene/gl_sprite.cpp | 2 +- src/polyrenderer/scene/poly_particle.cpp | 2 +- src/swrenderer/things/r_particle.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index cfaa34f6f..74e5b8ed9 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -1211,7 +1211,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s } double timefrac = r_viewpoint.TicFrac; - if (paused || bglobal.freeze) + if (paused || bglobal.freeze || (level.flags2 & LEVEL2_FROZEN)) timefrac = 0.; float xvf = (particle->Vel.X) * timefrac; float yvf = (particle->Vel.Y) * timefrac; diff --git a/src/polyrenderer/scene/poly_particle.cpp b/src/polyrenderer/scene/poly_particle.cpp index 0ab3beb22..942ef1346 100644 --- a/src/polyrenderer/scene/poly_particle.cpp +++ b/src/polyrenderer/scene/poly_particle.cpp @@ -35,7 +35,7 @@ EXTERN_CVAR(Int, gl_particles_style) void RenderPolyParticle::Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t stencilValue) { double timefrac = r_viewpoint.TicFrac; - if (paused || bglobal.freeze) + if (paused || bglobal.freeze || (level.flags2 & LEVEL2_FROZEN)) timefrac = 0.; DVector3 pos = particle->Pos + (particle->Vel * timefrac); double psize = particle->size / 8.0; diff --git a/src/swrenderer/things/r_particle.cpp b/src/swrenderer/things/r_particle.cpp index 7c2d88f48..ee791b56b 100644 --- a/src/swrenderer/things/r_particle.cpp +++ b/src/swrenderer/things/r_particle.cpp @@ -79,7 +79,7 @@ namespace swrenderer sector_t* heightsec = NULL; double timefrac = r_viewpoint.TicFrac; - if (paused || bglobal.freeze) + if (paused || bglobal.freeze || (level.flags2 & LEVEL2_FROZEN)) timefrac = 0.; double ippx = particle->Pos.X + particle->Vel.X * timefrac; From 9a8e724761064ca81bcf5d7a8dee2edac08c0925 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 27 Feb 2018 09:52:42 +0100 Subject: [PATCH 13/27] - added a compatibility setting for Perdition's Gate MAP31 which was having render issues with an unsupported vanilla effect. --- src/compatibility.cpp | 29 +++++++++++++++++++++++++++++ wadsrc/static/compatibility.txt | 14 ++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/compatibility.cpp b/src/compatibility.cpp index 8c3cc16c5..b99f2a51b 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -92,6 +92,7 @@ enum CP_SETTHINGSKILLS, CP_SETSECTORTEXTURE, CP_SETSECTORLIGHT, + CP_SETLINESECTORREF, }; // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- @@ -283,6 +284,18 @@ void ParseCompatibility() CompatParams.Push(sc.Number); } } + else if (sc.Compare("setlinesectorref")) + { + if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); + CompatParams.Push(CP_SETLINESECTORREF); + sc.MustGetNumber(); + CompatParams.Push(sc.Number); + sc.MustGetString(); + CompatParams.Push(sc.MustMatchString(LineSides)); + sc.MustGetNumber(); + CompatParams.Push(sc.Number); + flags.CompatFlags[SLOT_BCOMPAT] |= BCOMPATF_REBUILDNODES; + } else if (sc.Compare("clearlinespecial")) { if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); @@ -719,6 +732,22 @@ void SetCompatibilityParams() i += 3; break; } + case CP_SETLINESECTORREF: + { + if ((unsigned)CompatParams[i + 1] < level.lines.Size()) + { + line_t *line = &level.lines[CompatParams[i + 1]]; + assert(line != nullptr); + side_t *side = line->sidedef[CompatParams[i + 2]]; + if (side != nullptr && (unsigned)CompatParams[i + 3] < level.sectors.Size()) + { + side->sector = &level.sectors[CompatParams[i + 3]]; + } + } + i += 4; + break; + } + } } } diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index b78b4e664..673002877 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -868,3 +868,17 @@ CA3773ED313E8899311F3DD0CA195A68 // e3m6 { shorttex } + +FCCA97FC851F6473EAA069F74247B317 // pg-raw.wad map31 +{ + setlinesectorref 331 front 74 + setlinesectorref 326 front 74 + setlinesectorref 497 front 74 + setlinesectorref 474 front 74 + setlinesectorref 471 front 74 + setlinesectorref 327 front 74 + setlinesectorref 328 front 74 + setlinesectorref 329 front 74 + setsectortag 74 4 + setlinespecial 357 Transfer_Heights 4 2 0 0 0 +} From 883a6ffe3a80aa5d19d0bf8a96e4d13e23bca6ac Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 27 Feb 2018 10:40:43 +0100 Subject: [PATCH 14/27] - added an inventory check to A_KeenDie so that it still works if a patch repurposes a pickup item that may end up in the player's inventory. --- wadsrc/static/zscript/doom/keen.txt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/wadsrc/static/zscript/doom/keen.txt b/wadsrc/static/zscript/doom/keen.txt index 6d596c717..083df92b4 100644 --- a/wadsrc/static/zscript/doom/keen.txt +++ b/wadsrc/static/zscript/doom/keen.txt @@ -70,8 +70,13 @@ extend class Actor { if (mo.health > 0 && mo != self) { - // other Keen not dead - return; + // Added check for Dehacked and repurposed inventory items. + let inv = Inventory(mo); + if (inv == null || inv.Owner == null) + { + // other Keen not dead + return; + } } } Door_Open(doortag, 16); From fd27b228575c914cebaab3b42ab7112f465bee0b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 27 Feb 2018 11:10:47 +0100 Subject: [PATCH 15/27] - use iswspace to classify whitespace in V_BreakLines. isspace does not work because it is limited to 8-bit character sets. --- src/v_text.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/v_text.cpp b/src/v_text.cpp index f4829ec18..06b09a2ef 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include "v_text.h" @@ -387,7 +388,7 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bo continue; } - if (isspace(c)) + if (iswspace(c)) { if (!lastWasSpace) { @@ -420,12 +421,12 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bo start = space; space = NULL; - while (*start && isspace (*start) && *start != '\n') + while (*start && iswspace (*start) && *start != '\n') start++; if (*start == '\n') start++; else - while (*start && isspace (*start)) + while (*start && iswspace (*start)) start++; string = start; } @@ -443,7 +444,7 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bo while (s < string) { // If there is any non-white space in the remainder of the string, add it. - if (!isspace (*s++)) + if (!iswspace (*s++)) { auto i = Lines.Reserve(1); breakit (&Lines[i], font, start, string, linecolor); From f3deaf54c63665509ec6b45e849f07fc1eaf6377 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 27 Feb 2018 11:16:28 +0100 Subject: [PATCH 16/27] - added light definition for megasphere. --- wadsrc_lights/static/filter/doom.doom1/gldefs.txt | 15 +++++++++++++++ wadsrc_lights/static/filter/doom.doom2/gldefs.txt | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/wadsrc_lights/static/filter/doom.doom1/gldefs.txt b/wadsrc_lights/static/filter/doom.doom1/gldefs.txt index d79ba5296..83c30369d 100644 --- a/wadsrc_lights/static/filter/doom.doom1/gldefs.txt +++ b/wadsrc_lights/static/filter/doom.doom1/gldefs.txt @@ -559,6 +559,21 @@ object SoulSphere frame SOUL { light SOULSPHERE } } +pulselight MEGASPHERE +{ + color 0.5 0.5 0.4 + size 60 + secondarySize 63 + interval 2.0 + offset 0 16 0 + attenuate 1 +} + +object MegaSphere +{ + frame MEGA { light MEGASPHERE } +} + // Invulnerability Sphere pulselight INVULN { diff --git a/wadsrc_lights/static/filter/doom.doom2/gldefs.txt b/wadsrc_lights/static/filter/doom.doom2/gldefs.txt index d79ba5296..83c30369d 100644 --- a/wadsrc_lights/static/filter/doom.doom2/gldefs.txt +++ b/wadsrc_lights/static/filter/doom.doom2/gldefs.txt @@ -559,6 +559,21 @@ object SoulSphere frame SOUL { light SOULSPHERE } } +pulselight MEGASPHERE +{ + color 0.5 0.5 0.4 + size 60 + secondarySize 63 + interval 2.0 + offset 0 16 0 + attenuate 1 +} + +object MegaSphere +{ + frame MEGA { light MEGASPHERE } +} + // Invulnerability Sphere pulselight INVULN { From d873ae75ab9430e42a93b05da457eee406192a9e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 27 Feb 2018 11:34:44 +0100 Subject: [PATCH 17/27] - silence all error messages in the state map parser for DEHSUPP when re-reading the data. The state map will just be skipped and the parser only needs to run to get over the data. However, due to changes from a previous patch the data cannot be validated so aside from not using the data it may also not abort on errors. --- src/d_dehacked.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 92d574d69..ddabdb772 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -2840,14 +2840,14 @@ static bool LoadDehSupp () sc.MustGetString(); PClassActor *actortype = static_cast(type); s.State = actortype->FindState(sc.String); - if (s.State == NULL) + if (s.State == NULL && addit) { sc.ScriptError("Invalid state '%s' in '%s'", sc.String, type->TypeName.GetChars()); } sc.MustGetStringName(","); sc.MustGetNumber(); - if (s.State == NULL || sc.Number < 1 || !actortype->OwnsState(s.State + sc.Number - 1)) + if (addit && (s.State == NULL || sc.Number < 1 || !actortype->OwnsState(s.State + sc.Number - 1))) { sc.ScriptError("Invalid state range in '%s'", type->TypeName.GetChars()); } From aaaf9aa108d1d74e247d59bdad78f8a2be29a6be Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 27 Feb 2018 12:44:00 +0100 Subject: [PATCH 18/27] Added 'TeleportSpecial' as an alias for 'Teleport' in ZScript to deconflict from the Actor.Teleport function. --- src/namedef.h | 2 ++ src/scripting/backend/codegen.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/namedef.h b/src/namedef.h index ace456a69..9e6d3811a 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -377,6 +377,8 @@ xx(MomZ) xx(Threshold) xx(DefThreshold) xx(Abs) +xx(TeleportSpecial) +xx(Teleport) xx(ACS_NamedExecuteWithResult) xx(CallACS) xx(Sqrt) diff --git a/src/scripting/backend/codegen.cpp b/src/scripting/backend/codegen.cpp index 96393ad4c..24e541a36 100644 --- a/src/scripting/backend/codegen.cpp +++ b/src/scripting/backend/codegen.cpp @@ -7758,6 +7758,8 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx) } else { + // This alias is needed because Actor has a Teleport function. + if (MethodName == NAME_TeleportSpecial) MethodName = NAME_Teleport; special = P_FindLineSpecial(MethodName.GetChars(), &min, &max); } if (special != 0 && min >= 0) From af14609de77e82d5c7c2213949d921b39fb058cc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 27 Feb 2018 15:42:22 +0100 Subject: [PATCH 19/27] - don't skip empty arrays which are themselves array elements in the ZScript serializer. --- src/scripting/types.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/scripting/types.cpp b/src/scripting/types.cpp index 5059834d4..d683e62d6 100644 --- a/src/scripting/types.cpp +++ b/src/scripting/types.cpp @@ -1968,7 +1968,10 @@ void PDynArray::SetPointerArray(void *base, unsigned offset, TArray *spe void PDynArray::WriteValue(FSerializer &ar, const char *key, const void *addr) const { FArray *aray = (FArray*)addr; - if (aray->Count > 0) + // We may skip an empty array only if it gets stored under a named key. + // If no name is given, i.e. it's part of an outer array's element list, even empty arrays must be stored, + // because otherwise the array would lose its entry. + if (aray->Count > 0 || key == nullptr) { if (ar.BeginArray(key)) { From 7ac8b496f1ae92ad55c42352444f4a101a00dcdb Mon Sep 17 00:00:00 2001 From: Major Cooke Date: Sat, 24 Feb 2018 14:36:17 -0600 Subject: [PATCH 20/27] Added Distance(2/3)DSquared functions. --- src/actor.h | 6 ++++++ src/p_mobj.cpp | 14 ++++++++++++++ wadsrc/static/zscript/actor.txt | 2 ++ 3 files changed, 22 insertions(+) diff --git a/src/actor.h b/src/actor.h index 1510a5787..863e4fb46 100644 --- a/src/actor.h +++ b/src/actor.h @@ -886,6 +886,12 @@ public: // a full 3D version of the above + double Distance3DSquared(AActor *other, bool absolute = false) + { + DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this); + return (Pos() - otherpos).LengthSquared(); + } + double Distance3D(AActor *other, bool absolute = false) { DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 8e5e1d3a2..371e3f977 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -8127,6 +8127,20 @@ DEFINE_ACTION_FUNCTION(AActor, absangle) // should this be global? ACTION_RETURN_FLOAT(absangle(DAngle(a1), DAngle(a2)).Degrees); } +DEFINE_ACTION_FUNCTION(AActor, Distance2DSquared) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_OBJECT_NOT_NULL(other, AActor); + ACTION_RETURN_FLOAT(self->Distance2DSquared(other)); +} + +DEFINE_ACTION_FUNCTION(AActor, Distance3DSquared) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_OBJECT_NOT_NULL(other, AActor); + ACTION_RETURN_FLOAT(self->Distance3DSquared(other)); +} + DEFINE_ACTION_FUNCTION(AActor, Distance2D) { PARAM_SELF_PROLOGUE(AActor); diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index fa0644755..cb2ceb945 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -580,6 +580,8 @@ class Actor : Thinker native native void SetDamage(int dmg); native clearscope double Distance2D(Actor other) const; native clearscope double Distance3D(Actor other) const; + native clearscope double Distance2DSquared(Actor other) const; + native clearscope double Distance3DSquared(Actor other) const; native void SetOrigin(vector3 newpos, bool moving); native void SetXYZ(vector3 newpos); native Actor GetPointer(int aaptr); From 4ccbc4ea9e8822bf915a09c6aa01aca07eaca89d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 28 Feb 2018 09:46:28 +0100 Subject: [PATCH 21/27] - Send a GM reset SYSEX event when music playback is started. --- src/sound/musicformats/music_midistream.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/sound/musicformats/music_midistream.cpp b/src/sound/musicformats/music_midistream.cpp index 2a8abdae9..cf8f293c6 100644 --- a/src/sound/musicformats/music_midistream.cpp +++ b/src/sound/musicformats/music_midistream.cpp @@ -745,6 +745,14 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, uint32_t max_time) if (InitialPlayback) { InitialPlayback = false; + // Send the GS System Reset SysEx message. + events[0] = 0; // dwDeltaTime + events[1] = 0; // dwStreamID + events[2] = (MEVENT_LONGMSG << 24) | 6; // dwEvent + events[3] = MAKE_ID(0xf0, 0x7e, 0x7f, 0x09); // dwParms[0] + events[4] = MAKE_ID(0x01, 0xf7, 0x00, 0x00); // dwParms[1] + events += 5; + // Send the full master volume SysEx message. events[0] = 0; // dwDeltaTime events[1] = 0; // dwStreamID @@ -752,6 +760,7 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, uint32_t max_time) events[3] = MAKE_ID(0xf0,0x7f,0x7f,0x04); // dwParms[0] events[4] = MAKE_ID(0x01,0x7f,0x7f,0xf7); // dwParms[1] events += 5; + DoInitialSetup(); } From 910a3062c79be5e63bba64491270e993a46d6083 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 28 Feb 2018 10:12:10 +0100 Subject: [PATCH 22/27] - fixed some problems with the stepping up through a portal logic: * this has to be disabled for missiles which should explode instead of stepping up. * interpolation adjustment was not correct * it could crash because the target portal group could be retrieved from a non-portal sector. --- src/p_map.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index 7d5a79de8..16d8ac564 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -898,7 +898,9 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec } // check if the actor can step through the ceiling portal. In this case one-sided lines in the current area should not block - if (!cres.line->frontsector->PortalBlocksMovement(sector_t::ceiling)) + // Use the same rules for stepping through a portal as for non-portal case. + bool ismissile = (tm.thing->flags & MF_MISSILE) && !(tm.thing->flags6 & MF6_STEPMISSILE) && !(tm.thing->flags3 & MF3_FLOORHUGGER); + if (!ismissile && !cres.line->frontsector->PortalBlocksMovement(sector_t::ceiling)) { double portz = cres.line->frontsector->GetPortalPlaneZ(sector_t::ceiling); if (tm.thing->Z() < portz && tm.thing->Z() + tm.thing->MaxStepHeight >= portz && tm.floorz < portz) @@ -1008,7 +1010,9 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec FLineOpening open; P_LineOpening(open, tm.thing, ld, ref, &cres.Position, cres.portalflags); - if (!tm.thing->Sector->PortalBlocksMovement(sector_t::ceiling)) + // Use the same rules for stepping through a portal as for non-portal case. + bool ismissile = (tm.thing->flags & MF_MISSILE) && !(tm.thing->flags6 & MF6_STEPMISSILE) && !(tm.thing->flags3 & MF3_FLOORHUGGER); + if (!ismissile && !tm.thing->Sector->PortalBlocksMovement(sector_t::ceiling)) { sector_t *oppsec = cres.line->frontsector == tm.thing->Sector ? cres.line->backsector : cres.line->frontsector; if (oppsec->PortalBlocksMovement(sector_t::ceiling)) @@ -2707,8 +2711,8 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, FLinkContext ctx; DVector3 oldpos = thing->Pos(); thing->UnlinkFromWorld(&ctx); - thing->SetXYZ(thing->PosRelative(thing->Sector->GetOppositePortalGroup(sector_t::ceiling))); - thing->Prev = thing->Pos() - oldpos; + thing->SetXYZ(thing->PosRelative(tm.portalgroup)); + thing->Prev += thing->Pos() - oldpos; thing->Sector = P_PointInSector(thing->Pos()); thing->PrevPortalGroup = thing->Sector->PortalGroup; thing->LinkToWorld(&ctx); From e70250425a876f26b3467350f1ac15b45cd7d0d0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 28 Feb 2018 13:15:04 +0100 Subject: [PATCH 23/27] - fixed: For two-sided midtextures the light lists were always taken from the sector referenced by the rendered sidedef, not the sector in which the line gets renderered. For polyobjects these two are not identical. --- src/gl/scene/gl_walls.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index 470cd9776..5db32de04 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -1060,8 +1060,8 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary, // Draw the stuff // // - if (realfront->e->XFloor.lightlist.Size()==0 || mDrawer->FixedColormap) split.PutWall(translucent); - else split.SplitWall(realfront, translucent); + if (front->e->XFloor.lightlist.Size()==0 || mDrawer->FixedColormap) split.PutWall(translucent); + else split.SplitWall(front, translucent); t=1; } @@ -1074,8 +1074,8 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary, // Draw the stuff without splitting // // - if (realfront->e->XFloor.lightlist.Size()==0 || mDrawer->FixedColormap) PutWall(translucent); - else SplitWall(realfront, translucent); + if (front->e->XFloor.lightlist.Size()==0 || mDrawer->FixedColormap) PutWall(translucent); + else SplitWall(front, translucent); } alpha=1.0f; } @@ -1437,7 +1437,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) sector_t * segback; #ifdef _DEBUG - if (seg->linedef->Index() == 1) + if (seg->linedef->Index() == 10) { int a = 0; } From 56df88c7929d6b241b1148a37030ea5a60470457 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 28 Feb 2018 14:27:22 +0200 Subject: [PATCH 24/27] Use 64-bit fixed point for node builder's vertex map https://forum.zdoom.org/viewtopic.php?t=59368 --- src/nodebuild.cpp | 4 ++-- src/nodebuild.h | 6 ++++-- src/nodebuild_utility.cpp | 12 ++++++------ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/nodebuild.cpp b/src/nodebuild.cpp index d4794c639..5b849687c 100644 --- a/src/nodebuild.cpp +++ b/src/nodebuild.cpp @@ -814,8 +814,8 @@ void FNodeBuilder::SplitSegs (uint32_t set, node_t &node, uint32_t splitseg, uin frac = InterceptVector (node, *seg); newvert.x = Vertices[seg->v1].x; newvert.y = Vertices[seg->v1].y; - newvert.x += fixed_t(frac * double(Vertices[seg->v2].x - newvert.x)); - newvert.y += fixed_t(frac * double(Vertices[seg->v2].y - newvert.y)); + newvert.x += fixed_t(frac * (double(Vertices[seg->v2].x) - newvert.x)); + newvert.y += fixed_t(frac * (double(Vertices[seg->v2].y) - newvert.y)); vertnum = VertexMap->SelectVertexClose (newvert); if (vertnum != (unsigned int)seg->v1 && vertnum != (unsigned int)seg->v2) diff --git a/src/nodebuild.h b/src/nodebuild.h index f66e64aa4..fd943cbbd 100644 --- a/src/nodebuild.h +++ b/src/nodebuild.h @@ -91,6 +91,8 @@ struct FSimpleVert fixed_t x, y; }; +typedef int64_t fixed64_t; + class FNodeBuilder { struct FPrivSeg @@ -167,14 +169,14 @@ class FNodeBuilder FNodeBuilder &MyBuilder; TArray *VertexGrid; - fixed_t MinX, MinY, MaxX, MaxY; + fixed64_t MinX, MinY, MaxX, MaxY; int BlocksWide, BlocksTall; enum { BLOCK_SHIFT = 8 + FRACBITS }; enum { BLOCK_SIZE = 1 << BLOCK_SHIFT }; int InsertVertex (FPrivVert &vert); - inline int GetBlock (fixed_t x, fixed_t y) + inline int GetBlock (fixed64_t x, fixed64_t y) { assert (x >= MinX); assert (y >= MinY); diff --git a/src/nodebuild_utility.cpp b/src/nodebuild_utility.cpp index 754e3519c..9dd3c7786 100644 --- a/src/nodebuild_utility.cpp +++ b/src/nodebuild_utility.cpp @@ -641,8 +641,8 @@ FNodeBuilder::FVertexMap::FVertexMap (FNodeBuilder &builder, MinY = miny; BlocksWide = int(((double(maxx) - minx + 1) + (BLOCK_SIZE - 1)) / BLOCK_SIZE); BlocksTall = int(((double(maxy) - miny + 1) + (BLOCK_SIZE - 1)) / BLOCK_SIZE); - MaxX = MinX + BlocksWide * BLOCK_SIZE - 1; - MaxY = MinY + BlocksTall * BLOCK_SIZE - 1; + MaxX = MinX + fixed64_t(BlocksWide) * BLOCK_SIZE - 1; + MaxY = MinY + fixed64_t(BlocksTall) * BLOCK_SIZE - 1; VertexGrid = new TArray[BlocksWide * BlocksTall]; } @@ -703,10 +703,10 @@ int FNodeBuilder::FVertexMap::InsertVertex (FNodeBuilder::FPrivVert &vert) // If a vertex is near a block boundary, then it will be inserted on // both sides of the boundary so that SelectVertexClose can find // it by checking in only one block. - fixed_t minx = MAX (MinX, vert.x - VERTEX_EPSILON); - fixed_t maxx = MIN (MaxX, vert.x + VERTEX_EPSILON); - fixed_t miny = MAX (MinY, vert.y - VERTEX_EPSILON); - fixed_t maxy = MIN (MaxY, vert.y + VERTEX_EPSILON); + fixed64_t minx = MAX (MinX, fixed64_t(vert.x) - VERTEX_EPSILON); + fixed64_t maxx = MIN (MaxX, fixed64_t(vert.x) + VERTEX_EPSILON); + fixed64_t miny = MAX (MinY, fixed64_t(vert.y) - VERTEX_EPSILON); + fixed64_t maxy = MIN (MaxY, fixed64_t(vert.y) + VERTEX_EPSILON); int blk[4] = { From 425f1408f7f542037b6821601a2d41171bccff12 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 28 Feb 2018 18:09:32 +0100 Subject: [PATCH 25/27] - fixed skip_super application fro ZScript. The order of processing is different here so when the property gets parsed there are no states to delete. To fix this the property just flags the class and lets the ZScript state compiler deal with this as needed. --- src/info.h | 3 ++- src/scripting/thingdef_properties.cpp | 3 ++- src/scripting/zscript/zcc_compile.cpp | 13 ++++++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/info.h b/src/info.h index 3e497d0f6..8bd188730 100644 --- a/src/info.h +++ b/src/info.h @@ -244,6 +244,7 @@ struct FActorInfo PClassActor *Replacee = nullptr; FState *OwnedStates = nullptr; int NumOwnedStates = 0; + bool SkipSuperSet = false; uint8_t GameFilter = GAME_Any; uint16_t SpawnID = 0; uint16_t ConversationID = 0; @@ -287,7 +288,7 @@ struct FActorInfo }; // This is now merely a wrapper that adds actor-specific functionality to PClass. -// No objects of this type will be created ever - its only use is to static_casr +// No objects of this type will be created ever - its only use is to static_cast // PClass to it. class PClassActor : public PClass { diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index c36058ca4..03ad9c1cc 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -540,7 +540,7 @@ DEFINE_PROPERTY(skip_super, 0, Actor) if (info->Size != actorclass->Size) { bag.ScriptPosition.Message(MSG_OPTERROR, - "'skip_super' is only allowed in subclasses of AActor with no additional fields and will be ignored in type %s.", info->TypeName.GetChars()); + "'skip_super' is only allowed in subclasses of Actor with no additional fields and will be ignored in type %s.", info->TypeName.GetChars()); return; } if (bag.StateSet) @@ -552,6 +552,7 @@ DEFINE_PROPERTY(skip_super, 0, Actor) *defaults = *GetDefault(); ResetBaggage (&bag, RUNTIME_CLASS(AActor)); + static_cast(bag.Info)->ActorInfo()->SkipSuperSet = true; // ZScript processes the states later so this property must be flagged for later handling. } //========================================================================== diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index ab8bef5f0..e4773f1c6 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -2872,7 +2872,18 @@ void ZCCCompiler::CompileStates() FString statename; // The state builder wants the label as one complete string, not separated into tokens. FStateDefinitions statedef; - statedef.MakeStateDefines(ValidateActor(c->ClassType()->ParentClass)); + + if (static_cast(c->ClassType())->ActorInfo()->SkipSuperSet) + { + // SKIP_SUPER'ed actors only get the base states from AActor. + statedef.MakeStateDefines(RUNTIME_CLASS(AActor)); + } + else + { + statedef.MakeStateDefines(ValidateActor(c->ClassType()->ParentClass)); + } + + int numframes = 0; for (auto s : c->States) From 3a3cd87ce021958fbe426f5fd01612950060aef1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 28 Feb 2018 18:26:25 +0100 Subject: [PATCH 26/27] - perform the stepping adjustment for FastProjectiles in 3D. Not checking the z-Axis means that they might pass through 3D floors without noticing at steep angles and very high speeds. --- wadsrc/static/zscript/shared/fastprojectile.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/zscript/shared/fastprojectile.txt b/wadsrc/static/zscript/shared/fastprojectile.txt index 1bed8cba2..c861a3f8f 100644 --- a/wadsrc/static/zscript/shared/fastprojectile.txt +++ b/wadsrc/static/zscript/shared/fastprojectile.txt @@ -66,7 +66,7 @@ class FastProjectile : Actor int count = 8; if (radius > 0) { - while ( abs(Vel.X) > radius * count || abs(Vel.Y) > radius * count) + while ( abs(Vel.X) >= radius * count || abs(Vel.Y) >= radius * count || abs(Vel.Z) >= height * count) { // we need to take smaller steps. count += count; From 6e8dbb590dffaf7654ee4db65daff73f007ece22 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 28 Feb 2018 20:15:44 +0100 Subject: [PATCH 27/27] - fixed: PowerMorph.EndEffect should not tinker around with morph duration. There was a clear attempt here to let the item keep control of the remaining morph time, but since the item would have gotten destroyed right afterward it just shot itself in the foot badly by doing so. Just leaving the remaining work to the main unmorphing check in the PlayerThink code by doing nothing will avoid the bad situation where a player gets stuck in its morphed form. --- wadsrc/static/zscript/inventory/powerups.txt | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/wadsrc/static/zscript/inventory/powerups.txt b/wadsrc/static/zscript/inventory/powerups.txt index 6fb35b067..5ef03d420 100644 --- a/wadsrc/static/zscript/inventory/powerups.txt +++ b/wadsrc/static/zscript/inventory/powerups.txt @@ -1931,22 +1931,6 @@ class PowerMorph : Powerup int savedMorphTics = MorphedPlayer.morphTics; MorphedPlayer.UndoPlayerMorph (MorphedPlayer, 0, !!(MorphedPlayer.MorphStyle & MRF_UNDOALWAYS)); - - // Abort if unmorph failed; in that case, - // set the usual retry timer and return. - if (MorphedPlayer != null && MorphedPlayer.morphTics) - { - // Transfer retry timeout - // to the powerup's timer. - EffectTics = MorphedPlayer.morphTics; - // Reload negative morph tics; - // use actual value; it may - // be in use for animation. - MorphedPlayer.morphTics = savedMorphTics; - // Try again some time later - return; - } - // Unmorph suceeded MorphedPlayer = null; }