diff --git a/zone/client.h b/zone/client.h index 6829ce303..2b0693779 100644 --- a/zone/client.h +++ b/zone/client.h @@ -975,6 +975,7 @@ public: void SendDisciplineUpdate(); void SendDisciplineTimer(uint32 timer_id, uint32 duration); bool UseDiscipline(uint32 spell_id, uint32 target); + bool HasDisciplineLearned(uint16 spell_id); void SetLinkedSpellReuseTimer(uint32 timer_id, uint32 duration); bool IsLinkedSpellReuseTimerReady(uint32 timer_id); diff --git a/zone/effects.cpp b/zone/effects.cpp index c2a20cf71..b62a2b383 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -678,6 +678,17 @@ void Client::ResetDisciplineTimer(uint32 timer_id) { SendDisciplineTimer(timer_id, 0); } +bool Client::HasDisciplineLearned(uint16 spell_id) { + bool has_learned = false; + for (auto index = 0; index < MAX_PP_DISCIPLINES; ++index) { + if (GetPP().disciplines.values[index] == spell_id) { + has_learned = true; + break; + } + } + return has_learned; +} + void Client::SendDisciplineTimer(uint32 timer_id, uint32 duration) { if (timer_id < MAX_DISCIPLINE_TIMERS) diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index c04345cc6..fbe9bebdb 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -929,6 +929,11 @@ bool Lua_Client::UseDiscipline(int spell_id, int target_id) { return self->UseDiscipline(spell_id, target_id); } +bool Lua_Client::HasDisciplineLearned(uint16 spell_id) { + Lua_Safe_Call_Bool(); + return self->HasDisciplineLearned(spell_id); +} + int Lua_Client::GetCharacterFactionLevel(int faction_id) { Lua_Safe_Call_Int(); return self->GetCharacterFactionLevel(faction_id); @@ -2104,6 +2109,7 @@ luabind::scope lua_register_client() { .def("GetDisciplineTimer", (uint32(Lua_Client::*)(uint32))&Lua_Client::GetDisciplineTimer) .def("ResetDisciplineTimer", (void(Lua_Client::*)(uint32))&Lua_Client::ResetDisciplineTimer) .def("UseDiscipline", (bool(Lua_Client::*)(int,int))&Lua_Client::UseDiscipline) + .def("HasDisciplineLearned", (bool(Lua_Client::*)(uint16))&Lua_Client::HasDisciplineLearned) .def("GetCharacterFactionLevel", (int(Lua_Client::*)(int))&Lua_Client::GetCharacterFactionLevel) .def("SetZoneFlag", (void(Lua_Client::*)(int))&Lua_Client::SetZoneFlag) .def("ClearZoneFlag", (void(Lua_Client::*)(int))&Lua_Client::ClearZoneFlag) diff --git a/zone/lua_client.h b/zone/lua_client.h index 50043ab77..fda6f08ee 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -213,6 +213,7 @@ public: uint32 GetDisciplineTimer(uint32 timer_id); void ResetDisciplineTimer(uint32 timer_id); bool UseDiscipline(int spell_id, int target_id); + bool HasDisciplineLearned(uint16 spell_id); int GetCharacterFactionLevel(int faction_id); void SetZoneFlag(int zone_id); void ClearZoneFlag(int zone_id); diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index de30d0c50..3697335d3 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -7086,6 +7086,32 @@ XS(XS_Client_Fling) { XSRETURN_EMPTY; } +XS(XS_Client_HasDisciplineLearned); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_HasDisciplineLearned) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::HasDisciplineLearned(THIS, uint16 spell_id)"); + { + Client *THIS; + bool has_learned; + uint16 spell_id = (uint16) SvUV(ST(1)); + + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + has_learned = THIS->HasDisciplineLearned(spell_id); + ST(0) = boolSV(has_learned); + sv_2mortal(ST(0)); + } + XSRETURN(1); +} + XS(XS_Client_GetClassBitmask); XS(XS_Client_GetClassBitmask) { dXSARGS; @@ -7294,6 +7320,7 @@ XS(boot_Client) { newXSproto(strcpy(buf, "GrantAlternateAdvancementAbility"), XS_Client_GrantAlternateAdvancementAbility, file, "$$$;$"); newXSproto(strcpy(buf, "GuildID"), XS_Client_GuildID, file, "$"); newXSproto(strcpy(buf, "GuildRank"), XS_Client_GuildRank, file, "$"); + newXSproto(strcpy(buf, "HasDisciplineLearned"), XS_Client_HasDisciplineLearned, file, "$$"); newXSproto(strcpy(buf, "HasExpeditionLockout"), XS_Client_HasExpeditionLockout, file, "$$$"); newXSproto(strcpy(buf, "HasSkill"), XS_Client_HasSkill, file, "$$"); newXSproto(strcpy(buf, "HasSpellScribed"), XS_Client_HasSkill, file, "$$");