From 85a84b5e94513504be78cc50a6a68cb97ecec1f9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 13 Jan 2017 00:35:56 +0100 Subject: [PATCH] - scriptified FastProjectile. --- src/CMakeLists.txt | 1 - src/b_bot.h | 4 +- src/g_inventory/a_ammo.h | 2 +- src/g_inventory/a_pickups.h | 2 +- src/g_inventory/a_weaponpiece.h | 4 +- src/g_inventory/a_weapons.h | 2 +- src/g_shared/a_fastprojectile.cpp | 164 ------------------ src/g_shared/a_sharedglobal.h | 8 - src/p_mobj.cpp | 33 ++++ src/scripting/thingdef_data.cpp | 12 +- wadsrc/static/zscript/actor.txt | 9 +- .../static/zscript/shared/fastprojectile.txt | 145 +++++++++++++++- 12 files changed, 200 insertions(+), 186 deletions(-) delete mode 100644 src/g_shared/a_fastprojectile.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 14b11731a..70e4715b1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1159,7 +1159,6 @@ set (PCH_SOURCES g_strife/strife_sbar.cpp g_shared/a_action.cpp g_shared/a_decals.cpp - g_shared/a_fastprojectile.cpp g_shared/a_flashfader.cpp g_shared/a_fountain.cpp g_shared/a_lightning.cpp diff --git a/src/b_bot.h b/src/b_bot.h index 5dfbb7e63..58a9b7640 100644 --- a/src/b_bot.h +++ b/src/b_bot.h @@ -110,8 +110,8 @@ public: bool IsDangerous (sector_t *sec); TArray getspawned; //Array of bots (their names) which should be spawned when starting a game. - BYTE freeze:1; //Game in freeze mode. - BYTE changefreeze:1; //Game wants to change freeze mode. + BYTE freeze; //Game in freeze mode. + BYTE changefreeze; //Game wants to change freeze mode. int botnum; botinfo_t *botinfo; int spawn_tries; diff --git a/src/g_inventory/a_ammo.h b/src/g_inventory/a_ammo.h index d74f1405a..fbe96e4bc 100644 --- a/src/g_inventory/a_ammo.h +++ b/src/g_inventory/a_ammo.h @@ -3,7 +3,7 @@ class AAmmo : public AInventory { - DECLARE_CLASS(AAmmo, AInventory) + DECLARE_CLASS (AAmmo, AInventory) public: virtual void Serialize(FSerializer &arc) override; diff --git a/src/g_inventory/a_pickups.h b/src/g_inventory/a_pickups.h index db61e3a22..894849ef2 100644 --- a/src/g_inventory/a_pickups.h +++ b/src/g_inventory/a_pickups.h @@ -182,7 +182,7 @@ private: class AStateProvider : public AInventory { - DECLARE_CLASS(AStateProvider, AInventory) + DECLARE_CLASS (AStateProvider, AInventory) }; // CustomInventory: Supports the Use, Pickup, and Drop states from 96x diff --git a/src/g_inventory/a_weaponpiece.h b/src/g_inventory/a_weaponpiece.h index a8c6a2e76..ca5ed6a06 100644 --- a/src/g_inventory/a_weaponpiece.h +++ b/src/g_inventory/a_weaponpiece.h @@ -4,7 +4,7 @@ class AWeaponPiece : public AInventory { - DECLARE_CLASS(AWeaponPiece, AInventory) + DECLARE_CLASS (AWeaponPiece, AInventory) HAS_OBJECT_POINTERS protected: bool PrivateShouldStay (); @@ -26,7 +26,7 @@ public: // [BL] Needs to be available for SBarInfo to check weaponpieces class AWeaponHolder : public AInventory { - DECLARE_CLASS(AWeaponHolder, AInventory) + DECLARE_CLASS (AWeaponHolder, AInventory) public: int PieceMask; diff --git a/src/g_inventory/a_weapons.h b/src/g_inventory/a_weapons.h index efabf1fcf..564c0df02 100644 --- a/src/g_inventory/a_weapons.h +++ b/src/g_inventory/a_weapons.h @@ -221,7 +221,7 @@ enum class AWeaponGiver : public AWeapon { - DECLARE_CLASS(AWeaponGiver, AWeapon) + DECLARE_CLASS (AWeaponGiver, AWeapon) public: virtual bool TryPickup(AActor *&toucher) override; diff --git a/src/g_shared/a_fastprojectile.cpp b/src/g_shared/a_fastprojectile.cpp deleted file mode 100644 index 3bfaf8d94..000000000 --- a/src/g_shared/a_fastprojectile.cpp +++ /dev/null @@ -1,164 +0,0 @@ - -#include "a_sharedglobal.h" -#include "p_local.h" -#include "g_level.h" -#include "r_sky.h" -#include "p_lnspec.h" -#include "b_bot.h" -#include "p_checkposition.h" -#include "virtual.h" -#include "g_levellocals.h" - -IMPLEMENT_CLASS(AFastProjectile, false, false) - - -//---------------------------------------------------------------------------- -// -// AFastProjectile :: Tick -// -// Thinker for the ultra-fast projectiles used by Heretic and Hexen -// -//---------------------------------------------------------------------------- - -void AFastProjectile::Tick () -{ - int i; - DVector3 frac; - int changexy; - - ClearInterpolation(); - double oldz = Z(); - - if (!(flags5 & MF5_NOTIMEFREEZE)) - { - //Added by MC: Freeze mode. - if (bglobal.freeze || level.flags2 & LEVEL2_FROZEN) - { - return; - } - } - - - // [RH] Ripping is a little different than it was in Hexen - FCheckPosition tm(!!(flags2 & MF2_RIP)); - - int count = 8; - if (radius > 0) - { - while ( fabs(Vel.X) > radius * count || fabs(Vel.Y) > radius * count) - { - // we need to take smaller steps. - count += count; - } - } - - // Handle movement - if (!Vel.isZero() || (Z() != floorz)) - { - // force some lateral movement so that collision detection works as intended. - if ((flags & MF_MISSILE) && Vel.X == 0 && Vel.Y == 0 && !IsZeroDamage()) - { - Vel.X = MinVel; - } - - frac = Vel / count; - changexy = frac.X != 0 || frac.Y != 0; - int ripcount = count / 8; - for (i = 0; i < count; i++) - { - if (changexy) - { - if (--ripcount <= 0) - { - tm.LastRipped.Clear(); // [RH] Do rip damage each step, like Hexen - } - - if (!P_TryMove (this, Pos() + frac, true, NULL, tm)) - { // Blocked move - if (!(flags3 & MF3_SKYEXPLODE)) - { - if (tm.ceilingline && - tm.ceilingline->backsector && - tm.ceilingline->backsector->GetTexture(sector_t::ceiling) == skyflatnum && - Z() >= tm.ceilingline->backsector->ceilingplane.ZatPoint(PosRelative(tm.ceilingline))) - { - // Hack to prevent missiles exploding against the sky. - // Does not handle sky floors. - Destroy (); - return; - } - // [RH] Don't explode on horizon lines. - if (BlockingLine != NULL && BlockingLine->special == Line_Horizon) - { - Destroy (); - return; - } - } - - P_ExplodeMissile (this, BlockingLine, BlockingMobj); - return; - } - } - AddZ(frac.Z); - UpdateWaterLevel (); - oldz = Z(); - if (oldz <= floorz) - { // Hit the floor - - if (floorpic == skyflatnum && !(flags3 & MF3_SKYEXPLODE)) - { - // [RH] Just remove the missile without exploding it - // if this is a sky floor. - Destroy (); - return; - } - - SetZ(floorz); - P_HitFloor (this); - P_ExplodeMissile (this, NULL, NULL); - return; - } - if (Top() > ceilingz) - { // Hit the ceiling - - if (ceilingpic == skyflatnum && !(flags3 & MF3_SKYEXPLODE)) - { - Destroy (); - return; - } - - SetZ(ceilingz - Height); - P_ExplodeMissile (this, NULL, NULL); - return; - } - if (!frac.isZero() && ripcount <= 0) - { - ripcount = count >> 3; - - // call the scripted 'Effect' method. - IFVIRTUAL(AFastProjectile, Effect) - { - // Without the type cast this picks the 'void *' assignment... - VMValue params[1] = { (DObject*)this }; - GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr); - } - } - } - } - if (!CheckNoDelay()) - return; // freed itself - // Advance the state - if (tics != -1) - { - if (tics > 0) tics--; - while (!tics) - { - if (!SetState (state->GetNextState ())) - { // mobj was removed - return; - } - } - } -} - - diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index 96dbb1531..93e0c7e0e 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -215,12 +215,4 @@ public: ActorFlags FlagsSave; }; -class AFastProjectile : public AActor -{ - DECLARE_CLASS(AFastProjectile, AActor) -public: - void Tick (); -}; - - #endif //__A_SHAREDGLOBAL_H__ diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 54dbca780..4af97bbee 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4333,6 +4333,12 @@ bool AActor::CheckNoDelay() return true; } +DEFINE_ACTION_FUNCTION(AActor, CheckNoDelay) +{ + PARAM_SELF_PROLOGUE(AActor); + ACTION_RETURN_BOOL(self->CheckNoDelay()); +} + //========================================================================== // // AActor :: CheckSectorTransition @@ -4486,6 +4492,12 @@ bool AActor::UpdateWaterLevel (bool dosplash) return false; // we did the splash ourselves } +DEFINE_ACTION_FUNCTION(AActor, UpdateWaterLevel) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_BOOL_DEF(splash); + ACTION_RETURN_BOOL(self->UpdateWaterLevel(splash)); +} //========================================================================== // @@ -7821,6 +7833,13 @@ DEFINE_ACTION_FUNCTION(AActor, Vec3Offset) ACTION_RETURN_VEC3(self->Vec3Offset(x, y, z, absolute)); } +DEFINE_ACTION_FUNCTION(AActor, PosRelative) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_POINTER(sec, sector_t); + ACTION_RETURN_VEC3(self->PosRelative(sec)); +} + DEFINE_ACTION_FUNCTION(AActor, RestoreDamage) { PARAM_SELF_PROLOGUE(AActor); @@ -7861,6 +7880,19 @@ DEFINE_ACTION_FUNCTION(AActor, CountsAsKill) ACTION_RETURN_FLOAT(self->CountsAsKill()); } +DEFINE_ACTION_FUNCTION(AActor, IsZeroDamage) +{ + PARAM_SELF_PROLOGUE(AActor); + ACTION_RETURN_BOOL(self->IsZeroDamage()); +} + +DEFINE_ACTION_FUNCTION(AActor, ClearInterpolation) +{ + PARAM_SELF_PROLOGUE(AActor); + self->ClearInterpolation(); + return 0; +} + DEFINE_ACTION_FUNCTION(AActor, ApplyDamageFactors) { PARAM_PROLOGUE; @@ -7880,6 +7912,7 @@ DEFINE_ACTION_FUNCTION(AActor, ApplyDamageFactors) } } + //---------------------------------------------------------------------------- // // DropItem handling diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index 407fd6307..9c9659356 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -52,6 +52,7 @@ #include "g_levellocals.h" #include "vm.h" #include "p_checkposition.h" +#include "r_sky.h" static TArray properties; static TArray AFTable; @@ -742,9 +743,8 @@ void InitThingdef() // As a result, the size has to be set to something large and arbritrary because it can change between maps. This will need some serious improvement when things get cleaned up. sectorstruct->AddNativeField("lines", NewPointer(NewResizableArray(NewPointer(linestruct, false)), false), myoffsetof(sector_t, Lines), VARF_Native); - // add the sector planes. These are value items of native structs so they have to be done here. Write access should be through functions only to allow later optimization inside the renderer. - sectorstruct->AddNativeField("ceilingplane", secplanestruct, myoffsetof(sector_t, ceilingplane), VARF_Native|VARF_ReadOnly); - sectorstruct->AddNativeField("floorplane", secplanestruct, myoffsetof(sector_t, floorplane), VARF_Native|VARF_ReadOnly); + sectorstruct->AddNativeField("ceilingplane", secplanestruct, myoffsetof(sector_t, ceilingplane), VARF_Native); + sectorstruct->AddNativeField("floorplane", secplanestruct, myoffsetof(sector_t, floorplane), VARF_Native); @@ -788,6 +788,12 @@ void InitThingdef() playerf = new PField("gameaction", TypeUInt8, VARF_Native | VARF_Static, (intptr_t)&gameaction); GlobalSymbols.AddSymbol(playerf); + playerf = new PField("skyflatnum", TypeTextureID, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&skyflatnum); + GlobalSymbols.AddSymbol(playerf); + + playerf = new PField("globalfreeze", TypeUInt8, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&bglobal.freeze); + GlobalSymbols.AddSymbol(playerf); + playerf = new PField("consoleplayer", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&consoleplayer); GlobalSymbols.AddSymbol(playerf); diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index dc058aaf9..87d4491f0 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -145,6 +145,7 @@ class Actor : Thinker native native int lastbump; native int DesignatedTeam; native Actor BlockingMobj; + native Line BlockingLine; native int PoisonDamage; native name PoisonDamageType; native int PoisonDuration; @@ -207,7 +208,6 @@ class Actor : Thinker native // need some definition work first //FRenderStyle RenderStyle; - //line_t *BlockingLine; // Line that blocked the last move //int ConversationRoot; // THe root of the current dialogue // deprecated things. @@ -345,7 +345,12 @@ class Actor : Thinker native native void ClearBounce(); native TerrainDef GetFloorTerrain(); native bool CheckLocalView(int consoleplayer); - + native bool CheckNoDelay(); + native bool UpdateWaterLevel (bool splash = true); + native bool IsZeroDamage(); + native void ClearInterpolation(); + native Vector3 PosRelative(sector sec); + native void ExplodeMissile(line lin = null, Actor target = null); native void RestoreDamage(); native int SpawnHealth(); diff --git a/wadsrc/static/zscript/shared/fastprojectile.txt b/wadsrc/static/zscript/shared/fastprojectile.txt index b1d509073..fd877bd83 100644 --- a/wadsrc/static/zscript/shared/fastprojectile.txt +++ b/wadsrc/static/zscript/shared/fastprojectile.txt @@ -1,6 +1,6 @@ // Fast projectiles -------------------------------------------------------- -class FastProjectile : Actor native +class FastProjectile : Actor { Default { @@ -37,5 +37,148 @@ class FastProjectile : Actor native } } + //---------------------------------------------------------------------------- + // + // AFastProjectile :: Tick + // + // Thinker for the ultra-fast projectiles used by Heretic and Hexen + // + //---------------------------------------------------------------------------- + + override void Tick () + { + ClearInterpolation(); + double oldz = pos.Z; + + if (!bNoTimeFreeze) + { + //Added by MC: Freeze mode. + if (globalfreeze || level.Frozen) + { + return; + } + } + + // [RH] Ripping is a little different than it was in Hexen + FCheckPosition tm; + tm.DoRipping = bRipper; + + int count = 8; + if (radius > 0) + { + while ( abs(Vel.X) > radius * count || abs(Vel.Y) > radius * count) + { + // we need to take smaller steps. + count += count; + } + } + + // Handle movement + if (Vel != (0, 0, 0) || (pos.Z != floorz)) + { + // force some lateral movement so that collision detection works as intended. + if (bMissile && Vel.X == 0 && Vel.Y == 0 && !IsZeroDamage()) + { + Vel.X = MinVel; + } + + Vector3 frac = Vel / count; + int changexy = frac.X != 0 || frac.Y != 0; + int ripcount = count / 8; + for (int i = 0; i < count; i++) + { + if (changexy) + { + if (--ripcount <= 0) + { + tm.ClearLastRipped(); // [RH] Do rip damage each step, like Hexen + } + + if (!TryMove (Pos.XY + frac.XY, true, NULL, tm)) + { // Blocked move + if (!bSkyExplode) + { + let l = tm.ceilingline; + if (l && + l.backsector && + l.backsector.GetTexture(sector.ceiling) == skyflatnum) + { + let posr = PosRelative(l.backsector); + if (pos.Z >= l.backsector.ceilingplane.ZatPoint(posr.XY)) + { + // Hack to prevent missiles exploding against the sky. + // Does not handle sky floors. + Destroy (); + return; + } + } + // [RH] Don't explode on horizon lines. + if (BlockingLine != NULL && BlockingLine.special == Line_Horizon) + { + Destroy (); + return; + } + } + + ExplodeMissile (BlockingLine, BlockingMobj); + return; + } + } + AddZ(frac.Z); + UpdateWaterLevel (); + oldz = pos.Z; + if (oldz <= floorz) + { // Hit the floor + + if (floorpic == skyflatnum && !bSkyExplode) + { + // [RH] Just remove the missile without exploding it + // if this is a sky floor. + Destroy (); + return; + } + + SetZ(floorz); + HitFloor (); + ExplodeMissile (NULL, NULL); + return; + } + if (pos.Z + height > ceilingz) + { // Hit the ceiling + + if (ceilingpic == skyflatnum && !bSkyExplode) + { + Destroy (); + return; + } + + SetZ(ceilingz - Height); + ExplodeMissile (NULL, NULL); + return; + } + if (frac != (0, 0, 0) && ripcount <= 0) + { + ripcount = count >> 3; + + // call the 'Effect' method. + Effect(); + } + } + } + if (!CheckNoDelay()) + return; // freed itself + // Advance the state + if (tics != -1) + { + if (tics > 0) tics--; + while (!tics) + { + if (!SetState (CurState.NextState)) + { // mobj was removed + return; + } + } + } + } }