mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-24 16:10:14 +00:00
Add mail item attachment support for sending
- CMSG_SEND_MAIL now includes item GUIDs (up to 12 per WotLK) - Right-click items in bags to attach when mail compose is open - Compose window shows 12-slot attachment grid with item icons - Click attached items to remove them - Classic/Vanilla falls back to single item GUID format
This commit is contained in:
parent
ce30cedf4a
commit
9906269671
8 changed files with 203 additions and 17 deletions
|
|
@ -12851,10 +12851,114 @@ void GameHandler::sendMail(const std::string& recipient, const std::string& subj
|
|||
LOG_WARNING("sendMail: mailboxGuid_ is 0 (mailbox closed?)");
|
||||
return;
|
||||
}
|
||||
auto packet = packetParsers_->buildSendMail(mailboxGuid_, recipient, subject, body, money, cod);
|
||||
// Collect attached item GUIDs
|
||||
std::vector<uint64_t> itemGuids;
|
||||
for (const auto& att : mailAttachments_) {
|
||||
if (att.occupied()) {
|
||||
itemGuids.push_back(att.itemGuid);
|
||||
}
|
||||
}
|
||||
auto packet = packetParsers_->buildSendMail(mailboxGuid_, recipient, subject, body, money, cod, itemGuids);
|
||||
LOG_INFO("sendMail: to='", recipient, "' subject='", subject, "' money=", money,
|
||||
" mailboxGuid=", mailboxGuid_);
|
||||
" attachments=", itemGuids.size(), " mailboxGuid=", mailboxGuid_);
|
||||
socket->send(packet);
|
||||
clearMailAttachments();
|
||||
}
|
||||
|
||||
bool GameHandler::attachItemFromBackpack(int backpackIndex) {
|
||||
if (backpackIndex < 0 || backpackIndex >= inventory.getBackpackSize()) return false;
|
||||
const auto& slot = inventory.getBackpackSlot(backpackIndex);
|
||||
if (slot.empty()) return false;
|
||||
|
||||
uint64_t itemGuid = backpackSlotGuids_[backpackIndex];
|
||||
if (itemGuid == 0) {
|
||||
itemGuid = resolveOnlineItemGuid(slot.item.itemId);
|
||||
}
|
||||
if (itemGuid == 0) {
|
||||
addSystemChatMessage("Cannot attach: item not found.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check not already attached
|
||||
for (const auto& att : mailAttachments_) {
|
||||
if (att.occupied() && att.itemGuid == itemGuid) return false;
|
||||
}
|
||||
|
||||
// Find free attachment slot
|
||||
for (int i = 0; i < MAIL_MAX_ATTACHMENTS; ++i) {
|
||||
if (!mailAttachments_[i].occupied()) {
|
||||
mailAttachments_[i].itemGuid = itemGuid;
|
||||
mailAttachments_[i].item = slot.item;
|
||||
mailAttachments_[i].srcBag = 0xFF;
|
||||
mailAttachments_[i].srcSlot = static_cast<uint8_t>(23 + backpackIndex);
|
||||
LOG_INFO("Mail attach: slot=", i, " item='", slot.item.name, "' guid=0x",
|
||||
std::hex, itemGuid, std::dec, " from backpack[", backpackIndex, "]");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
addSystemChatMessage("Cannot attach: all attachment slots full.");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GameHandler::attachItemFromBag(int bagIndex, int slotIndex) {
|
||||
if (bagIndex < 0 || bagIndex >= inventory.NUM_BAG_SLOTS) return false;
|
||||
if (slotIndex < 0 || slotIndex >= inventory.getBagSize(bagIndex)) return false;
|
||||
const auto& slot = inventory.getBagSlot(bagIndex, slotIndex);
|
||||
if (slot.empty()) return false;
|
||||
|
||||
uint64_t itemGuid = 0;
|
||||
uint64_t bagGuid = equipSlotGuids_[19 + bagIndex];
|
||||
if (bagGuid != 0) {
|
||||
auto it = containerContents_.find(bagGuid);
|
||||
if (it != containerContents_.end() && slotIndex < static_cast<int>(it->second.numSlots)) {
|
||||
itemGuid = it->second.slotGuids[slotIndex];
|
||||
}
|
||||
}
|
||||
if (itemGuid == 0) {
|
||||
itemGuid = resolveOnlineItemGuid(slot.item.itemId);
|
||||
}
|
||||
if (itemGuid == 0) {
|
||||
addSystemChatMessage("Cannot attach: item not found.");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& att : mailAttachments_) {
|
||||
if (att.occupied() && att.itemGuid == itemGuid) return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAIL_MAX_ATTACHMENTS; ++i) {
|
||||
if (!mailAttachments_[i].occupied()) {
|
||||
mailAttachments_[i].itemGuid = itemGuid;
|
||||
mailAttachments_[i].item = slot.item;
|
||||
mailAttachments_[i].srcBag = static_cast<uint8_t>(19 + bagIndex);
|
||||
mailAttachments_[i].srcSlot = static_cast<uint8_t>(slotIndex);
|
||||
LOG_INFO("Mail attach: slot=", i, " item='", slot.item.name, "' guid=0x",
|
||||
std::hex, itemGuid, std::dec, " from bag[", bagIndex, "][", slotIndex, "]");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
addSystemChatMessage("Cannot attach: all attachment slots full.");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GameHandler::detachMailAttachment(int attachIndex) {
|
||||
if (attachIndex < 0 || attachIndex >= MAIL_MAX_ATTACHMENTS) return false;
|
||||
if (!mailAttachments_[attachIndex].occupied()) return false;
|
||||
LOG_INFO("Mail detach: slot=", attachIndex, " item='", mailAttachments_[attachIndex].item.name, "'");
|
||||
mailAttachments_[attachIndex] = MailAttachSlot{};
|
||||
return true;
|
||||
}
|
||||
|
||||
void GameHandler::clearMailAttachments() {
|
||||
for (auto& att : mailAttachments_) att = MailAttachSlot{};
|
||||
}
|
||||
|
||||
int GameHandler::getMailAttachmentCount() const {
|
||||
int count = 0;
|
||||
for (const auto& att : mailAttachments_) {
|
||||
if (att.occupied()) ++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void GameHandler::mailTakeMoney(uint32_t mailId) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue