mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-17 01:31:25 +00:00
- scriptified A_FireBullets and A_CustomBulletAttack.
This commit is contained in:
parent
4440bff83a
commit
e071be8371
5 changed files with 234 additions and 280 deletions
|
@ -75,7 +75,6 @@ AActor *SingleActorFromTID(int tid, AActor *defactor);
|
||||||
|
|
||||||
static FRandom pr_camissile ("CustomActorfire");
|
static FRandom pr_camissile ("CustomActorfire");
|
||||||
static FRandom pr_cabullet ("CustomBullet");
|
static FRandom pr_cabullet ("CustomBullet");
|
||||||
static FRandom pr_cwbullet ("CustomWpBullet");
|
|
||||||
static FRandom pr_cwjump ("CustomWpJump");
|
static FRandom pr_cwjump ("CustomWpJump");
|
||||||
static FRandom pr_cwpunch ("CustomWpPunch");
|
static FRandom pr_cwpunch ("CustomWpPunch");
|
||||||
static FRandom pr_grenade ("ThrowGrenade");
|
static FRandom pr_grenade ("ThrowGrenade");
|
||||||
|
@ -1516,112 +1515,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnProjectile)
|
||||||
ACTION_RETURN_OBJECT(missile);
|
ACTION_RETURN_OBJECT(missile);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// An even more customizable hitscan attack
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
enum CBA_Flags
|
|
||||||
{
|
|
||||||
CBAF_AIMFACING = 1,
|
|
||||||
CBAF_NORANDOM = 2,
|
|
||||||
CBAF_EXPLICITANGLE = 4,
|
|
||||||
CBAF_NOPITCH = 8,
|
|
||||||
CBAF_NORANDOMPUFFZ = 16,
|
|
||||||
CBAF_PUFFTARGET = 32,
|
|
||||||
CBAF_PUFFMASTER = 64,
|
|
||||||
CBAF_PUFFTRACER = 128,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void AimBulletMissile(AActor *proj, AActor *puff, int flags, bool temp, bool cba);
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(AActor, A_CustomBulletAttack)
|
|
||||||
{
|
|
||||||
PARAM_SELF_PROLOGUE(AActor);
|
|
||||||
PARAM_ANGLE (spread_xy);
|
|
||||||
PARAM_ANGLE (spread_z);
|
|
||||||
PARAM_INT (numbullets);
|
|
||||||
PARAM_INT (damageperbullet);
|
|
||||||
PARAM_CLASS (pufftype, AActor);
|
|
||||||
PARAM_FLOAT (range);
|
|
||||||
PARAM_INT (flags);
|
|
||||||
PARAM_INT (ptr);
|
|
||||||
PARAM_CLASS (missile, AActor);
|
|
||||||
PARAM_FLOAT (Spawnheight);
|
|
||||||
PARAM_FLOAT (Spawnofs_xy);
|
|
||||||
|
|
||||||
AActor *ref = COPY_AAPTR(self, ptr);
|
|
||||||
|
|
||||||
if (range == 0)
|
|
||||||
range = MISSILERANGE;
|
|
||||||
|
|
||||||
int i;
|
|
||||||
DAngle bangle;
|
|
||||||
DAngle bslope = 0.;
|
|
||||||
int laflags = (flags & CBAF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0;
|
|
||||||
|
|
||||||
if (ref != NULL || (flags & CBAF_AIMFACING))
|
|
||||||
{
|
|
||||||
if (!(flags & CBAF_AIMFACING))
|
|
||||||
{
|
|
||||||
A_Face(self, ref);
|
|
||||||
}
|
|
||||||
bangle = self->Angles.Yaw;
|
|
||||||
|
|
||||||
if (!(flags & CBAF_NOPITCH)) bslope = P_AimLineAttack (self, bangle, MISSILERANGE);
|
|
||||||
if (pufftype == nullptr) pufftype = PClass::FindActor(NAME_BulletPuff);
|
|
||||||
|
|
||||||
S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
|
|
||||||
for (i = 0; i < numbullets; i++)
|
|
||||||
{
|
|
||||||
DAngle angle = bangle;
|
|
||||||
DAngle slope = bslope;
|
|
||||||
|
|
||||||
if (flags & CBAF_EXPLICITANGLE)
|
|
||||||
{
|
|
||||||
angle += spread_xy;
|
|
||||||
slope += spread_z;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
angle += spread_xy * (pr_cwbullet.Random2() / 255.);
|
|
||||||
slope += spread_z * (pr_cwbullet.Random2() / 255.);
|
|
||||||
}
|
|
||||||
|
|
||||||
int damage = damageperbullet;
|
|
||||||
|
|
||||||
if (!(flags & CBAF_NORANDOM))
|
|
||||||
damage *= ((pr_cabullet()%3)+1);
|
|
||||||
|
|
||||||
AActor *puff = P_LineAttack(self, angle, range, slope, damage, NAME_Hitscan, pufftype, laflags);
|
|
||||||
if (missile != nullptr && pufftype != nullptr)
|
|
||||||
{
|
|
||||||
double x = Spawnofs_xy * angle.Cos();
|
|
||||||
double y = Spawnofs_xy * angle.Sin();
|
|
||||||
|
|
||||||
DVector3 pos = self->Pos();
|
|
||||||
self->SetXYZ(self->Vec3Offset(x, y, 0.));
|
|
||||||
AActor *proj = P_SpawnMissileAngleZSpeed(self, self->Z() + self->GetBobOffset() + Spawnheight, missile, self->Angles.Yaw, 0, GetDefaultByType(missile)->Speed, self, false);
|
|
||||||
self->SetXYZ(pos);
|
|
||||||
|
|
||||||
if (proj)
|
|
||||||
{
|
|
||||||
bool temp = (puff == nullptr);
|
|
||||||
if (!puff)
|
|
||||||
{
|
|
||||||
puff = P_LineAttack(self, angle, range, slope, 0, NAME_Hitscan, pufftype, laflags | LAF_NOINTERACT);
|
|
||||||
}
|
|
||||||
if (puff)
|
|
||||||
{
|
|
||||||
AimBulletMissile(proj, puff, flags, temp, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// A fully customizable melee attack
|
// A fully customizable melee attack
|
||||||
|
@ -1732,177 +1625,6 @@ DEFINE_ACTION_FUNCTION(AStateProvider, A_JumpIfNoAmmo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// An even more customizable hitscan attack
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
enum FB_Flags
|
|
||||||
{
|
|
||||||
FBF_USEAMMO = 1,
|
|
||||||
FBF_NORANDOM = 2,
|
|
||||||
FBF_EXPLICITANGLE = 4,
|
|
||||||
FBF_NOPITCH = 8,
|
|
||||||
FBF_NOFLASH = 16,
|
|
||||||
FBF_NORANDOMPUFFZ = 32,
|
|
||||||
FBF_PUFFTARGET = 64,
|
|
||||||
FBF_PUFFMASTER = 128,
|
|
||||||
FBF_PUFFTRACER = 256,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void AimBulletMissile(AActor *proj, AActor *puff, int flags, bool temp, bool cba)
|
|
||||||
{
|
|
||||||
if (proj && puff)
|
|
||||||
{
|
|
||||||
if (proj)
|
|
||||||
{
|
|
||||||
// FAF_BOTTOM = 1
|
|
||||||
// Aim for the base of the puff as that's where blood puffs will spawn... roughly.
|
|
||||||
|
|
||||||
A_Face(proj, puff, 0., 0., 0., 0., 1);
|
|
||||||
proj->Vel3DFromAngle(proj->Angles.Pitch, proj->Speed);
|
|
||||||
|
|
||||||
if (!temp)
|
|
||||||
{
|
|
||||||
if (cba)
|
|
||||||
{
|
|
||||||
if (flags & CBAF_PUFFTARGET) proj->target = puff;
|
|
||||||
if (flags & CBAF_PUFFMASTER) proj->master = puff;
|
|
||||||
if (flags & CBAF_PUFFTRACER) proj->tracer = puff;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (flags & FBF_PUFFTARGET) proj->target = puff;
|
|
||||||
if (flags & FBF_PUFFMASTER) proj->master = puff;
|
|
||||||
if (flags & FBF_PUFFTRACER) proj->tracer = puff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (puff && temp)
|
|
||||||
{
|
|
||||||
puff->Destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(AStateProvider, A_FireBullets)
|
|
||||||
{
|
|
||||||
PARAM_ACTION_PROLOGUE(AStateProvider);
|
|
||||||
PARAM_ANGLE (spread_xy);
|
|
||||||
PARAM_ANGLE (spread_z);
|
|
||||||
PARAM_INT (numbullets);
|
|
||||||
PARAM_INT (damageperbullet);
|
|
||||||
PARAM_CLASS (pufftype, AActor);
|
|
||||||
PARAM_INT (flags);
|
|
||||||
PARAM_FLOAT (range);
|
|
||||||
PARAM_CLASS (missile, AActor);
|
|
||||||
PARAM_FLOAT (Spawnheight);
|
|
||||||
PARAM_FLOAT (Spawnofs_xy);
|
|
||||||
|
|
||||||
if (!self->player) return 0;
|
|
||||||
|
|
||||||
player_t *player = self->player;
|
|
||||||
AWeapon *weapon = player->ReadyWeapon;
|
|
||||||
|
|
||||||
int i;
|
|
||||||
DAngle bangle;
|
|
||||||
DAngle bslope = 0.;
|
|
||||||
int laflags = (flags & FBF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0;
|
|
||||||
|
|
||||||
if ((flags & FBF_USEAMMO) && weapon && ACTION_CALL_FROM_PSPRITE())
|
|
||||||
{
|
|
||||||
if (!weapon->DepleteAmmo(weapon->bAltFire, true))
|
|
||||||
return 0; // out of ammo
|
|
||||||
}
|
|
||||||
|
|
||||||
if (range == 0) range = PLAYERMISSILERANGE;
|
|
||||||
|
|
||||||
if (!(flags & FBF_NOFLASH)) static_cast<APlayerPawn *>(self)->PlayAttacking2 ();
|
|
||||||
|
|
||||||
if (!(flags & FBF_NOPITCH)) bslope = P_BulletSlope(self);
|
|
||||||
bangle = self->Angles.Yaw;
|
|
||||||
|
|
||||||
if (pufftype == NULL) pufftype = PClass::FindActor(NAME_BulletPuff);
|
|
||||||
|
|
||||||
if (weapon != NULL)
|
|
||||||
{
|
|
||||||
S_Sound(self, CHAN_WEAPON, weapon->AttackSound, 1, ATTN_NORM);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((numbullets == 1 && !player->refire) || numbullets == 0)
|
|
||||||
{
|
|
||||||
int damage = damageperbullet;
|
|
||||||
|
|
||||||
if (!(flags & FBF_NORANDOM))
|
|
||||||
damage *= ((pr_cwbullet()%3)+1);
|
|
||||||
|
|
||||||
AActor *puff = P_LineAttack(self, bangle, range, bslope, damage, NAME_Hitscan, pufftype, laflags);
|
|
||||||
|
|
||||||
if (missile != nullptr)
|
|
||||||
{
|
|
||||||
bool temp = false;
|
|
||||||
DAngle ang = self->Angles.Yaw - 90;
|
|
||||||
DVector2 ofs = ang.ToVector(Spawnofs_xy);
|
|
||||||
AActor *proj = P_SpawnPlayerMissile(self, ofs.X, ofs.Y, Spawnheight, missile, bangle, nullptr, nullptr, false, true);
|
|
||||||
if (proj)
|
|
||||||
{
|
|
||||||
if (!puff)
|
|
||||||
{
|
|
||||||
temp = true;
|
|
||||||
puff = P_LineAttack(self, bangle, range, bslope, 0, NAME_Hitscan, pufftype, laflags | LAF_NOINTERACT);
|
|
||||||
}
|
|
||||||
AimBulletMissile(proj, puff, flags, temp, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (numbullets < 0)
|
|
||||||
numbullets = 1;
|
|
||||||
for (i = 0; i < numbullets; i++)
|
|
||||||
{
|
|
||||||
DAngle angle = bangle;
|
|
||||||
DAngle slope = bslope;
|
|
||||||
|
|
||||||
if (flags & FBF_EXPLICITANGLE)
|
|
||||||
{
|
|
||||||
angle += spread_xy;
|
|
||||||
slope += spread_z;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
angle += spread_xy * (pr_cwbullet.Random2() / 255.);
|
|
||||||
slope += spread_z * (pr_cwbullet.Random2() / 255.);
|
|
||||||
}
|
|
||||||
|
|
||||||
int damage = damageperbullet;
|
|
||||||
|
|
||||||
if (!(flags & FBF_NORANDOM))
|
|
||||||
damage *= ((pr_cwbullet()%3)+1);
|
|
||||||
|
|
||||||
AActor *puff = P_LineAttack(self, angle, range, slope, damage, NAME_Hitscan, pufftype, laflags);
|
|
||||||
|
|
||||||
if (missile != nullptr)
|
|
||||||
{
|
|
||||||
bool temp = false;
|
|
||||||
DAngle ang = self->Angles.Yaw - 90;
|
|
||||||
DVector2 ofs = ang.ToVector(Spawnofs_xy);
|
|
||||||
AActor *proj = P_SpawnPlayerMissile(self, ofs.X, ofs.Y, Spawnheight, missile, angle, nullptr, nullptr, false, true);
|
|
||||||
if (proj)
|
|
||||||
{
|
|
||||||
if (!puff)
|
|
||||||
{
|
|
||||||
temp = true;
|
|
||||||
puff = P_LineAttack(self, angle, range, slope, 0, NAME_Hitscan, pufftype, laflags | LAF_NOINTERACT);
|
|
||||||
}
|
|
||||||
AimBulletMissile(proj, puff, flags, temp, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
|
|
@ -5,6 +5,7 @@ version "3.7"
|
||||||
#include "zscript/dynarrays.txt"
|
#include "zscript/dynarrays.txt"
|
||||||
#include "zscript/constants.txt"
|
#include "zscript/constants.txt"
|
||||||
#include "zscript/actor.txt"
|
#include "zscript/actor.txt"
|
||||||
|
#include "zscript/actor_attacks.txt"
|
||||||
#include "zscript/actor_checks.txt"
|
#include "zscript/actor_checks.txt"
|
||||||
#include "zscript/events.txt"
|
#include "zscript/events.txt"
|
||||||
#include "zscript/destructible.txt"
|
#include "zscript/destructible.txt"
|
||||||
|
|
|
@ -1067,7 +1067,6 @@ class Actor : Thinker native
|
||||||
native void A_SeekerMissile(int threshold, int turnmax, int flags = 0, int chance = 50, int distance = 10);
|
native void A_SeekerMissile(int threshold, int turnmax, int flags = 0, int chance = 50, int distance = 10);
|
||||||
native action state A_Jump(int chance, statelabel label, ...);
|
native action state A_Jump(int chance, statelabel label, ...);
|
||||||
native Actor A_SpawnProjectile(class<Actor> missiletype, double spawnheight = 32, double spawnofs_xy = 0, double angle = 0, int flags = 0, double pitch = 0, int ptr = AAPTR_TARGET);
|
native Actor A_SpawnProjectile(class<Actor> missiletype, double spawnheight = 32, double spawnofs_xy = 0, double angle = 0, int flags = 0, double pitch = 0, int ptr = AAPTR_TARGET);
|
||||||
native void A_CustomBulletAttack(double spread_xy, double spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", double range = 0, int flags = 0, int ptr = AAPTR_TARGET, class<Actor> missile = null, double Spawnheight = 32, double Spawnofs_xy = 0);
|
|
||||||
native void A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = 0, color color2 = 0, int flags = 0, int aim = 0, double maxdiff = 0, class<Actor> pufftype = "BulletPuff", double spread_xy = 0, double spread_z = 0, double range = 0, int duration = 0, double sparsity = 1.0, double driftspeed = 1.0, class<Actor> spawnclass = null, double spawnofs_z = 0, int spiraloffset = 270, int limit = 0, double veleffect = 3);
|
native void A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = 0, color color2 = 0, int flags = 0, int aim = 0, double maxdiff = 0, class<Actor> pufftype = "BulletPuff", double spread_xy = 0, double spread_z = 0, double range = 0, int duration = 0, double sparsity = 1.0, double driftspeed = 1.0, class<Actor> spawnclass = null, double spawnofs_z = 0, int spiraloffset = 270, int limit = 0, double veleffect = 3);
|
||||||
native bool A_SetInventory(class<Inventory> itemtype, int amount, int ptr = AAPTR_DEFAULT, bool beyondMax = false);
|
native bool A_SetInventory(class<Inventory> itemtype, int amount, int ptr = AAPTR_DEFAULT, bool beyondMax = false);
|
||||||
native bool A_GiveInventory(class<Inventory> itemtype, int amount = 0, int giveto = AAPTR_DEFAULT);
|
native bool A_GiveInventory(class<Inventory> itemtype, int amount = 0, int giveto = AAPTR_DEFAULT);
|
||||||
|
|
120
wadsrc/static/zscript/actor_attacks.txt
Normal file
120
wadsrc/static/zscript/actor_attacks.txt
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
extend class Actor
|
||||||
|
{
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Used by A_CustomBulletAttack and A_FireBullets
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static void AimBulletMissile(Actor proj, Actor puff, int flags, bool temp, bool cba)
|
||||||
|
{
|
||||||
|
if (proj && puff)
|
||||||
|
{
|
||||||
|
// FAF_BOTTOM = 1
|
||||||
|
// Aim for the base of the puff as that's where blood puffs will spawn... roughly.
|
||||||
|
|
||||||
|
proj.A_Face(puff, 0., 0., 0., 0., 1);
|
||||||
|
proj.Vel3DFromAngle(proj.Speed, proj.Angle, proj.Pitch);
|
||||||
|
|
||||||
|
if (!temp)
|
||||||
|
{
|
||||||
|
if (cba)
|
||||||
|
{
|
||||||
|
if (flags & CBAF_PUFFTARGET) proj.target = puff;
|
||||||
|
if (flags & CBAF_PUFFMASTER) proj.master = puff;
|
||||||
|
if (flags & CBAF_PUFFTRACER) proj.tracer = puff;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (flags & FBF_PUFFTARGET) proj.target = puff;
|
||||||
|
if (flags & FBF_PUFFMASTER) proj.master = puff;
|
||||||
|
if (flags & FBF_PUFFTRACER) proj.tracer = puff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (puff && temp)
|
||||||
|
{
|
||||||
|
puff.Destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void A_CustomBulletAttack(double spread_xy, double spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", double range = 0, int flags = 0, int ptr = AAPTR_TARGET, class<Actor> missile = null, double Spawnheight = 32, double Spawnofs_xy = 0)
|
||||||
|
{
|
||||||
|
let ref = GetPointer(ptr);
|
||||||
|
|
||||||
|
if (range == 0)
|
||||||
|
range = MISSILERANGE;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
double bangle;
|
||||||
|
double bslope = 0.;
|
||||||
|
int laflags = (flags & CBAF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0;
|
||||||
|
|
||||||
|
if (ref != NULL || (flags & CBAF_AIMFACING))
|
||||||
|
{
|
||||||
|
if (!(flags & CBAF_AIMFACING))
|
||||||
|
{
|
||||||
|
A_Face(ref);
|
||||||
|
}
|
||||||
|
bangle = self.Angle;
|
||||||
|
|
||||||
|
if (!(flags & CBAF_NOPITCH)) bslope = AimLineAttack (bangle, MISSILERANGE);
|
||||||
|
if (pufftype == null) pufftype = 'BulletPuff';
|
||||||
|
|
||||||
|
A_PlaySound(AttackSound, CHAN_WEAPON);
|
||||||
|
for (i = 0; i < numbullets; i++)
|
||||||
|
{
|
||||||
|
double pangle = bangle;
|
||||||
|
double slope = bslope;
|
||||||
|
|
||||||
|
if (flags & CBAF_EXPLICITANGLE)
|
||||||
|
{
|
||||||
|
pangle += spread_xy;
|
||||||
|
slope += spread_z;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pangle += spread_xy * Random2[cwbullet]() / 255.;
|
||||||
|
slope += spread_z * Random2[cwbullet]() / 255.;
|
||||||
|
}
|
||||||
|
|
||||||
|
int damage = damageperbullet;
|
||||||
|
|
||||||
|
if (!(flags & CBAF_NORANDOM))
|
||||||
|
damage *= random[cwbullet](1, 3);
|
||||||
|
|
||||||
|
let puff = LineAttack(pangle, range, slope, damage, 'Hitscan', pufftype, laflags);
|
||||||
|
if (missile != null && pufftype != null)
|
||||||
|
{
|
||||||
|
double x = Spawnofs_xy * cos(pangle);
|
||||||
|
double y = Spawnofs_xy * sin(pangle);
|
||||||
|
|
||||||
|
SetXYZ(Vec3Offset(x, y, 0.));
|
||||||
|
let proj = SpawnMissileAngleZSpeed(Pos.Z + GetBobOffset() + Spawnheight, missile, self.Angle, 0, GetDefaultByType(missile).Speed, self, false);
|
||||||
|
SetXYZ(pos);
|
||||||
|
|
||||||
|
if (proj)
|
||||||
|
{
|
||||||
|
bool temp = (puff == null);
|
||||||
|
if (!puff)
|
||||||
|
{
|
||||||
|
puff = LineAttack(pangle, range, slope, 0, 'Hitscan', pufftype, laflags | LAF_NOINTERACT);
|
||||||
|
}
|
||||||
|
if (puff)
|
||||||
|
{
|
||||||
|
AimBulletMissile(proj, puff, flags, temp, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -3,11 +3,123 @@ class StateProvider : Inventory native
|
||||||
{
|
{
|
||||||
action native state A_JumpIfNoAmmo(statelabel label);
|
action native state A_JumpIfNoAmmo(statelabel label);
|
||||||
action native void A_CustomPunch(int damage, bool norandom = false, int flags = CPF_USEAMMO, class<Actor> pufftype = "BulletPuff", double range = 0, double lifesteal = 0, int lifestealmax = 0, class<BasicArmorBonus> armorbonustype = "ArmorBonus", sound MeleeSound = 0, sound MissSound = "");
|
action native void A_CustomPunch(int damage, bool norandom = false, int flags = CPF_USEAMMO, class<Actor> pufftype = "BulletPuff", double range = 0, double lifesteal = 0, int lifestealmax = 0, class<BasicArmorBonus> armorbonustype = "ArmorBonus", sound MeleeSound = 0, sound MissSound = "");
|
||||||
action native void A_FireBullets(double spread_xy, double spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", int flags = 1, double range = 0, class<Actor> missile = null, double Spawnheight = 32, double Spawnofs_xy = 0);
|
|
||||||
action native Actor A_FireProjectile(class<Actor> missiletype, double angle = 0, bool useammo = true, double spawnofs_xy = 0, double spawnheight = 0, int flags = 0, double pitch = 0);
|
action native Actor A_FireProjectile(class<Actor> missiletype, double angle = 0, bool useammo = true, double spawnofs_xy = 0, double spawnheight = 0, int flags = 0, double pitch = 0);
|
||||||
action native void A_RailAttack(int damage, int spawnofs_xy = 0, bool useammo = true, color color1 = 0, color color2 = 0, int flags = 0, double maxdiff = 0, class<Actor> pufftype = "BulletPuff", double spread_xy = 0, double spread_z = 0, double range = 0, int duration = 0, double sparsity = 1.0, double driftspeed = 1.0, class<Actor> spawnclass = "none", double spawnofs_z = 0, int spiraloffset = 270, int limit = 0);
|
action native void A_RailAttack(int damage, int spawnofs_xy = 0, bool useammo = true, color color1 = 0, color color2 = 0, int flags = 0, double maxdiff = 0, class<Actor> pufftype = "BulletPuff", double spread_xy = 0, double spread_z = 0, double range = 0, int duration = 0, double sparsity = 1.0, double driftspeed = 1.0, class<Actor> spawnclass = "none", double spawnofs_z = 0, int spiraloffset = 270, int limit = 0);
|
||||||
action native void A_WeaponReady(int flags = 0);
|
action native void A_WeaponReady(int flags = 0);
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
action void A_FireBullets(double spread_xy, double spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", int flags = 1, double range = 0, class<Actor> missile = null, double Spawnheight = 32, double Spawnofs_xy = 0)
|
||||||
|
{
|
||||||
|
let player = self.player;
|
||||||
|
if (!player) return;
|
||||||
|
|
||||||
|
let pawn = PlayerPawn(self);
|
||||||
|
let weapon = player.ReadyWeapon;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
double bangle;
|
||||||
|
double bslope = 0.;
|
||||||
|
int laflags = (flags & FBF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0;
|
||||||
|
|
||||||
|
if ((flags & FBF_USEAMMO) && weapon && stateinfo != null && stateinfo.mStateType == STATE_Psprite)
|
||||||
|
{
|
||||||
|
if (!weapon.DepleteAmmo(weapon.bAltFire, true))
|
||||||
|
return; // out of ammo
|
||||||
|
}
|
||||||
|
|
||||||
|
if (range == 0) range = PLAYERMISSILERANGE;
|
||||||
|
|
||||||
|
if (!(flags & FBF_NOFLASH)) pawn.PlayAttacking2 ();
|
||||||
|
|
||||||
|
if (!(flags & FBF_NOPITCH)) bslope = BulletSlope();
|
||||||
|
bangle = self.Angle;
|
||||||
|
|
||||||
|
if (pufftype == NULL) pufftype = 'BulletPuff';
|
||||||
|
|
||||||
|
if (weapon != NULL)
|
||||||
|
{
|
||||||
|
A_PlaySound(weapon.AttackSound, CHAN_WEAPON);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((numbullets == 1 && !player.refire) || numbullets == 0)
|
||||||
|
{
|
||||||
|
int damage = damageperbullet;
|
||||||
|
|
||||||
|
if (!(flags & FBF_NORANDOM))
|
||||||
|
damage *= random[cabullet](1, 3);
|
||||||
|
|
||||||
|
let puff = LineAttack(bangle, range, bslope, damage, 'Hitscan', pufftype, laflags);
|
||||||
|
|
||||||
|
if (missile != null)
|
||||||
|
{
|
||||||
|
bool temp = false;
|
||||||
|
double ang = self.Angle - 90;
|
||||||
|
Vector2 ofs = AngleToVector(Spawnofs_xy);
|
||||||
|
Actor proj = SpawnPlayerMissile(missile, bangle, ofs.X, ofs.Y, Spawnheight);
|
||||||
|
if (proj)
|
||||||
|
{
|
||||||
|
if (!puff)
|
||||||
|
{
|
||||||
|
temp = true;
|
||||||
|
puff = LineAttack(bangle, range, bslope, 0, 'Hitscan', pufftype, laflags | LAF_NOINTERACT);
|
||||||
|
}
|
||||||
|
AimBulletMissile(proj, puff, flags, temp, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (numbullets < 0)
|
||||||
|
numbullets = 1;
|
||||||
|
for (i = 0; i < numbullets; i++)
|
||||||
|
{
|
||||||
|
double pangle = bangle;
|
||||||
|
double slope = bslope;
|
||||||
|
|
||||||
|
if (flags & FBF_EXPLICITANGLE)
|
||||||
|
{
|
||||||
|
pangle += spread_xy;
|
||||||
|
slope += spread_z;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pangle += spread_xy * Random2[cabullet]() / 255.;
|
||||||
|
slope += spread_z * Random2[cabullet]() / 255.;
|
||||||
|
}
|
||||||
|
|
||||||
|
int damage = damageperbullet;
|
||||||
|
|
||||||
|
if (!(flags & FBF_NORANDOM))
|
||||||
|
damage *= random[cabullet](1, 3);
|
||||||
|
|
||||||
|
let puff = LineAttack(pangle, range, slope, damage, 'Hitscan', pufftype, laflags);
|
||||||
|
|
||||||
|
if (missile != null)
|
||||||
|
{
|
||||||
|
bool temp = false;
|
||||||
|
double ang = self.Angle - 90;
|
||||||
|
Vector2 ofs = AngleToVector(Spawnofs_xy);
|
||||||
|
Actor proj = SpawnPlayerMissile(missile, bangle, ofs.X, ofs.Y, Spawnheight);
|
||||||
|
if (proj)
|
||||||
|
{
|
||||||
|
if (!puff)
|
||||||
|
{
|
||||||
|
temp = true;
|
||||||
|
puff = LineAttack(bangle, range, bslope, 0, 'Hitscan', pufftype, laflags | LAF_NOINTERACT);
|
||||||
|
}
|
||||||
|
AimBulletMissile(proj, puff, flags, temp, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// PROC A_ReFire
|
// PROC A_ReFire
|
||||||
|
|
Loading…
Reference in a new issue