- scriptified A_FireProjectile

This commit is contained in:
Christoph Oelckers 2018-11-24 14:16:08 +01:00
parent e071be8371
commit 7bb3855439
2 changed files with 62 additions and 77 deletions

View file

@ -1626,77 +1626,6 @@ DEFINE_ACTION_FUNCTION(AStateProvider, A_JumpIfNoAmmo)
//==========================================================================
//
// A_FireProjectile
//
//==========================================================================
enum FP_Flags
{
FPF_AIMATANGLE = 1,
FPF_TRANSFERTRANSLATION = 2,
FPF_NOAUTOAIM = 4,
};
DEFINE_ACTION_FUNCTION(AStateProvider, A_FireProjectile)
{
PARAM_ACTION_PROLOGUE(AStateProvider);
PARAM_CLASS (ti, AActor);
PARAM_ANGLE (angle);
PARAM_BOOL (useammo);
PARAM_FLOAT (spawnofs_xy);
PARAM_FLOAT (spawnheight);
PARAM_INT (flags);
PARAM_ANGLE (pitch);
if (!self->player)
ACTION_RETURN_OBJECT(nullptr);
player_t *player = self->player;
AWeapon *weapon = player->ReadyWeapon;
FTranslatedLineTarget t;
// Only use ammo if called from a weapon
if (useammo && ACTION_CALL_FROM_PSPRITE() && weapon)
{
if (!weapon->DepleteAmmo(weapon->bAltFire, true))
ACTION_RETURN_OBJECT(nullptr); // out of ammo
}
if (ti)
{
DAngle ang = self->Angles.Yaw - 90;
DVector2 ofs = ang.ToVector(spawnofs_xy);
DAngle shootangle = self->Angles.Yaw;
if (flags & FPF_AIMATANGLE) shootangle += angle;
// Temporarily adjusts the pitch
DAngle saved_player_pitch = self->Angles.Pitch;
self->Angles.Pitch += pitch;
AActor * misl=P_SpawnPlayerMissile (self, ofs.X, ofs.Y, spawnheight, ti, shootangle, &t, NULL, false, (flags & FPF_NOAUTOAIM) != 0);
self->Angles.Pitch = saved_player_pitch;
// automatic handling of seeker missiles
if (misl)
{
if (flags & FPF_TRANSFERTRANSLATION)
misl->Translation = self->Translation;
if (t.linetarget && !t.unlinked && (misl->flags2 & MF2_SEEKERMISSILE))
misl->tracer = t.linetarget;
if (!(flags & FPF_AIMATANGLE))
{
// This original implementation is to aim straight ahead and then offset
// the angle from the resulting direction.
misl->Angles.Yaw += angle;
misl->VelFromAngle(misl->VelXYToSpeed());
}
}
ACTION_RETURN_OBJECT(misl);
}
ACTION_RETURN_OBJECT(nullptr);
}
//========================================================================== //==========================================================================
// //
// A_CustomPunch // A_CustomPunch

View file

@ -3,7 +3,6 @@ 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 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);
@ -15,7 +14,7 @@ class StateProvider : Inventory native
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) 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; let player = player;
if (!player) return; if (!player) return;
let pawn = PlayerPawn(self); let pawn = PlayerPawn(self);
@ -37,7 +36,7 @@ class StateProvider : Inventory native
if (!(flags & FBF_NOFLASH)) pawn.PlayAttacking2 (); if (!(flags & FBF_NOFLASH)) pawn.PlayAttacking2 ();
if (!(flags & FBF_NOPITCH)) bslope = BulletSlope(); if (!(flags & FBF_NOPITCH)) bslope = BulletSlope();
bangle = self.Angle; bangle = Angle;
if (pufftype == NULL) pufftype = 'BulletPuff'; if (pufftype == NULL) pufftype = 'BulletPuff';
@ -58,7 +57,7 @@ class StateProvider : Inventory native
if (missile != null) if (missile != null)
{ {
bool temp = false; bool temp = false;
double ang = self.Angle - 90; double ang = Angle - 90;
Vector2 ofs = AngleToVector(Spawnofs_xy); Vector2 ofs = AngleToVector(Spawnofs_xy);
Actor proj = SpawnPlayerMissile(missile, bangle, ofs.X, ofs.Y, Spawnheight); Actor proj = SpawnPlayerMissile(missile, bangle, ofs.X, ofs.Y, Spawnheight);
if (proj) if (proj)
@ -102,7 +101,7 @@ class StateProvider : Inventory native
if (missile != null) if (missile != null)
{ {
bool temp = false; bool temp = false;
double ang = self.Angle - 90; double ang = Angle - 90;
Vector2 ofs = AngleToVector(Spawnofs_xy); Vector2 ofs = AngleToVector(Spawnofs_xy);
Actor proj = SpawnPlayerMissile(missile, bangle, ofs.X, ofs.Y, Spawnheight); Actor proj = SpawnPlayerMissile(missile, bangle, ofs.X, ofs.Y, Spawnheight);
if (proj) if (proj)
@ -119,6 +118,63 @@ class StateProvider : Inventory native
} }
} }
//==========================================================================
//
// A_FireProjectile
//
//==========================================================================
action Actor A_FireProjectile(class<Actor> ti, double spawnangle = 0, bool useammo = true, double spawnofs_xy = 0, double spawnheight = 0, int flags = 0, double pitch = 0)
{
let player = self.player;
if (!player) return null;
let weapon = player.ReadyWeapon;
FTranslatedLineTarget t;
// Only use ammo if called from a weapon
if (useammo && weapon && stateinfo != null && stateinfo.mStateType == STATE_Psprite)
{
if (!weapon.DepleteAmmo(weapon.bAltFire, true))
return null; // out of ammo
}
if (ti)
{
double ang = Angle - 90;
Vector2 ofs = AngleToVector(Spawnofs_xy);
double shootangle = Angle;
if (flags & FPF_AIMATANGLE) shootangle += spawnangle;
// Temporarily adjusts the pitch
double saved_player_pitch = self.Pitch;
self.Pitch += pitch;
let misl = SpawnPlayerMissile (ti, shootangle, ofs.X, ofs.Y, spawnheight, t, NULL, false, (flags & FPF_NOAUTOAIM) != 0);
self.Pitch = saved_player_pitch;
// automatic handling of seeker missiles
if (misl)
{
if (flags & FPF_TRANSFERTRANSLATION)
misl.Translation = Translation;
if (t.linetarget && !t.unlinked && misl.bSeekerMissile)
misl.tracer = t.linetarget;
if (!(flags & FPF_AIMATANGLE))
{
// This original implementation is to aim straight ahead and then offset
// the angle from the resulting direction.
misl.Angle += spawnangle;
misl.VelFromAngle(misl.Vel.XY.Length());
}
}
return misl;
}
return null;
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
@ -130,7 +186,7 @@ class StateProvider : Inventory native
action void A_ReFire(statelabel flash = null) action void A_ReFire(statelabel flash = null)
{ {
let player = self.player; let player = player;
bool pending; bool pending;
if (NULL == player) if (NULL == player)