From ab1803bd5b16bf3e5fd3178dc17a438ed2432b2b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 17 Jan 2022 00:51:40 +0100 Subject: [PATCH] - DukeActor scriptification framework. --- source/games/duke/src/actors.cpp | 1 - source/games/duke/src/actors_d.cpp | 6 ++++- source/games/duke/src/actors_r.cpp | 5 ++++ source/games/duke/src/duke3d.h | 5 ++++ source/games/duke/src/game.cpp | 27 +++++++++++++++++++ source/games/duke/src/premap.cpp | 16 ++++++----- source/games/duke/src/spawn.cpp | 5 +++- source/games/duke/src/spawn_d.cpp | 5 ++++ source/games/duke/src/spawn_r.cpp | 5 ++++ source/games/duke/src/types.h | 11 +++++++- wadsrc/static/zscript.txt | 2 ++ .../zscript/games/duke/actors/DukeActor.zs | 16 +++++++++++ 12 files changed, 94 insertions(+), 10 deletions(-) create mode 100644 wadsrc/static/zscript/games/duke/actors/DukeActor.zs diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index 1f9baf3fabd..ab34506deb2 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -622,7 +622,6 @@ void movefx(void) //--------------------------------------------------------------------------- // -// split out of movestandables // //--------------------------------------------------------------------------- diff --git a/source/games/duke/src/actors_d.cpp b/source/games/duke/src/actors_d.cpp index 9eed8605337..4adfa57f8d4 100644 --- a/source/games/duke/src/actors_d.cpp +++ b/source/games/duke/src/actors_d.cpp @@ -1188,7 +1188,11 @@ void movestandables_d(void) continue; } - + if (act->GetClass() != RUNTIME_CLASS(DDukeActor)) + { + CallTick(act); + continue; + } if (picnum >= CRANE && picnum <= CRANE +3) { movecrane(act, CRANE); diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp index b34556c05d5..1d39de52611 100644 --- a/source/games/duke/src/actors_r.cpp +++ b/source/games/duke/src/actors_r.cpp @@ -830,6 +830,11 @@ void movestandables_r(void) continue; } + if (act->GetClass() != RUNTIME_CLASS(DDukeActor)) + { + CallTick(act); + continue; + } if (picnum >= CRANE && picnum <= CRANE +3) { movecrane(act, CRANE); diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index 5e25d586bb4..8bbcd601793 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -118,5 +118,10 @@ struct Dispatcher extern Dispatcher fi; +void CallInitialize(DDukeActor* actor); +void CallTick(DDukeActor* actor); +void CallAction(DDukeActor* actor); + + END_DUKE_NS diff --git a/source/games/duke/src/game.cpp b/source/games/duke/src/game.cpp index e5d22799eb2..14a15145ec6 100644 --- a/source/games/duke/src/game.cpp +++ b/source/games/duke/src/game.cpp @@ -400,4 +400,31 @@ void GameInterface::app_init() } +void CallInitialize(DDukeActor* actor) +{ + IFVIRTUALPTR(actor, DDukeActor, initialize) + { + VMValue val = actor; + VMCall(func, &val, 1, nullptr, 0); + } +} + +void CallTick(DDukeActor* actor) +{ + IFVIRTUALPTR(actor, DDukeActor, Tick) + { + VMValue val = actor; + VMCall(func, &val, 1, nullptr, 0); + } +} + +void CallAction(DDukeActor* actor) +{ + IFVIRTUALPTR(actor, DDukeActor, RunState) + { + VMValue val = actor; + VMCall(func, &val, 1, nullptr, 0); + } +} + END_DUKE_NS diff --git a/source/games/duke/src/premap.cpp b/source/games/duke/src/premap.cpp index 12bdb0cd350..0d629b2f22e 100644 --- a/source/games/duke/src/premap.cpp +++ b/source/games/duke/src/premap.cpp @@ -941,12 +941,16 @@ static TArray spawnactors(SpawnSpriteDef& sprites) continue; } auto sprt = &sprites.sprites[i]; - auto actor = static_cast(InsertActor(RUNTIME_CLASS(DDukeActor), sprt->sectp, sprt->statnum)); - spawns[j++] = actor; - actor->spr = sprites.sprites[i]; - if (sprites.sprext.Size()) actor->sprext = sprites.sprext[i]; - else actor->sprext = {}; - actor->spsmooth = {}; + auto info = spawnMap.CheckKey(sprt->picnum); + auto actor = static_cast(InsertActor(info? info->Class() : RUNTIME_CLASS(DDukeActor), sprt->sectp, sprt->statnum)); + if (actor) + { + spawns[j++] = actor; + actor->spr = sprites.sprites[i]; + if (sprites.sprext.Size()) actor->sprext = sprites.sprext[i]; + else actor->sprext = {}; + actor->spsmooth = {}; + } } return spawns; } diff --git a/source/games/duke/src/spawn.cpp b/source/games/duke/src/spawn.cpp index 105939d6ab0..f73f694d9db 100644 --- a/source/games/duke/src/spawn.cpp +++ b/source/games/duke/src/spawn.cpp @@ -53,7 +53,9 @@ DDukeActor* EGS(sectortype* whatsectp, int s_x, int s_y, int s_z, int s_pn, int8 { // sector pointer must be strictly validated here or the engine will crash. if (whatsectp == nullptr || !validSectorIndex(sectnum(whatsectp))) return nullptr; - auto act = static_cast(::InsertActor(RUNTIME_CLASS(DDukeActor), whatsectp, s_ss)); + + auto info = spawnMap.CheckKey(s_pn); + auto act = static_cast(InsertActor(info ? info->Class() : RUNTIME_CLASS(DDukeActor), whatsectp, s_ss)); if (act == nullptr) return nullptr; SetupGameVarsForActor(act); @@ -126,6 +128,7 @@ DDukeActor* EGS(sectortype* whatsectp, int s_x, int s_y, int s_z, int s_pn, int8 act->spsmooth = {}; return act; + } diff --git a/source/games/duke/src/spawn_d.cpp b/source/games/duke/src/spawn_d.cpp index 36c31f70ab1..cd6fbe74cb0 100644 --- a/source/games/duke/src/spawn_d.cpp +++ b/source/games/duke/src/spawn_d.cpp @@ -43,6 +43,11 @@ BEGIN_DUKE_NS DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray* actors) { + if (act->GetClass() != RUNTIME_CLASS(DDukeActor)) + { + CallOnSpawn(act); + return act; + } auto sectp = act->sector(); if (isWorldTour()) diff --git a/source/games/duke/src/spawn_r.cpp b/source/games/duke/src/spawn_r.cpp index 4630fe0912d..44b5455dc93 100644 --- a/source/games/duke/src/spawn_r.cpp +++ b/source/games/duke/src/spawn_r.cpp @@ -37,6 +37,11 @@ BEGIN_DUKE_NS DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray* actors) { + if (act->GetClass() != RUNTIME_CLASS(DDukeActor)) + { + CallInitialize(act); + return act; + } auto sectp = act->sector(); switch (act->spr.picnum) diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h index 7ae1be049fa..d2a40da9fcb 100644 --- a/source/games/duke/src/types.h +++ b/source/games/duke/src/types.h @@ -120,6 +120,16 @@ class DDukeActor : public DCoreActor void Serialize(FSerializer& arc) override; + void ChangeType(PClass* newtype) + { + if (newtype->IsDescendantOf(RUNTIME_CLASS(DDukeActor)) && newtype->Size == RUNTIME_CLASS(DDukeActor)->Size && GetClass()->Size == RUNTIME_CLASS(DDukeActor)->Size) + { + // It sucks having to do this but the game heavily depends on being able to swap out the class type and often uses this to manage actor state. + // We'll allow this only for classes that do not add their own data, though. + SetClass(newtype); + } + } + }; // subclassed to add a game specific actor() method @@ -335,7 +345,6 @@ struct player_struct { return cursector != nullptr; } - }; struct Cycler diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 50a0806c832..aa1e91509fd 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -46,6 +46,8 @@ version "4.3" #include "zscript/games/duke/ui/screens.zs" #include "zscript/games/duke/ui/cutscenes.zs" #include "zscript/games/duke/ui/menu.zs" +#include "zscript/games/duke/actors/dukeactor.zs" + #include "zscript/games/blood/bloodgame.zs" #include "zscript/games/blood/ui/menu.zs" #include "zscript/games/blood/ui/sbar.zs" diff --git a/wadsrc/static/zscript/games/duke/actors/DukeActor.zs b/wadsrc/static/zscript/games/duke/actors/DukeActor.zs new file mode 100644 index 00000000000..8983b72e0e5 --- /dev/null +++ b/wadsrc/static/zscript/games/duke/actors/DukeActor.zs @@ -0,0 +1,16 @@ +class DukeActor : CoreActor native +{ + virtual native void Initialize(); + virtual native void Tick(); + virtual native void RunState(); // this is the CON function. +} + +class DukeCrane : DukeActor +{ + override native void Initialize(); + override native void Tick(); +} + +class DukeCranePole : DukeActor +{ +}