[Bugfix] Add SetItemCooldown to tell client exact timer of item when clicked and export to perl and lua (#2795)

Items that are on cooldown but client doesn't show.. clicking item will fix the timer in client
This commit is contained in:
Natedog2012 2023-01-27 17:31:14 -06:00 committed by GitHub
parent c05f951f81
commit 68a34565f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 82 additions and 1 deletions

View File

@ -10498,6 +10498,71 @@ void Client::ResetItemCooldown(uint32 item_id)
}
}
void Client::SetItemCooldown(uint32 item_id, bool use_saved_timer, uint32 in_seconds)
{
EQ::ItemInstance *item = nullptr;
const EQ::ItemData* item_d = database.GetItem(item_id);
if (!item_d) {
return;
}
int recast_type = item_d->RecastType;
auto timestamps = database.GetItemRecastTimestamps(CharacterID());
uint32 total_time = 0;
uint32 current_time = static_cast<uint32>(std::time(nullptr));
uint32 final_time = 0;
const auto timer_type = item_d->RecastType != RECAST_TYPE_UNLINKED_ITEM ? item_d->RecastType : item_id;
const int timer_id = recast_type != RECAST_TYPE_UNLINKED_ITEM ? (pTimerItemStart + recast_type) : (pTimerNegativeItemReuse * item_id);
if (use_saved_timer) {
if (item_d->RecastType != RECAST_TYPE_UNLINKED_ITEM) {
total_time = timestamps.count(item_d->RecastType) ? timestamps.at(item_d->RecastType) : 0;
} else {
total_time = timestamps.count(item_id) ? timestamps.at(item_id) : 0;
}
} else {
total_time = current_time + in_seconds;
}
if (total_time > current_time) {
final_time = total_time - current_time;
}
static const int16 slots[][2] = {
{ EQ::invslot::POSSESSIONS_BEGIN, EQ::invslot::POSSESSIONS_END },
{ EQ::invbag::GENERAL_BAGS_BEGIN, EQ::invbag::GENERAL_BAGS_END },
{ EQ::invbag::CURSOR_BAG_BEGIN, EQ::invbag::CURSOR_BAG_END},
{ EQ::invslot::BANK_BEGIN, EQ::invslot::BANK_END },
{ EQ::invbag::BANK_BAGS_BEGIN, EQ::invbag::BANK_BAGS_END },
{ EQ::invslot::SHARED_BANK_BEGIN, EQ::invslot::SHARED_BANK_END },
{ EQ::invbag::SHARED_BANK_BAGS_BEGIN, EQ::invbag::SHARED_BANK_BAGS_END },
};
const size_t slot_index_count = sizeof(slots) / sizeof(slots[0]);
for (int slot_index = 0; slot_index < slot_index_count; ++slot_index) {
for (int slot_id = slots[slot_index][0]; slot_id <= slots[slot_index][1]; ++slot_id) {
item = GetInv().GetItem(slot_id);
if (item) {
item_d = item->GetItem();
if (item_d && item->GetID() == item_id || (item_d->RecastType != RECAST_TYPE_UNLINKED_ITEM && item_d->RecastType == recast_type)) {
item->SetRecastTimestamp(total_time);
SendItemPacket(slot_id, item, ItemPacketCharmUpdate);
}
}
}
}
//Start timers and update in database only when timer is changed
if (!use_saved_timer) {
GetPTimers().Clear(&database, timer_id);
GetPTimers().Start((timer_id), in_seconds);
database.UpdateItemRecast(
CharacterID(),
timer_type,
GetPTimers().Get(timer_id)->GetReadyTimestamp()
);
}
SendItemRecastTimer(recast_type, final_time, true);
}
void Client::RemoveItem(uint32 item_id, uint32 quantity)
{
EQ::ItemInstance *item = nullptr;

View File

@ -967,6 +967,7 @@ public:
void DeleteItemInInventory(int16 slot_id, int16 quantity = 0, bool client_update = false, bool update_db = true);
int CountItem(uint32 item_id);
void ResetItemCooldown(uint32 item_id);
void SetItemCooldown(uint32 item_id, bool use_saved_timer = false, uint32 in_seconds = 1);
void RemoveItem(uint32 item_id, uint32 quantity = 1);
bool SwapItem(MoveItem_Struct* move_in);
void SwapItemResync(MoveItem_Struct* move_slots);

View File

@ -8928,11 +8928,12 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
if (item->RecastDelay > 0)
{
if (item->RecastType != RECAST_TYPE_UNLINKED_ITEM && !GetPTimers().Expired(&database, (pTimerItemStart + item->RecastType), false)) {
SendItemRecastTimer(item->RecastType); //Problem: When you loot corpse, recast display is not present. This causes it to display again. Could not get to display when sending from looting.
SetItemCooldown(item->ID, true);
SendSpellBarEnable(item->Click.Effect);
LogSpells("Casting of [{}] canceled: item spell reuse timer not expired", spell_id);
return;
} else if (item->RecastType == RECAST_TYPE_UNLINKED_ITEM && !GetPTimers().Expired(&database, (pTimerNegativeItemReuse * item->ID), false)) {
SetItemCooldown(item->ID, true);
SendSpellBarEnable(item->Click.Effect);
LogSpells("Casting of [{}] canceled: item spell reuse timer not expired", spell_id);
return;

View File

@ -3020,6 +3020,12 @@ void Lua_Client::ResetItemCooldown(uint32 item_id)
self->ResetItemCooldown(item_id);
}
void Lua_Client::SetItemCooldown(uint32 item_id, uint32 in_time)
{
Lua_Safe_Call_Void();
self->SetItemCooldown(item_id, false, in_time);
}
luabind::scope lua_register_client() {
return luabind::class_<Lua_Client, Lua_Mob>("Client")
.def(luabind::constructor<>())
@ -3454,6 +3460,7 @@ luabind::scope lua_register_client() {
.def("SetHunger", (void(Lua_Client::*)(int))&Lua_Client::SetHunger)
.def("SetInvulnerableEnvironmentDamage", (void(Lua_Client::*)(int))&Lua_Client::SetInvulnerableEnvironmentDamage)
.def("SetIPExemption", (void(Lua_Client::*)(int))&Lua_Client::SetIPExemption)
.def("SetItemCooldown", (void(Lua_Client::*)(uint32,uint32))&Lua_Client::SetItemCooldown)
.def("SetLanguageSkill", (void(Lua_Client::*)(int,int))&Lua_Client::SetLanguageSkill)
.def("SetMaterial", (void(Lua_Client::*)(int,uint32))&Lua_Client::SetMaterial)
.def("SetPEQZoneFlag", (void(Lua_Client::*)(uint32))&Lua_Client::SetPEQZoneFlag)

View File

@ -463,6 +463,7 @@ public:
bool CanEnterZone(std::string zone_short_name, int16 instance_version);
void SendPath(Lua_Mob target);
void ResetItemCooldown(uint32 item_id);
void SetItemCooldown(uint32 item_id, uint32 in_time);
void ApplySpell(int spell_id);
void ApplySpell(int spell_id, int duration);

View File

@ -2877,6 +2877,11 @@ void Perl_Client_ResetItemCooldown(Client* self, uint32 item_id)
self->ResetItemCooldown(item_id);
}
void Perl_Client_SetItemCooldown(Client* self, uint32 item_id, uint32 in_time)
{
self->SetItemCooldown(item_id, false, in_time);
}
void perl_register_client()
{
perl::interpreter perl(PERL_GET_THX);
@ -3313,6 +3318,7 @@ void perl_register_client()
package.add("SetHunger", &Perl_Client_SetHunger);
package.add("SetIPExemption", &Perl_Client_SetIPExemption);
package.add("SetInvulnerableEnvironmentDamage", &Perl_Client_SetInvulnerableEnvironmentDamage);
package.add("SetItemCooldown", &Perl_Client_SetItemCooldown);
package.add("SetLanguageSkill", &Perl_Client_SetLanguageSkill);
package.add("SetMaterial", &Perl_Client_SetMaterial);
package.add("SetPEQZoneFlag", &Perl_Client_SetPEQZoneFlag);