From e75f87a53566aeb2b86d743c9c000d5a1f265eab Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 10 Jun 2022 13:52:22 -0400 Subject: [PATCH] [Quest API] Expand SaveGuardSpot (#2258) * Expand SaveGuardSpot - Adds -- mob:saveguardspot() -- mob:saveguardspot(true) * Perl Support Thanks to KinglyKrab for the perl implementation. --- zone/lua_npc.cpp | 12 ++++++++++++ zone/lua_npc.h | 2 ++ zone/npc.h | 1 + zone/perl_npc.cpp | 29 ++++++++++++++++++++--------- zone/waypoints.cpp | 14 ++++++++++++++ 5 files changed, 49 insertions(+), 9 deletions(-) diff --git a/zone/lua_npc.cpp b/zone/lua_npc.cpp index edc0caa8a..2581864d5 100644 --- a/zone/lua_npc.cpp +++ b/zone/lua_npc.cpp @@ -318,6 +318,16 @@ void Lua_NPC::NextGuardPosition() { self->NextGuardPosition(); } +void Lua_NPC::SaveGuardSpot() { + Lua_Safe_Call_Void(); + self->SaveGuardSpot(); +} + +void Lua_NPC::SaveGuardSpot(bool clear) { + Lua_Safe_Call_Void(); + self->SaveGuardSpot(clear); +} + void Lua_NPC::SaveGuardSpot(float x, float y, float z, float heading) { Lua_Safe_Call_Void(); self->SaveGuardSpot(glm::vec4(x, y, z, heading)); @@ -759,6 +769,8 @@ luabind::scope lua_register_npc() { .def("RemoveItem", (void(Lua_NPC::*)(int,int))&Lua_NPC::RemoveItem) .def("RemoveItem", (void(Lua_NPC::*)(int,int,int))&Lua_NPC::RemoveItem) .def("ResumeWandering", (void(Lua_NPC::*)(void))&Lua_NPC::ResumeWandering) + .def("SaveGuardSpot", (void(Lua_NPC::*)(void))&Lua_NPC::SaveGuardSpot) + .def("SaveGuardSpot", (void(Lua_NPC::*)(bool))&Lua_NPC::SaveGuardSpot) .def("SaveGuardSpot", (void(Lua_NPC::*)(float,float,float,float))&Lua_NPC::SaveGuardSpot) .def("ScaleNPC", (void(Lua_NPC::*)(uint8))&Lua_NPC::ScaleNPC) .def("SetCopper", (void(Lua_NPC::*)(uint32))&Lua_NPC::SetCopper) diff --git a/zone/lua_npc.h b/zone/lua_npc.h index 90a91e3aa..a5b0ddc3c 100644 --- a/zone/lua_npc.h +++ b/zone/lua_npc.h @@ -90,6 +90,8 @@ public: void PauseWandering(int pause_time); void MoveTo(float x, float y, float z, float h, bool save); void NextGuardPosition(); + void SaveGuardSpot(); + void SaveGuardSpot(bool clear); void SaveGuardSpot(float x, float y, float z, float heading); bool IsGuarding(); void AI_SetRoambox(float dist, float max_x, float min_x, float max_y, float min_y); diff --git a/zone/npc.h b/zone/npc.h index 76ff091ef..ccc6d8af8 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -348,6 +348,7 @@ public: int32 GetEquipmentMaterial(uint8 material_slot) const; void NextGuardPosition(); + void SaveGuardSpot(bool ClearGuardSpot = false); void SaveGuardSpot(const glm::vec4 &pos); inline bool IsGuarding() const { return(m_GuardPoint.w != 0); } void SaveGuardSpotCharm(); diff --git a/zone/perl_npc.cpp b/zone/perl_npc.cpp index a0cb935f3..1f11fe60b 100644 --- a/zone/perl_npc.cpp +++ b/zone/perl_npc.cpp @@ -929,16 +929,27 @@ XS(XS_NPC_NextGuardPosition) { XS(XS_NPC_SaveGuardSpot); /* prototype to pass -Wmissing-prototypes */ XS(XS_NPC_SaveGuardSpot) { dXSARGS; - if (items != 5) + if (items != 1 && items != 2 && items != 5) Perl_croak(aTHX_ "Usage: NPC::SaveGuardSpot(THIS, x, y, z, heading)"); // @categories Script Utility { - NPC *THIS; - float x = (float)SvNV(ST(1)); - float y = (float)SvNV(ST(2)); - float z = (float)SvNV(ST(3)); - float heading = (float)SvNV(ST(4)); - VALIDATE_THIS_IS_NPC; - THIS->SaveGuardSpot(glm::vec4(x, y, z, heading)); + NPC *THIS; + if (items == 1 || items == 2) { + bool clear_guard_spot = false; + + if (items > 1) { + clear_guard_spot = (bool) SvTRUE(ST(1)); + } + + VALIDATE_THIS_IS_NPC; + THIS->SaveGuardSpot(clear_guard_spot); + } else if (items == 5) { + float x = (float)SvNV(ST(1)); + float y = (float)SvNV(ST(2)); + float z = (float)SvNV(ST(3)); + float heading = (float)SvNV(ST(4)); + VALIDATE_THIS_IS_NPC; + THIS->SaveGuardSpot(glm::vec4(x, y, z, heading)); + } } XSRETURN_EMPTY; } @@ -2017,7 +2028,7 @@ XS(boot_NPC) { newXSproto(strcpy(buf, "RemoveMeleeProc"), XS_NPC_RemoveMeleeProc, file, "$$"); newXSproto(strcpy(buf, "RemoveRangedProc"), XS_NPC_RemoveRangedProc, file, "$$"); newXSproto(strcpy(buf, "ResumeWandering"), XS_NPC_ResumeWandering, file, "$"); - newXSproto(strcpy(buf, "SaveGuardSpot"), XS_NPC_SaveGuardSpot, file, "$$$$$"); + newXSproto(strcpy(buf, "SaveGuardSpot"), XS_NPC_SaveGuardSpot, file, "$;$$$$"); newXSproto(strcpy(buf, "ScaleNPC"), XS_NPC_ScaleNPC, file, "$$"); newXSproto(strcpy(buf, "SetCopper"), XS_NPC_SetCopper, file, "$$"); newXSproto(strcpy(buf, "SetGold"), XS_NPC_SetGold, file, "$$"); diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 91016544c..8a31cb06d 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -557,6 +557,20 @@ void NPC::SetWaypointPause() } } +void NPC::SaveGuardSpot(bool ClearGuardSpot) { + if (ClearGuardSpot) { + LogAI("Clearing guard order."); + m_GuardPoint = glm::vec4(); + } else { + m_GuardPoint = m_Position; + + if (m_GuardPoint.w == 0) { + m_GuardPoint.w = 0.0001; //hack to make IsGuarding simpler + } + LogAI("Setting guard position to {0}", to_string(static_cast(m_GuardPoint))); + } +} + void NPC::SaveGuardSpot(const glm::vec4 &pos) { m_GuardPoint = pos;