- scriptified the freezer projectile.

This commit is contained in:
Christoph Oelckers 2022-11-29 17:36:01 +01:00
parent 83080beed4
commit fcd05e38c9
10 changed files with 111 additions and 115 deletions

View file

@ -608,32 +608,6 @@ void detonate(DDukeActor *actor, int explosion)
//
//---------------------------------------------------------------------------
void bounce(DDukeActor* actor)
{
DVector3 vect(actor->spr.Angles.Yaw.ToVector() * actor->vel.X, actor->vel.Z);
auto sectp = actor->sector();
DAngle daang = sectp->walls[0].delta().Angle();
double k;
if (actor->spr.pos.Z < (actor->floorz + actor->ceilingz) * 0.5)
k = sectp->ceilingheinum;
else
k = sectp->floorheinum;
DVector3 davec(daang.Sin() * k, -daang.Cos() * k, 4096);
double dot = vect.dot(davec);
double l = davec.LengthSquared();
vect -= davec * (2 * dot / l);
actor->vel.Z = vect.Z;
actor->vel.X = vect.XY().Length();
actor->spr.Angles.Yaw = vect.Angle();
}
//---------------------------------------------------------------------------
//
//

View file

@ -803,20 +803,6 @@ static bool movefireball(DDukeActor* actor)
static bool weaponhitsprite(DDukeActor* proj, DDukeActor *targ, bool fireball)
{
if (proj->spr.picnum == FREEZEBLAST && targ->spr.pal == 1)
if (badguy(targ) || targ->isPlayer())
{
auto spawned = spawn(targ, TRANSPORTERSTAR);
if (spawned)
{
spawned->spr.pal = 1;
spawned->spr.scale = DVector2(0.5, 0.5);
}
proj->Destroy();
return true;
}
if (!isWorldTour() || proj->spr.picnum != FIREBALL || fireball)
fi.checkhitsprite(targ, proj);
@ -878,19 +864,6 @@ static bool weaponhitwall(DDukeActor *proj, walltype* wal, const DVector3 &oldpo
{
SetActor(proj, oldpos);
fi.checkhitwall(proj, wal, proj->spr.pos, proj->spr.picnum);
if (proj->spr.picnum == FREEZEBLAST)
{
if (wal->overpicnum != MIRROR && wal->picnum != MIRROR)
{
proj->spr.extra >>= 1;
proj->spr.yint--;
}
DAngle k = wal->delta().Angle();
proj->spr.Angles.Yaw = k * 2 - proj->spr.Angles.Yaw;
return true;
}
}
return false;
}
@ -928,19 +901,6 @@ static bool weaponhitsector(DDukeActor* proj, const DVector3& oldpos, bool fireb
proj->Destroy();
return true;
}
if (proj->spr.picnum == FREEZEBLAST)
{
bounce(proj);
ssp(proj, CLIPMASK1);
proj->spr.extra >>= 1;
if (proj->spr.scale.X > 0.125 )
proj->spr.scale.X += (-0.03125);
if (proj->spr.scale.Y > 0.125 )
proj->spr.scale.Y += (-0.03125);
proj->spr.yint--;
return true;
}
return false;
}
@ -1102,19 +1062,6 @@ void moveweapons_d(void)
switch(act->spr.picnum)
{
case FREEZEBLAST:
if (act->spr.yint < 1 || act->spr.extra < 2 || (act->vel.X == 0 && act->vel.Z == 0))
{
auto spawned = spawn(act,TRANSPORTERSTAR);
if (spawned)
{
spawned->spr.pal = 1;
spawned->spr.scale = DVector2(0.5, 0.5);
}
act->Destroy();
continue;
}
[[fallthrough]];
case FIREBALL:
// Twentieth Anniversary World Tour
if (act->spr.picnum == FIREBALL && !isWorldTour()) break;

View file

@ -836,18 +836,6 @@ bool weaponhitsector(DDukeActor *proj, const DVector3& oldpos)
fi.checkhitceiling(proj->sector());
}
if (!isRRRA() && proj->spr.picnum == FREEZEBLAST)
{
bounce(proj);
ssp(proj, CLIPMASK1);
proj->spr.extra >>= 1;
if (proj->spr.scale.X > 0.125 )
proj->spr.scale.X += (-0.03125);
if (proj->spr.scale.Y > 0.125 )
proj->spr.scale.Y += (-0.03125);
proj->spr.yint--;
return true;
}
return false;
}
@ -1014,19 +1002,6 @@ void moveweapons_r(void)
switch (proj->spr.picnum)
{
case FREEZEBLAST:
if (proj->spr.yint < 1 || proj->spr.extra < 2 || (proj->vel.X == 0 && proj->vel.Z == 0))
{
auto star = spawn(proj, TRANSPORTERSTAR);
if (star)
{
star->spr.pal = 1;
star->spr.scale = DVector2(0.5, 0.5);
}
proj->Destroy();
continue;
}
[[fallthrough]];
case RPG2:
case BOATGRENADE:
if (!isRRRA()) continue;

View file

@ -496,7 +496,6 @@ void animatesprites_d(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi
{
case EXPLOSION2:
case EXPLOSION2BOT:
case FREEZEBLAST:
case ATOMICHEALTH:
case GROWSPARK:
case CHAINGUN:

View file

@ -643,7 +643,6 @@ void animatesprites_r(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi
if (!isRRRA()) break;
[[fallthrough]];
case EXPLOSION2:
case FREEZEBLAST:
case ATOMICHEALTH:
case SAWBLADE:
case CHAINGUN:

View file

@ -37,14 +37,9 @@ void movefta();
void clearcameras(player_struct* p);
void RANDOMSCRAP(DDukeActor* i);
void detonate(DDukeActor* i, int explosion);
void bounce(DDukeActor* i);
void rpgexplode(DDukeActor* i, int j, const DVector3& pos, int EXPLOSION2, int EXPLOSIONBOT2, int newextra, int playsound);
void lotsofstuff(DDukeActor* s, int n, int spawntype);
bool respawnmarker(DDukeActor* i, int yellow, int green);
void forcesphere(DDukeActor* i, int forcesphere);
void recon(DDukeActor* i, int explosion, int firelaser, int attacksnd, int painsnd, int roamsnd, int shift, int (*getspawn)(DDukeActor* i));
void reactor(DDukeActor* i, int REACTOR, int REACTOR2, int REACTORBURNT, int REACTOR2BURNT, int REACTORSPARK, int REACTOR2SPARK);
void forcesphereexplode(DDukeActor* i);
void watersplash2(DDukeActor* i);
void frameeffect1(DDukeActor* i);
bool money(DDukeActor* i, int BLOODPOOL);

View file

@ -577,7 +577,7 @@ void checkhitwall_d(DDukeActor* spr, walltype* wal, const DVector3& pos, int atw
{
int j, sn = -1, darkestwall;
if (wal->overpicnum == MIRROR && gs.actorinfo[atwith].flags2 & SFLAG2_BREAKMIRRORS)
if (wal->overpicnum == MIRROR && atwith != -1 && gs.actorinfo[atwith].flags2 & SFLAG2_BREAKMIRRORS)
{
lotsofglass(spr, wal, 70);
wal->cstat &= ~CSTAT_WALL_MASKED;
@ -950,7 +950,7 @@ void checkhitdefault_d(DDukeActor* targ, DDukeActor* proj)
if ((targ->spr.picnum != DRONE) && (targ->spr.picnum != ROTATEGUN) && (targ->spr.picnum != COMMANDER) && (targ->spr.picnum < GREENSLIME || targ->spr.picnum > GREENSLIME + 7))
if (proj->spr.picnum != FREEZEBLAST)
//if (actortype[targ->spr.picnum] == 0) //TRANSITIONAL. Cannot be done right with EDuke mess backing the engine.
//if (actortype[targ->spr.picnum] == 0) //TRANSITIONAL.
{
auto spawned = spawn(proj, JIBS6);
if (spawned)

View file

@ -784,7 +784,7 @@ void checkhitwall_r(DDukeActor* spr, walltype* wal, const DVector3& pos, int atw
int j;
int darkestwall;
if (wal->overpicnum == MIRROR && gs.actorinfo[atwith].flags2 & SFLAG2_BREAKMIRRORS)
if (wal->overpicnum == MIRROR && atwith != -1 && gs.actorinfo[atwith].flags2 & SFLAG2_BREAKMIRRORS)
{
lotsofglass(spr, wal, 70);
wal->cstat &= ~CSTAT_WALL_MASKED;
@ -1314,7 +1314,7 @@ void checkhitdefault_r(DDukeActor* targ, DDukeActor* proj)
if ((targ->spr.picnum != DRONE))
if (proj->spr.picnum != FREEZEBLAST)
//if (actortype[targ->spr.picnum] == 0) //TRANSITIONAL. Cannot be done right with EDuke mess backing the engine.
//if (actortype[targ->spr.picnum] == 0)
{
auto spawned = spawn(proj, JIBS6);
if (spawned)

View file

@ -58,6 +58,7 @@ spawnclasses
1625 = DukeFireLaser
1646 = DukeShrinkSpark
2605 = DukeRPG
1641 = DukeFreezeBlast
1272 = DukeTrash
634 = DukeBolt1

View file

@ -2,6 +2,35 @@
// even if it is given the right statnum the projectile code won't get called for it.
// So even in the future any projectile needs to inherit from this to gain the needed feature support.
extend class DukeActor
{
// placed in DukeActor so it remains reusable.
void bounce()
{
Vector3 vect = (self.angle.ToVector() * self.vel.X, self.vel.Z);
let sectp = self.sector;
double daang = sectp.walls[0].delta().Angle();
double k;
if (self.pos.Z < (self.floorz + self.ceilingz) * 0.5)
k = sectp.ceilingheinum;
else
k = sectp.floorheinum;
Vector3 davec = (sin(daang) * k, -cos(daang) * k, 4096);
double dotp = vect dot davec;
double l = davec.LengthSquared();
vect -= davec * (2 * dotp / l);
self.vel.Z = vect.Z;
self.vel.X = vect.XY.Length();
self.angle = vect.Angle();
}
}
class DukeProjectile : DukeActor
{
default
@ -349,3 +378,80 @@ class DukeRPG : DukeProjectile
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
class DukeFreezeBlast : DukeProjectile
{
default
{
pic "FREEZEBLAST";
}
override bool postmoveeffect(CollisionData coll)
{
return false;
}
override bool weaponhitsprite_pre(DukeActor targ)
{
if (targ.pal == 1) // is target already frozen?
{
if (targ.badguy() || targ.isPlayer())
{
let spawned = targ.spawn('DukeTransporterStar');
if (spawned)
{
spawned.pal = 1;
spawned.scale = (0.5, 0.5);
}
self.Destroy();
return true;
}
}
return super.weaponhitsprite_pre(targ);
}
override void Tick()
{
if (self.yint < 1 || self.extra < 2 || (self.vel.X == 0 && self.vel.Z == 0))
{
let star = self.spawn("DukeTransporterStar");
if (star)
{
star.pal = 1;
star.scale = (0.5, 0.5);
}
self.Destroy();
}
else
Super.Tick();
}
override bool weaponhitsector()
{
self.bounce();
self.doMove(CLIPMASK1);
self.extra >>= 1;
if (self.scale.X > 0.125 )
self.scale.X -= 0.03125;
if (self.scale.Y > 0.125 )
self.scale.Y -= 0.03125;
self.yint--;
return true;
}
override bool animate(tspritetype tspr)
{
tspr.shade = -127;
return true;
}
}