From afe7086189f35f426cdda8f52efbcb85e81d7a38 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 16 Apr 2023 14:38:02 +0200 Subject: [PATCH] - reimplemented WW2GI's hitscan related events in ZScript. --- source/games/duke/src/funct.h | 2 +- source/games/duke/src/player.cpp | 4 +- source/games/duke/src/vmexports.cpp | 3 +- .../static/filter/ww2gi/rmapinfo.spawnclasses | 7 +++ .../games/duke/actors/dukeweapons/hitscan.zs | 63 +++++++++++++++++-- wadsrc/static/zscript/games/duke/dukeactor.zs | 2 +- 6 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 wadsrc/static/filter/ww2gi/rmapinfo.spawnclasses diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 128294004..1af526edb 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -107,7 +107,7 @@ void playerLookDown(int snum, ESyncBits actions); void playerAimUp(int snum, ESyncBits actions); void playerAimDown(int snum, ESyncBits actions); DDukeActor* aim(DDukeActor* s, int aang, bool force = true); -DDukeActor* aim_(DDukeActor* actor, DDukeActor* weapon); +DDukeActor* aim_(DDukeActor* actor, DDukeActor* weapon, double aimangle); void checkweapons(player_struct* const p); int findotherplayer(int p, double* d); void quickkill(player_struct* p); diff --git a/source/games/duke/src/player.cpp b/source/games/duke/src/player.cpp index de2201fde..2c801960a 100644 --- a/source/games/duke/src/player.cpp +++ b/source/games/duke/src/player.cpp @@ -332,10 +332,10 @@ DDukeActor* aim(DDukeActor* actor, int abase, bool force) } // This is what aim should be. -DDukeActor* aim_(DDukeActor* actor, DDukeActor* weapon) +DDukeActor* aim_(DDukeActor* actor, DDukeActor* weapon, double aimangle) { if (!weapon || (weapon->flags1 & SFLAG_NOAUTOAIM)) return nullptr; - return aim(actor, int(weapon->FloatVar(NAME_autoaimangle) * (512 / 90.)), (weapon->flags1 & SFLAG_FORCEAUTOAIM)); + return aim(actor, int((aimangle > 0 ? aimangle : weapon->FloatVar(NAME_autoaimangle)) * (512 / 90.)), (weapon->flags1 & SFLAG_FORCEAUTOAIM)); } //--------------------------------------------------------------------------- diff --git a/source/games/duke/src/vmexports.cpp b/source/games/duke/src/vmexports.cpp index 5c6ad4a7d..df0f17959 100644 --- a/source/games/duke/src/vmexports.cpp +++ b/source/games/duke/src/vmexports.cpp @@ -703,7 +703,8 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, aim, aim_) { PARAM_SELF_PROLOGUE(DDukeActor); PARAM_POINTER(weapon, DDukeActor); - ACTION_RETURN_POINTER(aim_(self, weapon)); + PARAM_FLOAT(aimangle) + ACTION_RETURN_POINTER(aim_(self, weapon, aimangle)); } diff --git a/wadsrc/static/filter/ww2gi/rmapinfo.spawnclasses b/wadsrc/static/filter/ww2gi/rmapinfo.spawnclasses new file mode 100644 index 000000000..258767dee --- /dev/null +++ b/wadsrc/static/filter/ww2gi/rmapinfo.spawnclasses @@ -0,0 +1,7 @@ +spawnclasses +{ + 2595 = WW2GIShotSpark, noskill + 2613 = WW2GIShotgunShot, noskill + 2536 = WW2GIChaingunShot, noskill +} + diff --git a/wadsrc/static/zscript/games/duke/actors/dukeweapons/hitscan.zs b/wadsrc/static/zscript/games/duke/actors/dukeweapons/hitscan.zs index 6549b5549..0b1034c89 100644 --- a/wadsrc/static/zscript/games/duke/actors/dukeweapons/hitscan.zs +++ b/wadsrc/static/zscript/games/duke/actors/dukeweapons/hitscan.zs @@ -35,7 +35,7 @@ extend class DukeActor // //--------------------------------------------------------------------------- - bool HitscanAttack(DukeActor actor, DukePlayer p, Vector3 pos, double ang, double hspread, double vspread, double enemyspread, bool forcespread, bool waterhalfhitchance = false, class sparktype = "DukeShotSpark") const + bool HitscanAttack(DukeActor actor, DukePlayer p, Vector3 pos, double ang, double hspread, double vspread, double enemyspread, bool forcespread, double aimangle = -1, bool waterhalfhitchance = false, class sparktype = "DukeShotSpark") const { let sectp = actor.sector; double vel = 1024, zvel = 0; @@ -45,7 +45,7 @@ extend class DukeActor if (p != null) { - let aimed = actor.aim(self); + let aimed = actor.aim(self, aimangle); if (aimed) { double dal = ((aimed.scale.X * aimed.spriteHeight()) * 0.5) + aimed.sparkoffset; @@ -331,7 +331,7 @@ class RedneckShotgunShot : DukeShotgunShot { override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) { - return HitscanAttack(actor, p, pos, ang, 22.5, 4, 11.25, true, true); + return HitscanAttack(actor, p, pos, ang, 22.5, 4, 11.25, true, -1, true); } } @@ -344,12 +344,65 @@ class RedneckChaingunShot : DukeChaingunShot } } -// WW2GI uses different spread settings for its pistol +extend class DukeActor +{ + // Todo: once we have real weapons, this should be cleaned up. + double WW2GIAimAngle(DukePlayer p) + { + if (p == null) return -1; + int lAmount = p.GetGameVar("PLR_MORALE", -1); + if (lAmount >= 40) return -1; + return 7.91015625; + } + + double, double WW2GIGetShotRange(DukePlayer p) + { + // the logic here looks very broken... + if (p == null) return 5.625, 4; + int lAmount = p.GetGameVar("PLR_MORALE", -1); + + if (lAmount < 25) return 11.25, 4; + if (lAmount > 70) switch(p.curr_weapon) + { + case DukeWpn.PISTOL_WEAPON: + return 5.626, 4; + case DukeWpn.CHAINGUN_WEAPON: + return 2.8175, 2; + case DukeWpn.SHRINKER_WEAPON: + return 11.25, 8; + default: + return 2.8175, 4; + } + return 5.625, 4; + } +} + + +// WW2GI has different settings. class WW2GIShotSpark : DukeShotSpark { override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) { - return HitscanAttack(actor, p, pos, ang, 0.3515625, 0.25, 5.625, true); + let [hspread, vspread] = self.WW2GIGetShotRange(p); + return HitscanAttack(actor, p, pos, ang, hspread, vspread, 5.625, true, self.WW2GIAimAngle(p)); } } +class WW2GIShotgunShot : DukeShotgunShot +{ + override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) + { + let [hspread, vspread] = self.WW2GIGetShotRange(p); + return HitscanAttack(actor, p, pos, ang, hspread, vspread, 5.625, true, self.WW2GIAimAngle(p)); + } +} + + +class WW2GIChaingunShot : DukeChaingunShot +{ + override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) + { + let [hspread, vspread] = self.WW2GIGetShotRange(p); + return HitscanAttack(actor, p, pos, ang, hspread, vspread, 5.625, true, self.WW2GIAimAngle(p)); + } +} diff --git a/wadsrc/static/zscript/games/duke/dukeactor.zs b/wadsrc/static/zscript/games/duke/dukeactor.zs index bce5d0bff..3952a66c8 100644 --- a/wadsrc/static/zscript/games/duke/dukeactor.zs +++ b/wadsrc/static/zscript/games/duke/dukeactor.zs @@ -204,7 +204,7 @@ class DukeActor : CoreActor native native void operatesectors(sectortype sec); native int SpriteWidth(); native int SpriteHeight(); - native DukeActor aim(readonly weapon); + native DukeActor aim(readonly weapon, double aimangle = -1); virtual native void Tick();