diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index 676057321..a8dac6b54 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -270,6 +270,7 @@ bool DMenu::CallMenuEvent(int mkey, bool fromcontroller) void DMenu::Close () { + if (DMenu::CurrentMenu == nullptr) return; // double closing can happen in the save menu. assert(DMenu::CurrentMenu == this); DMenu::CurrentMenu = mParentMenu; Destroy(); diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index 40629bfcb..15e82a56c 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -1410,26 +1410,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_RadiusDamageSelf) return 0; } -//========================================================================== -// -// Execute a line special / script -// -//========================================================================== -DEFINE_ACTION_FUNCTION(AActor, A_CallSpecial) -{ - PARAM_SELF_PROLOGUE(AActor); - PARAM_INT (special); - PARAM_INT_DEF (arg1); - PARAM_INT_DEF (arg2); - PARAM_INT_DEF (arg3); - PARAM_INT_DEF (arg4); - PARAM_INT_DEF (arg5); - - bool res = !!P_ExecuteSpecial(special, NULL, self, false, arg1, arg2, arg3, arg4, arg5); - - ACTION_RETURN_BOOL(res); -} - //========================================================================== // // The ultimate code pointer: Fully customizable missiles! diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index e71cf2f79..6f44cedcd 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -3717,3 +3717,27 @@ int P_ExecuteSpecial(int num, } return 0; } + +//========================================================================== +// +// Execute a line special / script +// +//========================================================================== +DEFINE_ACTION_FUNCTION(FLevelLocals, ExecuteSpecial) +{ + PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals); + PARAM_INT(special); + PARAM_OBJECT(activator, AActor); + PARAM_POINTER(linedef, line_t); + PARAM_BOOL(lineside); + PARAM_INT_DEF(arg1); + PARAM_INT_DEF(arg2); + PARAM_INT_DEF(arg3); + PARAM_INT_DEF(arg4); + PARAM_INT_DEF(arg5); + + bool res = !!P_ExecuteSpecial(special, linedef, activator, lineside, arg1, arg2, arg3, arg4, arg5); + + ACTION_RETURN_BOOL(res); +} + diff --git a/src/p_trace.cpp b/src/p_trace.cpp index 3597535e5..818372e74 100644 --- a/src/p_trace.cpp +++ b/src/p_trace.cpp @@ -41,6 +41,7 @@ #include "r_defs.h" #include "p_spec.h" #include "g_levellocals.h" +#include "p_terrain.h" //========================================================================== // @@ -135,6 +136,13 @@ static void GetPortalTransition(DVector3 &pos, sector_t *&sec) } } +static bool isLiquid(F3DFloor *ff) +{ + if (ff->flags & FF_SWIMMABLE) return true; + auto terrain = ff->model->GetTerrain(ff->flags & FF_INVERTPLANES ? sector_t::floor : sector_t::ceiling); + return Terrains[terrain].IsLiquid && Terrains[terrain].Splash != -1; +} + //========================================================================== // // Trace entry point @@ -300,9 +308,9 @@ void FTraceInfo::Setup3DFloors() if (!(rover->flags&FF_EXISTS)) continue; - if (rover->flags&FF_SWIMMABLE && Results->Crossed3DWater == NULL) + if (Results->Crossed3DWater == NULL) { - if (Check3DFloorPlane(rover, false)) + if (Check3DFloorPlane(rover, false) && isLiquid(rover)) { // only consider if the plane is above the actual floor. if (rover->top.plane->ZatPoint(Results->HitPos) > bf) @@ -767,7 +775,7 @@ bool FTraceInfo::TraceTraverse (int ptflags) { for (auto rover : CurSector->e->XFloor.ffloors) { - if ((rover->flags & FF_EXISTS) && (rover->flags&FF_SWIMMABLE)) + if ((rover->flags & FF_EXISTS) && isLiquid(rover)) { if (Check3DFloorPlane(rover, false)) { diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index feb61807b..413cdc816 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -738,7 +738,11 @@ class Actor : Thinker native native void A_VileChase(); native void A_BossDeath(); native void A_Detonate(); - native bool A_CallSpecial(int special, int arg1=0, int arg2=0, int arg3=0, int arg4=0, int arg5=0); + bool A_CallSpecial(int special, int arg1=0, int arg2=0, int arg3=0, int arg4=0, int arg5=0) + { + return Level.ExecuteSpecial(special, self, null, false, arg1, arg2, arg3, arg4, arg5); + } + native void A_ActiveSound(); diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index bffee91f0..7b872f472 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -469,6 +469,7 @@ struct LevelLocals native native String GetUDMFString(int type, int index, Name key); native int GetUDMFInt(int type, int index, Name key); native double GetUDMFFloat(int type, int index, Name key); + native bool ExecuteSpecial(int special, Actor activator, line linedef, bool lineside, int arg1 = 0, int arg2 = 0, int arg3 = 0, int arg4 = 0, int arg5 = 0); } diff --git a/wadsrc/static/zscript/inventory/powerups.txt b/wadsrc/static/zscript/inventory/powerups.txt index d355a5e14..828113ac8 100644 --- a/wadsrc/static/zscript/inventory/powerups.txt +++ b/wadsrc/static/zscript/inventory/powerups.txt @@ -1767,7 +1767,7 @@ class PowerProtection : Powerup { if (passive && damage > 0) { - newdamage = max(1, ApplyDamageFactors(GetClass(), damageType, damage, damage / 4)); + newdamage = max(0, ApplyDamageFactors(GetClass(), damageType, damage, damage / 4)); if (Owner != null && newdamage < damage) Owner.A_PlaySound(ActiveSound, CHAN_AUTO, 1.0, false, ATTN_NONE); } } diff --git a/wadsrc/static/zscript/shared/movingcamera.txt b/wadsrc/static/zscript/shared/movingcamera.txt index 15fdd0836..c6af13b42 100644 --- a/wadsrc/static/zscript/shared/movingcamera.txt +++ b/wadsrc/static/zscript/shared/movingcamera.txt @@ -311,7 +311,7 @@ class PathFollower : Actor while ( (spec = InterpolationSpecial(iterator.Next ())) ) { - A_CallSpecial(spec.special, spec.args[0], spec.args[1], spec.args[2], spec.args[3], spec.args[4]); + Level.ExecuteSpecial(spec.special, null, null, false, spec.args[0], spec.args[1], spec.args[2], spec.args[3], spec.args[4]); } }