From 0643ab22c079362da4e92c84887607999b2cd569 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 22 Dec 2022 21:42:43 +0100 Subject: [PATCH] - scriptified the melee attack. --- source/core/vmexports.cpp | 10 ++ source/games/duke/src/player_d.cpp | 89 ----------- source/games/duke/src/player_r.cpp | 125 --------------- source/games/duke/src/vmexports.cpp | 14 ++ .../filter/dukelike/rmapinfo.spawnclasses | 2 +- .../redneck.ridesagain/rmapinfo.spawnclasses | 1 + .../filter/redneck/rmapinfo.spawnclasses | 2 +- wadsrc/static/zscript.txt | 1 + wadsrc/static/zscript/coreactor.zs | 1 + .../games/duke/actors/_placeholders.zs | 17 -- .../games/duke/actors/dukeweapons/melee.zs | 145 ++++++++++++++++++ .../zscript/games/duke/actors/powderkeg.zs | 2 +- .../zscript/games/duke/actors/redneckmisc.zs | 8 - wadsrc/static/zscript/games/duke/dukegame.zs | 1 + 14 files changed, 176 insertions(+), 242 deletions(-) create mode 100644 wadsrc/static/zscript/games/duke/actors/dukeweapons/melee.zs diff --git a/source/core/vmexports.cpp b/source/core/vmexports.cpp index dad43c800..d44899735 100644 --- a/source/core/vmexports.cpp +++ b/source/core/vmexports.cpp @@ -986,6 +986,16 @@ DEFINE_ACTION_FUNCTION_NATIVE(DCoreActor, ChangeStat, ChangeActorStat) return 0; } +static int CoreActor_spritetexture(DCoreActor* self) +{ + return self->spr.spritetexture().GetIndex(); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DCoreActor, spritetexture, CoreActor_spritetexture) +{ + PARAM_SELF_PROLOGUE(DCoreActor); + ACTION_RETURN_INT(CoreActor_spritetexture(self)); +} diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index 1ecc86e71..e1202caf3 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -81,91 +81,6 @@ void incur_damage_d(player_struct* p) } -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -static void shootknee(DDukeActor* actor, int p, DVector3 pos, DAngle ang) -{ - auto sectp = actor->sector(); - double vel = 1024., zvel; - HitInfo hit{}; - - if (p >= 0) - { - setFreeAimVelocity(vel, zvel, ps[p].Angles.getPitchWithView(), 16.); - pos.Z += 6; - ang += DAngle1 * 2.64; - } - else - { - double x; - auto pactor = ps[findplayer(actor, &x)].GetActor(); - zvel = ((pactor->spr.pos.Z - pos.Z) * 16) / (x + 1/16.); - ang = (pactor->spr.pos.XY() - pos.XY()).Angle(); - } - - hitscan(pos, sectp, DVector3(ang.ToVector() * vel, zvel * 64), hit, CLIPMASK1); - - - if (hit.hitSector == nullptr) return; - - if ((pos.XY() - hit.hitpos.XY()).Sum() < 64) - { - if (hit.hitWall || hit.actor()) - { - auto knee = CreateActor(hit.hitSector, hit.hitpos, DTILE_KNEE, -15, DVector2(0, 0), ang, 2., 0., actor, 4); - if (knee) - { - knee->spr.extra += (krand() & 7); - if (p >= 0) - { - auto k = spawn(knee, PClass::FindActor(NAME_DukeSmallSmoke)); - if (k) k->spr.pos.Z -= 8; - S_PlayActorSound(KICK_HIT, knee); - } - - if (p >= 0 && ps[p].steroids_amount > 0 && ps[p].steroids_amount < 400) - knee->spr.extra += (gs.max_player_health >> 2); - } - if (hit.actor() && ! isaccessswitch(hit.actor()->spr.spritetexture())) - { - checkhitsprite(hit.actor(), knee); - if (p >= 0) checkhitswitch(p, nullptr, hit.actor()); - } - - else if (hit.hitWall) - { - if (hit.hitWall->cstat & CSTAT_WALL_BOTTOM_SWAP) - if (hit.hitWall->twoSided()) - if (hit.hitpos.Z >= hit.hitWall->nextSector()->floorz) - hit.hitWall =hit.hitWall->nextWall(); - - if (!isaccessswitch(hit.hitWall->walltexture)) - { - checkhitwall(knee, hit.hitWall, hit.hitpos); - if (p >= 0) checkhitswitch(p, hit.hitWall, nullptr); - } - } - } - else if (p >= 0 && zvel > 0 && hit.hitSector->lotag == 1) - { - auto splash = spawn(ps[p].GetActor(), DTILE_WATERSPLASH2); - if (splash) - { - splash->spr.pos.XY() = hit.hitpos.XY(); - splash->spr.Angles.Yaw = ps[p].GetActor()->spr.Angles.Yaw; - splash->vel.X = 2; - ssp(actor, CLIPMASK0); - splash->vel.X = 0; - } - - } - } -} - //--------------------------------------------------------------------------- // // @@ -702,10 +617,6 @@ void shoot_d(DDukeActor* actor, int atwith, PClass *cls) switch (atwith) { - case DTILE_KNEE: - shootknee(actor, p, spos, sang); - break; - case DTILE_SHOTSPARK1: case DTILE_SHOTGUN: case DTILE_CHAINGUN: diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index 6595c2f42..8494dcc92 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -83,123 +83,6 @@ void incur_damage_r(player_struct* p) // //--------------------------------------------------------------------------- -static void shootmelee(DDukeActor *actor, int p, DVector3 pos, DAngle ang, int atwith) -{ - auto sectp = actor->sector(); - double vel = 1024., zvel; - HitInfo hit{}; - - if (p >= 0) - { - setFreeAimVelocity(vel, zvel, ps[p].Angles.getPitchWithView(), 16.); - pos.Z += 6; - ang += DAngle1 * 2.64; - } - else - { - double x; - auto pactor = ps[findplayer(actor, &x)].GetActor(); - zvel = ((pactor->spr.pos.Z - pos.Z) * 16) / (x + 1 / 16.); - ang = (pactor->spr.pos.XY() - pos.XY()).Angle(); - } - - hitscan(pos, sectp, DVector3(ang.ToVector() * vel, zvel * 64), hit, CLIPMASK1); - - if (isRRRA() && hit.hitSector != nullptr && ((hit.hitSector->lotag == ST_160_FLOOR_TELEPORT && zvel > 0) || (hit.hitSector->lotag == ST_161_CEILING_TELEPORT && zvel < 0)) - && hit.actor() == nullptr && hit.hitWall == nullptr) - { - DukeStatIterator its(STAT_EFFECTOR); - while (auto effector = its.Next()) - { - if (effector->sector() == hit.hitSector && iseffector(effector) && effector->GetOwner() - && effector->spr.lotag == SE_7_TELEPORT) - { - DVector3 npos; - npos.XY() = hit.hitpos.XY() + (effector->GetOwner()->spr.pos.XY() - effector->spr.pos.XY()); - if (hit.hitSector->lotag == ST_161_CEILING_TELEPORT) - { - npos.Z = effector->GetOwner()->sector()->floorz; - } - else - { - npos.Z = effector->GetOwner()->sector()->ceilingz; - } - hitscan(npos, effector->GetOwner()->sector(), DVector3(ang.ToVector() * 1024, zvel * 0.25), hit, CLIPMASK1); - break; - } - } - } - - if (hit.hitSector == nullptr) return; - - if ((pos.XY() - hit.hitpos.XY()).Sum() < 64) - { - if (hit.hitWall != nullptr || hit.actor()) - { - DDukeActor* wpn; - if (isRRRA() && atwith == RTILE_SLINGBLADE) - { - wpn = CreateActor(hit.hitSector, hit.hitpos, RTILE_SLINGBLADE, -15, DVector2(0, 0), ang, 32., 0., actor, 4); - if (!wpn) return; - wpn->spr.extra += 50; - } - else - { - wpn = CreateActor(hit.hitSector, hit.hitpos, RTILE_KNEE, -15, DVector2(0, 0), ang, 32., 0., actor, 4); - if (!wpn) return; - wpn->spr.extra += (krand() & 7); - } - if (p >= 0) - { - auto k = spawn(wpn, PClass::FindActor(NAME_DukeSmallSmoke)); - if (k) k->spr.pos.Z -= 8; - if (atwith == RTILE_KNEE) S_PlayActorSound(KICK_HIT, wpn); - else if (isRRRA() && atwith == RTILE_SLINGBLADE) S_PlayActorSound(260, wpn); - } - - if (p >= 0 && ps[p].steroids_amount > 0 && ps[p].steroids_amount < 400) - wpn->spr.extra += (gs.max_player_health >> 2); - - if (hit.actor() && !isaccessswitch(hit.actor()->spr.spritetexture())) - { - checkhitsprite(hit.actor(), wpn); - if (p >= 0) checkhitswitch(p, nullptr, hit.actor()); - } - else if (hit.hitWall) - { - if (hit.hitWall->cstat & CSTAT_WALL_BOTTOM_SWAP) - if (hit.hitWall->twoSided()) - if (hit.hitpos.Z >= hit.hitWall->nextSector()->floorz) - hit.hitWall = hit.hitWall->nextWall(); - - if (!isaccessswitch(hit.hitWall->walltexture)) - { - checkhitwall(wpn, hit.hitWall, hit.hitpos); - if (p >= 0) checkhitswitch(p, hit.hitWall, nullptr); - } - } - } - else if (p >= 0 && zvel > 0 && hit.hitSector->lotag == 1) - { - auto splash = spawn(ps[p].GetActor(), RTILE_WATERSPLASH2); - if (splash) - { - splash->spr.pos.XY() = hit.hitpos.XY(); - splash->spr.Angles.Yaw = ps[p].GetActor()->spr.Angles.Yaw; - splash->vel.X = 2; - ssp(actor, 0); - splash->vel.X = 0; - } - } - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - static void shootweapon(DDukeActor* actor, int p, DVector3 pos, DAngle ang, int atwith) { auto sectp = actor->sector(); @@ -772,14 +655,6 @@ void shoot_r(DDukeActor* actor, int atwith, PClass* cls) switch (atwith) { - case RTILE_SLINGBLADE: - if (!isRRRA()) break; - [[fallthrough]]; - case RTILE_KNEE: - case RTILE_GROWSPARK: - shootmelee(actor, p, spos, sang, atwith); - return; - case RTILE_SHOTSPARK1: case RTILE_SHOTGUN: case RTILE_CHAINGUN: diff --git a/source/games/duke/src/vmexports.cpp b/source/games/duke/src/vmexports.cpp index aff2b8f66..d47c27bb6 100644 --- a/source/games/duke/src/vmexports.cpp +++ b/source/games/duke/src/vmexports.cpp @@ -1103,6 +1103,20 @@ DEFINE_ACTION_FUNCTION_NATIVE(_DukePlayer, StartBoat, OnBoat) return 0; } +void pl_checkhitswitch(player_struct* p, walltype* wal, DDukeActor* act) +{ + checkhitswitch(p->GetPlayerNum(), wal, act); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_DukePlayer, checkhitswitch, pl_checkhitswitch) +{ + PARAM_SELF_STRUCT_PROLOGUE(player_struct); + PARAM_POINTER(wal, walltype); + PARAM_POINTER(act, DDukeActor); + pl_checkhitswitch(self, wal, act); + return 0; +} + static DDukeActor* duke_firstStat(DukeStatIterator* it, int statnum) { diff --git a/wadsrc/static/filter/dukelike/rmapinfo.spawnclasses b/wadsrc/static/filter/dukelike/rmapinfo.spawnclasses index 881a87c63..8b6712c47 100644 --- a/wadsrc/static/filter/dukelike/rmapinfo.spawnclasses +++ b/wadsrc/static/filter/dukelike/rmapinfo.spawnclasses @@ -11,7 +11,7 @@ spawnclasses 9 = DukeRespawnController, noskill 10 = DukeGPSpeed, noskill 4890 = DukeNaturalLightning, noskill - 2521 = DukeKneeAttack, noskill + 2521 = DukeMeleeAttack, noskill 2613 = DukeShotgunShot, noskill 2536 = DukeChaingunShot, noskill 1670 = DukeRadiusExplosion, noskill diff --git a/wadsrc/static/filter/redneck.ridesagain/rmapinfo.spawnclasses b/wadsrc/static/filter/redneck.ridesagain/rmapinfo.spawnclasses index 73345cc79..20e43ea93 100644 --- a/wadsrc/static/filter/redneck.ridesagain/rmapinfo.spawnclasses +++ b/wadsrc/static/filter/redneck.ridesagain/rmapinfo.spawnclasses @@ -193,4 +193,5 @@ spawnclasses 78 = RedneckMotoAmmo, noskill 8460 = RedneckBoatAmmo, noskill 7170 = RedneckMotoHit, noskill + 3510 = RedneckSlingbladeAttack, noskill } diff --git a/wadsrc/static/filter/redneck/rmapinfo.spawnclasses b/wadsrc/static/filter/redneck/rmapinfo.spawnclasses index e28b3548e..533ac0b0f 100644 --- a/wadsrc/static/filter/redneck/rmapinfo.spawnclasses +++ b/wadsrc/static/filter/redneck/rmapinfo.spawnclasses @@ -35,7 +35,7 @@ spawnclasses 34 = RedneckKeyinfoSetter, noskill 3380 = RedneckChaingunShot, noskill 3350 = RedneckShotgunShot, noskill - 3340 = RedneckCrowbarAttack, noskill + 3340 = DukeMeleeAttack, noskill 1426 = DukeRadiusExplosion, noskill 1298 = DukeCranePole, noskill diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index e92b1cc01..2a3a8f416 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -158,6 +158,7 @@ version "4.10" #include "zscript/games/duke/actors/rabbit.zs" +#include "zscript/games/duke/actors/dukeweapons/melee.zs" #include "zscript/games/duke/actors/dukeweapons/shrinker.zs" #include "zscript/games/duke/actors/dukeweapons/grower.zs" #include "zscript/games/duke/actors/dukeweapons/tripbomb.zs" diff --git a/wadsrc/static/zscript/coreactor.zs b/wadsrc/static/zscript/coreactor.zs index 8ad6ce4dd..f88cf75da 100644 --- a/wadsrc/static/zscript/coreactor.zs +++ b/wadsrc/static/zscript/coreactor.zs @@ -69,6 +69,7 @@ class CoreActor native native void setPosition(Vector3 pos); native void setPositionZ(Vector3 pos); native bool isAwayFromWall(double dist); + native TextureID spritetexture(); native void ChangeSector(sectortype s, bool forcetail = false); native void ChangeStat(int s, bool forcetail = false); diff --git a/wadsrc/static/zscript/games/duke/actors/_placeholders.zs b/wadsrc/static/zscript/games/duke/actors/_placeholders.zs index dab4536a4..6d6a2f76e 100644 --- a/wadsrc/static/zscript/games/duke/actors/_placeholders.zs +++ b/wadsrc/static/zscript/games/duke/actors/_placeholders.zs @@ -1,20 +1,3 @@ - -// dummy items representing certain weapons - -class DukeKneeAttack : DukeActor -{ - default - { - pic "KNEE"; - +DIENOW; - } -} - -class RedneckCrowbarAttack : DukeKneeAttack -{ -} - - class DukeRadiusExplosion : DukeActor { default diff --git a/wadsrc/static/zscript/games/duke/actors/dukeweapons/melee.zs b/wadsrc/static/zscript/games/duke/actors/dukeweapons/melee.zs new file mode 100644 index 000000000..2fee40018 --- /dev/null +++ b/wadsrc/static/zscript/games/duke/actors/dukeweapons/melee.zs @@ -0,0 +1,145 @@ + +class DukeMeleeAttack : DukeActor +{ + meta sound attacksound; + meta int extradamage; + property attacksound: attacksound; + property extradamage: extradamage; + default + { + pic "KNEE"; + +DIENOW; + DukeMeleeAttack.extradamage 0; + DukeMeleeAttack.attacksound "KICK_HIT"; + } + + override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const + { + let sectp = actor.sector; + double vel = 1024., zvel; + HitInfo hit; + + if (p) + { + [vel, zvel] = Raze.setFreeAimVelocity(vel, zvel, p.getPitchWithView(), 16.); + pos.Z += 6; + ang += 2.64; + } + else + { + double x; + let pactor = self.findplayer().Actor; + zvel = ((pactor.pos.Z - pos.Z) * 16) / (x + 1 / 16.); + ang = (pactor.pos.XY - pos.XY).Angle(); + } + + Raze.hitscan(pos, sectp, (ang.ToVector() * vel, zvel * 64), hit, CLIPMASK1); + + if (Raze.isRRRA() && hit.hitSector != nullptr && ((hit.hitSector.lotag == ST_160_FLOOR_TELEPORT && zvel > 0) || (hit.hitSector.lotag == ST_161_CEILING_TELEPORT && zvel < 0)) + && hit.hitActor == nullptr && hit.hitWall == nullptr) + { + DukeStatIterator its; + for (let effector = its.First(STAT_EFFECTOR); effector; effector = its.Next()) + { + if (effector.sector == hit.hitSector && effector.GetClassName() == 'DukeSectorEffector' && effector.ownerActor && effector.lotag == SE_7_TELEPORT) + { + let owner = effector.ownerActor; + Vector3 npos; + npos.XY = hit.hitpos.XY + (owner.pos.XY - effector.pos.XY); + if (hit.hitSector.lotag == ST_161_CEILING_TELEPORT) + { + npos.Z = owner.sector.floorz; + } + else + { + npos.Z = owner.sector.ceilingz; + } + Raze.hitscan(npos, owner.sector, (ang.ToVector() * 1024, zvel * 0.25), hit, CLIPMASK1); + break; + } + } + } + + if (hit.hitSector == nullptr) return true; + + if ((pos.XY - hit.hitpos.XY).Sum() < 64) + { + if (hit.hitWall != nullptr || hit.hitactor) + { + let wpn = dlevel.SpawnActor(hit.hitSector, hit.hitpos, GetClass(), -15, (0, 0), ang, 2., 0., actor, STAT_PROJECTILE); + if (!wpn) return true; + + if (self.extradamage > 0) + { + wpn.extra += self.extradamage; + } + else + { + wpn.extra += random(0, 7); + } + if (p) + { + let k = wpn.spawn("DukeSmallSmoke"); + if (k) k.pos.Z -= 8; + wpn.PlayActorSound(self.attacksound); + if (p.steroids_amount > 0 && p.steroids_amount < 400) + wpn.extra += (gs.max_player_health >> 2); + } + + + if (hit.hitActor && !Duke.isaccessswitch(hit.hitactor.spritetexture())) + { + let da = DukeActor(hit.hitActor); + da.OnHit(wpn); + if (p) p.checkhitswitch(nullptr, da); + } + else if (hit.hitWall) + { + if (hit.hitWall.cstat & CSTAT_WALL_BOTTOM_SWAP) + if (hit.hitWall.twoSided()) + if (hit.hitpos.Z >= hit.hitWall.nextSectorp().floorz) + hit.hitWall = hit.hitWall.nextWallp(); + + if (!Duke.isaccessswitch(hit.hitWall.walltexture)) + { + dlevel.checkhitwall(hit.hitWall, wpn, hit.hitpos); + if (p) p.checkhitswitch(hit.hitWall, nullptr); + } + } + } + else if (p && zvel > 0 && hit.hitSector.lotag == 1) + { + let splash = p.actor.spawn("DukeWaterSplash"); + if (splash) + { + splash.pos.XY = hit.hitpos.XY; + splash.Angle = p.actor.Angle; + splash.vel.X = 2; + actor.DoMove(CLIPMASK0); + splash.vel.X = 0; + } + } + } + return true; + } + +} + +class RedneckBuzzSaw : DukeMeleeAttack +{ + default + { + pic "BUZSAW"; + } +} + +class RedneckSlingbladeAttack : DukeMeleeAttack +{ + default + { + pic "SLINGBLADE"; + DukeMeleeAttack.extradamage 50; // extra attack power. + DukeMeleeAttack.attacksound "SLINGHIT"; + } +} + diff --git a/wadsrc/static/zscript/games/duke/actors/powderkeg.zs b/wadsrc/static/zscript/games/duke/actors/powderkeg.zs index 4a26b257d..cdc5f37c5 100644 --- a/wadsrc/static/zscript/games/duke/actors/powderkeg.zs +++ b/wadsrc/static/zscript/games/duke/actors/powderkeg.zs @@ -14,7 +14,7 @@ class RedneckPowderKeg : DukeItemBase override void Tick() { let sectp = self.sector; - if (sectp.lotag != ST_1_ABOVE_WATER && sectp.lotag != ST_160_FLOOR_TELEPORT) + if (sectp.lotag != ST_1_ABOVE_WATER && (!Raze.isRRRA() && sectp.lotag != ST_160_FLOOR_TELEPORT)) if (self.vel.X != 0) { movesprite((self.Angle.ToVector()* self.vel.X, self.vel.Z), CLIPMASK0); diff --git a/wadsrc/static/zscript/games/duke/actors/redneckmisc.zs b/wadsrc/static/zscript/games/duke/actors/redneckmisc.zs index 4eb491a5b..077cfe28d 100644 --- a/wadsrc/static/zscript/games/duke/actors/redneckmisc.zs +++ b/wadsrc/static/zscript/games/duke/actors/redneckmisc.zs @@ -131,14 +131,6 @@ class RedneckTeslaBall : DukeItemBase } } -class RedneckBuzzSaw : DukeItemBase -{ - default - { - pic "BUZSAW"; - } -} - class RedneckBustaWin5a : DukeItemBase { default diff --git a/wadsrc/static/zscript/games/duke/dukegame.zs b/wadsrc/static/zscript/games/duke/dukegame.zs index 6f44e99a3..8473d1823 100644 --- a/wadsrc/static/zscript/games/duke/dukegame.zs +++ b/wadsrc/static/zscript/games/duke/dukegame.zs @@ -379,6 +379,7 @@ struct DukePlayer native native void setbobpos(); native void StartMotorcycle(); native void StartBoat(); + native void checkhitswitch(walltype wal, DukeActor act); }