diff --git a/src/d_main.cpp b/src/d_main.cpp index 06a772066..29cc82a16 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1439,6 +1439,10 @@ void ParseCVarInfo() { cvarflags |= CVAR_CHEAT; } + else if (stricmp(sc.String, "latch") == 0) + { + cvarflags |= CVAR_LATCH; + } else { sc.ScriptError("Unknown cvar attribute '%s'", sc.String); diff --git a/src/g_level.cpp b/src/g_level.cpp index d5044942e..701d35b53 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -128,7 +128,7 @@ int starttime; extern FString BackupSaveName; bool savegamerestore; -int finishstate; +int finishstate = FINISH_NoHub; extern int mousex, mousey; extern bool sendpause, sendsave, sendturn180, SendLand; @@ -851,6 +851,8 @@ void G_DoCompleted (void) level.maptime = 0; } + finishstate = mode; + if (!deathmatch && ((level.flags & LEVEL_NOINTERMISSION) || ((nextcluster == thiscluster) && (thiscluster->flags & CLUSTER_HUB) && !(thiscluster->flags & CLUSTER_ALLOWINTERMISSION)))) @@ -860,7 +862,6 @@ void G_DoCompleted (void) } gamestate = GS_INTERMISSION; - finishstate = mode; viewactive = false; automapactive = false; @@ -1038,12 +1039,20 @@ void G_DoLoadLevel (int position, bool autosave) { players[ii].camera = players[ii].mo; } - if (!savegamerestore) + + if (savegamerestore) { - E_PlayerEntered(ii, finishstate == FINISH_SameHub); + continue; + } + + const bool fromSnapshot = level.FromSnapshot; + E_PlayerEntered(ii, fromSnapshot && finishstate == FINISH_SameHub); + + if (fromSnapshot) + { + // ENTER scripts are being handled when the player gets spawned, this cannot be changed due to its effect on voodoo dolls. + FBehavior::StaticStartTypedScripts(SCRIPT_Return, players[ii].mo, true); } - // ENTER scripts are being handled when the player gets spawned, this cannot be changed due to its effect on voodoo dolls. - if (level.FromSnapshot && !savegamerestore) FBehavior::StaticStartTypedScripts(SCRIPT_Return, players[ii].mo, true); } } diff --git a/src/s_sound.cpp b/src/s_sound.cpp index ea12fe97e..fede842b1 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -1761,6 +1761,12 @@ void S_RelinkSound (AActor *from, AActor *to) bool S_ChangeSoundVolume(AActor *actor, int channel, float volume) { + // don't let volume get out of bounds + if (volume < 0.0) + volume = 0.0; + else if (volume > 1.0) + volume = 1.0; + for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan) { if (chan->SourceType == SOURCE_Actor && diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index 540b61a36..c746c536d 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -1225,6 +1225,15 @@ DEFINE_ACTION_FUNCTION(FStringStruct, Truncate) return 0; } +DEFINE_ACTION_FUNCTION(FStringStruct, Remove) +{ + PARAM_SELF_STRUCT_PROLOGUE(FString); + PARAM_UINT(index); + PARAM_UINT(remlen); + self->Remove(index, remlen); + return 0; +} + // CharAt and CharCodeAt is how JS does it, and JS is similar here in that it doesn't have char type as int. DEFINE_ACTION_FUNCTION(FStringStruct, CharAt) { diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index ee676b051..f76ffebf6 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -345,6 +345,7 @@ F481922F4881F74760F3C0437FD5EDD0 // map03 8B2AC8D4DB4A49A5DCCBB067E04434D6 // The Hell Factory Hub One, map04 65A1EB4C87386F290816660A52932FF1 // Master Levels, garrison.wad 3DEE4EFEFAF3260C800A30734F54CE75 // Hellbound, map14 +5FAA25F5A6AAB3409CAE0AF87F910341 // DOOM.wad e1m6 { rebuildnodes } diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 9cba0cb09..89dd0ab7d 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -684,6 +684,7 @@ struct StringStruct native native String Left(int len) const; native String Mid(int pos = 0, int len = 2147483647) const; native void Truncate(int newlen); + native void Remove(int index, int remlen); native String CharAt(int pos) const; native int CharCodeAt(int pos) const; native String Filter();