diff --git a/src/info.cpp b/src/info.cpp index 81912150b..84d8e26be 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -257,6 +257,7 @@ PClassActor::PClassActor() WoundHealth = 6; FastSpeed = -1.; RDFactor = 1.; + SelfDamageFactor = 1.; CameraHeight = INT_MIN; DropItems = NULL; @@ -317,6 +318,7 @@ void PClassActor::DeriveData(PClass *newclass) newa->WoundHealth = WoundHealth; newa->FastSpeed = FastSpeed; newa->RDFactor = RDFactor; + newa->SelfDamageFactor = SelfDamageFactor; newa->CameraHeight = CameraHeight; newa->HowlSound = HowlSound; newa->BloodType = BloodType; diff --git a/src/info.h b/src/info.h index 50db1e4b6..a9f79182f 100644 --- a/src/info.h +++ b/src/info.h @@ -299,6 +299,7 @@ public: int WoundHealth; // Health needed to enter wound state double FastSpeed; // speed in fast mode double RDFactor; // Radius damage factor + double SelfDamageFactor; double CameraHeight; // Height of camera when used as such FSoundID HowlSound; // Sound being played when electrocuted or poisoned FName BloodType; // Blood replacement type diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index dc4fff1a7..239366dcf 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -871,6 +871,25 @@ static void ParseOptionMenu(FScanner &sc) } +//============================================================================= +// +// +// +//============================================================================= + +static void ParseAddOptionMenu(FScanner &sc) +{ + sc.MustGetString(); + + DMenuDescriptor **pOld = MenuDescriptors.CheckKey(sc.String); + if (pOld == nullptr || *pOld == nullptr || !(*pOld)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor))) + { + sc.ScriptError("%s is not an option menu that can be extended", sc.String); + } + ParseOptionMenuBody(sc, (DOptionMenuDescriptor*)(*pOld)); +} + + //============================================================================= // // @@ -935,6 +954,10 @@ void M_ParseMenuDefs() { ParseOptionMenu(sc); } + else if (sc.Compare("ADDOPTIONMENU")) + { + ParseAddOptionMenu(sc); + } else if (sc.Compare("DEFAULTOPTIONMENU")) { ParseOptionMenuBody(sc, DefaultOptionMenuSettings); diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 38d9cd375..4c23c8123 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1020,6 +1020,11 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da } return 0; } + if (target == source && damage < TELEFRAG_DAMAGE) + { + damage = int(damage * target->GetClass()->SelfDamageFactor); + } + // [MC] Changed it to check rawdamage here for consistency, even though that doesn't actually do anything // different here. At any rate, invulnerable is being checked before type factoring, which is then being // checked by player cheats/invul/buddha followed by monster buddha. This is inconsistent. Don't let the diff --git a/src/p_map.cpp b/src/p_map.cpp index 9b3a257ec..70b18df7f 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -2281,9 +2281,9 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, } #endif } - if (!(thing->flags & MF_TELEPORT) && !(thing->flags3 & MF3_FLOORHUGGER)) + if (!(thing->flags & MF_TELEPORT) && (!(thing->flags3 & MF3_FLOORHUGGER) || thing->flags5 & MF5_NODROPOFF)) { - if ((thing->flags & MF_MISSILE) && !(thing->flags6 & MF6_STEPMISSILE) && tm.floorz > thing->Z()) + if ((thing->flags & MF_MISSILE) && !(thing->flags6 & MF6_STEPMISSILE) && tm.floorz > thing->Z() && !(thing->flags3 & MF3_FLOORHUGGER)) { // [RH] Don't let normal missiles climb steps goto pushline; } @@ -2772,13 +2772,13 @@ bool P_CheckMove(AActor *thing, const DVector2 &pos, int flags) if (thing->Top() > tm.ceilingz) return false; } - if (!(thing->flags & MF_TELEPORT) && !(thing->flags3 & MF3_FLOORHUGGER)) + if (!(thing->flags & MF_TELEPORT) && (!(thing->flags3 & MF3_FLOORHUGGER) || thing->flags5 & MF5_NODROPOFF)) { if (tm.floorz - newz > thing->MaxStepHeight) { // too big a step up return false; } - else if ((thing->flags & MF_MISSILE) && !(thing->flags6 & MF6_STEPMISSILE) && tm.floorz > newz) + else if ((thing->flags & MF_MISSILE) && !(thing->flags6 & MF6_STEPMISSILE) && tm.floorz > newz && !(thing->flags3 & MF3_FLOORHUGGER)) { // [RH] Don't let normal missiles climb steps return false; } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index d6da38961..f85f2c9eb 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -321,6 +321,7 @@ DEFINE_FIELD(PClassActor, GibHealth) DEFINE_FIELD(PClassActor, WoundHealth) DEFINE_FIELD(PClassActor, FastSpeed) DEFINE_FIELD(PClassActor, RDFactor) +DEFINE_FIELD(PClassActor, SelfDamageFactor) DEFINE_FIELD(PClassActor, CameraHeight) DEFINE_FIELD(PClassActor, HowlSound) DEFINE_FIELD(PClassActor, BloodType) @@ -2958,7 +2959,7 @@ void P_ZMovement (AActor *mo, double oldfloorz) mo->Vel.Z = 0; return; } - else if (mo->flags3 & MF3_FLOORHUGGER) + else if ((mo->flags3 & MF3_FLOORHUGGER) && !(mo->flags5 & MF5_NODROPOFF)) { // Floor huggers can go up steps return; } diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index 50b81310c..6537e2482 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -1430,6 +1430,16 @@ DEFINE_PROPERTY(radiusdamagefactor, F, Actor) static_cast(info)->RDFactor = i; } +//========================================================================== +// +//========================================================================== +DEFINE_PROPERTY(selfdamagefactor, F, Actor) +{ + PROP_DOUBLE_PARM(i, 0); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->SelfDamageFactor = i; +} + //========================================================================== // //==========================================================================