#include "Client/Mode/CMode.h" #include "Client/Mode/ModeMgr.h" #include "Client/Session.h" #include "Contents/Skills/SkillInfo.h" #include #include #include // OFFSET: 0x00E12FC0 // FUNCTION: fn_23821 int CSession::RotateShortcut(int index, int bank) const { if (bank != 0 && bank != 1) { return index; } const int rotation = bank == 0 ? this->unknown_06FC : this->unknown_06A8; if (rotation == 0) { return index; } const int value = index + 9 * rotation; return value < 36 ? value : value - 36; } // OFFSET: 0x00E26050 // FUNCTION: fn_23913 void CSession::AssignShortcut(unsigned char type, std::uint32_t id, int level, int slot, int bank) { const int rowStart = this->RotateShortcut(9 * this->m_hotkeyPage, bank); const int destination = this->RotateShortcut(slot, bank); CMode* modeEvents = g_modeMgr.GetGameMode(); std::list& cooldowns = this->m_requestTimers; if (id == 0) { if (type != 0) { bool erased = false; for (ShortcutCooldownRecord& record : cooldowns) { const auto value = std::find_if(record.main.begin(), record.main.end(), [&](const CooldownState& state) { return state.slot == slot; }); if (value != record.main.end()) { record.main.erase(value); erased = true; } if (erased) { break; } } } if (bank == 0 || bank == 1) { (bank == 0 ? this->m_shortcutSlots : this->m_secondaryShortcutSlots)[destination] = {}; } modeEvents->SendMsg(313, destination, bank, 0, 0); return; } for (int offset = 0; offset < 9; ++offset) { if (bank != 0 && bank != 1) { continue; } const int index = rowStart + offset; const NormalItemSlot previous = (bank == 0 ? this->m_shortcutSlots : this->m_secondaryShortcutSlots)[index]; bool duplicate = previous.itemId == id && previous.unknown_0005 == level && previous.unknown_0000 == type; if (!duplicate) { const bool usesLevel = CSkillInfo::UsesLevel(*this->m_hotkeyScript, static_cast(previous.itemId)); duplicate = !usesLevel && previous.itemId == id && previous.unknown_0000 == type; } if (!duplicate) { continue; } const auto record = std::find_if(cooldowns.begin(), cooldowns.end(), [&](const ShortcutCooldownRecord& value) { return value.id == id; }); if (record != cooldowns.end() && record->end > timeGetTime()) { const int position = index + 9 * this->m_hotkeyPage - rowStart; const auto value = std::find_if(record->main.begin(), record->main.end(), [&](const CooldownState& state) { return state.slot == position; }); if (value != record->main.end()) { record->main.erase(value); } } (bank == 0 ? this->m_shortcutSlots : this->m_secondaryShortcutSlots)[index] = {}; modeEvents->SendMsg(313, index, bank, 0, 0); } if (bank == 0 || bank == 1) { NormalItemSlot& value = (bank == 0 ? this->m_shortcutSlots : this->m_secondaryShortcutSlots)[destination]; value.unknown_0005 = static_cast(level); value.unknown_0000 = type; value.itemId = id; } modeEvents->SendMsg(313, destination, bank, 0, 0); } // OFFSET: 0x00E492D0 // FUNCTION: fn_24233 void CSession::AssignItemShortcut(std::uint32_t id, int slot) { if (id != 0) { for (int index = 0; index < 9; ++index) { if (this->m_normalItemSlots[index].itemId == id) { this->m_normalItemSlots[index] = {}; break; } } this->m_normalItemSlots[slot].unknown_0005 = 0; this->m_normalItemSlots[slot].unknown_0000 = 0; this->m_normalItemSlots[slot].itemId = id; } else { this->m_normalItemSlots[slot] = {}; } }