From 21a37d2c07deac92f09552e8d8beefd8d95fb6c6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 30 Apr 2023 08:11:30 +0200 Subject: [PATCH] - added helpers needed to run CON replacement code. * killit must exit to the top level right away. Use an exception for this. * two new flags to make checking easier. * do not export killit_flag to scripting. --- source/games/duke/src/constants.h | 2 ++ source/games/duke/src/game.cpp | 2 +- source/games/duke/src/types.h | 12 +++++++++++ source/games/duke/src/vmexports.cpp | 21 +++++++++++++++++-- wadsrc/static/zscript/games/duke/dukeactor.zs | 3 ++- 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/source/games/duke/src/constants.h b/source/games/duke/src/constants.h index 5e0592eab..bb2bc8423 100644 --- a/source/games/duke/src/constants.h +++ b/source/games/duke/src/constants.h @@ -448,6 +448,8 @@ enum sflags4_t { SFLAG4_DOUBLEHITDAMAGE = 0x00000001, SFLAG4_NODAMAGETURN = 0x00000002, + SFLAG4_CONOVERRIDE = 0x00000004, // this is strictly internal + SFLAG4_INRUNSTATE = 0x00000008, // exception throwing guard. }; using EDukeFlags4 = TFlags; diff --git a/source/games/duke/src/game.cpp b/source/games/duke/src/game.cpp index b906c8481..da7b9dc83 100644 --- a/source/games/duke/src/game.cpp +++ b/source/games/duke/src/game.cpp @@ -498,7 +498,7 @@ void GameInterface::FinalizeSetup() } } - //ScriptCode[actinf.scriptaddress] = 0; // ignore strength values for hashing the script code. (later, we still need this.) + ScriptCode[actinf.scriptaddress] = 0; // ignore strength values for hashing the script code. // todo: hash the entire script code and compare against precalculated value for the current game. // If identical, remove all ScriptAddresses from the class list. diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h index 52976378b..6d1333429 100644 --- a/source/games/duke/src/types.h +++ b/source/games/duke/src/types.h @@ -170,6 +170,18 @@ public: using HitInfo = THitInfo; using Collision = TCollision; + +// This is to satisfy the CON-based requirement of 'killit' immediately aborting all script code execution. +class CDukeKillEvent : public std::exception +{ + int Type_; +public: + CDukeKillEvent(int type): Type_(type) {} + int Type() const { return Type_; } + // to print a meaningful message if killit got called from the wrong place. + const char* what() const override { return "killit called from outside RunState!"; } +}; + struct animwalltype { walltype* wall; diff --git a/source/games/duke/src/vmexports.cpp b/source/games/duke/src/vmexports.cpp index 62139a1f8..c1f6abd93 100644 --- a/source/games/duke/src/vmexports.cpp +++ b/source/games/duke/src/vmexports.cpp @@ -293,7 +293,7 @@ DEFINE_FIELD(DDukeActor, curAction) DEFINE_FIELD(DDukeActor, curMove) DEFINE_FIELD(DDukeActor, curAI) DEFINE_FIELD(DDukeActor, actioncounter) -DEFINE_FIELD(DDukeActor, killit_flag) +//DEFINE_FIELD(DDukeActor, killit_flag) void TickActor(DDukeActor*); DEFINE_ACTION_FUNCTION(DDukeActor, Tick) @@ -604,7 +604,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, badguy, badguy) int duke_scripted(const DDukeActor* act) { - return act->conInfo() != nullptr; + return act->conInfo() != nullptr || (act->flags4 & SFLAG4_CONOVERRIDE); } DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, scripted, duke_scripted) @@ -927,6 +927,23 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, subkill, subkill) return 0; } +DEFINE_ACTION_FUNCTION(DDukeActor, killit) +{ + PARAM_SELF_PROLOGUE(DDukeActor); + if (self->flags4 & SFLAG4_INRUNSTATE) + { + // this has to be done the hard way. The original CON interpreter stops running commands once an actor is set to be killed. + // The only safe way to handle this in native code while exiting all nested functions is throwing an exception. + throw CDukeKillEvent(1); + } + else + { + // if it is something else than the currently ticked actor we can outright destroy it. + self->Destroy(); + } + return 0; +} + //--------------------------------------------------------------------------- // // DukePlayer diff --git a/wadsrc/static/zscript/games/duke/dukeactor.zs b/wadsrc/static/zscript/games/duke/dukeactor.zs index 2123fbd41..4b8c9539f 100644 --- a/wadsrc/static/zscript/games/duke/dukeactor.zs +++ b/wadsrc/static/zscript/games/duke/dukeactor.zs @@ -312,7 +312,7 @@ class DukeActor : CoreActor native native ActorMove curMove; native Name curAI; native int16 actioncounter; - native uint8 killit_flag; + //native uint8 killit_flag; // flags are implemented natively to avoid the prefixes. @@ -402,6 +402,7 @@ class DukeActor : CoreActor native native double GetAmbientDist(); native void addkill(); native void subkill(); + native void killit();