diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index 2e9fd3b23..59847a9eb 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -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(); -} - //--------------------------------------------------------------------------- // // diff --git a/source/games/duke/src/actors_d.cpp b/source/games/duke/src/actors_d.cpp index 47bda121a..627be78e3 100644 --- a/source/games/duke/src/actors_d.cpp +++ b/source/games/duke/src/actors_d.cpp @@ -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; diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp index fdd67255b..b5b86f0cf 100644 --- a/source/games/duke/src/actors_r.cpp +++ b/source/games/duke/src/actors_r.cpp @@ -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; diff --git a/source/games/duke/src/animatesprites_d.cpp b/source/games/duke/src/animatesprites_d.cpp index f85040c3e..d5b1c7879 100644 --- a/source/games/duke/src/animatesprites_d.cpp +++ b/source/games/duke/src/animatesprites_d.cpp @@ -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: diff --git a/source/games/duke/src/animatesprites_r.cpp b/source/games/duke/src/animatesprites_r.cpp index 58adaa0da..9df2a174b 100644 --- a/source/games/duke/src/animatesprites_r.cpp +++ b/source/games/duke/src/animatesprites_r.cpp @@ -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: diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 97202c166..9cd1cc3de 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -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); diff --git a/source/games/duke/src/sectors_d.cpp b/source/games/duke/src/sectors_d.cpp index 038d597f7..5283b6e53 100644 --- a/source/games/duke/src/sectors_d.cpp +++ b/source/games/duke/src/sectors_d.cpp @@ -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) diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp index 05be43089..ca48e3786 100644 --- a/source/games/duke/src/sectors_r.cpp +++ b/source/games/duke/src/sectors_r.cpp @@ -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) diff --git a/wadsrc/static/filter/dukelike/engine/engine.def b/wadsrc/static/filter/dukelike/engine/engine.def index c7bd12547..5fba488d9 100644 --- a/wadsrc/static/filter/dukelike/engine/engine.def +++ b/wadsrc/static/filter/dukelike/engine/engine.def @@ -58,6 +58,7 @@ spawnclasses 1625 = DukeFireLaser 1646 = DukeShrinkSpark 2605 = DukeRPG + 1641 = DukeFreezeBlast 1272 = DukeTrash 634 = DukeBolt1 diff --git a/wadsrc/static/zscript/games/duke/actors/projectiles.zs b/wadsrc/static/zscript/games/duke/actors/projectiles.zs index 8106c2b58..4e13e325a 100644 --- a/wadsrc/static/zscript/games/duke/actors/projectiles.zs +++ b/wadsrc/static/zscript/games/duke/actors/projectiles.zs @@ -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; + } + +} +