diff --git a/src/actor.h b/src/actor.h index 8e1b16739..b627bac66 100644 --- a/src/actor.h +++ b/src/actor.h @@ -638,6 +638,7 @@ public: // Like DoSpecialDamage, but called on the actor receiving the damage. virtual int TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FName damagetype); + int CallTakeSpecialDamage(AActor *inflictor, AActor *source, int damage, FName damagetype); // Centaurs and ettins squeal when electrocuted, poisoned, or "holy"-ed // Made a metadata property so no longer virtual diff --git a/src/g_strife/a_strifeitems.cpp b/src/g_strife/a_strifeitems.cpp index aa48d9839..b9f3f288e 100644 --- a/src/g_strife/a_strifeitems.cpp +++ b/src/g_strife/a_strifeitems.cpp @@ -21,26 +21,6 @@ IMPLEMENT_CLASS(ADegninOre, false, false) -DEFINE_ACTION_FUNCTION(AActor, A_RemoveForceField) -{ - PARAM_SELF_PROLOGUE(AActor); - - self->flags &= ~MF_SPECIAL; - - for (int i = 0; i < self->Sector->linecount; ++i) - { - line_t *line = self->Sector->lines[i]; - if (line->backsector != NULL && line->special == ForceField) - { - line->flags &= ~(ML_BLOCKING|ML_BLOCKEVERYTHING); - line->special = 0; - line->sidedef[0]->SetTexture(side_t::mid, FNullTextureID()); - line->sidedef[1]->SetTexture(side_t::mid, FNullTextureID()); - } - } - return 0; -} - bool ADegninOre::Use (bool pickup) { if (pickup) diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp index 20fe55de3..6537f180e 100644 --- a/src/g_strife/a_strifestuff.cpp +++ b/src/g_strife/a_strifestuff.cpp @@ -28,13 +28,6 @@ #include "a_strifeweapons.cpp" // Notes so I don't forget them: -// Strife does some extra stuff in A_Explode if a player caused the explosion. (probably NoiseAlert) -// See the instructions @ 21249. -// -// Strife's FLOATSPEED is 5 and not 4. -// -// In P_CheckMissileRange, mobjtypes 53,54,55,56,57,58 shift the distance right 4 bits (some, but not all the acolytes) -// mobjtypes 61,63,91 shift it right 1 bit // // When shooting missiles at something, if MF_SHADOW is set, the angle is adjusted with the formula: // angle += pr_spawnmissile.Random2() << 21 @@ -42,80 +35,3 @@ // angle += pr_spawnmissile.Random2() << 22 // Note that these numbers are different from those used by all the other Doom engine games. -static FRandom pr_gibtosser ("GibTosser"); - -// Force Field Guard -------------------------------------------------------- - -void A_RemoveForceField (AActor *); - -class AForceFieldGuard : public AActor -{ - DECLARE_CLASS (AForceFieldGuard, AActor) -public: - int TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FName damagetype); -}; - -IMPLEMENT_CLASS(AForceFieldGuard, false, false) - -int AForceFieldGuard::TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FName damagetype) -{ - if (inflictor == NULL || !inflictor->IsKindOf (RUNTIME_CLASS(ADegninOre))) - { - return -1; - } - return health; -} - -// Power Coupling ----------------------------------------------------------- - -class APowerCoupling : public AActor -{ - DECLARE_CLASS (APowerCoupling, AActor) -public: - void Die (AActor *source, AActor *inflictor, int dmgflags); -}; - -IMPLEMENT_CLASS(APowerCoupling, false, false) - -void APowerCoupling::Die (AActor *source, AActor *inflictor, int dmgflags) -{ - Super::Die (source, inflictor, dmgflags); - - int i; - - for (i = 0; i < MAXPLAYERS; ++i) - if (playeringame[i] && players[i].health > 0) - break; - - if (i == MAXPLAYERS) - return; - - // [RH] In case the player broke it with the dagger, alert the guards now. - if (LastHeard != source) - { - P_NoiseAlert (source, this); - } - EV_DoDoor (DDoor::doorClose, NULL, players[i].mo, 225, 2., 0, 0, 0); - EV_DoFloor (DFloor::floorLowerToHighest, NULL, 44, 1., 0., -1, 0, false); - players[i].mo->GiveInventoryType (QuestItemClasses[5]); - S_Sound (CHAN_VOICE, "svox/voc13", 1, ATTN_NORM); - players[i].SetLogNumber (13); - P_DropItem (this, PClass::FindActor("BrokenPowerCoupling"), -1, 256); - Destroy (); -} - -// Gibs for things that bleed ----------------------------------------------- - -class AMeat : public AActor -{ - DECLARE_CLASS (AMeat, AActor) -public: - void BeginPlay () - { - // Strife used mod 19, but there are 20 states. Hmm. - SetState (SpawnState + pr_gibtosser() % 20); - } -}; - -IMPLEMENT_CLASS(AMeat, false, false) - diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 4d9393152..6a59986c0 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -3224,6 +3224,15 @@ AInventory *P_DropItem (AActor *source, PClassActor *type, int dropamount, int c return NULL; } +DEFINE_ACTION_FUNCTION(AActor, DoDropItem) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_CLASS(cls, AActor); + PARAM_INT(amt); + PARAM_INT(chance); + ACTION_RETURN_OBJECT(P_DropItem(self, cls, amt, chance)); +} + //============================================================================ // // P_TossItem diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 41994c38e..a5fcc2dda 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1121,7 +1121,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, if (damage >= 0) { - damage = target->TakeSpecialDamage(inflictor, source, damage, mod); + damage = target->CallTakeSpecialDamage(inflictor, source, damage, mod); } // '<0' is handled below. This only handles the case where damage gets reduced to 0. diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index e41912e23..1f318f559 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -347,7 +347,7 @@ FUNC(LS_Floor_LowerToHighest) } FUNC(LS_Floor_LowerToHighestEE) -// Floor_LowerToHighest (tag, speed, change) +// Floor_LowerToHighestEE (tag, speed, change) { return EV_DoFloor (DFloor::floorLowerToHighest, ln, arg0, SPEED(arg1), 0, -1, CHANGE(arg2), false); } @@ -3152,17 +3152,7 @@ FUNC(LS_ClearForceField) sector_t *sec = §ors[secnum]; rtn = true; - for (int i = 0; i < sec->linecount; ++i) - { - line_t *line = sec->lines[i]; - if (line->backsector != NULL && line->special == ForceField) - { - line->flags &= ~(ML_BLOCKING|ML_BLOCKEVERYTHING); - line->special = 0; - line->sidedef[0]->SetTexture(side_t::mid, FNullTextureID()); - line->sidedef[1]->SetTexture(side_t::mid, FNullTextureID()); - } - } + sec->RemoveForceField(); } return rtn; } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index c85b8bbbc..7257eff95 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -7018,6 +7018,32 @@ int AActor::TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FN return (death == NULL) ? -1 : damage; } +DEFINE_ACTION_FUNCTION(AActor, TakeSpecialDamage) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_OBJECT(inflictor, AActor); + PARAM_OBJECT(source, AActor); + PARAM_INT(damage); + PARAM_NAME(damagetype); + ACTION_RETURN_INT(self->TakeSpecialDamage(inflictor, source, damage, damagetype)); +} + +int AActor::CallTakeSpecialDamage(AActor *inflictor, AActor *source, int damage, FName damagetype) +{ + IFVIRTUAL(AActor, TakeSpecialDamage) + { + VMValue params[5] = { (DObject*)this, inflictor, source, damage, damagetype.GetIndex() }; + VMReturn ret; + VMFrameStack stack; + int retval; + ret.IntAt(&retval); + stack.Call(func, params, 5, &ret, 1, nullptr); + return retval; + } + else return TakeSpecialDamage(inflictor, source, damage, damagetype); + +} + void AActor::Crash() { // [RC] Weird that this forces the Crash state regardless of flag. diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 585c60f4b..e6302199b 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -22,6 +22,7 @@ //----------------------------------------------------------------------------- #include "p_spec.h" +#include "p_lnspec.h" #include "c_cvars.h" #include "doomstat.h" #include "g_level.h" @@ -1075,6 +1076,33 @@ double sector_t::NextLowestFloorAt(double x, double y, double z, int flags, doub } } + //=========================================================================== + // + // + // + //=========================================================================== + + void sector_t::RemoveForceField() + { + for (int i = 0; i < linecount; ++i) + { + line_t *line = lines[i]; + if (line->backsector != NULL && line->special == ForceField) + { + line->flags &= ~(ML_BLOCKING | ML_BLOCKEVERYTHING); + line->special = 0; + line->sidedef[0]->SetTexture(side_t::mid, FNullTextureID()); + line->sidedef[1]->SetTexture(side_t::mid, FNullTextureID()); + } + } + } + + DEFINE_ACTION_FUNCTION(_Sector, RemoveForceField) + { + PARAM_SELF_STRUCT_PROLOGUE(sector_t); + self->RemoveForceField(); + return 0; + } //=========================================================================== // // diff --git a/src/p_spec.cpp b/src/p_spec.cpp index c9a8294b5..eb6b9bea7 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -1591,3 +1591,4 @@ void sector_t::AdjustFloorClip () const } } } + diff --git a/src/r_defs.h b/src/r_defs.h index 9c2a822f2..a7de16c59 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -625,6 +625,7 @@ public: sector_t *NextSpecialSector (int type, sector_t *prev) const; // [RH] double FindLowestCeilingPoint(vertex_t **v) const; double FindHighestFloorPoint(vertex_t **v) const; + void RemoveForceField(); void AdjustFloorClip () const; void SetColor(int r, int g, int b, int desat); diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 7dbb5ee55..c5052ab79 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -264,6 +264,7 @@ class Actor : Thinker native virtual native void Activate(Actor activator); virtual native void Deactivate(Actor activator); virtual native int DoSpecialDamage (Actor target, int damage, Name damagetype); + virtual native int TakeSpecialDamage (Actor inflictor, Actor source, int damage, Name damagetype); virtual native void Die(Actor source, Actor inflictor, int dmgflags = 0); virtual native bool Slam(Actor victim); virtual native bool UseInventory(Inventory item); @@ -290,6 +291,7 @@ class Actor : Thinker native native void NoiseAlert(Actor target, bool splash = false, double maxdist = 0); native void ClearBounce(); native TerrainDef GetFloorTerrain(); + native Inventory DoDropItem(Class type, int dropamount, int chance); native void ExplodeMissile(line lin = null, Actor target = null); native void RestoreDamage(); @@ -691,7 +693,6 @@ class Actor : Thinker native native bool A_SelectWeapon(class whichweapon, int flags = 0); native void A_ClassBossHealth(); native void A_RocketInFlight(); - native void A_RemoveForcefield(); native void A_SetAngle(double angle = 0, int flags = 0, int ptr = AAPTR_DEFAULT); native void A_SetPitch(double pitch, int flags = 0, int ptr = AAPTR_DEFAULT); native void A_SetRoll(double roll, int flags = 0, int ptr = AAPTR_DEFAULT); diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 0f9c4f23d..b0abc73ec 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -247,6 +247,7 @@ struct Sector native native double, Sector, F3DFloor NextHighestCeilingAt(double x, double y, double bottomz, double topz, int flags = 0); + native void RemoveForceField(); } struct Wads diff --git a/wadsrc/static/zscript/strife/crusader.txt b/wadsrc/static/zscript/strife/crusader.txt index 834464e06..ce2ba6ef8 100644 --- a/wadsrc/static/zscript/strife/crusader.txt +++ b/wadsrc/static/zscript/strife/crusader.txt @@ -52,11 +52,11 @@ class Crusader : Actor ROB2 G 3 A_Scream; ROB2 H 5 A_TossGib; ROB2 I 4 Bright A_TossGib; - ROB2 J 4 Bright A_Explode(64,64,1,1); + ROB2 J 4 Bright A_Explode(64, 64, alert:true); ROB2 K 4 Bright A_Fall; - ROB2 L 4 A_Explode(64,64,1,1); + ROB2 L 4 A_Explode(64, 64, alert:true); ROB2 MN 4 A_TossGib; - ROB2 O 4 A_Explode(64,64,1,1); + ROB2 O 4 A_Explode(64, 64, alert:true); ROB2 P -1 A_CrusaderDeath; Stop; } diff --git a/wadsrc/static/zscript/strife/inquisitor.txt b/wadsrc/static/zscript/strife/inquisitor.txt index ef73ade1e..6d3c5bc7f 100644 --- a/wadsrc/static/zscript/strife/inquisitor.txt +++ b/wadsrc/static/zscript/strife/inquisitor.txt @@ -58,16 +58,16 @@ class Inquisitor : Actor ROB3 L 4 A_TossGib; ROB3 M 4 A_Scream; ROB3 N 4 A_TossGib; - ROB3 O 4 Bright A_Explode(128,128,1,1); + ROB3 O 4 Bright A_Explode(128, 128, alert:true); ROB3 P 4 Bright A_TossGib; ROB3 Q 4 Bright A_NoBlocking; ROB3 RSTUV 4 A_TossGib; - ROB3 W 4 Bright A_Explode(128,128,1,1); + ROB3 W 4 Bright A_Explode(128, 128, alert:true); ROB3 XY 4 Bright A_TossGib; ROB3 Z 4 A_TossGib; ROB3 [ 4 A_TossGib; ROB3 \ 3 A_TossGib; - ROB3 ] 3 Bright A_Explode(128,128,1,1); + ROB3 ] 3 Bright A_Explode(128, 128, alert:true); RBB3 A 3 Bright A_TossArm; RBB3 B 3 Bright A_TossGib; RBB3 CD 3 A_TossGib; @@ -206,7 +206,7 @@ class InquisitorShot : Actor Loop; Death: BNG2 A 0 Bright A_SetRenderStyle(1, STYLE_Normal); - BNG2 A 4 Bright A_Explode(192, 192, 1, 1); + BNG2 A 4 Bright A_Explode(192, 192, alert:true); BNG2 B 4 Bright; BNG2 C 4 Bright; BNG2 D 4 Bright; diff --git a/wadsrc/static/zscript/strife/reaver.txt b/wadsrc/static/zscript/strife/reaver.txt index d1c206b73..6ebcd47e2 100644 --- a/wadsrc/static/zscript/strife/reaver.txt +++ b/wadsrc/static/zscript/strife/reaver.txt @@ -49,7 +49,7 @@ class Reaver : Actor ROB1 L 5; ROB1 M 5 A_NoBlocking; ROB1 NOP 5; - ROB1 Q 6 A_Explode(32,32,1,1); + ROB1 Q 6 A_Explode(32, 32, alert:true); ROB1 R -1; Stop; XDeath: diff --git a/wadsrc/static/zscript/strife/strifebishop.txt b/wadsrc/static/zscript/strife/strifebishop.txt index 98b09ecee..b7de186a2 100644 --- a/wadsrc/static/zscript/strife/strifebishop.txt +++ b/wadsrc/static/zscript/strife/strifebishop.txt @@ -47,7 +47,7 @@ class StrifeBishop : Actor MLDR G 3 Bright; MLDR H 5 Bright A_Scream; MLDR I 4 Bright A_TossGib; - MLDR J 4 Bright A_Explode(64,64,1,1); + MLDR J 4 Bright A_Explode(64, 64, alert:true); MLDR KL 3 Bright; MLDR M 4 Bright A_NoBlocking; MLDR N 4 Bright; @@ -88,8 +88,8 @@ class BishopMissile : Actor MISS B 3 Bright A_Tracer2; Loop; Death: - SMIS A 0 Bright A_SetTranslucent(1,1); - SMIS A 5 Bright A_Explode(64,64,1,1); + SMIS A 0 Bright A_SetRenderStyle(1, STYLE_Normal); + SMIS A 5 Bright A_Explode(64, 64, alert:true); SMIS B 5 Bright; SMIS C 4 Bright; SMIS DEFG 2 Bright; diff --git a/wadsrc/static/zscript/strife/strifefunctions.txt b/wadsrc/static/zscript/strife/strifefunctions.txt index ed7db24d3..febb2fdcb 100644 --- a/wadsrc/static/zscript/strife/strifefunctions.txt +++ b/wadsrc/static/zscript/strife/strifefunctions.txt @@ -117,4 +117,9 @@ extend class Actor A_Explode(64, 64, XF_NOSPLASH, damagetype: 'Fire'); } + void A_RemoveForceField() + { + bSpecial = false; + CurSector.RemoveForceField(); + } } diff --git a/wadsrc/static/zscript/strife/strifeitems.txt b/wadsrc/static/zscript/strife/strifeitems.txt index cfc939413..4d8e3d5e4 100644 --- a/wadsrc/static/zscript/strife/strifeitems.txt +++ b/wadsrc/static/zscript/strife/strifeitems.txt @@ -415,9 +415,9 @@ class DegninOre : Inventory native Stop; Death: XPRK A 1 A_RemoveForceField; - BNG3 A 0 A_SetTranslucent(1,1); + BNG3 A 0 A_SetRenderStyle(1, STYLE_Normal); BNG3 A 0 A_Scream; - BNG3 A 3 Bright A_Explode(192,192,1,1); + BNG3 A 3 Bright A_Explode(192, 192, alert:true); BNG3 BCDEFGH 3 Bright; Stop; } diff --git a/wadsrc/static/zscript/strife/strifestuff.txt b/wadsrc/static/zscript/strife/strifestuff.txt index 38a27889f..12502ad0d 100644 --- a/wadsrc/static/zscript/strife/strifestuff.txt +++ b/wadsrc/static/zscript/strife/strifestuff.txt @@ -192,7 +192,7 @@ class ExplosiveBarrel2 : Actor BART B 2 Bright A_Scream; BART CD 2 Bright; BART E 2 Bright A_NoBlocking; - BART F 2 Bright A_Explode(64, 64, 1, 1); + BART F 2 Bright A_Explode(64, 64, alert:true); BART GHIJ 2 Bright; BART K 3 Bright; BART L -1; @@ -1726,7 +1726,7 @@ class TargetPractice : Actor // Force Field Guard -------------------------------------------------------- -class ForceFieldGuard : Actor native +class ForceFieldGuard : Actor { Default { @@ -1748,6 +1748,16 @@ class ForceFieldGuard : Actor native TNT1 A 1 A_RemoveForceField; Stop; } + + override int TakeSpecialDamage (Actor inflictor, Actor source, int damage, Name damagetype) + { + if (inflictor == NULL || !(inflictor is "DegninOre")) + { + return -1; + } + return health; + } + } // Kneeling Guy ------------------------------------------------------------- @@ -1800,7 +1810,7 @@ class KneelingGuy : Actor // Power Coupling ----------------------------------------------------------- -class PowerCoupling : Actor native +class PowerCoupling : Actor { Default { @@ -1821,11 +1831,39 @@ class PowerCoupling : Actor native COUP AB 5; Loop; } + + override void Die (Actor source, Actor inflictor, int dmgflags) + { + Super.Die (source, inflictor, dmgflags); + + int i; + + for (i = 0; i < MAXPLAYERS; ++i) + if (playeringame[i] && players[i].health > 0) + break; + + if (i == MAXPLAYERS) + return; + + // [RH] In case the player broke it with the dagger, alert the guards now. + if (LastHeard != source) + { + NoiseAlert (source); + } + Door_Close(225, 16); + Floor_LowerToHighestEE(44, 8); + players[i].mo.GiveInventoryType ("QuestItem6"); + S_Sound ("svox/voc13", CHAN_VOICE); + players[i].SetLogNumber (13); + DoDropItem ("BrokenPowerCoupling", -1, 256); + Destroy (); + } + } // Gibs for things that bleed ----------------------------------------------- -class Meat : Actor native +class Meat : Actor { Default { @@ -1875,6 +1913,13 @@ class Meat : Actor native MEAT T 700; Stop; } + + override void BeginPlay () + { + // Strife used mod 19, but there are 20 states. Hmm. + SetState (SpawnState + random[GibTosser]() % 20); + } + } // Gibs for things that don't bleed ----------------------------------------- diff --git a/wadsrc/static/zscript/strife/strifeweapons.txt b/wadsrc/static/zscript/strife/strifeweapons.txt index 968e4c4c5..0180ea445 100644 --- a/wadsrc/static/zscript/strife/strifeweapons.txt +++ b/wadsrc/static/zscript/strife/strifeweapons.txt @@ -418,8 +418,8 @@ class MiniMissile : Actor MICR A 6 Bright A_RocketInFlight; Loop; Death: - SMIS A 0 Bright A_SetTranslucent(1,1); - SMIS A 5 Bright A_Explode(64,64,1,1); + SMIS A 0 Bright A_SetRenderStyle(1, STYLE_Normal); + SMIS A 5 Bright A_Explode(64, 64, alert:true); SMIS B 5 Bright; SMIS C 4 Bright; SMIS DEFG 2 Bright; @@ -715,8 +715,8 @@ class HEGrenade : Actor Loop; Death: BNG4 A 0 Bright A_NoGravity; - BNG4 A 0 Bright A_SetTranslucent(1,1); - BNG4 A 2 Bright A_Explode(192,192,1,1); + BNG4 A 0 Bright A_SetRenderStyle(1, STYLE_Normal); + BNG4 A 2 Bright A_Explode(192, 192, alert:true); BNG4 BCDEFGHIJKLMN 3 Bright; Stop; }