- scriptified shootstuff.

This commit is contained in:
Christoph Oelckers 2022-12-23 19:56:39 +01:00
parent 9085157130
commit e97fc54179
13 changed files with 196 additions and 263 deletions

View file

@ -175,6 +175,8 @@ static FFlagDef DukeActorFlagDefs[] =
DEFINE_FLAG(SFLAG3, NOGRAVITY, DDukeActor, flags3),
DEFINE_FLAG(SFLAG3, SIMPLEINIT, DDukeActor, flags3),
DEFINE_FLAG(SFLAG3, NOHITSCANHIT, DDukeActor, flags1),
DEFINE_FLAG(SFLAG3, SPECIALINIT, DDukeActor, flags3),
DEFINE_FLAG(SFLAG3, DONTLIGHTSHOOTER, DDukeActor, flags3),
};

View file

@ -408,6 +408,9 @@ enum sflags3_t
SFLAG3_NOGRAVITY = 0x00000040, // disables makeitfall.
SFLAG3_SIMPLEINIT = 0x00000080, // Internal: skip default init stuff in DukeActor::Initialize.
SFLAG3_NOHITSCANHIT = 0x00000100, // just pretend the hit never happened. RR's tornado uses it.
SFLAG3_SPECIALINIT = 0x00000200, // special aiming case for Duke's BOSS2
SFLAG3_DONTLIGHTSHOOTER = 0x00000400,
};
using EDukeFlags3 = TFlags<sflags3_t, uint32_t>;

View file

@ -81,107 +81,6 @@ void incur_damage_d(player_struct* p)
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void shootstuff(DDukeActor* actor, int p, DVector3 pos, DAngle ang, int atwith)
{
sectortype* sect = actor->sector();
double vel, zvel;
int scount;
if (actor->spr.extra >= 0) actor->spr.shade = -96;
scount = 1;
if (atwith == DTILE_SPIT) vel = 292 / 16.;
else
{
if (atwith == DTILE_COOLEXPLOSION1)
{
if (actor->spr.picnum == DTILE_BOSS2) vel = 644 / 16.;
else vel = 348 / 16.;
pos.Z -= 2;
}
else
{
vel = 840 / 16.;
pos.Z -= 2;
}
}
if (p >= 0)
{
auto aimed = aim(actor, AUTO_AIM_ANGLE);
if (aimed)
{
auto tex = TexMan.GetGameTexture(aimed->spr.spritetexture());
double dal = ((aimed->spr.scale.X * tex->GetDisplayHeight()) * 0.5) - 12;
double dist = (ps[p].GetActor()->spr.pos.XY() - aimed->spr.pos.XY()).Length();
zvel = ((aimed->spr.pos.Z - pos.Z - dal) * vel) / dist;
ang = (aimed->spr.pos.XY() - pos.XY()).Angle();
}
else
setFreeAimVelocity(vel, zvel, ps[p].Angles.getPitchWithView(), 49.);
}
else
{
double x;
int j = findplayer(actor, &x);
ang += DAngle22_5 / 8 - randomAngle(22.5 / 4);
#if 1
double dist = (ps[j].GetActor()->spr.pos.XY() - actor->spr.pos.XY()).Length();
zvel = ((ps[j].GetActor()->getPrevOffsetZ() - pos.Z + 3) * vel) / dist;
#else
// this is for pitch corrected velocity
auto dist = (ps[j].GetActor()->spr.pos - actor->spr.pos).Resized(vel);
vel = dist.XY().Length();
zvel = dist.Z;
#endif
}
double oldzvel = zvel;
double scale = p >= 0? 0.109375 : 0.28125;
if (atwith == DTILE_SPIT)
{
pos.Z -= 10;
}
// Whatever else was here always got overridden by the final 'p>=0' check.
while (scount > 0)
{
auto spawned = CreateActor(sect, pos, atwith, -127, DVector2(scale, scale), ang, vel, zvel, actor, 4);
if (!spawned) return;
spawned->spr.extra += (krand() & 7);
if (atwith == DTILE_COOLEXPLOSION1)
{
spawned->spr.shade = 0;
if (actor->spr.picnum == DTILE_BOSS2)
{
auto ovel = spawned->vel.X;
spawned->vel.X = 64;
ssp(spawned, CLIPMASK0);
spawned->vel.X = ovel;
spawned->spr.Angles.Yaw += DAngle22_5 - randomAngle(45);
}
}
spawned->spr.cstat = CSTAT_SPRITE_YCENTER;
spawned->clipdist = 1;
ang = actor->spr.Angles.Yaw + DAngle22_5 / 4 - randomAngle(22.5 / 2);
zvel = oldzvel + 2 - krandf(4);
scount--;
}
}
//---------------------------------------------------------------------------
//
//
@ -389,12 +288,6 @@ void shoot_d(DDukeActor* actor, int atwith, PClass *cls)
switch (atwith)
{
case DTILE_FIRELASER:
case DTILE_SPIT:
case DTILE_COOLEXPLOSION1:
shootstuff(actor, p, spos, sang, atwith);
return;
case DTILE_FREEZEBLAST:
spos.Z += 3;
[[fallthrough]];

View file

@ -83,116 +83,6 @@ void incur_damage_r(player_struct* p)
//
//---------------------------------------------------------------------------
static void shootstuff(DDukeActor* actor, int p, DVector3 pos, DAngle ang, int atwith)
{
auto sect = actor->sector();
double vel = 0, zvel;
int scount;
if (isRRRA())
{
if (atwith != RTILE_SHITBALL && actor->spr.extra >= 0) actor->spr.shade = -96;
scount = 1;
if (atwith == RTILE_SHITBALL)
{
if (actor->spr.picnum == RTILE_MAMA)
vel = 37.5;
else
vel = 25;
}
}
else
{
if (actor->spr.extra >= 0) actor->spr.shade = -96;
scount = 1;
if (atwith == RTILE_SHITBALL) vel = 25;
}
if (atwith != RTILE_SHITBALL)
{
vel = 52.5;
pos.Z -= 4;
if (actor->spr.picnum == RTILE_HULK)
{
pos += (actor->spr.Angles.Yaw + DAngle45).ToVector() * 16;
pos.Z += 12;
}
if (actor->spr.picnum == RTILE_VIXEN)
{
pos.Z -= 12;
}
}
if (p >= 0)
{
auto aimed = aim(actor, AUTO_AIM_ANGLE);
pos += (actor->spr.Angles.Yaw + DAngle22_5 * 1.25).ToVector() * 16;
if (aimed)
{
auto tex = TexMan.GetGameTexture(aimed->spr.spritetexture());
double dal = ((aimed->spr.scale.X * tex->GetDisplayHeight()) * 0.5) - 12;
double dist = (ps[p].GetActor()->spr.pos.XY() - aimed->spr.pos.XY()).Length();
zvel = ((aimed->spr.pos.Z - pos.Z - dal) * vel) / dist;
ang = (aimed->spr.pos.XY() - pos.XY()).Angle();
}
else
{
setFreeAimVelocity(vel, zvel, ps[p].Angles.getPitchWithView(), 49.);
}
}
else
{
double x;
int j = findplayer(actor, &x);
if (actor->spr.picnum == RTILE_HULK)
ang -= randomAngle(22.5 / 4);
else if (actor->spr.picnum == RTILE_VIXEN)
ang -= randomAngle(22.5 / 8);
else if (actor->spr.picnum != RTILE_UFOBEAM)
ang += DAngle22_5 / 8. - randomAngle(22.5 / 4);
double dist = (ps[j].GetActor()->spr.pos.XY() - actor->spr.pos.XY()).Length();
zvel = ((ps[j].GetActor()->getPrevOffsetZ() - pos.Z + 3) * vel) / dist;
}
double oldzvel = zvel;
double scale = p >= 0? 0.109375 : atwith == RTILE_VIXENSHOT? 0.125 : 0.28125;
if (atwith == RTILE_SHITBALL)
{
if (!isRRRA() || actor->spr.picnum != RTILE_MAMA) pos.Z -= 10; else pos.Z -= 20;
}
while (scount > 0)
{
auto spawned = CreateActor(sect, pos, atwith, -127, DVector2(scale, scale), ang, vel, zvel, actor, 4);
if (!spawned) return;
spawned->spr.extra += (krand() & 7);
spawned->spr.cstat = CSTAT_SPRITE_YCENTER;
spawned->clipdist = 1;
ang = actor->spr.Angles.Yaw + DAngle22_5 / 4 + randomAngle(22.5 / 2);
zvel = oldzvel + 2 - krandf(4);
if (atwith == RTILE_FIRELASER)
{
spawned->spr.scale = DVector2(0.125, 0.125);
}
scount--;
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void shootrpg(DDukeActor* actor, int p, DVector3 pos, DAngle ang, int atwith)
{
auto sect = actor->sector();
@ -352,12 +242,6 @@ void shoot_r(DDukeActor* actor, int atwith, PClass* cls)
switch (atwith)
{
case RTILE_FIRELASER:
case RTILE_SHITBALL:
case RTILE_VIXENSHOT:
shootstuff(actor, p, spos, sang, atwith);
return;
case RTILE_RPG2:
case RTILE_BOATGRENADE:
if (isRRRA()) goto rrra_rpg2;

View file

@ -78,7 +78,7 @@ spawnclasses
1526 = DukeBloodSplat2, noskill
1527 = DukeBloodSplat3, noskill
1528 = DukeBloodSplat4, noskill
3420 = DukeFireLaser, noskill
3420 = RedneckFireLaser, noskill
3471 = RedneckOWhip, noskill
3475 = RedneckUWhip, noskill
2095 = RedneckVixenShot, noskill

View file

@ -160,6 +160,7 @@ version "4.10"
#include "zscript/games/duke/actors/dukeweapons/melee.zs"
#include "zscript/games/duke/actors/dukeweapons/hitscan.zs"
#include "zscript/games/duke/actors/dukeweapons/projectiles.zs"
#include "zscript/games/duke/actors/dukeweapons/shrinker.zs"
#include "zscript/games/duke/actors/dukeweapons/grower.zs"
#include "zscript/games/duke/actors/dukeweapons/tripbomb.zs"

View file

@ -5,6 +5,7 @@ class DukeBoss2 : DukeBoss1
pic "BOSS2";
-ALTHITSCANDIRECTION;
+NONSMOKYROCKET; // If this wasn't needed for a CON defined actor it could be handled better
+SPECIALINIT;
}
override void PlayFTASound()

View file

@ -205,6 +205,7 @@ class RedneckUfoBeam : DukeActor
{
pic "UFOBEAM";
+BADGUY;
ProjectileSpread 0;
}
override bool animate(tspritetype t)

View file

@ -0,0 +1,60 @@
extend class DukeActor
{
DukeActor shootprojectile1(DukeActor actor, DukePlayer p, Vector3 pos, double ang, double vel, double zofs_post = 0, double scale = 0) const
{
sectortype sect = actor.sector;
int scount;
double zvel;
if (actor.extra >= 0 && !self.bDONTLIGHTSHOOTER) actor.shade = -96; // not for shitball
if (p != null)
{
let aimed = actor.aim(self);
if (aimed)
{
double dal = ((aimed.scale.X * aimed.spriteHeight()) * 0.5);
double dist = (p.actor.pos.XY - aimed.pos.XY).Length();
zvel = ((aimed.pos.Z - pos.Z - dal) * vel) / dist;
ang = (aimed.pos.XY - pos.XY).Angle();
}
else
{
[vel, zvel] = Raze.setFreeAimVelocity(vel, zvel, p.getPitchWithView(), 49.);
}
}
else
{
pos += actor.SpecialProjectileOffset();
let j = actor.findplayer();
if (actor.projectilespread < 0)
ang += frandom(self.projectilespread, 0);
else
ang += frandom(-self.projectilespread / 2, self.projectilespread / 2);
double dist = (j.actor.pos.XY - actor.pos.XY).Length();
zvel = ((j.actor.opos.Z + j.actor.viewzoffset - pos.Z + 3) * vel) / dist;
}
if (scale <= 0) scale = p? 0.109375 : 0.28125;
pos.Z += zofs_post;
let spawned = dlevel.SpawnActor(sect, pos, self.GetClass(), -127, (scale, scale), ang, vel, zvel, actor, STAT_PROJECTILE);
if (!spawned) return nullptr;
spawned.extra += random(0, 7);
spawned.cstat = CSTAT_SPRITE_YCENTER;
spawned.clipdist = 1;
return spawned;
}
virtual Vector3 SpecialProjectileOffset()
{
return (0, 0, 0);
}
}

View file

@ -227,12 +227,14 @@ class DukeFirelaser : DukeProjectile // Liztrooper shot
return false;
}
override bool animate(tspritetype tspr)
override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const
{
if (Raze.isRR()) tspr.setSpritePic(self, ((PlayClock >> 2) % 6));
pos.Z -= 2;
shootprojectile1(actor, p, pos, ang, 52.5, 0);
return true;
}
}
class DukeFirelaserTrail : DukeActor
@ -257,6 +259,29 @@ class DukeFirelaserTrail : DukeActor
if (Raze.isRR()) tspr.setSpritePic(self, ((PlayClock >> 2) % 6));
return true;
}
}
class RedneckFirelaser : DukeFirelaser
{
default
{
spriteset "FIRELASER", "FIRELASER2", "FIRELASER3", "FIRELASER4", "FIRELASER5", "FIRELASER6";
}
override bool animate(tspritetype tspr)
{
tspr.setSpritePic(self, ((PlayClock >> 2) % 6));
return true;
}
override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const
{
pos.Z -= 4;
shootprojectile1(actor, p, pos, ang, 52.5, 0, 0.125);
return true;
}
}
@ -476,6 +501,13 @@ class DukeSpit : DukeProjectile
}
return false;
}
override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const
{
pos.Z -= 10;
shootprojectile1(actor, p, pos, ang, 292/16., 0);
return true;
}
}
//---------------------------------------------------------------------------
@ -494,18 +526,23 @@ class DukeCoolExplosion1 : DukeProjectile // octabrain shot.
"COOLEXPLOSION16", "COOLEXPLOSION17", "COOLEXPLOSION18", "COOLEXPLOSION19", "COOLEXPLOSION20";
+FULLBRIGHT;
+MIRRORREFLECT;
+SPECIALINIT;
}
override void Initialize()
{
self.angle = self.ownerActor.angle;
self.shade = -64;
self.cstat = CSTAT_SPRITE_YCENTER | self.randomXFlip();
if (!bSIMPLEINIT)
{
// looks like this case is never used anywhere.
self.cstat = CSTAT_SPRITE_YCENTER | self.randomXFlip();
self.angle = self.ownerActor.angle;
self.shade = -64;
double c, f;
[c, f] = self.sector.getSlopes(self.pos.XY);
if (self.pos.Z > f - 12)
self.pos.Z = f - 12;
double c, f;
[c, f] = self.sector.getSlopes(self.pos.XY);
if (self.pos.Z > f - 12)
self.pos.Z = f - 12;
}
}
override bool premoveeffect()
@ -557,6 +594,27 @@ class DukeCoolExplosion1 : DukeProjectile // octabrain shot.
return true;
}
override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const
{
pos.Z -= 10;
let spawned = shootprojectile1(actor, p, pos, ang, 292/16., 0);
if (spawned)
{
spawned.shade = 0;
// special hack case.
if (actor.bSPECIALINIT)
{
let ovel = spawned.vel.X;
spawned.vel.X = 64;
spawned.DoMove(CLIPMASK0);
spawned.vel.X = ovel;
spawned.Angle += frandom(-22.5, 22.5);
}
}
return true;
}
}
//---------------------------------------------------------------------------
@ -731,21 +789,6 @@ class DukeFireball : DukeProjectile // WorldTour only
}
}
//---------------------------------------------------------------------------
//
// These 3 just use the base projectile code...
//
//---------------------------------------------------------------------------
class RedneckVixenShot : RedneckUWhip // COOLEXPLOSION1
{
default
{
pic "VIXENSHOT";
+INFLAME;
}
}
//---------------------------------------------------------------------------
//
//
@ -983,6 +1026,20 @@ class RedneckShitBall : DukeSpit
}
return true;
}
override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const
{
if (actor.bSPAWNRABBITGUTS)
{
shootprojectile1(actor, p, pos, ang, 37.5, -20);
}
else
{
shootprojectile1(actor, p, pos, ang, 25, -10);
}
return true;
}
}
//---------------------------------------------------------------------------

View file

@ -336,6 +336,7 @@ class RedneckHulk : DukeActor
+INTERNAL_BADGUY;
+KILLCOUNT;
+NORADIUSPUSH;
ProjectileSpread -5.625;
}
override void Initialize()
@ -343,6 +344,12 @@ class RedneckHulk : DukeActor
self.scale = (0.5, 0.5);
self.setClipDistFromTile();
}
override Vector3 SpecialProjectileOffset()
{
return ((self.Angle + 45).ToVector() * 16, 12);
}
}
class RedneckHulkStayput : RedneckHulk

View file

@ -6,16 +6,7 @@ class RedneckVixen : DukeActor
+INTERNAL_BADGUY;
+KILLCOUNT;
+LOOKALLAROUND;
}
class RedneckVixen : DukeActor
{
default
{
pic "VIXEN";
+INTERNAL_BADGUY;
+KILLCOUNT;
+LOOKALLAROUND;
ProjectileSpread -2.8125;
}
override void Initialize()
@ -31,6 +22,12 @@ class RedneckVixen : DukeActor
self.setClipDistFromTile();
}
override Vector3 SpecialProjectileOffset()
{
return (0, 0, -12);
}
}
@ -68,10 +65,10 @@ class RedneckUWhip : DukeProjectile
else
{
let j = actor.findplayer();
if (actor is 'RedneckVixen')
ang -= frandom(0, 22.5 / 8);
if (actor.projectilespread < 0)
ang += frandom(self.projectilespread, 0);
else
ang += frandom(-22.5 / 8, 22.5 / 8);
ang += frandom(-self.projectilespread / 2, self.projectilespread / 2);
double dist = (j.actor.pos.XY - actor.pos.XY).Length();
zvel = ((j.actor.opos.Z + j.actor.oviewzoffset - pos.Z + 3) * vel) / dist;
@ -112,3 +109,28 @@ class RedneckOWhip : RedneckUWhip
return true;
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
class RedneckVixenShot : DukeActor
{
default
{
pic "VIXENSHOT";
+INFLAME;
+FULLBRIGHT;
}
override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const
{
pos.Z -= 4;
shootprojectile1(actor, p, pos, ang, 52.5, 0, 0.125);
return true;
}
}

View file

@ -90,6 +90,7 @@ class DukeActor : CoreActor native
lookallarounddefault;
falladjustz 24;
autoaimangle 8.4375;
projectilespread 5.625;
}
enum EStatnums
{
@ -149,6 +150,7 @@ class DukeActor : CoreActor native
meta int strength;
meta double autoaimangle;
meta double sparkoffset;
meta double projectilespread;
property prefix: none;
property gutsoffset: gutsoffset;
@ -157,7 +159,7 @@ class DukeActor : CoreActor native
property strength: strength;
property autoaimangle: autoaimangle;
property sparkoffset: sparkoffset;
property projectilespread: projectilespread;
native void SetSpritesetImage(int index);
native int GetSpritesetSize();