diff --git a/src/playsim/p_map.cpp b/src/playsim/p_map.cpp index ef5438afdff..705ec395613 100644 --- a/src/playsim/p_map.cpp +++ b/src/playsim/p_map.cpp @@ -5702,6 +5702,47 @@ void R_OffsetView(FRenderViewpoint& viewPoint, const DVector3& dir, const double // //========================================================================== +static int CanTalk(AActor *self) +{ + return self->Conversation != nullptr && self->health > 0 && !(self->flags4 & MF4_INCOMBAT); +} + +DEFINE_ACTION_FUNCTION_NATIVE(AActor, CanTalk, CanTalk) +{ + PARAM_SELF_PROLOGUE(AActor); + ACTION_RETURN_BOOL(CanTalk(self)); +} + +static int HasConversation(AActor *self) +{ + return self->Conversation != nullptr; +} + +DEFINE_ACTION_FUNCTION_NATIVE(AActor, HasConversation, HasConversation) +{ + PARAM_SELF_PROLOGUE(AActor); + ACTION_RETURN_BOOL(HasConversation(self)); +} + +static int NativeStartConversation(AActor *self, AActor *player, bool faceTalker, bool saveAngle) +{ + if (!CanTalk(self)) + return false; + + self->ConversationAnimation(0); + P_StartConversation(self, player, faceTalker, saveAngle); + return true; +} + +DEFINE_ACTION_FUNCTION_NATIVE(AActor, StartConversation, NativeStartConversation) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_OBJECT(player, AActor); + PARAM_BOOL(faceTalker); + PARAM_BOOL(saveAngle); + ACTION_RETURN_BOOL(NativeStartConversation(self, player, faceTalker, saveAngle)); +} + bool P_TalkFacing(AActor *player) { static const double angleofs[] = { 0, 90./16, -90./16 }; @@ -5710,19 +5751,8 @@ bool P_TalkFacing(AActor *player) for (double angle : angleofs) { P_AimLineAttack(player, player->Angles.Yaw + DAngle::fromDeg(angle), TALKRANGE, &t, DAngle::fromDeg(35.), ALF_FORCENOSMART | ALF_CHECKCONVERSATION | ALF_PORTALRESTRICT); - if (t.linetarget != NULL) - { - if (t.linetarget->health > 0 && // Dead things can't talk. - !(t.linetarget->flags4 & MF4_INCOMBAT) && // Fighting things don't talk either. - t.linetarget->Conversation != NULL) - { - // Give the NPC a chance to play a brief animation - t.linetarget->ConversationAnimation(0); - P_StartConversation(t.linetarget, player, true, true); - return true; - } - return false; - } + if (t.linetarget != nullptr) + return NativeStartConversation(t.linetarget, player, true, true); } return false; } diff --git a/wadsrc/static/zscript/actors/actor.zs b/wadsrc/static/zscript/actors/actor.zs index e0633d599b8..f480192622f 100644 --- a/wadsrc/static/zscript/actors/actor.zs +++ b/wadsrc/static/zscript/actors/actor.zs @@ -698,7 +698,10 @@ class Actor : Thinker native native clearscope int GetRenderStyle() const; native clearscope bool CheckKeys(int locknum, bool remote, bool quiet = false); protected native void CheckPortalTransition(bool linked = true); - + native clearscope bool HasConversation() const; + native clearscope bool CanTalk() const; + native bool StartConversation(Actor player, bool faceTalker = true, bool saveAngle = true); + native clearscope string GetTag(string defstr = "") const; native clearscope string GetCharacterName() const; native void SetTag(string defstr = "");