diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp index a808c7fc4..f9482e9f3 100644 --- a/source/games/duke/src/actors_r.cpp +++ b/source/games/duke/src/actors_r.cpp @@ -1899,36 +1899,14 @@ void resetswitch(int tag) void rr_specialstats() { - DukeStatIterator it(STAT_LUMBERMILL); - while (auto act = it.Next()) - { - if (act->spr.hitag == 100) - { - act->spr.pos.Z += 4; - if (act->spr.pos.Z >= act->sector()->floorz + 59.25) - act->spr.pos.Z = act->sector()->floorz + 59.25; - } - - if (act->spr.picnum == LUMBERBLADE) - { - act->spr.extra++; - if (act->spr.extra == 192) - { - act->spr.hitag = 0; - act->spr.pos.Z = act->sector()->floorz - 59.25; - act->spr.extra = 0; - act->spr.picnum = LUMBERBLADE1; - resetswitch(999); - } - } - } + tickstat(STAT_LUMBERMILL); if (ud.chickenplant) { tickstat(STAT_CHICKENPLANT); } - it.Reset(STAT_BOWLING); + DukeStatIterator it(STAT_BOWLING); while (auto act = it.Next()) { if (act->spr.picnum == BOWLINGPINSPOT) diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index 5b7841789..deed404b3 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -121,6 +121,7 @@ bool CallOperate(DDukeActor* actor, int plnum); void CallAction(DDukeActor* actor); void CallOnHit(DDukeActor* actor, DDukeActor* hitter); void CallOnHurt(DDukeActor* actor, player_struct* hitter); +void CallOnTouch(DDukeActor* actor, player_struct* hitter); bool CallOnUse(DDukeActor* actor, player_struct* user); void CallOnRespawn(DDukeActor* actor, int low); bool CallAnimate(DDukeActor* actor, tspritetype* hitter); diff --git a/source/games/duke/src/game.cpp b/source/games/duke/src/game.cpp index bfc30f0bb..338a4ed1b 100644 --- a/source/games/duke/src/game.cpp +++ b/source/games/duke/src/game.cpp @@ -444,6 +444,14 @@ void CallOnHurt(DDukeActor* actor, player_struct* hitter) } } +void CallOnTouch(DDukeActor* actor, player_struct* hitter) +{ + IFVIRTUALPTR(actor, DDukeActor, onTouch) + { + VMValue val[2] = { actor, hitter }; + VMCall(func, val, 2, nullptr, 0); + } +} bool CallOnUse(DDukeActor* actor, player_struct* user) diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index 96cfb9a0f..7896c229e 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -3801,19 +3801,10 @@ HORIZONLY: ChangeActorStat(clip.actor(), 1); } } - else if (!isRRRA() && clip.actor()->spr.picnum == LUMBERBLADE1) - { - quickkill(p); - S_PlayActorSound(446, pact); - } + CallOnTouch(clip.actor(), p); if (isRRRA()) { - if (clip.actor()->spr.picnum == LUMBERBLADE1) - { - quickkill(p); - S_PlayActorSound(446, pact); - } - else if (clip.actor()->spr.picnum == RRTILE2443 && clip.actor()->spr.pal == 19) + if (clip.actor()->spr.picnum == RRTILE2443 && clip.actor()->spr.pal == 19) { clip.actor()->spr.pal = 0; p->DrugMode = 5; diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp index 0b019bd0f..fc4e3d19c 100644 --- a/source/games/duke/src/sectors_r.cpp +++ b/source/games/duke/src/sectors_r.cpp @@ -519,15 +519,7 @@ bool checkhitswitch_r(int snum, walltype* wwal, DDukeActor* act) DukeStatIterator it1(STAT_LUMBERMILL); while (auto other2 = it1.Next()) { - if (other2->spr.picnum == LUMBERBLADE1) - { - other2->spr.picnum++; - other2->spr.hitag = 100; - other2->spr.extra = 0; - S_PlayActorSound(474, other2); - } - else if (other2->spr.picnum == KEGHOLDER) - other2->Destroy(); + CallOnUse(other2, nullptr); } other->spr.picnum++; break; diff --git a/source/games/duke/src/spawn_r.cpp b/source/games/duke/src/spawn_r.cpp index 839bc40e5..cebd933bd 100644 --- a/source/games/duke/src/spawn_r.cpp +++ b/source/games/duke/src/spawn_r.cpp @@ -65,10 +65,6 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray* act->spr.extra = 0; ChangeActorStat(act, STAT_BOWLING); break; - case LUMBERBLADE1: - act->spr.extra = 0; - ChangeActorStat(act, STAT_LUMBERMILL); - break; case RRTILE8450: if (!isRRRA()) goto default_case; act->spr.scale = DVector2(1, 1); @@ -435,10 +431,6 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray* act->spr.scale = DVector2(0.328125, 0.234375); ChangeActorStat(act, STAT_ZOMBIEACTOR); break; - case KEGHOLDER: - act->spr.cstat |= CSTAT_SPRITE_INVISIBLE; - ChangeActorStat(act, STAT_LUMBERMILL); - break; case RRTELEPORT: case RRTELEPORTDEST: act->spr.scale = DVector2(1, 1); diff --git a/source/games/duke/src/vmexports.cpp b/source/games/duke/src/vmexports.cpp index 9ca9e8792..e18830d6f 100644 --- a/source/games/duke/src/vmexports.cpp +++ b/source/games/duke/src/vmexports.cpp @@ -1,5 +1,7 @@ BEGIN_DUKE_NS +void resetswitch(int tag); + // Workaround so that the script code can be written in its final form. This must go away later. int PicForName(int intname) { @@ -836,6 +838,12 @@ DEFINE_ACTION_FUNCTION_NATIVE(_DukePlayer, clearcameras, clearcameras) return 0; } +DEFINE_ACTION_FUNCTION_NATIVE(_DukePlayer, quickkill, quickkill) +{ + PARAM_SELF_STRUCT_PROLOGUE(player_struct); + quickkill(self); + return 0; +} static DDukeActor* duke_firstStat(DukeStatIterator* it, int statnum) { @@ -1007,9 +1015,17 @@ DEFINE_ACTION_FUNCTION_NATIVE(_DukeLevel, addambient, addambient) PARAM_INT(hitag); PARAM_INT(lotag); ACTION_RETURN_INT(addambient(hitag, lotag)); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_DukeLevel, resetswitch, resetswitch) +{ + PARAM_PROLOGUE; + PARAM_INT(tag); + resetswitch(tag); return 0; } + DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, playerfriction); DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, gravity); DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, respawnactortime); diff --git a/wadsrc/static/filter/redneck/engine/engine.def b/wadsrc/static/filter/redneck/engine/engine.def index 98e90e92c..fd86f6add 100644 --- a/wadsrc/static/filter/redneck/engine/engine.def +++ b/wadsrc/static/filter/redneck/engine/engine.def @@ -65,6 +65,8 @@ spawnclasses 3123 = RedneckRoastedChicken 3124 = RedneckBonelessChicken 3132 = RedneckChickenHead + 3410 = RedneckLumberBlade + 295 = RedneckKegHolder } diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 07e04d241..3c7e2c326 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -75,6 +75,7 @@ version "4.10" #include "zscript/games/duke/actors/rabbitspawner.zs" #include "zscript/games/duke/actors/chickenplant.zs" +#include "zscript/games/duke/actors/lumberblade.zs" #include "zscript/games/blood/bloodgame.zs" #include "zscript/games/blood/ui/menu.zs" diff --git a/wadsrc/static/zscript/games/duke/actors/lumberblade.zs b/wadsrc/static/zscript/games/duke/actors/lumberblade.zs new file mode 100644 index 000000000..ebd05bc20 --- /dev/null +++ b/wadsrc/static/zscript/games/duke/actors/lumberblade.zs @@ -0,0 +1,79 @@ + +class RedneckLumberBlade : DukeActor +{ + default + { + statnum STAT_LUMBERMILL; + extra 0; + spriteset "LUMBERBLADE1", "LUMBERBLADE"; + } + + override void Tick() + { + if (self.hitag == 100) + { + self.pos.Z += 4; + if (self.pos.Z >= self.sector.floorz + 59.25) + self.pos.Z = self.sector.floorz + 59.25; + } + + if (self.spritesetindex == 1) + { + self.extra++; + if (self.extra == 192) + { + self.hitag = 0; + self.pos.Z = self.sector.floorz - 59.25; + self.extra = 0; + self.setSpritesetImage(0); + dlevel.resetswitch(999); + } + } + } + + override bool onUse(DukePlayer user) + { + if (user == null) // guard against unwanted activation + { + self.setSpritesetImage(1); + self.hitag = 100; + self.extra = 0; + self.PlayActorSound(RRSnd.BK_JIB2); + return true; + } + return false; + } + + override void onTouch(DukePlayer user) + { + if (self.spritesetindex == 0) + { + user.quickkill(); + user.actor.PlayActorSound(RRSnd.JOE9000B); + } + } +} + + +// Development garbage? +Class RedneckKegHolder : DukeActor +{ + default + { + statnum STAT_LUMBERMILL; + pic "KEGHOLDER"; + } + + override void Initialize() + { + self.cstat = CSTAT_SPRITE_INVISIBLE; + } + + override bool OnUse(DukePlayer user) + { + if (user != null) return false; + self.Destroy(); + return true; + } + +} \ No newline at end of file diff --git a/wadsrc/static/zscript/games/duke/dukeactor.zs b/wadsrc/static/zscript/games/duke/dukeactor.zs index 24e4c44fe..7ebd15443 100644 --- a/wadsrc/static/zscript/games/duke/dukeactor.zs +++ b/wadsrc/static/zscript/games/duke/dukeactor.zs @@ -177,6 +177,7 @@ class DukeActor : CoreActor native virtual void onHit(DukeActor hitter) { checkhitdefault(hitter); } virtual void onHurt(DukePlayer p) {} virtual bool onUse(DukePlayer user) { return false; } + virtual void onTouch(DukePlayer toucher) {} virtual void onRespawn(int tag) { } virtual bool animate(tspritetype tspr) { return false; } virtual void RunState() {} // this is the CON function. @@ -223,6 +224,7 @@ struct DukeLevel native static void addtorch(sectortype sector, int shade, int lotag); native static void addlightning(sectortype sector, int shade); native static int addambient(int hitag, int lotag); + native static void resetswitch(int tag); // } struct DukeStatIterator diff --git a/wadsrc/static/zscript/games/duke/dukegame.zs b/wadsrc/static/zscript/games/duke/dukegame.zs index e4ea5deab..6c0bcfa8e 100644 --- a/wadsrc/static/zscript/games/duke/dukegame.zs +++ b/wadsrc/static/zscript/games/duke/dukegame.zs @@ -292,6 +292,7 @@ struct DukePlayer native native void settargetangle(double angle, bool backup = false); native double angle(); native void clearcameras(); + native void quickkill(); }