2022-12-23 08:17:51 +00:00
|
|
|
class DukeShrinker : DukeActor
|
|
|
|
{
|
|
|
|
default
|
|
|
|
{
|
|
|
|
pic "SHRINKER";
|
|
|
|
}
|
|
|
|
|
|
|
|
override bool ShootThis(DukeActor shooter, DukePlayer p, Vector3 pos, double ang) const
|
|
|
|
{
|
|
|
|
double vel = 48.;
|
|
|
|
double zvel;
|
|
|
|
if (shooter.extra >= 0) shooter.shade = -96;
|
|
|
|
if (p != null)
|
|
|
|
{
|
|
|
|
let aimed = Raze.IsNamWW2GI()? null : shooter.aim(self);
|
|
|
|
if (aimed)
|
|
|
|
{
|
|
|
|
double dal = ((aimed.scale.X * aimed.spriteHeight()) * 0.5); // note the incorrect scale this uses!
|
|
|
|
double dist = (p.actor.pos.XY - aimed.pos.XY).Length();
|
|
|
|
zvel = ((aimed.pos.Z - pos.Z - dal - 4) * 48) / dist;
|
|
|
|
ang = (aimed.pos.XY - pos.XY).Angle();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
[vel, zvel] = Raze.setFreeAimVelocity(vel, zvel, p.getPitchWithView(), 49.);
|
|
|
|
}
|
|
|
|
else if (shooter.statnum != STAT_EFFECTOR)
|
|
|
|
{
|
|
|
|
double x;
|
|
|
|
DukePlayer j;
|
|
|
|
[j, x] = shooter.findplayer();
|
|
|
|
double dist = (j.actor.pos.XY - shooter.pos.XY).Length();
|
2022-12-23 16:53:04 +00:00
|
|
|
zvel = ((j.actor.pos.Z + j.actor.viewzoffset - pos.Z) * 32) / dist;
|
2022-12-23 08:17:51 +00:00
|
|
|
}
|
|
|
|
else zvel = 0;
|
|
|
|
|
|
|
|
let spawned = dlevel.SpawnActor(shooter.sector, pos.plusZ(2) + ang.ToVector() * 0.25, "DukeShrinkSpark", -16, (0.4375, 0.4375), ang, vel, zvel, shooter, STAT_PROJECTILE);
|
|
|
|
|
|
|
|
if (spawned)
|
|
|
|
{
|
|
|
|
spawned.cstat = CSTAT_SPRITE_YCENTER;
|
|
|
|
spawned.clipdist = 8;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
class NamShrinker : DukeShrinker
|
|
|
|
{
|
|
|
|
default
|
|
|
|
{
|
|
|
|
+NOAUTOAIM;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
class DukeShrinkSpark : DukeProjectile
|
|
|
|
{
|
|
|
|
default
|
|
|
|
{
|
|
|
|
spriteset "SHRINKSPARK", "SHRINKSPARK1", "SHRINKSPARK2", "SHRINKSPARK3";
|
|
|
|
+FULLBRIGHT;
|
|
|
|
+MIRRORREFLECT;
|
|
|
|
+NOFLOORPAL;
|
2022-12-29 14:19:22 +00:00
|
|
|
+NOCEILINGBLAST;
|
2022-12-29 14:57:03 +00:00
|
|
|
+HITRADIUS_DONTHURTSHOOTER;
|
|
|
|
+HITRADIUS_NODAMAGE;
|
2022-12-23 08:17:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
override void posthiteffect(CollisionData coll)
|
|
|
|
{
|
|
|
|
self.spawn('DukeShrinkerExplosion');
|
|
|
|
self.PlayActorSound("SHRINKER_HIT");
|
|
|
|
self.hitradius(gs.shrinkerblastradius, 0, 0, 0, 0);
|
|
|
|
self.Destroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
override bool animate(tspritetype tspr)
|
|
|
|
{
|
|
|
|
tspr.setSpritePic(self, (PlayClock >> 4) & 3);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
override class<DukeActor> GetRadiusDamageType(int targhealth)
|
|
|
|
{
|
|
|
|
return 'DukeShrinkSpark';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class DukeShrinkerExplosion : DukeActor
|
|
|
|
{
|
|
|
|
default
|
|
|
|
{
|
|
|
|
spriteset "SHRINKEREXPLOSION";
|
|
|
|
+FULLBRIGHT;
|
|
|
|
+FORCERUNCON;
|
|
|
|
}
|
|
|
|
|
|
|
|
override void Initialize()
|
|
|
|
{
|
|
|
|
let owner = self.ownerActor;
|
|
|
|
if (owner != self)
|
|
|
|
{
|
|
|
|
self.Angle = owner.Angle;
|
|
|
|
self.cstat = CSTAT_SPRITE_YCENTER | randomXFlip();
|
|
|
|
double c,f;
|
|
|
|
[c, f] = self.sector.getSlopes(self.pos.XY);
|
|
|
|
self.pos.Z = min(self.pos.Z, f - 12);
|
|
|
|
}
|
|
|
|
self.shade = -64;
|
|
|
|
self.scale = (0.5, 0.5);
|
|
|
|
self.ChangeStat(STAT_MISC);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|