diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index 6c0c821a6..704df40d7 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -116,6 +116,7 @@ extern Dispatcher fi; void CallInitialize(DDukeActor* actor); void CallTick(DDukeActor* actor); void CallAction(DDukeActor* actor); +void CallOnHit(DDukeActor* actor, DDukeActor* hitter); END_DUKE_NS diff --git a/source/games/duke/src/dukeactor.h b/source/games/duke/src/dukeactor.h index 28bea92d0..585b07f75 100644 --- a/source/games/duke/src/dukeactor.h +++ b/source/games/duke/src/dukeactor.h @@ -20,6 +20,8 @@ inline int player_struct::GetPlayerNum() } DDukeActor* spawn(DDukeActor* spawner, int type); +DDukeActor* spawn(DDukeActor* actj, PClassActor* pname); + inline int badguy(DDukeActor* pSprite) { diff --git a/source/games/duke/src/game.cpp b/source/games/duke/src/game.cpp index 90842fb6b..ef149b868 100644 --- a/source/games/duke/src/game.cpp +++ b/source/games/duke/src/game.cpp @@ -427,4 +427,14 @@ void CallAction(DDukeActor* actor) } } +void CallOnHit(DDukeActor* actor, DDukeActor* hitter) +{ + IFVIRTUALPTR(actor, DDukeActor, onHit) + { + VMValue val[2] = { actor, hitter }; + VMCall(func, val, 2, nullptr, 0); + } +} + + END_DUKE_NS diff --git a/source/games/duke/src/sectors_d.cpp b/source/games/duke/src/sectors_d.cpp index 6aea81870..1a8a04c97 100644 --- a/source/games/duke/src/sectors_d.cpp +++ b/source/games/duke/src/sectors_d.cpp @@ -1014,6 +1014,13 @@ void checkhitsprite_d(DDukeActor* targ, DDukeActor* proj) { int j, k, p; + if (targ->GetClass() != RUNTIME_CLASS(DDukeActor)) + { + CallOnHit(targ, proj); + return; + } + + switch (targ->spr.picnum) { case WTGLASS1: diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp index b2dbac8b4..764daf65c 100644 --- a/source/games/duke/src/sectors_r.cpp +++ b/source/games/duke/src/sectors_r.cpp @@ -1522,6 +1522,12 @@ void checkhitsprite_r(DDukeActor* targ, DDukeActor* proj) { int j, k, p; + if (targ->GetClass() != RUNTIME_CLASS(DDukeActor)) + { + CallOnHit(targ, proj); + return; + } + if (isRRRA()) switch (targ->spr.picnum) { case RRTILE8464: diff --git a/source/games/duke/src/spawn.cpp b/source/games/duke/src/spawn.cpp index e3e05a154..6a164f3ea 100644 --- a/source/games/duke/src/spawn.cpp +++ b/source/games/duke/src/spawn.cpp @@ -221,6 +221,24 @@ DDukeActor* spawn(DDukeActor* actj, int pn) return nullptr; } +DDukeActor* spawn(DDukeActor* actj, PClassActor * cls) +{ + // still needs work to do. +#if 0 + if (actj) + { + if (pn < 0) return nullptr; + auto spawned = CreateActor(actj->sector(), actj->spr.pos, pn, 0, DVector2(0, 0), nullAngle, 0., 0., actj, 0); + if (spawned) + { + spawned->attackertype = actj->spr.picnum; + return fi.spawninit(actj, spawned, nullptr); + } + } +#endif + return nullptr; +} + //--------------------------------------------------------------------------- // // diff --git a/wadsrc/static/zscript/games/duke/dukeactor.zs b/wadsrc/static/zscript/games/duke/dukeactor.zs index 4fd217e6c..3d7a1c6ef 100644 --- a/wadsrc/static/zscript/games/duke/dukeactor.zs +++ b/wadsrc/static/zscript/games/duke/dukeactor.zs @@ -74,6 +74,7 @@ class DukeActor : CoreActor native virtual void BeginPlay() {} virtual void Initialize() {} virtual void Tick() {} + virtual void onHit(DukeActor hitter) {} virtual void RunState() {} // this is the CON function. }