From 8f89f38f5c72db27a0cc89befdd3907d2bb8f51e Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 9 Feb 2021 00:08:07 -0500 Subject: [PATCH] Add ScaleNPC() to Perl and Lua. (#1238) --- zone/lua_npc.cpp | 9 ++++++++- zone/lua_npc.h | 1 + zone/npc.cpp | 8 ++++++++ zone/npc.h | 2 ++ zone/npc_scale_manager.cpp | 10 ++++++++++ zone/npc_scale_manager.h | 1 + zone/perl_npc.cpp | 15 +++++++++++++++ 7 files changed, 45 insertions(+), 1 deletion(-) diff --git a/zone/lua_npc.cpp b/zone/lua_npc.cpp index 23be1e3ee..32d268fb5 100644 --- a/zone/lua_npc.cpp +++ b/zone/lua_npc.cpp @@ -558,6 +558,12 @@ void Lua_NPC::RecalculateSkills() self->RecalculateSkills(); } +void Lua_NPC::ScaleNPC(uint8 npc_level) +{ + Lua_Safe_Call_Void(); + self->ScaleNPC(npc_level); +} + luabind::scope lua_register_npc() { return luabind::class_("NPC") .def(luabind::constructor<>()) @@ -670,7 +676,8 @@ luabind::scope lua_register_npc() { .def("MerchantCloseShop", (void(Lua_NPC::*)(void))&Lua_NPC::MerchantCloseShop) .def("GetRawAC", (int(Lua_NPC::*)(void))&Lua_NPC::GetRawAC) .def("GetAvoidanceRating", &Lua_NPC::GetAvoidanceRating) - .def("RecalculateSkills", (void(Lua_NPC::*)(void))&Lua_NPC::RecalculateSkills); + .def("RecalculateSkills", (void(Lua_NPC::*)(void))&Lua_NPC::RecalculateSkills) + .def("ScaleNPC", (void(Lua_NPC::*)(uint8))&Lua_NPC::ScaleNPC); } #endif diff --git a/zone/lua_npc.h b/zone/lua_npc.h index 3b1714095..042a114ef 100644 --- a/zone/lua_npc.h +++ b/zone/lua_npc.h @@ -136,6 +136,7 @@ public: void SetSimpleRoamBox(float box_size, float move_distance); void SetSimpleRoamBox(float box_size, float move_distance, int move_delay); void RecalculateSkills(); + void ScaleNPC(uint8 npc_level); }; #endif diff --git a/zone/npc.cpp b/zone/npc.cpp index c2416abac..7a0f4f411 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -3329,3 +3329,11 @@ void NPC::RecalculateSkills() } } } + +void NPC::ScaleNPC(uint8 npc_level) { + if (GetLevel() != npc_level) { + SetLevel(npc_level); + } + npc_scale_manager->ResetNPCScaling(this); + npc_scale_manager->ScaleNPC(this); +} \ No newline at end of file diff --git a/zone/npc.h b/zone/npc.h index 2396325db..271b6549a 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -494,6 +494,8 @@ public: inline bool IsSkipAutoScale() const { return skip_auto_scale; } + void ScaleNPC(uint8 npc_level); + void RecalculateSkills(); static LootDropEntries_Struct NewLootDropEntry(); diff --git a/zone/npc_scale_manager.cpp b/zone/npc_scale_manager.cpp index 191d2540f..158ac299b 100644 --- a/zone/npc_scale_manager.cpp +++ b/zone/npc_scale_manager.cpp @@ -164,6 +164,16 @@ void NpcScaleManager::ScaleNPC(NPC *npc) } } +void NpcScaleManager::ResetNPCScaling(NPC *npc) { + for (const auto &scaling_stat : scaling_stats) { + std::string stat_name = fmt::format("modify_stat_{}", scaling_stat); + std::string reset_value = "0"; + if (npc->EntityVariableExists(stat_name.c_str())) { + npc->ModifyNPCStat(scaling_stat.c_str(), reset_value.c_str()); + } + } +} + bool NpcScaleManager::LoadScaleData() { auto results = content_db.QueryDatabase( diff --git a/zone/npc_scale_manager.h b/zone/npc_scale_manager.h index 1135ee8a2..2b52de1e4 100644 --- a/zone/npc_scale_manager.h +++ b/zone/npc_scale_manager.h @@ -87,6 +87,7 @@ public: }; void ScaleNPC(NPC * npc); + void ResetNPCScaling(NPC * npc); bool IsAutoScaled(NPC * npc); bool LoadScaleData(); diff --git a/zone/perl_npc.cpp b/zone/perl_npc.cpp index c622d9950..08bc282ac 100644 --- a/zone/perl_npc.cpp +++ b/zone/perl_npc.cpp @@ -1711,6 +1711,20 @@ XS(XS_NPC_RecalculateSkills) { XSRETURN_EMPTY; } +XS(XS_NPC_ScaleNPC); /* prototype to pass -Wmissing-prototypes */ +XS(XS_NPC_ScaleNPC) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: NPC::ScaleNPC(THIS, uint8 npc_level)"); + { + NPC *THIS; + uint8 npc_level = (uint8) SvUV(ST(1)); + VALIDATE_THIS_IS_NPC; + THIS->ScaleNPC(npc_level); + } + XSRETURN_EMPTY; +} + #ifdef __cplusplus extern "C" #endif @@ -1827,6 +1841,7 @@ XS(boot_NPC) { newXSproto(strcpy(buf, "GetCombatState"), XS_NPC_GetCombatState, file, "$"); newXSproto(strcpy(buf, "SetSimpleRoamBox"), XS_NPC_SetSimpleRoamBox, file, "$$;$$"); newXSproto(strcpy(buf, "RecalculateSkills"), XS_NPC_RecalculateSkills, file, "$"); + newXSproto(strcpy(buf, "ScaleNPC"), XS_NPC_ScaleNPC, file, "$$"); XSRETURN_YES; }