mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-13 16:07:45 +00:00
174 lines
4.1 KiB
Text
174 lines
4.1 KiB
Text
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//============================================================================
|
|
//
|
|
// P_DaggerAlert
|
|
//
|
|
//============================================================================
|
|
|
|
void DaggerAlert(Actor target)
|
|
{
|
|
Actor looker;
|
|
|
|
if (LastHeard != NULL)
|
|
return;
|
|
if (health <= 0)
|
|
return;
|
|
if (!bIsMonster)
|
|
return;
|
|
if (bInCombat)
|
|
return;
|
|
bInCombat = true;
|
|
|
|
self.target = target;
|
|
let painstate = FindState('Pain', 'Dagger');
|
|
if (painstate != NULL)
|
|
{
|
|
SetState(painstate);
|
|
}
|
|
|
|
for (looker = cursector.thinglist; looker != NULL; looker = looker.snext)
|
|
{
|
|
if (looker == self || looker == target)
|
|
continue;
|
|
|
|
if (looker.health <= 0)
|
|
continue;
|
|
|
|
if (!looker.bSeesDaggers)
|
|
continue;
|
|
|
|
if (!looker.bInCombat)
|
|
{
|
|
if (!looker.CheckSight(target) && !looker.CheckSight(self))
|
|
continue;
|
|
|
|
looker.target = target;
|
|
if (looker.SeeSound)
|
|
{
|
|
looker.A_PlaySound(looker.SeeSound, CHAN_VOICE);
|
|
}
|
|
looker.SetState(looker.SeeState);
|
|
looker.bInCombat = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|