diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index f184bc576..1b6e2335c 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -714,79 +714,6 @@ static void shootrpg(DDukeActor *actor, int p, DVector3 pos, DAngle ang, int atw // //--------------------------------------------------------------------------- -static void shootlaser(DDukeActor* actor, int p, DVector3 pos, DAngle ang) -{ - auto sectp = actor->sector(); - double vel = 1024., zvel; - int j; - HitInfo hit{}; - - if (p >= 0) - setFreeAimVelocity(vel, zvel, ps[p].Angles.getPitchWithView(), 16.); - else zvel = 0; - - hitscan(pos, sectp, DVector3(ang.ToVector() * vel, zvel * 64), hit, CLIPMASK1); - - j = 0; - if (hit.actor()) return; - - if (hit.hitWall && hit.hitSector) - { - if ((hit.hitpos.XY() - pos.XY()).LengthSquared() < 18.125 * 18.125) - { - if (hit.hitWall->twoSided()) - { - if (hit.hitWall->nextSector()->lotag <= 2 && hit.hitSector->lotag <= 2) - j = 1; - } - else if (hit.hitSector->lotag <= 2) - j = 1; - } - - if (j == 1) - { - auto bomb = CreateActor(hit.hitSector, hit.hitpos, DTILE_TRIPBOMB, -16, DVector2(0.0625, 0.078125), ang, 0., 0., actor, STAT_STANDABLE); - if (!bomb) return; - if (isWW2GI()) - { - int lTripBombControl = GetGameVar("TRIPBOMB_CONTROL", TRIPBOMB_TRIPWIRE, nullptr, -1).value(); - if (lTripBombControl & TRIPBOMB_TIMER) - { - int lLifetime = GetGameVar("STICKYBOMB_LIFETIME", NAM_GRENADE_LIFETIME, nullptr, p).value(); - int lLifetimeVar = GetGameVar("STICKYBOMB_LIFETIME_VAR", NAM_GRENADE_LIFETIME_VAR, nullptr, p).value(); - // set timer. blows up when at zero.... - bomb->spr.extra = lLifetime - + MulScale(krand(), lLifetimeVar, 14) - - lLifetimeVar; - } - bomb->spr.detail = lTripBombControl; - } - else bomb->spr.detail = TRIPBOMB_TRIPWIRE; - - // this originally used the sprite index as tag to link the laser segments. - // This value is never used again to reference an actor by index. Decouple this for robustness. - ud.bomb_tag = (ud.bomb_tag + 1) & 32767; - bomb->spr.hitag = ud.bomb_tag; - S_PlayActorSound(LASERTRIP_ONWALL, bomb); - bomb->vel.X = -1.25; - ssp(bomb, CLIPMASK0); - bomb->spr.cstat = CSTAT_SPRITE_ALIGNMENT_WALL; - auto delta = -hit.hitWall->delta(); - bomb->spr.Angles.Yaw = delta.Angle() - DAngle90; - bomb->temp_angle = bomb->spr.Angles.Yaw; - - if (p >= 0) - ps[p].ammo_amount[TRIPBOMB_WEAPON]--; - } - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - static void shootmortar(DDukeActor* actor, int p, const DVector3& pos, DAngle ang, int atwith) { auto sect = actor->sector(); @@ -886,10 +813,6 @@ void shoot_d(DDukeActor* actor, int atwith, PClass *cls) shootrpg(actor, p, spos, sang, atwith); break; - case DTILE_HANDHOLDINGLASER: - shootlaser(actor, p, spos, sang); - return; - case DTILE_BOUNCEMINE: case DTILE_MORTER: shootmortar(actor, p, spos, sang, atwith); diff --git a/wadsrc/static/filter/dukelike/rmapinfo.spawnclasses b/wadsrc/static/filter/dukelike/rmapinfo.spawnclasses index 82bc44659..881a87c63 100644 --- a/wadsrc/static/filter/dukelike/rmapinfo.spawnclasses +++ b/wadsrc/static/filter/dukelike/rmapinfo.spawnclasses @@ -455,6 +455,7 @@ spawnclasses 1810 = DukeCannon 4427 = DukeHotMeat 4340 = DukeLavaBubble + 2563 = DukeHandHoldingLaser 1405 = DukePlayerPawn, noskill diff --git a/wadsrc/static/zscript/games/duke/actors/dukeweapons/tripbomb.zs b/wadsrc/static/zscript/games/duke/actors/dukeweapons/tripbomb.zs index 00e70490b..c54bea7a6 100644 --- a/wadsrc/static/zscript/games/duke/actors/dukeweapons/tripbomb.zs +++ b/wadsrc/static/zscript/games/duke/actors/dukeweapons/tripbomb.zs @@ -266,8 +266,74 @@ class DukeLaserLine : DukeActor t.scale.Y = 0; return true; } - - - } +class DukeHandHoldingLaser : DukeActor +{ + default + { + pic "HANDHOLDINGLASER"; + } + + override bool ShootThis(DukeActor shooter, DukePlayer p, Vector3 pos, double ang) const + { + let sectp = shooter.sector; + double vel = 1024., zvel; + int j; + HitInfo hit; + + if (p != null) + [vel, zvel] = Raze.setFreeAimVelocity(vel, zvel, p.getPitchWithView(), 16.); + else zvel = 0; + + Raze.hitscan(pos, sectp, (ang.ToVector() * vel, zvel * 64), hit, CLIPMASK1); + + j = 0; + if (hit.hitActor) return true; + + if (hit.hitWall && hit.hitSector) + { + if ((hit.hitpos.XY - pos.XY).LengthSquared() < 18.125 * 18.125) + { + if (hit.hitWall.twoSided()) + { + if (hit.hitWall.nextSectorp().lotag <= 2 && hit.hitSector.lotag <= 2) + j = 1; + } + else if (hit.hitSector.lotag <= 2) + j = 1; + } + + if (j == 1) + { + let bomb = dlevel.SpawnActor(hit.hitSector, hit.hitpos, "DukeTripBomb", -16, (0.0625, 0.078125), ang, 0., 0., shooter, STAT_STANDABLE); + if (!bomb) return true; + + if (gs.TripBombControl & DukeTripBomb.TRIPBOMB_TIMER) + { + // set timer. blows up when at zero.... + bomb.extra = gs.stickybomb_lifetime + ((random(0, 65535) * gs.stickybomb_lifetime_var) >> 14) - gs.stickybomb_lifetime_var; + bomb.detail = DukeTripBomb.TRIPBOMB_TIMER; + } + else + bomb.detail = DukeTripBomb.TRIPBOMB_TRIPWIRE; // this also covers the originally undefined case of tripbombcontrol == 0. + + // this originally used the sprite index as tag to link the laser segments. + // This value is never used again to reference an shooter by index. Decouple this for robustness. + ud.bomb_tag = (ud.bomb_tag + 1) & 32767; + bomb.hitag = ud.bomb_tag; + bomb.PlayActorSound("LASERTRIP_ONWALL"); + bomb.vel.X = -1.25; + bomb.DoMove(CLIPMASK0); + bomb.cstat = CSTAT_SPRITE_ALIGNMENT_WALL; + let delta = -hit.hitWall.delta(); + bomb.Angle = delta.Angle() - 90; + bomb.temp_angle = bomb.Angle; + + if (p) + p.ammo_amount[DukeWpn.TRIPBOMB_WEAPON]--; // this should be elsewhere. + } + } + return true; + } +}