diff --git a/zone/client.h b/zone/client.h index 4253e6643..c6c44b969 100644 --- a/zone/client.h +++ b/zone/client.h @@ -948,7 +948,9 @@ public: void DropInst(const EQ::ItemInstance* inst); bool TrainDiscipline(uint32 itemid); void TrainDiscBySpellID(int32 spell_id); + uint32 GetDisciplineTimer(uint32 timer_id); int GetDiscSlotBySpellID(int32 spellid); + void ResetDisciplineTimer(uint32 timer_id); void SendDisciplineUpdate(); void SendDisciplineTimer(uint32 timer_id, uint32 duration); bool UseDiscipline(uint32 spell_id, uint32 target); diff --git a/zone/effects.cpp b/zone/effects.cpp index b82f74a4d..67ad52314 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -660,6 +660,23 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) { return(true); } +uint32 Client::GetDisciplineTimer(uint32 timer_id) { + pTimerType disc_timer_id = pTimerDisciplineReuseStart + timer_id; + uint32 disc_timer = 0; + if (GetPTimers().Enabled((uint32)disc_timer_id)) { + disc_timer = GetPTimers().GetRemainingTime(disc_timer_id); + } + return disc_timer; +} + +void Client::ResetDisciplineTimer(uint32 timer_id) { + pTimerType disc_timer_id = pTimerDisciplineReuseStart + timer_id; + if (GetPTimers().Enabled((uint32)disc_timer_id)) { + GetPTimers().Clear(&database, (uint32)disc_timer_id); + } + SendDisciplineTimer(timer_id, 0); +} + 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 5898215f3..65058ec4c 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -845,6 +845,16 @@ void Lua_Client::ResetTrade() { self->ResetTrade(); } +uint32 Lua_Client::GetDisciplineTimer(uint32 timer_id) { + Lua_Safe_Call_Int(); + return self->GetDisciplineTimer(timer_id); +} + +void Lua_Client::ResetDisciplineTimer(uint32 timer_id) { + Lua_Safe_Call_Void(); + self->ResetDisciplineTimer(timer_id); +} + bool Lua_Client::UseDiscipline(int spell_id, int target_id) { Lua_Safe_Call_Bool(); return self->UseDiscipline(spell_id, target_id); @@ -1752,6 +1762,8 @@ luabind::scope lua_register_client() { .def("ForageItem", (void(Lua_Client::*)(bool))&Lua_Client::ForageItem) .def("CalcPriceMod", (float(Lua_Client::*)(Lua_Mob,bool))&Lua_Client::CalcPriceMod) .def("ResetTrade", (void(Lua_Client::*)(void))&Lua_Client::ResetTrade) + .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("GetCharacterFactionLevel", (int(Lua_Client::*)(int))&Lua_Client::GetCharacterFactionLevel) .def("SetZoneFlag", (void(Lua_Client::*)(int))&Lua_Client::SetZoneFlag) diff --git a/zone/lua_client.h b/zone/lua_client.h index 600b594f2..f684de72c 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -196,6 +196,8 @@ public: void ForageItem(bool guarantee); float CalcPriceMod(Lua_Mob other, bool reverse); void ResetTrade(); + uint32 GetDisciplineTimer(uint32 timer_id); + void ResetDisciplineTimer(uint32 timer_id); bool UseDiscipline(int spell_id, int target_id); int GetCharacterFactionLevel(int faction_id); void SetZoneFlag(int zone_id); diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index ff17e041c..a2e02231e 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -3670,6 +3670,54 @@ XS(XS_Client_UseDiscipline) { XSRETURN(1); } +XS(XS_Client_GetDisciplineTimer); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_GetDisciplineTimer) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::GetDisciplineTimer(THIS, uint32 timer_id)"); + { + Client *THIS; + uint32 RETVAL; + dXSTARG; + uint32 timer_id = (uint32) 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."); + + RETVAL = THIS->GetDisciplineTimer(timer_id); + XSprePUSH; + PUSHu((UV) RETVAL); + } + XSRETURN(1); +} + +XS(XS_Client_ResetDisciplineTimer); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_ResetDisciplineTimer) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::ResetDisciplineTimer(THIS, uint32 timer_id)"); + { + Client *THIS; + uint32 timer_id = (uint32) 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."); + + THIS->ResetDisciplineTimer(timer_id); + } + XSRETURN_EMPTY; +} + XS(XS_Client_GetCharacterFactionLevel); /* prototype to pass -Wmissing-prototypes */ XS(XS_Client_GetCharacterFactionLevel) { dXSARGS; @@ -6451,6 +6499,7 @@ XS(boot_Client) { newXSproto(strcpy(buf, "GetCorpseID"), XS_Client_GetCorpseID, file, "$$"); newXSproto(strcpy(buf, "GetCorpseItemAt"), XS_Client_GetCorpseItemAt, file, "$$$"); newXSproto(strcpy(buf, "GetCustomItemData"), XS_Client_GetCustomItemData, file, "$$$"); + newXSproto(strcpy(buf, "GetDisciplineTimer"), XS_Client_GetDisciplineTimer, file, "$$"); newXSproto(strcpy(buf, "GetDiscSlotBySpellID"), XS_Client_GetDiscSlotBySpellID, file, "$$"); newXSproto(strcpy(buf, "GetDuelTarget"), XS_Client_GetDuelTarget, file, "$"); newXSproto(strcpy(buf, "GetEbonCrystals"), XS_Client_GetEbonCrystals, file, "$"); @@ -6548,6 +6597,7 @@ XS(boot_Client) { newXSproto(strcpy(buf, "RefundAA"), XS_Client_RefundAA, file, "$$"); newXSproto(strcpy(buf, "RemoveNoRent"), XS_Client_RemoveNoRent, file, "$"); newXSproto(strcpy(buf, "ResetAA"), XS_Client_ResetAA, file, "$"); + newXSproto(strcpy(buf, "ResetDisciplineTimer"), XS_Client_ResetDisciplineTimer, file, "$$"); newXSproto(strcpy(buf, "ResetTrade"), XS_Client_ResetTrade, file, "$"); newXSproto(strcpy(buf, "Save"), XS_Client_Save, file, "$$"); newXSproto(strcpy(buf, "SaveBackup"), XS_Client_SaveBackup, file, "$");