diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 95db06b2f..d53429d05 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -855,7 +855,6 @@ set( NOT_COMPILED_SOURCE_FILES ${OTHER_SYSTEM_SOURCES} sc_man_scanner.h sc_man_scanner.re - g_hexen/a_blastradius.cpp g_hexen/a_boostarmor.cpp g_hexen/a_clericflame.cpp g_hexen/a_clericholy.cpp diff --git a/src/g_hexen/a_blastradius.cpp b/src/g_hexen/a_blastradius.cpp deleted file mode 100644 index 0776e107f..000000000 --- a/src/g_hexen/a_blastradius.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* -#include "info.h" -#include "a_pickups.h" -#include "a_artifacts.h" -#include "gstrings.h" -#include "p_local.h" -#include "p_enemy.h" -#include "s_sound.h" -*/ - -/* For reference, the default values: -#define BLAST_RADIUS_DIST 255*F.RACUNIT -#define BLAST_SPEED 20*F.RACUNIT -#define BLAST_FULLSTRENGTH 255 -*/ - -// Disc of Repulsion -------------------------------------------------------- - -//========================================================================== -// -// AArtiBlastRadius :: BlastActor -// -//========================================================================== - -void BlastActor (AActor *victim, double strength, double speed, AActor *Owner, PClassActor *blasteffect, bool dontdamage) -{ - DAngle angle; - AActor *mo; - DVector3 pos; - - if (!victim->SpecialBlastHandling (Owner, strength)) - { - return; - } - - angle = Owner->AngleTo(victim); - DVector2 move = angle.ToVector(speed); - victim->Vel.X = move.X; - victim->Vel.Y = move.Y; - - // Spawn blast puff - angle -= 180.; - pos = victim->Vec3Offset( - (victim->radius + 1) * angle.Cos(), - (victim->radius + 1) * angle.Sin(), - (victim->Height / 2) - victim->Floorclip); - mo = Spawn (blasteffect, pos, ALLOW_REPLACE); - if (mo) - { - mo->Vel.X = victim->Vel.X; - mo->Vel.Y = victim->Vel.Y; - } - if (victim->flags & MF_MISSILE) - { - // [RH] Floor and ceiling huggers should not be blasted vertically. - if (!(victim->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))) - { - mo->Vel.Z = victim->Vel.Z = 8; - } - } - else - { - victim->Vel.Z = 1000. / victim->Mass; - } - if (victim->player) - { - // Players handled automatically - } - else if (!dontdamage) - { - victim->flags2 |= MF2_BLASTED; - } - if (victim->flags6 & MF6_TOUCHY) - { // Touchy objects die when blasted - victim->flags6 &= ~MF6_ARMED; // Disarm - P_DamageMobj(victim, Owner, Owner, victim->health, NAME_Melee, DMG_FORCED); - } -} - -enum -{ - BF_USEAMMO = 1, - BF_DONTWARN = 2, - BF_AFFECTBOSSES = 4, - BF_NOIMPACTDAMAGE = 8, -}; - -//========================================================================== -// -// AArtiBlastRadius :: Activate -// -// Blast all actors away -// -//========================================================================== - -DEFINE_ACTION_FUNCTION (AActor, A_Blast) -{ - PARAM_ACTION_PROLOGUE(AActor); - PARAM_INT_DEF (blastflags) - PARAM_FLOAT_DEF (strength) - PARAM_FLOAT_DEF (radius) - PARAM_FLOAT_DEF (speed) - PARAM_CLASS_DEF (blasteffect, AActor) - PARAM_SOUND_DEF (blastsound) - - AActor *mo; - TThinkerIterator iterator; - - if (self->player && (blastflags & BF_USEAMMO) && ACTION_CALL_FROM_PSPRITE()) - { - AWeapon *weapon = self->player->ReadyWeapon; - if (weapon != NULL && !weapon->DepleteAmmo(weapon->bAltFire)) - { - return 0; - } - } - - S_Sound (self, CHAN_AUTO, blastsound, 1, ATTN_NORM); - - if (!(blastflags & BF_DONTWARN)) - { - P_NoiseAlert (self, self); - } - while ( (mo = iterator.Next ()) ) - { - if ((mo == self) || ((mo->flags2 & MF2_BOSS) && !(blastflags & BF_AFFECTBOSSES)) - || (mo->flags2 & MF2_DORMANT) || (mo->flags3 & MF3_DONTBLAST)) - { // Not a valid monster: originator, boss, dormant, or otherwise protected - continue; - } - if ((mo->flags & MF_ICECORPSE) || (mo->flags3 & MF3_CANBLAST)) - { - // Let these special cases go - } - else if ((mo->flags3 & MF3_ISMONSTER) && (mo->health <= 0)) - { - continue; - } - else if (!(mo->player) && - !(mo->flags & MF_MISSILE) && - !(mo->flags3 & (MF3_ISMONSTER|MF3_CANBLAST)) && - !(mo->flags6 & (MF6_TOUCHY|MF6_VULNERABLE))) - { // Must be monster, player, missile, touchy or vulnerable - continue; - } - if (self->Distance2D(mo) > radius) - { // Out of range - continue; - } - if (mo->Sector->PortalGroup != self->Sector->PortalGroup && !P_CheckSight(self, mo)) - { - // in another region and cannot be seen. - continue; - } - BlastActor (mo, strength, speed, self, blasteffect, !!(blastflags & BF_NOIMPACTDAMAGE)); - } - return 0; -} diff --git a/src/g_hexen/a_hexenmisc.cpp b/src/g_hexen/a_hexenmisc.cpp index f442df65e..2384a8518 100644 --- a/src/g_hexen/a_hexenmisc.cpp +++ b/src/g_hexen/a_hexenmisc.cpp @@ -24,7 +24,6 @@ #include "serializer.h" // Include all the Hexen stuff here to reduce compile time -#include "a_blastradius.cpp" #include "a_boostarmor.cpp" #include "a_clericflame.cpp" #include "a_clericholy.cpp" diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index db237e8bb..a4be4dd1b 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -262,7 +262,15 @@ void P_NoiseAlert (AActor *target, AActor *emitter, bool splash, double maxdist) } } - +DEFINE_ACTION_FUNCTION(AActor, NoiseAlert) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_OBJECT(emitter, AActor); + PARAM_BOOL_DEF(splash); + PARAM_FLOAT_DEF(maxdist); + P_NoiseAlert(self, emitter, splash, maxdist); + return 0; +} //---------------------------------------------------------------------------- diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 559efda82..e9c6a2980 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -22,7 +22,6 @@ //----------------------------------------------------------------------------- // HEADER FILES ------------------------------------------------------------ - #include #include "templates.h" #include "i_system.h" @@ -3342,6 +3341,16 @@ bool AActor::SpecialBlastHandling (AActor *source, double strength) return true; } +// This only gets called from the script side so we do not need a native wrapper like for the other virtual methods. +DEFINE_ACTION_FUNCTION(AActor, SpecialBlastHandling) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_OBJECT(source, AActor); + PARAM_FLOAT(strength); + ACTION_RETURN_BOOL(self->SpecialBlastHandling(source, strength)); +} + + int AActor::SpecialMissileHit (AActor *victim) { return -1; diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index e93d718cd..841401226 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -1265,3 +1265,48 @@ int side_t::GetLightLevel (bool foggy, int baselight, bool is3dlight, int *pfake } return baselight; } + + +DEFINE_FIELD_X(Sector, sector_t, floorplane) +DEFINE_FIELD_X(Sector, sector_t, ceilingplane) +DEFINE_FIELD_X(Sector, sector_t, ColorMap) +DEFINE_FIELD_X(Sector, sector_t, SoundTarget) +DEFINE_FIELD_X(Sector, sector_t, special) +DEFINE_FIELD_X(Sector, sector_t, lightlevel) +DEFINE_FIELD_X(Sector, sector_t, seqType) +DEFINE_FIELD_X(Sector, sector_t, sky) +DEFINE_FIELD_X(Sector, sector_t, SeqName) +DEFINE_FIELD_X(Sector, sector_t, centerspot) +DEFINE_FIELD_X(Sector, sector_t, validcount) +DEFINE_FIELD_X(Sector, sector_t, thinglist) +DEFINE_FIELD_X(Sector, sector_t, friction) +DEFINE_FIELD_X(Sector, sector_t, movefactor) +DEFINE_FIELD_X(Sector, sector_t, terrainnum) +DEFINE_FIELD_X(Sector, sector_t, floordata) +DEFINE_FIELD_X(Sector, sector_t, ceilingdata) +DEFINE_FIELD_X(Sector, sector_t, lightingdata) +DEFINE_FIELD_X(Sector, sector_t, interpolations) +DEFINE_FIELD_X(Sector, sector_t, soundtraversed) +DEFINE_FIELD_X(Sector, sector_t, stairlock) +DEFINE_FIELD_X(Sector, sector_t, prevsec) +DEFINE_FIELD_X(Sector, sector_t, nextsec) +DEFINE_FIELD_X(Sector, sector_t, linecount) +DEFINE_FIELD_X(Sector, sector_t, lines) +DEFINE_FIELD_X(Sector, sector_t, heightsec) +DEFINE_FIELD_X(Sector, sector_t, bottommap) +DEFINE_FIELD_X(Sector, sector_t, midmap) +DEFINE_FIELD_X(Sector, sector_t, topmap) +DEFINE_FIELD_X(Sector, sector_t, touching_thinglist) +DEFINE_FIELD_X(Sector, sector_t, render_thinglist) +DEFINE_FIELD_X(Sector, sector_t, gravity) +DEFINE_FIELD_X(Sector, sector_t, damagetype) +DEFINE_FIELD_X(Sector, sector_t, damageamount) +DEFINE_FIELD_X(Sector, sector_t, damageinterval) +DEFINE_FIELD_X(Sector, sector_t, leakydamage) +DEFINE_FIELD_X(Sector, sector_t, ZoneNumber) +DEFINE_FIELD_X(Sector, sector_t, MoreFlags) +DEFINE_FIELD_X(Sector, sector_t, Flags) +DEFINE_FIELD_X(Sector, sector_t, SecActTarget) +DEFINE_FIELD_X(Sector, sector_t, Portals) +DEFINE_FIELD_X(Sector, sector_t, PortalGroup) +DEFINE_FIELD_X(Sector, sector_t, sectornum) diff --git a/src/r_defs.h b/src/r_defs.h index 2d16d28f9..f33baeedc 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -983,8 +983,8 @@ public: BYTE soundtraversed; // 0 = untraversed, 1,2 = sndlines -1 // jff 2/26/98 lockout machinery for stairbuilding SBYTE stairlock; // -2 on first locked -1 after thinker done 0 normally - SWORD prevsec; // -1 or number of sector for previous step - SWORD nextsec; // -1 or number of next step sector + int prevsec; // -1 or number of sector for previous step + int nextsec; // -1 or number of next step sector short linecount; struct line_t **lines; // [linecount] size diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index a006c79ed..62d88237f 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -265,6 +265,7 @@ class Actor : Thinker native virtual native void Die(Actor source, Actor inflictor, int dmgflags); virtual native bool Slam(Actor victim); virtual native bool UseInventory(Inventory item); + virtual native bool SpecialBlastHandling (Actor source, double strength); native void AdjustPlayerAngle(FTranslatedLineTarget t); @@ -279,6 +280,7 @@ class Actor : Thinker native native bool isTeammate(Actor other); native int PlayerNumber(); native void SetFriendPlayer(PlayerInfo player); + native void NoiseAlert(Actor emitter, bool splash = false, double maxdist = 0); native void RestoreDamage(); native int SpawnHealth(); @@ -669,7 +671,6 @@ class Actor : Thinker native native void A_CustomMeleeAttack(int damage = 0, sound meleesound = "", sound misssound = "", name damagetype = "none", bool bleed = true); native void A_CustomComboAttack(class missiletype, double spawnheight, int damage, sound meleesound = "", name damagetype = "none", bool bleed = true); native void A_Burst(class chunktype); - action native void A_Blast(int flags = 0, double strength = 255, double radius = 255, double speed = 20, class blasteffect = "BlastEffect", sound blastsound = "BlastRadius"); native void A_RadiusThrust(int force = 128, int distance = -1, int flags = RTF_AFFECTSOURCE, int fullthrustdistance = 0); native void A_RadiusDamageSelf(int damage = 128, double distance = 128, int flags = 0, class flashtype = null); native int A_Explode(int damage = -1, int distance = -1, int flags = XF_HURTSOURCE, bool alert = false, int fulldamagedistance = 0, int nails = 0, int naildamage = 10, class pufftype = "BulletPuff", name damagetype = "none"); diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index c91b7aaa4..3766bb6b2 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -131,6 +131,72 @@ struct F3DFloor native struct Sector native { + //secplane_t floorplane, ceilingplane; + //FDynamicColormap *ColorMap; // [RH] Per-sector colormap + + native Actor SoundTarget; + + native int16 special; + native int16 lightlevel; + native int16 seqType; + + native int sky; + native Name SeqName; + + native readonly Vector2 centerspot; + native int validcount; + //AActor* thinglist; + + native double friction, movefactor; + native int terrainnum[2]; + + // thinker_t for reversable actions + //SectorEffect floordata; + //SectorEffect ceilingdata; + //SectorEffect lightingdata; + + enum EInterpolationType + { + CeilingMove, + FloorMove, + CeilingScroll, + FloorScroll + }; + //Interpolation interpolations[4]; + + native uint8 soundtraversed; + native int8 stairlock; + native int prevsec; + native int nextsec; + + native readonly int16 linecount; + //line_t **lines; + + native readonly Sector heightsec; + + native uint bottommap, midmap, topmap; + + //struct msecnode_t *touching_thinglist; + //struct msecnode_t *render_thinglist; + + native double gravity; + native Name damagetype; + native int damageamount; + native int16 damageinterval; + native int16 leakydamage; + + native uint16 ZoneNumber; + native uint16 MoreFlags; + native uint Flags; + + native SectorAction SecActTarget; + + native readonly uint Portals[2]; + native readonly int PortalGroup; + + native readonly int sectornum; + + native double, Sector, F3DFloor NextHighestCeilingAt(double x, double y, double bottomz, double topz, int flags = 0); } diff --git a/wadsrc/static/zscript/heretic/hereticmisc.txt b/wadsrc/static/zscript/heretic/hereticmisc.txt index 4cb094d06..ea79f5f80 100644 --- a/wadsrc/static/zscript/heretic/hereticmisc.txt +++ b/wadsrc/static/zscript/heretic/hereticmisc.txt @@ -1,4 +1,12 @@ +class HereticWeapon : Weapon +{ + Default + { + Weapon.Kickback 150; + } +} + // Pod ---------------------------------------------------------------------- class Pod : Actor diff --git a/wadsrc/static/zscript/heretic/weaponphoenix.txt b/wadsrc/static/zscript/heretic/weaponphoenix.txt index 554d52d21..6b949b8f6 100644 --- a/wadsrc/static/zscript/heretic/weaponphoenix.txt +++ b/wadsrc/static/zscript/heretic/weaponphoenix.txt @@ -1,13 +1,3 @@ - -class HereticWeapon : Weapon -{ - Default - { - Weapon.Kickback 150; - } -} - - // Phoenix Rod -------------------------------------------------------------- class PhoenixRod : Weapon diff --git a/wadsrc/static/zscript/hexen/blastradius.txt b/wadsrc/static/zscript/hexen/blastradius.txt index 17ac75dc3..a9c631318 100644 --- a/wadsrc/static/zscript/hexen/blastradius.txt +++ b/wadsrc/static/zscript/hexen/blastradius.txt @@ -20,6 +20,137 @@ class ArtiBlastRadius : CustomInventory Use: TNT1 A 0 A_Blast; } + +} + +//========================================================================== +// +// A_Blast is public to Actor +// +//========================================================================== + +extend class Actor +{ + /* For reference, the default values: + #define BLAST_RADIUS_DIST 255.0 + #define BLAST_SPEED 20.0 + #define BLAST_FULLSTRENGTH 255 + */ + + //========================================================================== + // + // AArtiBlastRadius :: BlastActor + // + //========================================================================== + + private void BlastActor (Actor victim, double strength, double speed, Class blasteffect, bool dontdamage) + { + if (!victim.SpecialBlastHandling (self, strength)) + { + return; + } + + double ang = AngleTo(victim); + Vector2 move = AngleToVector(ang, speed); + victim.Vel.XY = move; + + // Spawn blast puff + ang -= 180.; + Vector3 spawnpos = victim.Vec3Offset( + (victim.radius + 1) * cos(ang), + (victim.radius + 1) * sin(ang), + (victim.Height / 2) - victim.Floorclip); + Actor mo = Spawn (blasteffect, spawnpos, ALLOW_REPLACE); + if (mo) + { + mo.Vel.XY = victim.Vel.XY; + } + if (victim.bMissile) + { + // [RH] Floor and ceiling huggers should not be blasted vertically. + if (!victim.bFloorHugger && !victim.bCeilingHugger) + { + mo.Vel.Z = victim.Vel.Z = 8; + } + } + else + { + victim.Vel.Z = 1000. / victim.Mass; + } + if (victim.player) + { + // Players handled automatically + } + else if (!dontdamage) + { + victim.bBlasted = true; + } + if (victim.bTouchy) + { // Touchy objects die when blasted + victim.bArmed = false; // Disarm + victim.DamageMobj(self, self, victim.health, 'Melee', DMG_FORCED); + } + } + + //========================================================================== + // + // AArtiBlastRadius :: Activate + // + // Blast all actors away + // + //========================================================================== + + action void A_Blast(int blastflags = 0, double strength = 255, double radius = 255, double speed = 20, class blasteffect = "BlastEffect", sound blastsound = "BlastRadius") + { + + Weapon weapon = player.ReadyWeapon; + if (player && (blastflags & BF_USEAMMO) && invoker == weapon && stateinfo != null && stateinfo.mStateType == STATE_Psprite) + + { + if (weapon != null && !weapon.DepleteAmmo(weapon.bAltFire)) + { + return; + } + } + + A_PlaySound (blastsound, CHAN_AUTO); + + if (!(blastflags & BF_DONTWARN)) + { + NoiseAlert (self); + } + ThinkerIterator it = ThinkerIterator.Create("Actor"); + Actor mo; + while ( (mo = Actor(it.Next ())) ) + { + if (mo == self || (mo.bBoss && !(blastflags & BF_AFFECTBOSSES)) || mo.bDormant || mo.bDontBlast) + { // Not a valid monster: originator, boss, dormant, or otherwise protected + continue; + } + if (mo.bIceCorpse || mo.bCanBlast) + { + // Let these special cases go + } + else if (mo.bIsMonster && mo.health <= 0) + { + continue; + } + else if (!mo.player && !mo.bMissile && !mo.bIsMonster && !mo.bCanBlast && !mo.bTouchy && !mo.bVulnerable) + { // Must be monster, player, missile, touchy or vulnerable + continue; + } + if (Distance2D(mo) > radius) + { // Out of range + continue; + } + if (mo.CurSector.PortalGroup != CurSector.PortalGroup && !CheckSight(mo)) + { + // in another region and cannot be seen. + continue; + } + BlastActor (mo, strength, speed, blasteffect, !!(blastflags & BF_NOIMPACTDAMAGE)); + } + } } // Blast Effect -------------------------------------------------------------