diff --git a/src/playsim/p_map.cpp b/src/playsim/p_map.cpp index a1e8d5167..813d841f8 100644 --- a/src/playsim/p_map.cpp +++ b/src/playsim/p_map.cpp @@ -4604,7 +4604,7 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, } P_GeometryLineAttack(trace, t1, damage, damageType); - + if (victim != NULL) victim->unlinked = trace.unlinked; // position a bit closer for puffs if (nointeract || trace.HitType != TRACE_HitWall || ((trace.Line->special != Line_Horizon) || spawnSky)) diff --git a/wadsrc/static/zscript/actors/attacks.zs b/wadsrc/static/zscript/actors/attacks.zs index 86bd07279..369474c44 100644 --- a/wadsrc/static/zscript/actors/attacks.zs +++ b/wadsrc/static/zscript/actors/attacks.zs @@ -55,6 +55,7 @@ extend class Actor double bangle; double bslope = 0.; int laflags = (flags & CBAF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0; + FTranslatedLineTarget t; if (ref != NULL || (flags & CBAF_AIMFACING)) { @@ -89,7 +90,7 @@ extend class Actor if (!(flags & CBAF_NORANDOM)) damage *= random[cwbullet](1, 3); - let puff = LineAttack(pangle, range, slope, damage, 'Hitscan', pufftype, laflags); + let puff = LineAttack(pangle, range, slope, damage, 'Hitscan', pufftype, laflags, t); if (missile != null && pufftype != null) { double ang = pangle - 90; @@ -104,11 +105,19 @@ extend class Actor bool temp = (puff == null); if (!puff) { - puff = LineAttack(pangle, range, slope, 0, 'Hitscan', pufftype, laflags | LAF_NOINTERACT); + puff = LineAttack(pangle, range, slope, 0, 'Hitscan', pufftype, laflags | LAF_NOINTERACT, t); } if (puff) { AimBulletMissile(proj, puff, flags, temp, true); + if (t.unlinked) + { + // Arbitary portals will make angle and pitch calculations unreliable. + // So use the angle and pitch we passed instead. + proj.Angle = pangle; + proj.Pitch = bslope; + proj.Vel3DFromAngle(proj.Speed, proj.Angle, proj.Pitch); + } } } } diff --git a/wadsrc/static/zscript/actors/inventory/stateprovider.zs b/wadsrc/static/zscript/actors/inventory/stateprovider.zs index 05aa06f22..1295c8283 100644 --- a/wadsrc/static/zscript/actors/inventory/stateprovider.zs +++ b/wadsrc/static/zscript/actors/inventory/stateprovider.zs @@ -89,6 +89,7 @@ class StateProvider : Inventory double bangle; double bslope = 0.; int laflags = (flags & FBF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0; + FTranslatedLineTarget t; if ((flags & FBF_USEAMMO) && weapon && stateinfo != null && stateinfo.mStateType == STATE_Psprite) { @@ -117,7 +118,7 @@ class StateProvider : Inventory if (!(flags & FBF_NORANDOM)) damage *= random[cabullet](1, 3); - let puff = LineAttack(bangle, range, bslope, damage, 'Hitscan', pufftype, laflags); + let puff = LineAttack(bangle, range, bslope, damage, 'Hitscan', pufftype, laflags, t); if (missile != null) { @@ -130,9 +131,17 @@ class StateProvider : Inventory if (!puff) { temp = true; - puff = LineAttack(bangle, range, bslope, 0, 'Hitscan', pufftype, laflags | LAF_NOINTERACT); + puff = LineAttack(bangle, range, bslope, 0, 'Hitscan', pufftype, laflags | LAF_NOINTERACT, t); } AimBulletMissile(proj, puff, flags, temp, false); + if (t.unlinked) + { + // Arbitary portals will make angle and pitch calculations unreliable. + // So use the angle and pitch we passed instead. + proj.Angle = bangle; + proj.Pitch = bslope; + proj.Vel3DFromAngle(proj.Speed, proj.Angle, proj.Pitch); + } } } } @@ -161,7 +170,7 @@ class StateProvider : Inventory if (!(flags & FBF_NORANDOM)) damage *= random[cabullet](1, 3); - let puff = LineAttack(pangle, range, slope, damage, 'Hitscan', pufftype, laflags); + let puff = LineAttack(pangle, range, slope, damage, 'Hitscan', pufftype, laflags, t); if (missile != null) { @@ -174,9 +183,17 @@ class StateProvider : Inventory if (!puff) { temp = true; - puff = LineAttack(bangle, range, bslope, 0, 'Hitscan', pufftype, laflags | LAF_NOINTERACT); + puff = LineAttack(bangle, range, bslope, 0, 'Hitscan', pufftype, laflags | LAF_NOINTERACT, t); } AimBulletMissile(proj, puff, flags, temp, false); + if (t.unlinked) + { + // Arbitary portals will make angle and pitch calculations unreliable. + // So use the angle and pitch we passed instead. + proj.Angle = bangle; + proj.Pitch = bslope; + proj.Vel3DFromAngle(proj.Speed, proj.Angle, proj.Pitch); + } } } }