ACS-Dialogue interface: New threads with dialogue auto-skip previous threads with dialogue

If some dialogue needs to be never-missable, that's the mapper's responsibility - but now they won't get randomly interleaved if multiple are activated just by regular free driving, which was the worst kind of default
This commit is contained in:
toaster 2023-12-10 16:10:45 +00:00
parent de7d53b4ea
commit cdb2b44aa6
5 changed files with 59 additions and 17 deletions

View file

@ -667,6 +667,27 @@ bool CallFunc_CameraWait(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::
return true; // Execution interrupted return true; // Execution interrupted
} }
/*--------------------------------------------------
bool Dialogue_ValidCheck(ACSVM::Thread *thread)
Helper to check if the thread's dialogue
context is valid, initialising if not set.
--------------------------------------------------*/
static bool Dialogue_ValidCheck(ACSVM::Thread *thread)
{
// TODO when we move away from g_dialogue
if (netgame)
{
return false;
}
auto info = &static_cast<Thread *>(thread)->info;
if (!info->dialogue_era)
info->dialogue_era = g_dialogue.GetNewEra();
return g_dialogue.EraIsValid(info->dialogue_era);
}
/*-------------------------------------------------- /*--------------------------------------------------
bool CallFunc_DialogueWaitDismiss(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) bool CallFunc_DialogueWaitDismiss(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
@ -678,17 +699,18 @@ bool CallFunc_DialogueWaitDismiss(ACSVM::Thread *thread, const ACSVM::Word *argV
(void)argV; (void)argV;
(void)argC; (void)argC;
// TODO when we move away from g_dialogue if (Dialogue_ValidCheck(thread) == false)
if (netgame)
{ {
return false; return false;
} }
g_dialogue.SetDismissable(true); g_dialogue.SetDismissable(true);
auto info = &static_cast<Thread *>(thread)->info;
thread->state = { thread->state = {
ACSVM::ThreadState::WaitTag, ACSVM::ThreadState::WaitTag,
0, info->dialogue_era,
ACS_TAGTYPE_DIALOGUE ACS_TAGTYPE_DIALOGUE
}; };
@ -706,17 +728,18 @@ bool CallFunc_DialogueWaitText(ACSVM::Thread *thread, const ACSVM::Word *argV, A
(void)argV; (void)argV;
(void)argC; (void)argC;
// TODO when we move away from g_dialogue if (Dialogue_ValidCheck(thread) == false)
if (netgame)
{ {
return false; return false;
} }
g_dialogue.SetDismissable(false); g_dialogue.SetDismissable(false);
auto info = &static_cast<Thread *>(thread)->info;
thread->state = { thread->state = {
ACSVM::ThreadState::WaitTag, ACSVM::ThreadState::WaitTag,
1, info->dialogue_era,
ACS_TAGTYPE_DIALOGUE ACS_TAGTYPE_DIALOGUE
}; };
@ -2025,8 +2048,7 @@ bool CallFunc_DialogueSetSpeaker(ACSVM::Thread *thread, const ACSVM::Word *argV,
(void)argC; (void)argC;
// TODO when we move away from g_dialogue if (Dialogue_ValidCheck(thread) == false)
if (netgame)
{ {
return false; return false;
} }
@ -2069,8 +2091,7 @@ bool CallFunc_DialogueSetCustomSpeaker(ACSVM::Thread *thread, const ACSVM::Word
(void)argC; (void)argC;
// TODO when we move away from g_dialogue if (Dialogue_ValidCheck(thread) == false)
if (netgame)
{ {
return false; return false;
} }
@ -2161,8 +2182,7 @@ bool CallFunc_DialogueNewText(ACSVM::Thread *thread, const ACSVM::Word *argV, AC
(void)argC; (void)argC;
// TODO when we move away from g_dialogue if (Dialogue_ValidCheck(thread) == false)
if (netgame)
{ {
return false; return false;
} }

View file

@ -312,12 +312,13 @@ bool Environment::checkTag(ACSVM::Word type, ACSVM::Word tag)
case ACS_TAGTYPE_DIALOGUE: case ACS_TAGTYPE_DIALOGUE:
{ {
// TODO when we move away from g_dialogue // TODO when we move away from g_dialogue
if (netgame) // See also call-funcs.cpp Dialogue_ValidCheck
if (netgame || !g_dialogue.EraIsValid(tag)) // cheeky reuse
{ {
return true; return true;
} }
if (tag == 0) // cheeky reuse if (g_dialogue.Dismissable())
{ {
// wait for dismissal // wait for dismissal
return (!g_dialogue.Active()); return (!g_dialogue.Active());

View file

@ -66,6 +66,7 @@ public:
sector_t *sector; // Sector that activated this thread. sector_t *sector; // Sector that activated this thread.
polyobj_t *po; // Polyobject that activated this thread. polyobj_t *po; // Polyobject that activated this thread.
bool fromLineSpecial; // Called from P_ProcessLineSpecial. bool fromLineSpecial; // Called from P_ProcessLineSpecial.
UINT32 dialogue_era; // Prevents overlapping dialogue scripts.
ThreadInfo() : ThreadInfo() :
thread_era { thinker_era }, thread_era { thinker_era },
@ -74,7 +75,8 @@ public:
side{ 0 }, side{ 0 },
sector{ nullptr }, sector{ nullptr },
po{ nullptr }, po{ nullptr },
fromLineSpecial{ false } fromLineSpecial{ false },
dialogue_era { 0 }
{ {
} }
@ -85,7 +87,8 @@ public:
side{ info.side }, side{ info.side },
sector{ info.sector }, sector{ info.sector },
po{ info.po }, po{ info.po },
fromLineSpecial{ info.fromLineSpecial } fromLineSpecial{ info.fromLineSpecial },
dialogue_era { info.dialogue_era }
{ {
P_SetTarget(&mo, info.mo); P_SetTarget(&mo, info.mo);
} }
@ -97,7 +100,8 @@ public:
side{ activator->side }, side{ activator->side },
sector{ activator->sector }, sector{ activator->sector },
po{ activator->po }, po{ activator->po },
fromLineSpecial{ static_cast<bool>(activator->fromLineSpecial) } fromLineSpecial{ static_cast<bool>(activator->fromLineSpecial) },
dialogue_era { 0 }
{ {
P_SetTarget(&mo, activator->mo); P_SetTarget(&mo, activator->mo);
} }
@ -118,6 +122,7 @@ public:
side = info.side; side = info.side;
sector = info.sector; sector = info.sector;
po = info.po; po = info.po;
dialogue_era = info.dialogue_era;
return *this; return *this;
} }

View file

@ -478,11 +478,22 @@ void Dialogue::Dismiss(void)
typewriter.ClearText(); typewriter.ClearText();
} }
UINT32 Dialogue::GetNewEra(void)
{
return (++current_era);
}
bool Dialogue::EraIsValid(INT32 comparison)
{
return (current_era == comparison);
}
void Dialogue::Unset(void) void Dialogue::Unset(void)
{ {
Dismiss(); Dismiss();
SetSpeaker(); SetSpeaker();
slide = 0; slide = 0;
current_era = 0;
} }
/* /*

View file

@ -49,6 +49,9 @@ public:
void Dismiss(void); void Dismiss(void);
void Unset(void); void Unset(void);
UINT32 GetNewEra(void);
bool EraIsValid(INT32 comparison);
class Typewriter class Typewriter
{ {
public: public:
@ -76,6 +79,8 @@ public:
private: private:
Typewriter typewriter; Typewriter typewriter;
INT32 current_era;
patch_t *bgPatch; patch_t *bgPatch;
patch_t *confirmPatch; patch_t *confirmPatch;