mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +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}
|
||||
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
|
||||
|
|
|
@ -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 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"
|
||||
|
|
|
@ -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 ------------------------------------------------------------
|
||||
|
||||
#include <float.h>
|
||||
#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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<Actor> missiletype, double spawnheight, int damage, sound meleesound = "", name damagetype = "none", bool bleed = true);
|
||||
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_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");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
|
||||
class HereticWeapon : Weapon
|
||||
{
|
||||
Default
|
||||
{
|
||||
Weapon.Kickback 150;
|
||||
}
|
||||
}
|
||||
|
||||
// Pod ----------------------------------------------------------------------
|
||||
|
||||
class Pod : Actor
|
||||
|
|
|
@ -1,13 +1,3 @@
|
|||
|
||||
class HereticWeapon : Weapon
|
||||
{
|
||||
Default
|
||||
{
|
||||
Weapon.Kickback 150;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Phoenix Rod --------------------------------------------------------------
|
||||
|
||||
class PhoenixRod : Weapon
|
||||
|
|
|
@ -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<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 -------------------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue