diff --git a/source/games/duke/src/actors_d.cpp b/source/games/duke/src/actors_d.cpp index 38c298a08..47bda121a 100644 --- a/source/games/duke/src/actors_d.cpp +++ b/source/games/duke/src/actors_d.cpp @@ -961,25 +961,11 @@ static void weaponcommon_d(DDukeActor* proj) int p = -1; - if (proj->spr.picnum == RPG && proj->sector()->lotag == 2) - { - vel *= 0.5; - velz *= 0.5; - } - auto oldpos = proj->spr.pos; getglobalz(proj); switch (proj->spr.picnum) { - case RPG: - if (proj->attackertype != BOSS2 && proj->spr.scale.X >= 0.15625 && proj->sector()->lotag != 2) - { - auto spawned = spawn(proj, SMALLSMOKE); - if (spawned) spawned->spr.pos.Z += 1; - } - break; - case FIREBALL: if (movefireball(proj)) return; break; @@ -1048,11 +1034,6 @@ static void weaponcommon_d(DDukeActor* proj) if (proj->spr.picnum != SPIT) { - if (proj->spr.picnum == RPG) - { - // j is only needed for the hit type mask. - rpgexplode(proj, coll.type, oldpos, EXPLOSION2, EXPLOSION2BOT, -1, RPG_EXPLODE); - } if (proj->spr.picnum != COOLEXPLOSION1 && proj->spr.picnum != FREEZEBLAST && (!isWorldTour() || proj->spr.picnum != FIREBALL)) { auto spawned = spawn(proj, EXPLOSION2); @@ -1095,9 +1076,6 @@ static void weaponcommon_d(DDukeActor* proj) return; } } - else if (proj->spr.picnum == RPG && proj->sector()->lotag == 2 && proj->spr.scale.X >= 0.15625 && rnd(140)) - spawn(proj, WATERBUBBLE); - } //--------------------------------------------------------------------------- // @@ -1141,7 +1119,6 @@ void moveweapons_d(void) // Twentieth Anniversary World Tour if (act->spr.picnum == FIREBALL && !isWorldTour()) break; [[fallthrough]]; - case RPG: case SPIT: case COOLEXPLOSION1: weaponcommon_d(act); diff --git a/source/games/duke/src/animatesprites_d.cpp b/source/games/duke/src/animatesprites_d.cpp index 417b266a5..f85040c3e 100644 --- a/source/games/duke/src/animatesprites_d.cpp +++ b/source/games/duke/src/animatesprites_d.cpp @@ -224,24 +224,6 @@ void animatesprites_d(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi case GROWSPARK: t->picnum = GROWSPARK + ((PlayClock >> 4) & 3); break; - case RPG: - if (hw_models && modelManager.CheckModel(h->spr.picnum, h->spr.pal)) - { - t->cstat &= ~CSTAT_SPRITE_XFLIP; - break; - } - - kang = (h->spr.pos - viewVec).Angle(); - k = angletorotation2(h->spr.Angles.Yaw, kang); - if (k > 6) - { - k = 12 - k; - t->cstat |= CSTAT_SPRITE_XFLIP; - } - else t->cstat &= ~CSTAT_SPRITE_XFLIP; - t->picnum = RPG + k; - break; - case APLAYER: p = h->PlayerIndex(); @@ -519,7 +501,6 @@ void animatesprites_d(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi case GROWSPARK: case CHAINGUN: case SHRINKEREXPLOSION: - case RPG: case FLOORFLAME: if (t->picnum == EXPLOSION2) { diff --git a/source/games/duke/src/flags_d.cpp b/source/games/duke/src/flags_d.cpp index 945e1fab1..16423baa2 100644 --- a/source/games/duke/src/flags_d.cpp +++ b/source/games/duke/src/flags_d.cpp @@ -118,7 +118,7 @@ void initactorflags_d() setflag(SFLAG2_DONTANIMATE, { TRIPBOMB, LASERLINE }); setflag(SFLAG2_INTERPOLATEANGLE, { BEARINGPLATE }); setflag(SFLAG2_GREENBLOOD, { OOZFILTER, NEWBEAST }); - setflag(SFLAG2_ALWAYSROTATE1, { RPG, RAT, CAMERA1 }); + setflag(SFLAG2_ALWAYSROTATE1, { RAT, CAMERA1 }); setflag(SFLAG2_ALWAYSROTATE2, { RPG }); setflag(SFLAG2_DIENOW, { RADIUSEXPLOSION, KNEE }); setflag(SFLAG2_TRANFERPALTOJIBS, { LIZTROOP }); diff --git a/source/games/duke/src/flags_r.cpp b/source/games/duke/src/flags_r.cpp index 08a952154..e09c9b306 100644 --- a/source/games/duke/src/flags_r.cpp +++ b/source/games/duke/src/flags_r.cpp @@ -176,7 +176,7 @@ void initactorflags_r() if (isRRRA()) setflag(SFLAG2_BREAKMIRRORS, { RPG2 }); setflag(SFLAG2_CAMERA, { CAMERA1 }); setflag(SFLAG2_GREENBLOOD, { OOZFILTER }); - setflag(SFLAG2_ALWAYSROTATE1, { RPG, RAT, CAMERA1 }); + setflag(SFLAG2_ALWAYSROTATE1, { RAT, CAMERA1 }); setflag(SFLAG2_ALWAYSROTATE2, { RPG }); setflag(SFLAG2_DIENOW, { RADIUSEXPLOSION }); setflag(SFLAG2_NORADIUSPUSH, { HULK }); diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index 4d74cc3be..f0671a06b 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -686,10 +686,6 @@ static void shootrpg(DDukeActor *actor, int p, DVector3 pos, DAngle ang, int atw } else setFreeAimVelocity(vel, zvel, ps[p].Angles.getPitchWithView(), 40.5); - - if (atwith == RPG) - S_PlayActorSound(RPG_SHOOT, actor); - } else { @@ -726,6 +722,12 @@ static void shootrpg(DDukeActor *actor, int p, DVector3 pos, DAngle ang, int atw if (!spawned) return; + if (p >= 0) + { + int snd = spawned->IntVar(NAME_spawnsound); + if (snd > 0) S_PlayActorSound(FSoundID::fromInt(snd), actor); + } + spawned->spr.extra += (krand() & 7); if (!(actorflag(spawned, SFLAG2_REFLECTIVE))) spawned->temp_actor = aimed; diff --git a/wadsrc/static/filter/dukelike/engine/engine.def b/wadsrc/static/filter/dukelike/engine/engine.def index 66955abe1..c7bd12547 100644 --- a/wadsrc/static/filter/dukelike/engine/engine.def +++ b/wadsrc/static/filter/dukelike/engine/engine.def @@ -57,6 +57,7 @@ spawnclasses 2299 = DukeBloodSplat4 1625 = DukeFireLaser 1646 = DukeShrinkSpark + 2605 = DukeRPG 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 470f13bda..8106c2b58 100644 --- a/wadsrc/static/zscript/games/duke/actors/projectiles.zs +++ b/wadsrc/static/zscript/games/duke/actors/projectiles.zs @@ -115,7 +115,7 @@ class DukeProjectile : DukeActor { double vel = self.vel.X; double velz = self.vel.Z; - let oldpos = self.pos; + oldpos = self.pos; int p = -1; @@ -255,3 +255,97 @@ class DukeShrinkSpark : DukeProjectile } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class DukeRPG : DukeProjectile +{ + default + { + pic "RPG"; + } + + override void Initialize() + { + SpawnSound = "RPG_SHOOT"; + } + + override bool premoveeffect() + { + if ((!self.ownerActor || !self.ownerActor.actorflag2(SFLAG2_NONSMOKYROCKET)) && self.scale.X >= 0.15625 && self.sector.lotag != ST_2_UNDERWATER) + { + let spawned = self.spawn("DukeSmallSmoke"); + if (spawned) spawned.pos.Z += 1; + } + return super.premoveeffect(); + } + + override bool postmoveeffect(CollisionData coll) + { + Super.postmoveeffect(coll); + if (self.temp_actor != nullptr && (self.pos.XY - self.temp_actor.pos.XY).LengthSquared() < 16 * 16) + coll.setActor(self.temp_actor); + return false; + } + + override void posthiteffect(CollisionData coll) + { + self.rpgexplode(coll.type, oldpos, true, -1, "RPG_EXPLODE"); + self.Destroy(); + } + + void rpgexplode(int hit, Vector3 pos, bool exbottom, int newextra, Sound playsound) + { + let explosion = self.spawn("DukeExplosion2"); + if (!explosion) return; + explosion.pos = pos; + + if (self.scale.X < 0.15625) + { + explosion.scale = (0.09375, 0.09375); + } + else if (hit == kHitSector) + { + if (self.vel.Z > 0 && exbottom) + self.spawn("DukeExplosion2Bot"); + else + { + explosion.cstat |= CSTAT_SPRITE_YFLIP; + explosion.pos.Z += 48; + } + } + if (newextra > 0) self.extra = newextra; + self.PlayActorSound(playsound); + + 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 void Tick() + { + super.Tick(); + if (self.sector && self.sector.lotag == ST_2_UNDERWATER && self.scale.X >= 0.15625 && Duke.rnd(140)) + self.spawn('DukeWaterBubble'); + + } + + override bool animate(tspritetype tspr) + { + tspr.shade = -127; + return true; + } + +} + +