mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-14 08:30:50 +00:00
- scriptified ArtiBlastRadius.
This commit is contained in:
parent
7385cd70c0
commit
4e802652c7
12 changed files with 273 additions and 175 deletions
|
@ -855,7 +855,6 @@ set( NOT_COMPILED_SOURCE_FILES
|
||||||
${OTHER_SYSTEM_SOURCES}
|
${OTHER_SYSTEM_SOURCES}
|
||||||
sc_man_scanner.h
|
sc_man_scanner.h
|
||||||
sc_man_scanner.re
|
sc_man_scanner.re
|
||||||
g_hexen/a_blastradius.cpp
|
|
||||||
g_hexen/a_boostarmor.cpp
|
g_hexen/a_boostarmor.cpp
|
||||||
g_hexen/a_clericflame.cpp
|
g_hexen/a_clericflame.cpp
|
||||||
g_hexen/a_clericholy.cpp
|
g_hexen/a_clericholy.cpp
|
||||||
|
|
|
@ -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<AActor> 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;
|
|
||||||
}
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
|
|
||||||
// Include all the Hexen stuff here to reduce compile time
|
// Include all the Hexen stuff here to reduce compile time
|
||||||
#include "a_blastradius.cpp"
|
|
||||||
#include "a_boostarmor.cpp"
|
#include "a_boostarmor.cpp"
|
||||||
#include "a_clericflame.cpp"
|
#include "a_clericflame.cpp"
|
||||||
#include "a_clericholy.cpp"
|
#include "a_clericholy.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
// HEADER FILES ------------------------------------------------------------
|
// HEADER FILES ------------------------------------------------------------
|
||||||
|
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
|
@ -3342,6 +3341,16 @@ bool AActor::SpecialBlastHandling (AActor *source, double strength)
|
||||||
return true;
|
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)
|
int AActor::SpecialMissileHit (AActor *victim)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -1265,3 +1265,48 @@ int side_t::GetLightLevel (bool foggy, int baselight, bool is3dlight, int *pfake
|
||||||
}
|
}
|
||||||
return baselight;
|
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)
|
||||||
|
|
|
@ -983,8 +983,8 @@ public:
|
||||||
BYTE soundtraversed; // 0 = untraversed, 1,2 = sndlines -1
|
BYTE soundtraversed; // 0 = untraversed, 1,2 = sndlines -1
|
||||||
// jff 2/26/98 lockout machinery for stairbuilding
|
// jff 2/26/98 lockout machinery for stairbuilding
|
||||||
SBYTE stairlock; // -2 on first locked -1 after thinker done 0 normally
|
SBYTE stairlock; // -2 on first locked -1 after thinker done 0 normally
|
||||||
SWORD prevsec; // -1 or number of sector for previous step
|
int prevsec; // -1 or number of sector for previous step
|
||||||
SWORD nextsec; // -1 or number of next step sector
|
int nextsec; // -1 or number of next step sector
|
||||||
|
|
||||||
short linecount;
|
short linecount;
|
||||||
struct line_t **lines; // [linecount] size
|
struct line_t **lines; // [linecount] size
|
||||||
|
|
|
@ -265,6 +265,7 @@ class Actor : Thinker native
|
||||||
virtual native void Die(Actor source, Actor inflictor, int dmgflags);
|
virtual native void Die(Actor source, Actor inflictor, int dmgflags);
|
||||||
virtual native bool Slam(Actor victim);
|
virtual native bool Slam(Actor victim);
|
||||||
virtual native bool UseInventory(Inventory item);
|
virtual native bool UseInventory(Inventory item);
|
||||||
|
virtual native bool SpecialBlastHandling (Actor source, double strength);
|
||||||
|
|
||||||
|
|
||||||
native void AdjustPlayerAngle(FTranslatedLineTarget t);
|
native void AdjustPlayerAngle(FTranslatedLineTarget t);
|
||||||
|
@ -279,6 +280,7 @@ class Actor : Thinker native
|
||||||
native bool isTeammate(Actor other);
|
native bool isTeammate(Actor other);
|
||||||
native int PlayerNumber();
|
native int PlayerNumber();
|
||||||
native void SetFriendPlayer(PlayerInfo player);
|
native void SetFriendPlayer(PlayerInfo player);
|
||||||
|
native void NoiseAlert(Actor emitter, bool splash = false, double maxdist = 0);
|
||||||
|
|
||||||
native void RestoreDamage();
|
native void RestoreDamage();
|
||||||
native int SpawnHealth();
|
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_CustomMeleeAttack(int damage = 0, sound meleesound = "", sound misssound = "", name damagetype = "none", bool bleed = true);
|
||||||
native void A_CustomComboAttack(class<Actor> missiletype, double spawnheight, int damage, sound meleesound = "", name damagetype = "none", bool bleed = true);
|
native void A_CustomComboAttack(class<Actor> missiletype, double spawnheight, int damage, sound meleesound = "", name damagetype = "none", bool bleed = true);
|
||||||
native void A_Burst(class<Actor> chunktype);
|
native void A_Burst(class<Actor> chunktype);
|
||||||
action native void A_Blast(int flags = 0, double strength = 255, double radius = 255, double speed = 20, class<Actor> 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_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<Actor> flashtype = null);
|
native void A_RadiusDamageSelf(int damage = 128, double distance = 128, int flags = 0, class<Actor> 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<Actor> pufftype = "BulletPuff", name damagetype = "none");
|
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<Actor> pufftype = "BulletPuff", name damagetype = "none");
|
||||||
|
|
|
@ -131,6 +131,72 @@ struct F3DFloor native
|
||||||
|
|
||||||
struct Sector 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);
|
native double, Sector, F3DFloor NextHighestCeilingAt(double x, double y, double bottomz, double topz, int flags = 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
|
|
||||||
|
class HereticWeapon : Weapon
|
||||||
|
{
|
||||||
|
Default
|
||||||
|
{
|
||||||
|
Weapon.Kickback 150;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Pod ----------------------------------------------------------------------
|
// Pod ----------------------------------------------------------------------
|
||||||
|
|
||||||
class Pod : Actor
|
class Pod : Actor
|
||||||
|
|
|
@ -1,13 +1,3 @@
|
||||||
|
|
||||||
class HereticWeapon : Weapon
|
|
||||||
{
|
|
||||||
Default
|
|
||||||
{
|
|
||||||
Weapon.Kickback 150;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Phoenix Rod --------------------------------------------------------------
|
// Phoenix Rod --------------------------------------------------------------
|
||||||
|
|
||||||
class PhoenixRod : Weapon
|
class PhoenixRod : Weapon
|
||||||
|
|
|
@ -20,6 +20,137 @@ class ArtiBlastRadius : CustomInventory
|
||||||
Use:
|
Use:
|
||||||
TNT1 A 0 A_Blast;
|
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<Actor> 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<Actor> 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 -------------------------------------------------------------
|
// Blast Effect -------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in a new issue