[11246] Provide mail template items for offline players

Implemented generation mail template items at mails loading in case when
original mail send in time when receiver has been offline. Before like
receiver not receive items.

Small change in mail.has_items meaning. Now it set also in cases when items
generated for template but none items really added to mail. This not affect
mostly existed code work aceept case when mail with template loading.
This commit is contained in:
VladimirMangos 2011-03-14 23:13:41 +03:00
parent 13776fa1e4
commit 52b0748282
5 changed files with 79 additions and 14 deletions

View file

@ -100,7 +100,7 @@ bool LoginQueryHolder::Initialize()
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADTALENTS, "SELECT talent_id, current_rank, spec FROM character_talent WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADTALENTS, "SELECT talent_id, current_rank, spec FROM character_talent WHERE guid = '%u'", m_guid.GetCounter());
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSKILLS, "SELECT skill, value, max FROM character_skills WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSKILLS, "SELECT skill, value, max FROM character_skills WHERE guid = '%u'", m_guid.GetCounter());
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGLYPHS, "SELECT spec, slot, glyph FROM character_glyphs WHERE guid='%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGLYPHS, "SELECT spec, slot, glyph FROM character_glyphs WHERE guid='%u'", m_guid.GetCounter());
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILS, "SELECT id,messageType,sender,receiver,subject,body,expire_time,deliver_time,money,cod,checked,stationery,mailTemplateId FROM mail WHERE receiver = '%u' ORDER BY id DESC", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILS, "SELECT id,messageType,sender,receiver,subject,body,expire_time,deliver_time,money,cod,checked,stationery,mailTemplateId,has_items FROM mail WHERE receiver = '%u' ORDER BY id DESC", m_guid.GetCounter());
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILEDITEMS, "SELECT data, text, mail_id, item_guid, item_template FROM mail_items JOIN item_instance ON item_guid = guid WHERE receiver = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILEDITEMS, "SELECT data, text, mail_id, item_guid, item_template FROM mail_items JOIN item_instance ON item_guid = guid WHERE receiver = '%u'", m_guid.GetCounter());
return res; return res;

View file

@ -873,10 +873,10 @@ MailDraft& MailDraft::AddItem( Item* item )
/** /**
* Prepares the items in a MailDraft. * Prepares the items in a MailDraft.
*/ */
void MailDraft::prepareItems(Player* receiver) bool MailDraft::prepareItems(Player* receiver)
{ {
if (!m_mailTemplateId || !m_mailTemplateItemsNeed) if (!m_mailTemplateId || !m_mailTemplateItemsNeed)
return; return false;
m_mailTemplateItemsNeed = false; m_mailTemplateItemsNeed = false;
@ -897,6 +897,8 @@ void MailDraft::prepareItems(Player* receiver)
} }
} }
} }
return true;
} }
/** /**
* Deletes the items included in a MailDraft. * Deletes the items included in a MailDraft.
@ -1002,9 +1004,14 @@ void MailDraft::SendMailTo(MailReceiver const& receiver, MailSender const& sende
{ {
Player* pReceiver = receiver.GetPlayer(); // can be NULL Player* pReceiver = receiver.GetPlayer(); // can be NULL
if (pReceiver) bool has_items = !m_items.empty();
prepareItems(pReceiver); // generate mail template items
// generate mail template items for online player, for offline player items will generated at open
if (pReceiver)
{
if (prepareItems(pReceiver))
has_items = true;
}
uint32 mailId = sObjectMgr.GenerateMailID(); uint32 mailId = sObjectMgr.GenerateMailID();
@ -1030,7 +1037,7 @@ void MailDraft::SendMailTo(MailReceiver const& receiver, MailSender const& sende
CharacterDatabase.BeginTransaction(); CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("INSERT INTO mail (id,messageType,stationery,mailTemplateId,sender,receiver,subject,body,has_items,expire_time,deliver_time,money,cod,checked) " CharacterDatabase.PExecute("INSERT INTO mail (id,messageType,stationery,mailTemplateId,sender,receiver,subject,body,has_items,expire_time,deliver_time,money,cod,checked) "
"VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%s', '%s', '%u', '" UI64FMTD "','" UI64FMTD "', '%u', '%u', '%u')", "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%s', '%s', '%u', '" UI64FMTD "','" UI64FMTD "', '%u', '%u', '%u')",
mailId, sender.GetMailMessageType(), sender.GetStationery(), GetMailTemplateId(), sender.GetSenderId(), receiver.GetPlayerGuid().GetCounter(), safe_subject.c_str(), safe_body.c_str(), (m_items.empty() ? 0 : 1), (uint64)expire_time, (uint64)deliver_time, m_money, m_COD, checked); mailId, sender.GetMailMessageType(), sender.GetStationery(), GetMailTemplateId(), sender.GetSenderId(), receiver.GetPlayerGuid().GetCounter(), safe_subject.c_str(), safe_body.c_str(), (has_items ? 1 : 0), (uint64)expire_time, (uint64)deliver_time, m_money, m_COD, checked);
for(MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter) for(MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
{ {
@ -1079,4 +1086,48 @@ void MailDraft::SendMailTo(MailReceiver const& receiver, MailSender const& sende
else if (!m_items.empty()) else if (!m_items.empty())
deleteIncludedItems(); deleteIncludedItems();
} }
/**
* Generate items from template at mails loading (this happens when mail with mail template items send in time when receiver has been offline)
*
* @param receiver reciver of mail
*/
void Mail::prepareTemplateItems( Player* receiver )
{
if (!mailTemplateId || !items.empty())
return;
has_items = true;
Loot mailLoot;
// can be empty
mailLoot.FillLoot(mailTemplateId, LootTemplates_Mail, receiver, true, true);
CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("UPDATE mail SET has_items = 1 WHERE id = %u", messageID);
uint32 max_slot = mailLoot.GetMaxSlotInLootFor(receiver);
for(uint32 i = 0; items.size() < MAX_MAIL_ITEMS && i < max_slot; ++i)
{
if (LootItem* lootitem = mailLoot.LootItemInSlot(i, receiver))
{
if (Item* item = Item::CreateItem(lootitem->itemid, lootitem->count, receiver))
{
item->SaveToDB();
AddItem(item->GetGUIDLow(), item->GetEntry());
receiver->AddMItem(item);
CharacterDatabase.PExecute("INSERT INTO mail_items (mail_id,item_guid,item_template,receiver) VALUES ('%u', '%u', '%u','%u')",
messageID, item->GetGUIDLow(), item->GetEntry(), receiver->GetGUIDLow());
}
}
}
CharacterDatabase.CommitTransaction();
}
/*! @} */ /*! @} */

View file

@ -249,7 +249,7 @@ class MailDraft
MailDraft& operator=(MailDraft const&); // trap decl, no body, ...because items clone is high price operation MailDraft& operator=(MailDraft const&); // trap decl, no body, ...because items clone is high price operation
void deleteIncludedItems(bool inDB = false); void deleteIncludedItems(bool inDB = false);
void prepareItems(Player* receiver); ///< called from SendMailTo for generate mailTemplateBase items bool prepareItems(Player* receiver); ///< called from SendMailTo for generate mailTemplateBase items
/// The ID of the template associated with this MailDraft. /// The ID of the template associated with this MailDraft.
uint16 m_mailTemplateId; uint16 m_mailTemplateId;
@ -298,6 +298,8 @@ struct Mail
std::string subject; std::string subject;
/// the body of the mail /// the body of the mail
std::string body; std::string body;
/// flag mark mail that already has items, or already generate none items for template
bool has_items;
/// A vector containing Information about the items in this mail. /// A vector containing Information about the items in this mail.
MailItemInfoVec items; MailItemInfoVec items;
/// A vector containing Information about the items that where already take from this mail. /// A vector containing Information about the items that where already take from this mail.
@ -331,6 +333,7 @@ struct Mail
mii.item_guid = itemGuidLow; mii.item_guid = itemGuidLow;
mii.item_template = item_template; mii.item_template = item_template;
items.push_back(mii); items.push_back(mii);
has_items = true;
} }
/** /**
@ -357,13 +360,19 @@ struct Mail
} }
/* /*
* Checks whether a mail contains items or not. * Checks whether a mail contains items (including case none items generated from template already) or not.
* HasItems() checks whether the mail contains items or not. * HasItems() checks whether the mail contains items or not.
* *
* @returns true if the mail contains items, false otherwise. * @returns true if the mail contains items or template items already generated possible none, false otherwise.
* *
*/ */
bool HasItems() const { return !items.empty(); } bool HasItems() const { return has_items; }
/*
* Generate items for template if items not genereated before (receiver has been offline, has_items == false)
*
*/
void prepareTemplateItems(Player* receiver); ///< called from _LoadMails for generate mailTemplateBase items not generated for offline player
}; };
#endif #endif

View file

@ -16328,8 +16328,8 @@ void Player::_LoadMailedItems(QueryResult *result)
void Player::_LoadMails(QueryResult *result) void Player::_LoadMails(QueryResult *result)
{ {
m_mail.clear(); m_mail.clear();
// 0 1 2 3 4 5 6 7 8 9 10 11 12 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13
//"SELECT id,messageType,sender,receiver,subject,body,expire_time,deliver_time,money,cod,checked,stationery,mailTemplateId FROM mail WHERE receiver = '%u' ORDER BY id DESC", GetGUIDLow() //"SELECT id,messageType,sender,receiver,subject,body,expire_time,deliver_time,money,cod,checked,stationery,mailTemplateId,has_items FROM mail WHERE receiver = '%u' ORDER BY id DESC", GetGUIDLow()
if(!result) if(!result)
return; return;
@ -16350,8 +16350,9 @@ void Player::_LoadMails(QueryResult *result)
m->checked = fields[10].GetUInt32(); m->checked = fields[10].GetUInt32();
m->stationery = fields[11].GetUInt8(); m->stationery = fields[11].GetUInt8();
m->mailTemplateId = fields[12].GetInt16(); m->mailTemplateId = fields[12].GetInt16();
m->has_items = fields[13].GetBool(); // true, if mail have items or mail have template and items generated (maybe none)
if(m->mailTemplateId && !sMailTemplateStore.LookupEntry(m->mailTemplateId)) if (m->mailTemplateId && !sMailTemplateStore.LookupEntry(m->mailTemplateId))
{ {
sLog.outError( "Player::_LoadMail - Mail (%u) have nonexistent MailTemplateId (%u), remove at load", m->messageID, m->mailTemplateId); sLog.outError( "Player::_LoadMail - Mail (%u) have nonexistent MailTemplateId (%u), remove at load", m->messageID, m->mailTemplateId);
m->mailTemplateId = 0; m->mailTemplateId = 0;
@ -16360,6 +16361,10 @@ void Player::_LoadMails(QueryResult *result)
m->state = MAIL_STATE_UNCHANGED; m->state = MAIL_STATE_UNCHANGED;
m_mail.push_back(m); m_mail.push_back(m);
if (m->mailTemplateId && !m->has_items)
m->prepareTemplateItems(this);
} while( result->NextRow() ); } while( result->NextRow() );
delete result; delete result;
} }

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "11245" #define REVISION_NR "11246"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__