raze/wadsrc/static/zscript/games/duke/actors/flamethrowerflame.zs
Christoph Oelckers 9783b8c402 - scriptified World Tour's flamethrowerflame.
The first of 3 mixed native/CON items which are the last things remaining in the main thinker loops.
2023-01-28 16:31:45 +01:00

192 lines
4.4 KiB
Text

class DukeFlamethrowerFlame : DukeActor
{
default
{
pic "FLAMETHROWERFLAME";
}
override void Tick()
{
Console.Printf("ticky");
let sectp = self.sector;
double xx;
Super.Tick(); // Run CON or its replacement.
if (self.bDestroyed) return; // killed by script.
self.temp_data[0]++;
if (sectp.lotag == ST_2_UNDERWATER)
{
let spawned = self.spawn("DukeExplosion2");
if (spawned) spawned.shade = 127;
self.Destroy();
return;
}
let dapos = self.pos;
self.getglobalz();
int ds = self.temp_data[0] / 6;
if (self.scale.X < 0.1250)
{
self.scale.X += (ds * REPEAT_SCALE);
self.scale.Y = (self.scale.X);
}
self.clipdist += ds * 0.25;
if (self.temp_data[0] <= 2)
self.temp_data[3] = random(0, 9);
if (self.temp_data[0] > 30)
{
let spawned = self.spawn("DukeExplosion2");
if (spawned) spawned.shade = 127;
self.Destroy();
return;
}
CollisionData coll;
self.movesprite_ex((self.angle.ToVector() * self.vel.X, self.vel.Z), CLIPMASK1, coll);
if (self.sector == null)
{
self.Destroy();
return;
}
if (coll.type != kHitSprite)
{
if (self.pos.Z < self.ceilingz)
{
coll.setSector(self.sector);
self.vel.Z -= 1/256.;
}
else if ((self.pos.Z > self.floorz && self.sector.lotag != ST_1_ABOVE_WATER)
|| (self.pos.Z > self.floorz + 16 && self.sector.lotag == ST_1_ABOVE_WATER))
{
coll.setSector(self.sector);
if (self.sector.lotag != 1)
self.vel.Z += 1/256.;
}
}
if (coll.type != 0)
{
self.vel.XY = (0, 0);
self.vel.Z = 0;
if (coll.type == kHitSprite)
{
let hitact = DukeActor(coll.hitActor());
hitact.checkhitsprite(self);
if (hitact.isPlayer())
hitact.PlayActorSound("PISTOL_BODYHIT");
}
else if (coll.type == kHitWall)
{
self.SetPosition(dapos);
dlevel.checkhitwall(coll.hitWall(), self, self.pos);
}
else if (coll.type == kHitSector)
{
self.SetPosition(dapos);
if (self.vel.Z < 0)
dlevel.checkhitceiling(self.sector, self);
}
if (self.scale.X >= 0.15625)
{
int x = self.extra;
self.hitradius(gs.rpgblastradius, x >> 2, x >> 1, x - (x >> 2), x);
}
else
{
int x = self.extra + (Duke.global_random() & 3);
self.hitradius((gs.rpgblastradius >> 1), x >> 2, x >> 1, x - (x >> 2), x);
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
override bool shootthis(DukeActor actor, DukePlayer p, Vector3 spos, double sang) const
{
Console.Printf("launching");
double vel, zvel = 0;
if (actor.extra >= 0)
actor.shade = -96;
vel = 25;
DukeActor spawned = nullptr;
if (p == null)
{
double x;
DukePlayer j;
[j, x] = actor.findplayer();
sang = (j.Actor.opos.XY - spos.XY).Angle();
if (actor.checktype("BOSS5"))
{
vel = 33;
spos.Z += 24;
}
else if (actor.checktype("BOSS3"))
spos.Z -= 32;
double dist = (j.actor.pos.XY - actor.pos.XY).Length();
if (dist != 0)
zvel = (((j.actor.opos.Z + j.actor.oviewzoffset - spos.Z) * vel) / dist);
if (actor.badguy() && (actor.hitag & face_player_smart) != 0)
sang = actor.Angle + Raze.BAngToDegree * random(-16, 15);
}
else
{
[vel, zvel] = Raze.setFreeAimVelocity(vel, zvel, p.getPitchWithView(), 40.5);
// WTF???
double myang = 90. - (180. - abs(abs((spos.XY - p.actor.pos.XY).Angle() - sang) - 180.));
if (p.actor.vel.X != 0)
vel = ((myang / 90.) * p.actor.vel.X) + 25;
}
if (actor.sector.lotag == ST_2_UNDERWATER && (random(0, 4)) == 0)
spawned = actor.spawn("DukeWaterBubble");
if (spawned == nullptr)
{
spawned = actor.spawn("DukeFlamethrowerFlame");
if (!spawned) return true;
spawned.vel.X = vel;
spawned.vel.Z = zvel;
}
Vector3 offset;
offset.X = cos(sang + Raze.BAngToDegree * 118) * (1024 / 448.); // Yes, these angles are really different!
offset.Y = sin(sang + Raze.BAngToDegree * 112) * (1024 / 448.);
offset.Z = -1;
spawned.pos = spos + offset;
spawned.pos.Z--;
spawned.sector = actor.sector;
spawned.cstat = CSTAT_SPRITE_YCENTER;
spawned.Angle = sang;
spawned.scale = (0.03125, 0.03125);
spawned.clipdist = 10;
spawned.yint = Duke.GetPlayerIndex(p);
spawned.ownerActor = actor;
if (p == null)
{
if (actor.checktype("BOSS5"))
{
spawned.pos += sang.ToVector() * (128. / 7);
spawned.scale = (0.15625, 0.15625);
}
}
return true;
}
}