mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-15 00:41:55 +00:00
- scriptified World Tour's flamethrowerflame.
The first of 3 mixed native/CON items which are the last things remaining in the main thinker loops.
This commit is contained in:
parent
dce0afe499
commit
9783b8c402
12 changed files with 244 additions and 224 deletions
|
@ -822,6 +822,7 @@ DEFINE_FIELD_NAMED(DCoreActor, spr.Angles.Yaw, angle)
|
|||
DEFINE_FIELD_NAMED(DCoreActor, spr.Angles.Pitch, pitch)
|
||||
DEFINE_FIELD(DCoreActor, vel)
|
||||
DEFINE_FIELD(DCoreActor, viewzoffset)
|
||||
DEFINE_FIELD(DCoreActor, oviewzoffset)
|
||||
DEFINE_FIELD(DCoreActor, opos)
|
||||
|
||||
void coreactor_setpos(DCoreActor* self, double x, double y, double z, int relink)
|
||||
|
|
|
@ -577,10 +577,12 @@ void tickstat(int stat, bool deleteinvalid)
|
|||
if (actorflag(act, SFLAG2_DIENOW) || act->sector() == nullptr || (deleteinvalid && act->spr.scale.X == 0))
|
||||
{
|
||||
act->Destroy();
|
||||
continue;
|
||||
}
|
||||
else if (stat != STAT_ACTOR || !badguy(act) || !monsterCheatCheck(act))
|
||||
{
|
||||
CallTick(act);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -991,138 +991,6 @@ void movetransports_d(void)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void flamethrowerflame(DDukeActor *actor)
|
||||
{
|
||||
auto sectp = actor->sector();
|
||||
double xx;
|
||||
int p = findplayer(actor, &xx);
|
||||
execute(actor, p, xx);
|
||||
if (actor->ObjectFlags & OF_EuthanizeMe) return; // killed by script.
|
||||
actor->temp_data[0]++;
|
||||
if (sectp->lotag == 2)
|
||||
{
|
||||
spawn(actor, DTILE_EXPLOSION2)->spr.shade = 127;
|
||||
actor->Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
auto dapos = actor->spr.pos;
|
||||
|
||||
getglobalz(actor);
|
||||
|
||||
int ds = actor->temp_data[0] / 6;
|
||||
if (actor->spr.scale.X < 0.1250)
|
||||
{
|
||||
actor->spr.scale.X += (ds * REPEAT_SCALE);
|
||||
actor->spr.scale.Y = (actor->spr.scale.X);
|
||||
}
|
||||
actor->clipdist += ds * 0.25;
|
||||
if (actor->temp_data[0] <= 2)
|
||||
actor->temp_data[3] = krand() % 10;
|
||||
if (actor->temp_data[0] > 30)
|
||||
{
|
||||
spawn(actor, DTILE_EXPLOSION2)->spr.shade = 127;
|
||||
actor->Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
Collision coll;
|
||||
movesprite_ex(actor, DVector3(actor->spr.Angles.Yaw.ToVector() * actor->vel.X, actor->vel.Z), CLIPMASK1, coll);
|
||||
|
||||
if (!actor->insector())
|
||||
{
|
||||
actor->Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
if (coll.type != kHitSprite)
|
||||
{
|
||||
if (actor->spr.pos.Z < actor->ceilingz)
|
||||
{
|
||||
coll.setSector(actor->sector());
|
||||
actor->vel.Z -= 1/256.;
|
||||
}
|
||||
else if ((actor->spr.pos.Z > actor->floorz && actor->sector()->lotag != 1)
|
||||
|| (actor->spr.pos.Z > actor->floorz + 16 && actor->sector()->lotag == 1))
|
||||
{
|
||||
coll.setSector(actor->sector());
|
||||
if (actor->sector()->lotag != 1)
|
||||
actor->vel.Z += 1/256.;
|
||||
}
|
||||
}
|
||||
|
||||
if (coll.type != 0) {
|
||||
actor->vel.XY().Zero();
|
||||
actor->vel.Z = 0;
|
||||
if (coll.type == kHitSprite)
|
||||
{
|
||||
fi.checkhitsprite(coll.actor(), actor);
|
||||
if (coll.actor()->isPlayer())
|
||||
S_PlayActorSound(PISTOL_BODYHIT, coll.actor());
|
||||
}
|
||||
else if (coll.type == kHitWall)
|
||||
{
|
||||
SetActor(actor, dapos);
|
||||
checkhitwall(actor, coll.hitWall, actor->spr.pos);
|
||||
}
|
||||
else if (coll.type == kHitSector)
|
||||
{
|
||||
SetActor(actor, dapos);
|
||||
if (actor->vel.Z < 0)
|
||||
checkhitceiling(actor->sector());
|
||||
}
|
||||
|
||||
if (actor->spr.scale.X >= 0.15625)
|
||||
{
|
||||
int x = actor->spr.extra;
|
||||
fi.hitradius(actor, gs.rpgblastradius, x >> 2, x >> 1, x - (x >> 2), x);
|
||||
}
|
||||
else
|
||||
{
|
||||
int x = actor->spr.extra + (global_random & 3);
|
||||
fi.hitradius(actor, (gs.rpgblastradius >> 1), x >> 2, x >> 1, x - (x >> 2), x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void moveactors_d(void)
|
||||
{
|
||||
DukeStatIterator it(STAT_ACTOR);
|
||||
while (auto act = it.Next())
|
||||
{
|
||||
if (act->spr.scale.X == 0 || act->spr.sectp == nullptr || actorflag(act, SFLAG2_DIENOW))
|
||||
{
|
||||
act->Destroy();
|
||||
}
|
||||
else if (monsterCheatCheck(act) && badguy(act))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (isWorldTour() && act->spr.picnum == DTILE_FLAMETHROWERFLAME)
|
||||
{
|
||||
flamethrowerflame(act);
|
||||
}
|
||||
else
|
||||
{
|
||||
CallTick(act);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void fireflyflyingeffect(DDukeActor *actor)
|
||||
{
|
||||
double xx;
|
||||
|
@ -1745,7 +1613,7 @@ void think_d(void)
|
|||
|
||||
actortime.Reset();
|
||||
actortime.Clock();
|
||||
moveactors_d(); //ST 1
|
||||
tickstat(STAT_ACTOR); //ST 1
|
||||
actortime.Unclock();
|
||||
|
||||
moveeffectors_d(); //ST 3
|
||||
|
|
|
@ -140,91 +140,6 @@ static void shootfireball(DDukeActor *actor, int p, DVector3 pos, DAngle ang)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void shootflamethrowerflame(DDukeActor* actor, int p, DVector3 spos, DAngle sang)
|
||||
{
|
||||
double vel, zvel = 0;
|
||||
|
||||
if (actor->spr.extra >= 0)
|
||||
actor->spr.shade = -96;
|
||||
vel = 25;
|
||||
|
||||
DDukeActor* spawned = nullptr;
|
||||
if (p < 0)
|
||||
{
|
||||
double x;
|
||||
int j = findplayer(actor, &x);
|
||||
sang = (ps[j].GetActor()->opos.XY() - spos.XY()).Angle();
|
||||
|
||||
if (actor->spr.picnum == DTILE_BOSS5)
|
||||
{
|
||||
vel = 33;
|
||||
spos.Z += 24;
|
||||
}
|
||||
else if (actor->spr.picnum == DTILE_BOSS3)
|
||||
spos.Z -= 32;
|
||||
|
||||
double dist = (ps[j].GetActor()->spr.pos.XY() - actor->spr.pos.XY()).Length();
|
||||
if (dist != 0)
|
||||
zvel = (((ps[j].GetActor()->getPrevOffsetZ() - spos.Z) * vel) / dist);
|
||||
|
||||
if (badguy(actor) && (actor->spr.hitag & face_player_smart) != 0)
|
||||
sang = actor->spr.Angles.Yaw + mapangle((krand() & 31) - 16);
|
||||
|
||||
if (actor->sector()->lotag == 2 && (krand() % 5) == 0)
|
||||
spawned = spawn(actor, DTILE_WATERBUBBLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
setFreeAimVelocity(vel, zvel, ps[p].Angles.getPitchWithView(), 40.5);
|
||||
|
||||
// WTF???
|
||||
DAngle myang = DAngle90 - (DAngle180 - abs(abs((spos.XY() - ps[p].GetActor()->spr.pos.XY()).Angle() - sang) - DAngle180));
|
||||
if (ps[p].GetActor()->vel.X != 0)
|
||||
vel = ((myang / DAngle90) * ps[p].GetActor()->vel.X) + 25;
|
||||
if (actor->sector()->lotag == 2 && (krand() % 5) == 0)
|
||||
spawned = spawn(actor, DTILE_WATERBUBBLE);
|
||||
}
|
||||
|
||||
if (spawned == nullptr)
|
||||
{
|
||||
spawned = spawn(actor, DTILE_FLAMETHROWERFLAME);
|
||||
if (!spawned) return;
|
||||
spawned->vel.X = vel;
|
||||
spawned->vel.Z = zvel;
|
||||
}
|
||||
|
||||
|
||||
DVector3 offset;
|
||||
offset.X = (sang + DAngle::fromBuild(118)).Cos() * (1024 / 448.); // Yes, these angles are really different!
|
||||
offset.Y = (sang + DAngle::fromBuild(112)).Sin() * (1024 / 448.);
|
||||
offset.Z = -1;
|
||||
|
||||
spawned->spr.pos = spos + offset;
|
||||
spawned->spr.pos.Z--;
|
||||
spawned->setsector(actor->sector());
|
||||
spawned->spr.cstat = CSTAT_SPRITE_YCENTER;
|
||||
spawned->spr.Angles.Yaw = sang;
|
||||
spawned->spr.scale = DVector2(0.03125, 0.03125);
|
||||
spawned->clipdist = 10;
|
||||
spawned->spr.yint = p;
|
||||
spawned->SetOwner(actor);
|
||||
|
||||
if (p == -1)
|
||||
{
|
||||
if (actor->spr.picnum == DTILE_BOSS5)
|
||||
{
|
||||
spawned->spr.pos += sang.ToVector() * (128. / 7);
|
||||
spawned->spr.scale = DVector2(0.15625, 0.15625);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void shootknee(DDukeActor* actor, int p, DVector3 pos, DAngle ang)
|
||||
{
|
||||
auto sectp = actor->sector();
|
||||
|
@ -1074,10 +989,6 @@ void shoot_d(DDukeActor* actor, int atwith, PClass *cls)
|
|||
shootfireball(actor, p, spos, sang);
|
||||
return;
|
||||
|
||||
case DTILE_FLAMETHROWERFLAME:
|
||||
shootflamethrowerflame(actor, p, spos, sang);
|
||||
return;
|
||||
|
||||
case DTILE_FIREFLY: // DTILE_BOSS5 shot
|
||||
{
|
||||
auto k = spawn(actor, atwith);
|
||||
|
|
|
@ -212,6 +212,20 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Duke, StopCommentary, StopCommentary)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int getPlayerIndex(player_struct* p)
|
||||
{
|
||||
if (!p) return -1;
|
||||
return int(p - ps);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(_Duke, getPlayerIndex, getPlayerIndex)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_POINTER(p, player_struct);
|
||||
ACTION_RETURN_INT(getPlayerIndex(p));
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_GLOBAL_UNSIZED(dlevel)
|
||||
DEFINE_GLOBAL(camsprite)
|
||||
|
||||
|
|
|
@ -5,4 +5,5 @@ spawnclasses
|
|||
5736 = DukeGenericDestructible, "WTGLASS1", "", "GLASS_BREAKING", spawnglass
|
||||
5737 = DukeGenericDestructible, "WTGLASS2", "", "GLASS_BREAKING", spawnglass
|
||||
5294 = DeveloperCommentary
|
||||
1891 = DukeFlamethrowerFlame
|
||||
}
|
||||
|
|
|
@ -102,6 +102,7 @@ version "4.10"
|
|||
#include "zscript/games/duke/actors/bloodpool.zs"
|
||||
#include "zscript/games/duke/actors/toilet.zs"
|
||||
|
||||
#include "zscript/games/duke/actors/flamethrowerflame.zs"
|
||||
|
||||
#include "zscript/games/duke/actors/redneckmisc.zs"
|
||||
#include "zscript/games/duke/actors/emptybike.zs"
|
||||
|
|
|
@ -57,6 +57,7 @@ class CoreActor native
|
|||
native double pitch;
|
||||
native Vector3 vel;
|
||||
native double viewzoffset;
|
||||
native double oviewzoffset;
|
||||
|
||||
native readonly int16 spritesetindex;
|
||||
native readonly int spawnindex;
|
||||
|
|
192
wadsrc/static/zscript/games/duke/actors/flamethrowerflame.zs
Normal file
192
wadsrc/static/zscript/games/duke/actors/flamethrowerflame.zs
Normal file
|
@ -0,0 +1,192 @@
|
|||
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;
|
||||
}
|
||||
}
|
|
@ -116,6 +116,28 @@ class DukeActor : CoreActor native
|
|||
|
||||
};
|
||||
|
||||
enum amoveflags_t
|
||||
{
|
||||
face_player = 1,
|
||||
geth = 2,
|
||||
getv = 4,
|
||||
random_angle = 8,
|
||||
face_player_slow = 16,
|
||||
spin = 32,
|
||||
face_player_smart = 64,
|
||||
fleeenemy = 128,
|
||||
jumptoplayer_only = 256,
|
||||
justjump1 = 256,
|
||||
jumptoplayer = 257,
|
||||
seekplayer = 512,
|
||||
furthestdir = 1024,
|
||||
dodgebullet = 4096,
|
||||
justjump2 = 8192,
|
||||
windang = 16384,
|
||||
antifaceplayerslow = 32768
|
||||
};
|
||||
|
||||
|
||||
native void SetSpritesetImage(int index);
|
||||
native int GetSpritesetSize();
|
||||
|
||||
|
|
|
@ -170,6 +170,7 @@ struct Duke native
|
|||
native static void updatepindisplay(int tag, int pinmask);
|
||||
native static bool StartCommentary(int tag, DukeActor act);
|
||||
native static void StopCommentary();
|
||||
static native int getPlayerIndex(DukePlayer p);
|
||||
static int rnd(int val)
|
||||
{
|
||||
return (random(0, 255) >= (255 - (val)));
|
||||
|
@ -216,6 +217,7 @@ struct Duke native
|
|||
if (align != -1) x -= myfont.StringWidth(t) * (align == 0 ? 0.5 : 1);
|
||||
Screen.DrawText(myfont, Font.CR_NATIVEPAL, x, y + 2, t, DTA_FullscreenScale, fsmode, DTA_TranslationIndex, Translation.MakeID(Translation_Remap, trans), DTA_Color, Raze.shadeToLight(shade));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct DukePlayer native
|
||||
|
|
|
@ -264,6 +264,11 @@ struct Raze
|
|||
// Right now, with no MP support there is no need, though.
|
||||
}
|
||||
|
||||
static double, double setFreeAimVelocity(double vel, double zvel, double pitch, double zvspeed)
|
||||
{
|
||||
return vel * cos(pitch), sin(pitch) * zvspeed;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue