MaNGOS merge: Mail System.

* Store loot in mail_loot_template indexed by mail template ids.
* Implement proper creating mail text copy item from mail template based mail.
* Move send functions to new MailDraft class from WorldSession.
* Implement mails sending at player levelup.
* Autor VladimirMangos, converted by me.

--HG--
branch : trunk
This commit is contained in:
win32
2009-12-16 18:58:36 +02:00
parent dc53b4a9de
commit bf2c3fd8cf
25 changed files with 779 additions and 571 deletions
+12 -11
View File
@@ -1708,16 +1708,6 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
{
Item* item = reward->itemId ? Item::CreateItem(reward->itemId,1,GetPlayer ()) : NULL;
MailItemsInfo mi;
if(item)
{
// save new item before send
item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
// item
mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
}
int loc_idx = GetPlayer()->GetSession()->GetSessionDbLocaleIndex();
// subject and text
@@ -1736,7 +1726,18 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
uint32 itemTextId = objmgr.CreateItemText( text );
WorldSession::SendMailTo(GetPlayer(), MAIL_CREATURE, MAIL_STATIONERY_NORMAL, reward->sender, GetPlayer()->GetGUIDLow(), subject, itemTextId , &mi, 0, 0, MAIL_CHECK_MASK_NONE);
MailDraft draft(subject, itemTextId);
if(item)
{
// save new item before send
item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
// item
draft.AddItem(item);
}
draft.SendMailTo(GetPlayer(), MailSender(MAIL_CREATURE, reward->sender));
}
}
+9 -6
View File
@@ -129,7 +129,9 @@ void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction, uint32 newPri
if (oldBidder && _player)
oldBidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, _player->GetGUID(), newPrice, auction->GetAuctionOutBid(), auction->item_template);
WorldSession::SendMailTo(oldBidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->bidder, msgAuctionOutbiddedSubject.str(), 0, NULL, auction->bid, 0, MAIL_CHECK_MASK_NONE);
MailDraft(msgAuctionOutbiddedSubject.str())
.AddMoney(auction->bid)
.SendMailTo(MailReceiver(oldBidder, auction->bidder), auction);
}
}
@@ -149,7 +151,9 @@ void WorldSession::SendAuctionCancelledToBidderMail(AuctionEntry* auction)
std::ostringstream msgAuctionCancelledSubject;
msgAuctionCancelledSubject << auction->item_template << ":0:" << AUCTION_CANCELLED_TO_BIDDER;
WorldSession::SendMailTo(bidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->bidder, msgAuctionCancelledSubject.str(), 0, NULL, auction->bid, 0, MAIL_CHECK_MASK_NONE);
MailDraft(msgAuctionCancelledSubject.str())
.AddMoney(auction->bid)
.SendMailTo(MailReceiver(bidder, auction->bidder), auction);
}
}
@@ -442,11 +446,10 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data)
std::ostringstream msgAuctionCanceledOwner;
msgAuctionCanceledOwner << auction->item_template << ":0:" << AUCTION_CANCELED;
MailItemsInfo mi;
mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
// item will deleted or added to received mail list
WorldSession::SendMailTo(pl, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), pl->GetGUIDLow(), msgAuctionCanceledOwner.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
MailDraft(msgAuctionCanceledOwner.str())
.AddItem(pItem)
.SendMailTo(pl, auction);
}
else
{
+11 -10
View File
@@ -160,13 +160,12 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction)
CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'",auction->bidder,pItem->GetGUIDLow());
CharacterDatabase.CommitTransaction();
MailItemsInfo mi;
mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
if (bidder)
bidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, bidder_guid, 0, 0, auction->item_template);
WorldSession::SendMailTo(bidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->bidder, msgAuctionWonSubject.str(), itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_AUCTION);
MailDraft(msgAuctionWonSubject.str(), itemTextId)
.AddItem(pItem)
.SendMailTo(MailReceiver(bidder,auction->bidder), auction, MAIL_CHECK_MASK_AUCTION);
}
}
@@ -196,7 +195,8 @@ void AuctionHouseMgr::SendAuctionSalePendingMail(AuctionEntry * auction)
uint32 itemTextId = objmgr.CreateItemText(msgAuctionSalePendingBody.str());
WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->owner, msgAuctionSalePendingSubject.str(), itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_AUCTION);
MailDraft(msgAuctionSalePendingSubject.str(), itemTextId)
.SendMailTo(MailReceiver(owner,auction->owner), auction, MAIL_CHECK_MASK_AUCTION);
}
}
@@ -233,7 +233,9 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry * auction)
//send auction owner notification, bidder must be current!
owner->GetSession()->SendAuctionOwnerNotification(auction);
}
WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->owner, msgAuctionSuccessfulSubject.str(), itemTextId, NULL, profit, 0, MAIL_CHECK_MASK_AUCTION, sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY));
MailDraft(msgAuctionSuccessfulSubject.str(), itemTextId)
.AddMoney(profit)
.SendMailTo(MailReceiver(owner,auction->owner), auction, MAIL_CHECK_MASK_AUCTION, HOUR);
}
}
@@ -256,10 +258,9 @@ void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry * auction)
if (owner && owner->GetGUIDLow() != auctionbot.GetAHBplayerGUID())
owner->GetSession()->SendAuctionOwnerNotification(auction);
MailItemsInfo mi;
mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), GUID_LOPART(owner_guid), subject.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
MailDraft(subject.str())
.AddItem(pItem)
.SendMailTo(MailReceiver(owner,auction->owner), auction);
}
}
+3 -5
View File
@@ -919,10 +919,6 @@ void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count)
// save new item before send
markItem->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
// item
MailItemsInfo mi;
mi.AddItem(markItem->GetGUIDLow(), markItem->GetEntry(), markItem);
// subject: item name
std::string subject = markProto->Name1;
int loc_idx = plr->GetSession()->GetSessionDbLocaleIndex();
@@ -937,7 +933,9 @@ void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count)
snprintf(textBuf,300,textFormat.c_str(),GetName(),GetName());
uint32 itemTextId = objmgr.CreateItemText( textBuf );
WorldSession::SendMailTo(plr, MAIL_CREATURE, MAIL_STATIONERY_NORMAL, bmEntry, plr->GetGUIDLow(), subject, itemTextId , &mi, 0, 0, MAIL_CHECK_MASK_NONE);
MailDraft(subject, itemTextId)
.AddItem(markItem)
.SendMailTo(plr, MailSender(MAIL_CREATURE, bmEntry));
}
}
+2 -1
View File
@@ -469,6 +469,8 @@ ChatCommand * ChatHandler::getCommandTable()
{ "locales_points_of_interest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesPointsOfInterestCommand, "", NULL },
{ "locales_quest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesQuestCommand, "", NULL },
// { "auctions", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAuctionsCommand, "", NULL },
{ "mail_level_reward", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadMailLevelRewardCommand, "", NULL },
{ "mail_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesMailCommand, "", NULL },
{ "milling_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesMillingCommand, "", NULL },
{ "npc_gossip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcGossipCommand, "", NULL },
{ "npc_option", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcOptionCommand, "", NULL },
@@ -480,7 +482,6 @@ ChatCommand * ChatHandler::getCommandTable()
{ "points_of_interest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadPointsOfInterestCommand, "",NULL},
{ "prospecting_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesProspectingCommand,"", NULL },
{ "quest_end_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestEndScriptsCommand, "", NULL },
{ "quest_mail_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesQuestMailCommand, "", NULL },
{ "quest_start_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestStartScriptsCommand, "", NULL },
{ "quest_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestTemplateCommand, "", NULL },
{ "reference_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesReferenceCommand, "", NULL },
+2 -1
View File
@@ -381,11 +381,12 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleReloadLootTemplatesFishingCommand(const char* args);
bool HandleReloadLootTemplatesGameobjectCommand(const char* args);
bool HandleReloadLootTemplatesItemCommand(const char* args);
bool HandleReloadLootTemplatesMailCommand(const char* args);
bool HandleReloadMailLevelRewardCommand(const char* args);
bool HandleReloadLootTemplatesMillingCommand(const char* args);
bool HandleReloadLootTemplatesPickpocketingCommand(const char* args);
bool HandleReloadLootTemplatesProspectingCommand(const char* args);
bool HandleReloadLootTemplatesReferenceCommand(const char* args);
bool HandleReloadLootTemplatesQuestMailCommand(const char* args);
bool HandleReloadLootTemplatesSkinningCommand(const char* args);
bool HandleReloadLootTemplatesSpellCommand(const char* args);
bool HandleReloadTrinityStringCommand(const char* args);
+1 -1
View File
@@ -1104,7 +1104,7 @@ struct MailTemplateEntry
uint32 ID; // 0
//char* subject[16]; // 1-16
// 17 name flags, unused
//char* content[16]; // 18-33
char* content[16]; // 18-33
};
struct MapEntry
+1 -1
View File
@@ -74,7 +74,7 @@ const char ItemRandomPropertiesfmt[]="nxiiiiixxxxxxxxxxxxxxxxx";
const char ItemRandomSuffixfmt[]="nxxxxxxxxxxxxxxxxxxiiiiiiiiii";
const char ItemSetEntryfmt[]="dssssssssssssssssxxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiiiii";
const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";
const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxssssssssssssssssx";
const char MapEntryfmt[]="nxixssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiffiixxix";
const char MovieEntryfmt[]="nxx";
const char QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx";
+2 -4
View File
@@ -527,10 +527,8 @@ void GameObject::getFishLoot(Loot *fishloot, Player* loot_owner)
GetZoneAndAreaId(zone,subzone);
// if subzone loot exist use it
if(LootTemplates_Fishing.HaveLootFor(subzone))
fishloot->FillLoot(subzone, LootTemplates_Fishing, loot_owner,true);
// else use zone loot
else
if (!fishloot->FillLoot(subzone, LootTemplates_Fishing, loot_owner, true, true))
// else use zone loot (must exist in like case)
fishloot->FillLoot(zone, LootTemplates_Fishing, loot_owner,true);
}
+3 -4
View File
@@ -2439,13 +2439,12 @@ bool ChatHandler::HandleSendMailCommand(const char* args)
std::string text = msgText;
// from console show not existed sender
uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
uint32 messagetype = MAIL_NORMAL;
uint32 stationery = MAIL_STATIONERY_GM;
uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
WorldSession::SendMailTo(target,messagetype, stationery, sender_guidlo, GUID_LOPART(target_guid), subject, itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_NONE);
MailDraft(subject, itemTextId)
.SendMailTo(MailReceiver(target,GUID_LOPART(target_guid)),sender);
std::string nameLink = playerLink(target_name);
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
+22 -15
View File
@@ -559,6 +559,7 @@ bool ChatHandler::HandleReloadAllCommand(const char*)
HandleReloadAllLocalesCommand("");
HandleReloadAccessRequirementCommand("");
HandleReloadMailLevelRewardCommand("");
HandleReloadCommandCommand("");
HandleReloadReservedNameCommand("");
HandleReloadTrinityStringCommand("");
@@ -880,12 +881,12 @@ bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*)
return true;
}
bool ChatHandler::HandleReloadLootTemplatesQuestMailCommand(const char*)
bool ChatHandler::HandleReloadLootTemplatesMailCommand(const char*)
{
sLog.outString( "Re-Loading Loot Tables... (`quest_mail_loot_template`)" );
LoadLootTemplates_QuestMail();
LootTemplates_QuestMail.CheckLootRefs();
SendGlobalGMSysMessage("DB table `quest_mail_loot_template` reloaded.");
sLog.outString( "Re-Loading Loot Tables... (`mail_loot_template`)" );
LoadLootTemplates_Mail();
LootTemplates_Mail.CheckLootRefs();
SendGlobalSysMessage("DB table `mail_loot_template` reloaded.");
return true;
}
@@ -1365,6 +1366,14 @@ bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/)
return true;
}
bool ChatHandler::HandleReloadMailLevelRewardCommand(const char* /*arg*/)
{
sLog.outString( "Re-Loading Player level dependent mail rewards..." );
objmgr.LoadMailLevelRewards();
SendGlobalSysMessage("DB table `mail_level_reward` reloaded.");
return true;
}
bool ChatHandler::HandleLoadScriptsCommand(const char *args)
{
if(!LoadScriptingModule(args)) return true;
@@ -7093,25 +7102,23 @@ bool ChatHandler::HandleSendItemsCommand(const char *args)
}
// from console show not existed sender
uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
uint32 messagetype = MAIL_NORMAL;
uint32 stationery = MAIL_STATIONERY_GM;
uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
// fill mail
MailItemsInfo mi; // item list preparing
MailDraft draft(subject, itemTextId);
for (ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
{
if(Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0))
{
item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
draft.AddItem(item);
}
}
WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
draft.SendMailTo(MailReceiver(receiver,GUID_LOPART(receiver_guid)), sender);
std::string nameLink = playerLink(receiver_name);
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
@@ -7155,13 +7162,13 @@ bool ChatHandler::HandleSendMoneyCommand(const char *args)
std::string text = msgText;
// from console show not existed sender
uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
uint32 messagetype = MAIL_NORMAL;
uint32 stationery = MAIL_STATIONERY_GM;
uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, money, 0, MAIL_CHECK_MASK_NONE);
MailDraft(subject, itemTextId)
.AddMoney(money)
.SendMailTo(MailReceiver(receiver,GUID_LOPART(receiver_guid)),sender);
std::string nameLink = playerLink(receiver_name);
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
+16 -22
View File
@@ -42,10 +42,10 @@ LootStore LootTemplates_Disenchant( "disenchant_loot_template", "item disenc
LootStore LootTemplates_Fishing( "fishing_loot_template", "area id", true);
LootStore LootTemplates_Gameobject( "gameobject_loot_template", "gameobject entry", true);
LootStore LootTemplates_Item( "item_loot_template", "item entry", true);
LootStore LootTemplates_Mail( "mail_loot_template", "mail template id", false);
LootStore LootTemplates_Milling( "milling_loot_template", "item entry (herb)", true);
LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template","creature pickpocket lootid", true);
LootStore LootTemplates_Prospecting( "prospecting_loot_template", "item entry (ore)", true);
LootStore LootTemplates_QuestMail( "quest_mail_loot_template", "quest id (with mail template)",false);
LootStore LootTemplates_Reference( "reference_loot_template", "reference id", false);
LootStore LootTemplates_Skinning( "skinning_loot_template", "creature skinning id", true);
LootStore LootTemplates_Spell( "spell_loot_template", "spell id (random item creating)",false);
@@ -388,18 +388,19 @@ void Loot::AddItem(LootStoreItem const & item)
}
// Calls processor of corresponding LootTemplate (which handles everything including references)
void Loot::FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner, bool personal, uint16 lootMode /*= DEFAULT_LOOT_MODE*/)
bool Loot::FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner, bool personal, bool noEmptyError, uint16 lootMode /*= DEFAULT_LOOT_MODE*/)
{
// Must be provided
if (!loot_owner)
return;
return false;
LootTemplate const* tab = store.GetLootFor(loot_id);
if (!tab)
{
sLog.outErrorDb("Table '%s' loot id #%u used but it doesn't have records.",store.GetName(),loot_id);
return;
if (!noEmptyError)
sLog.outErrorDb("Table '%s' loot id #%u used but it doesn't have records.",store.GetName(),loot_id);
return false;
}
items.reserve(MAX_NR_LOOT_ITEMS);
@@ -418,6 +419,8 @@ void Loot::FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner,
// ... for personal loot
else
FillNotNormalLootFor(loot_owner);
return true;
}
void Loot::FillNotNormalLootFor(Player* pl)
@@ -1351,28 +1354,19 @@ void LoadLootTemplates_Prospecting()
LootTemplates_Prospecting.ReportUnusedIds(ids_set);
}
void LoadLootTemplates_QuestMail()
void LoadLootTemplates_Mail()
{
LootIdSet ids_set;
LootTemplates_QuestMail.LoadAndCollectLootIds(ids_set);
LootTemplates_Mail.LoadAndCollectLootIds(ids_set);
// remove real entries and check existence loot
ObjectMgr::QuestMap const& questMap = objmgr.GetQuestTemplates();
for (ObjectMgr::QuestMap::const_iterator itr = questMap.begin(); itr != questMap.end(); ++itr)
{
if (!itr->second->GetRewMailTemplateId())
continue;
if (ids_set.count(itr->first))
ids_set.erase(itr->first);
/* disabled reporting: some quest mails not include items
else
LootTemplates_QuestMail.ReportNotExistedId(itr->first);
*/
}
for(uint32 i = 1; i < sMailTemplateStore.GetNumRows(); ++i)
if(sMailTemplateStore.LookupEntry(i))
if(ids_set.count(i))
ids_set.erase(i);
// output error for any still listed (not referenced from appropriate table) ids
LootTemplates_QuestMail.ReportUnusedIds(ids_set);
LootTemplates_Mail.ReportUnusedIds(ids_set);
}
void LoadLootTemplates_Skinning()
@@ -1449,7 +1443,7 @@ void LoadLootTemplates_Reference()
LootTemplates_Skinning.CheckLootRefs(&ids_set);
LootTemplates_Disenchant.CheckLootRefs(&ids_set);
LootTemplates_Prospecting.CheckLootRefs(&ids_set);
LootTemplates_QuestMail.CheckLootRefs(&ids_set);
LootTemplates_Mail.CheckLootRefs(&ids_set);
LootTemplates_Reference.CheckLootRefs(&ids_set);
// output error for any still listed ids (not referenced from any loot table)
+4 -4
View File
@@ -288,7 +288,7 @@ struct Loot
void RemoveLooter(uint64 GUID) { PlayersLooting.erase(GUID); }
void generateMoneyLoot(uint32 minAmount, uint32 maxAmount);
void FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner, bool personal, uint16 lootMode = DEFAULT_LOOT_MODE);
bool FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner, bool personal, bool noEmptyError = false, uint16 lootMode = DEFAULT_LOOT_MODE);
// Inserts the item into the loot (called by LootTemplate processors)
void AddItem(LootStoreItem const & item);
@@ -325,24 +325,24 @@ extern LootStore LootTemplates_Creature;
extern LootStore LootTemplates_Fishing;
extern LootStore LootTemplates_Gameobject;
extern LootStore LootTemplates_Item;
extern LootStore LootTemplates_Mail;
extern LootStore LootTemplates_Milling;
extern LootStore LootTemplates_Pickpocketing;
extern LootStore LootTemplates_Skinning;
extern LootStore LootTemplates_Disenchant;
extern LootStore LootTemplates_Prospecting;
extern LootStore LootTemplates_QuestMail;
extern LootStore LootTemplates_Spell;
void LoadLootTemplates_Creature();
void LoadLootTemplates_Fishing();
void LoadLootTemplates_Gameobject();
void LoadLootTemplates_Item();
void LoadLootTemplates_Mail();
void LoadLootTemplates_Milling();
void LoadLootTemplates_Pickpocketing();
void LoadLootTemplates_Skinning();
void LoadLootTemplates_Disenchant();
void LoadLootTemplates_Prospecting();
void LoadLootTemplates_QuestMail();
void LoadLootTemplates_Spell();
void LoadLootTemplates_Reference();
@@ -353,12 +353,12 @@ inline void LoadLootTables()
LoadLootTemplates_Fishing();
LoadLootTemplates_Gameobject();
LoadLootTemplates_Item();
LoadLootTemplates_Mail();
LoadLootTemplates_Milling();
LoadLootTemplates_Pickpocketing();
LoadLootTemplates_Skinning();
LoadLootTemplates_Disenchant();
LoadLootTemplates_Prospecting();
LoadLootTemplates_QuestMail();
LoadLootTemplates_Spell();
LoadLootTemplates_Reference();
+387 -295
View File
File diff suppressed because it is too large Load Diff
+92 -82
View File
@@ -23,20 +23,14 @@
#include "Common.h"
#include <map>
struct AuctionEntry;
class Item;
class Object;
class Player;
#define MAIL_BODY_ITEM_TEMPLATE 8383 // - plain letter, A Dusty Unsent Letter: 889
#define MAX_MAIL_ITEMS 12
enum MailCheckMask
{
MAIL_CHECK_MASK_NONE = 0,
MAIL_CHECK_MASK_READ = 1,
MAIL_CHECK_MASK_AUCTION = 4,
MAIL_CHECK_MASK_COD_PAYMENT = 8,
MAIL_CHECK_MASK_RETURNED = 16
};
enum MailMessageType
{
MAIL_NORMAL = 0,
@@ -46,6 +40,26 @@ enum MailMessageType
MAIL_ITEM = 5, // client send CMSG_ITEM_QUERY on this mailmessagetype
};
enum MailCheckMask
{
MAIL_CHECK_MASK_NONE = 0x00,
MAIL_CHECK_MASK_READ = 0x01,
MAIL_CHECK_MASK_AUCTION = 0x04,
MAIL_CHECK_MASK_COD_PAYMENT = 0x08,
MAIL_CHECK_MASK_RETURNED = 0x10
};
// gathered from Stationery.dbc
enum MailStationery
{
MAIL_STATIONERY_UNKNOWN = 1,
MAIL_STATIONERY_NORMAL = 41,
MAIL_STATIONERY_GM = 61,
MAIL_STATIONERY_AUCTION = 62,
MAIL_STATIONERY_VAL = 64,
MAIL_STATIONERY_CHR = 65,
};
enum MailState
{
MAIL_STATE_UNCHANGED = 1,
@@ -64,15 +78,75 @@ enum MailAuctionAnswers
AUCTION_SALE_PENDING = 6
};
// gathered from Stationery.dbc
enum MailStationery
class MailSender
{
MAIL_STATIONERY_UNKNOWN = 0x01,
MAIL_STATIONERY_NORMAL = 0x29,
MAIL_STATIONERY_GM = 0x3D,
MAIL_STATIONERY_AUCTION = 0x3E,
MAIL_STATIONERY_VAL = 0x40,
MAIL_STATIONERY_CHR = 0x41
public: // Constructors
MailSender(MailMessageType messageType, uint32 sender_guidlow_or_entry, MailStationery stationery = MAIL_STATIONERY_NORMAL)
: m_messageType(messageType), m_senderId(sender_guidlow_or_entry), m_stationery(stationery)
{
}
MailSender(Object* sender, MailStationery stationery = MAIL_STATIONERY_NORMAL);
MailSender(AuctionEntry* sender);
public: // Accessors
MailMessageType GetMailMessageType() const { return m_messageType; }
uint32 GetSenderId() const { return m_senderId; }
MailStationery GetStationery() const { return m_stationery; }
private:
MailMessageType m_messageType;
uint32 m_senderId; // player low guid or other object entry
MailStationery m_stationery;
};
class MailReceiver
{
public: // Constructors
explicit MailReceiver(uint32 receiver_lowguid) : m_receiver(NULL), m_receiver_lowguid(receiver_lowguid) {}
MailReceiver(Player* receiver);
MailReceiver(Player* receiver,uint32 receiver_lowguid);
public: // Accessors
Player* GetPlayer() const { return m_receiver; }
uint32 GetPlayerGUIDLow() const { return m_receiver_lowguid; }
private:
Player* m_receiver;
uint32 m_receiver_lowguid;
};
class MailDraft
{
typedef std::map<uint32, Item*> MailItemMap;
public: // Constructors
explicit MailDraft(uint16 mailTemplateId, bool need_items = true)
: m_mailTemplateId(mailTemplateId), m_mailTemplateItemsNeed(need_items), m_bodyId(0), m_money(0), m_COD(0)
{}
MailDraft(std::string subject, uint32 itemTextId = 0)
: m_mailTemplateId(0), m_mailTemplateItemsNeed(false), m_subject(subject), m_bodyId(itemTextId), m_money(0), m_COD(0) {}
public: // Accessors
uint16 GetMailTemplateId() const { return m_mailTemplateId; }
std::string const& GetSubject() const { return m_subject; }
uint32 GetBodyId() const { return m_bodyId; }
uint32 GetMoney() const { return m_money; }
uint32 GetCOD() const { return m_COD; }
public: // modifiers
MailDraft& AddItem(Item* item);
MailDraft& AddMoney(uint32 money) { m_money = money; return *this; }
MailDraft& AddCOD(uint32 COD) { m_COD = COD; return *this; }
public: // finishers
void SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid);
void SendMailTo(MailReceiver const& receiver, MailSender const& sender, MailCheckMask checked = MAIL_CHECK_MASK_NONE, uint32 deliver_delay = 0);
private:
void deleteIncludedItems(bool inDB = false);
void prepareItems(Player* receiver); // called from SendMailTo for generate mailTemplateBase items
uint16 m_mailTemplateId;
bool m_mailTemplateItemsNeed;
std::string m_subject;
uint32 m_bodyId;
MailItemMap m_items; // Keep the items in a map to avoid duplicate guids (which can happen), store only low part of guid
uint32 m_money;
uint32 m_COD;
};
struct MailItemInfo
@@ -81,61 +155,6 @@ struct MailItemInfo
uint32 item_template;
};
struct MailItem
{
MailItem() : item_slot(0), item_guidlow(0), item_template(0), item(NULL) {}
uint8 item_slot; // slot in mail
uint32 item_guidlow; // item guid (low part)
uint32 item_template; // item entry
Item *item; // item pointer
void deleteItem(bool inDB = false);
};
typedef std::map<uint32, MailItem> MailItemMap;
class MailItemsInfo
{
public:
MailItemMap::const_iterator begin() const { return i_MailItemMap.begin(); }
MailItemMap::const_iterator end() const { return i_MailItemMap.end(); }
MailItemMap::iterator begin() { return i_MailItemMap.begin(); }
MailItemMap::iterator end() { return i_MailItemMap.end(); }
void AddItem(uint32 guidlow, uint32 _template, Item *item, uint8 slot = 0)
{
MailItem mailItem;
mailItem.item_slot = slot;
mailItem.item_guidlow = guidlow;
mailItem.item_template = _template;
mailItem.item = item;
i_MailItemMap[guidlow] = mailItem;
}
void AddItem(uint32 guidlow, uint8 slot = 0)
{
MailItem mailItem;
mailItem.item_guidlow = guidlow;
mailItem.item_slot = slot;
i_MailItemMap[guidlow] = mailItem;
}
uint8 size() const { return i_MailItemMap.size(); }
bool empty() const { return i_MailItemMap.empty(); }
void deleteIncludedItems(bool inDB = false)
{
for (MailItemMap::iterator mailItemIter = begin(); mailItemIter != end(); ++mailItemIter)
{
MailItem& mailItem = mailItemIter->second;
mailItem.deleteItem(inDB);
}
}
private:
MailItemMap i_MailItemMap; // Keep the items in a map to avoid duplicate guids (which can happen), store only low part of guid
};
struct Mail
{
uint32 messageID;
@@ -163,15 +182,6 @@ struct Mail
items.push_back(mii);
}
void AddAllItems(MailItemsInfo& pMailItemsInfo)
{
for (MailItemMap::iterator mailItemIter = pMailItemsInfo.begin(); mailItemIter != pMailItemsInfo.end(); ++mailItemIter)
{
MailItem& mailItem = mailItemIter->second;
AddItem(mailItem.item_guidlow, mailItem.item_template);
}
}
bool RemoveItem(uint32 item_guid)
{
for (std::vector<MailItemInfo>::iterator itr = items.begin(); itr != items.end(); ++itr)
@@ -187,5 +197,5 @@ struct Mail
bool HasItems() const { return !items.empty(); }
};
#endif
#endif
+87 -8
View File
@@ -3537,6 +3537,9 @@ void ObjectMgr::LoadQuests()
delete result;
std::map<uint32,uint32> usedMailTemplates;
// Post processing
for (QuestMap::iterator iter = mQuestTemplates.begin(); iter != mQuestTemplates.end(); ++iter)
{
@@ -4030,21 +4033,31 @@ void ObjectMgr::LoadQuests()
}
}
if(qinfo->RewMailTemplateId)
if (qinfo->RewMailTemplateId)
{
if(!sMailTemplateStore.LookupEntry(qinfo->RewMailTemplateId))
if (!sMailTemplateStore.LookupEntry(qinfo->RewMailTemplateId))
{
sLog.outErrorDb("Quest %u has `RewMailTemplateId` = %u but mail template %u does not exist, quest will not have a mail reward.",
qinfo->GetQuestId(),qinfo->RewMailTemplateId,qinfo->RewMailTemplateId);
qinfo->RewMailTemplateId = 0; // no mail will send to player
qinfo->RewMailDelaySecs = 0; // no mail will send to player
}
else if (usedMailTemplates.find(qinfo->RewMailTemplateId) != usedMailTemplates.end())
{
std::map<uint32,uint32>::const_iterator used_mt_itr = usedMailTemplates.find(qinfo->RewMailTemplateId);
sLog.outErrorDb("Quest %u has `RewMailTemplateId` = %u but mail template %u already used for quest %u, quest will not have a mail reward.",
qinfo->GetQuestId(),qinfo->RewMailTemplateId,qinfo->RewMailTemplateId,used_mt_itr->second);
qinfo->RewMailTemplateId = 0; // no mail will send to player
qinfo->RewMailDelaySecs = 0; // no mail will send to player
}
else
usedMailTemplates[qinfo->RewMailTemplateId] = qinfo->GetQuestId();
}
if(qinfo->NextQuestInChain)
if (qinfo->NextQuestInChain)
{
QuestMap::iterator qNextItr = mQuestTemplates.find(qinfo->NextQuestInChain);
if(qNextItr == mQuestTemplates.end())
if (qNextItr == mQuestTemplates.end())
{
sLog.outErrorDb("Quest %u has `NextQuestInChain` = %u but quest %u does not exist, quest chain will not work.",
qinfo->GetQuestId(),qinfo->NextQuestInChain ,qinfo->NextQuestInChain );
@@ -4055,7 +4068,7 @@ void ObjectMgr::LoadQuests()
}
// fill additional data stores
if(qinfo->PrevQuestId)
if (qinfo->PrevQuestId)
{
if (mQuestTemplates.find(abs(qinfo->GetPrevQuestId())) == mQuestTemplates.end())
{
@@ -4067,7 +4080,7 @@ void ObjectMgr::LoadQuests()
}
}
if(qinfo->NextQuestId)
if (qinfo->NextQuestId)
{
QuestMap::iterator qNextItr = mQuestTemplates.find(abs(qinfo->GetNextQuestId()));
if (qNextItr == mQuestTemplates.end())
@@ -4081,9 +4094,9 @@ void ObjectMgr::LoadQuests()
}
}
if(qinfo->ExclusiveGroup)
if (qinfo->ExclusiveGroup)
mExclusiveQuestGroups.insert(std::pair<int32, uint32>(qinfo->ExclusiveGroup, qinfo->GetQuestId()));
if(qinfo->LimitTime)
if (qinfo->LimitTime)
qinfo->SetFlag(QUEST_TRINITY_FLAGS_TIMED);
}
@@ -7985,6 +7998,72 @@ bool ObjectMgr::DeleteGameTele(const std::string& name)
return false;
}
void ObjectMgr::LoadMailLevelRewards()
{
m_mailLevelRewardMap.clear(); // for reload case
uint32 count = 0;
QueryResult *result = WorldDatabase.Query("SELECT level, raceMask, mailTemplateId, senderEntry FROM mail_level_reward");
if( !result )
{
barGoLink bar( 1 );
bar.step();
sLog.outString();
sLog.outErrorDb(">> Loaded `mail_level_reward`, table is empty!");
return;
}
barGoLink bar( result->GetRowCount() );
do
{
bar.step();
Field *fields = result->Fetch();
uint8 level = fields[0].GetUInt8();
uint32 raceMask = fields[1].GetUInt32();
uint32 mailTemplateId = fields[2].GetUInt32();
uint32 senderEntry = fields[3].GetUInt32();
if(level > MAX_LEVEL)
{
sLog.outErrorDb("Table `mail_level_reward` have data for level %u that more supported by client (%u), ignoring.",level,MAX_LEVEL);
continue;
}
if(!(raceMask & RACEMASK_ALL_PLAYABLE))
{
sLog.outErrorDb("Table `mail_level_reward` have raceMask (%u) for level %u that not include any player races, ignoring.",raceMask,level);
continue;
}
if(!sMailTemplateStore.LookupEntry(mailTemplateId))
{
sLog.outErrorDb("Table `mail_level_reward` have invalid mailTemplateId (%u) for level %u that invalid not include any player races, ignoring.",mailTemplateId,level);
continue;
}
if(!GetCreatureTemplateStore(senderEntry))
{
sLog.outErrorDb("Table `mail_level_reward` have not existed sender creature entry (%u) for level %u that invalid not include any player races, ignoring.",senderEntry,level);
continue;
}
m_mailLevelRewardMap[level].push_back(MailLevelReward(raceMask,mailTemplateId,senderEntry));
++count;
}
while (result->NextRow());
delete result;
sLog.outString();
sLog.outString( ">> Loaded %u level dependent mail rewards,", count );
}
void ObjectMgr::LoadTrainerSpell()
{
// For reload case
+29
View File
@@ -180,6 +180,19 @@ struct PetLevelInfo
uint16 armor;
};
struct MailLevelReward
{
MailLevelReward() : raceMask(0), mailTemplateId(0), senderEntry(0) {}
MailLevelReward(uint32 _raceMask, uint32 _mailTemplateId, uint32 _senderEntry) : raceMask(_raceMask), mailTemplateId(_mailTemplateId), senderEntry(_senderEntry) {}
uint32 raceMask;
uint32 mailTemplateId;
uint32 senderEntry;
};
typedef std::list<MailLevelReward> MailLevelRewardList;
typedef UNORDERED_MAP<uint8,MailLevelRewardList> MailLevelRewardMap;
struct ReputationOnKillEntry
{
uint32 repfaction1;
@@ -570,6 +583,7 @@ class ObjectMgr
void LoadNpcOptionLocales();
void LoadPointOfInterestLocales();
void LoadInstanceTemplate();
void LoadMailLevelRewards();
void LoadGossipText();
@@ -645,6 +659,19 @@ class ObjectMgr
typedef std::multimap<int32, uint32> ExclusiveQuestGroups;
ExclusiveQuestGroups mExclusiveQuestGroups;
MailLevelReward const* GetMailLevelReward(uint32 level,uint32 raceMask)
{
MailLevelRewardMap::const_iterator map_itr = m_mailLevelRewardMap.find(level);
if (map_itr == m_mailLevelRewardMap.end())
return NULL;
for(MailLevelRewardList::const_iterator set_itr = map_itr->second.begin(); set_itr != map_itr->second.end(); ++set_itr)
if (set_itr->raceMask & raceMask)
return &*set_itr;
return NULL;
}
WeatherZoneChances const* GetWeatherChances(uint32 zone_id) const
{
WeatherZoneMap::const_iterator itr = mWeatherZoneMap.find(zone_id);
@@ -956,6 +983,8 @@ class ObjectMgr
void ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr);
void LoadQuestRelationsHelper(QuestRelations& map,char const* table);
MailLevelRewardMap m_mailLevelRewardMap;
typedef std::map<uint32,PetLevelInfo*> PetLevelInfoMap;
// PetLevelInfoMap[creature_id][level]
PetLevelInfoMap petInfo; // [creature_id][level]
+36 -71
View File
@@ -2566,6 +2566,9 @@ void Player::GiveLevel(uint8 level)
if (Pet* pet = GetPet())
pet->SynchronizeLevelWithOwner();
if (MailLevelReward const* mailReward = objmgr.GetMailLevelReward(level,getRaceMask()))
MailDraft(mailReward->mailTemplateId).SendMailTo(this,MailSender(MAIL_CREATURE,mailReward->senderEntry));
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL);
}
@@ -4131,8 +4134,8 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
// remove signs from petitions (also remove petitions if owner);
RemovePetitionsAndSigns(playerguid, 10);
// return back all mails with COD and Item 0 1 2 3 4 5 6
QueryResult *resultMail = CharacterDatabase.PQuery("SELECT id,mailTemplateId,sender,subject,itemTextId,money,has_items FROM mail WHERE receiver='%u' AND has_items<>0 AND cod<>0", guid);
// return back all mails with COD and Item 0 1 2 3 4 5 6 7
QueryResult *resultMail = CharacterDatabase.PQuery("SELECT id,messageType,mailTemplateId,sender,subject,itemTextId,money,has_items FROM mail WHERE receiver='%u' AND has_items<>0 AND cod<>0", guid);
if(resultMail)
{
do
@@ -4140,18 +4143,30 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
Field *fields = resultMail->Fetch();
uint32 mail_id = fields[0].GetUInt32();
uint16 mailTemplateId= fields[1].GetUInt16();
uint32 sender = fields[2].GetUInt32();
std::string subject = fields[3].GetCppString();
uint32 itemTextId = fields[4].GetUInt32();
uint32 money = fields[5].GetUInt32();
bool has_items = fields[6].GetBool();
uint16 mailType = fields[1].GetUInt16();
uint16 mailTemplateId= fields[2].GetUInt16();
uint32 sender = fields[3].GetUInt32();
std::string subject = fields[4].GetCppString();
uint32 itemTextId = fields[5].GetUInt32();
uint32 money = fields[6].GetUInt32();
bool has_items = fields[7].GetBool();
//we can return mail now
//so firstly delete the old one
CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", mail_id);
MailItemsInfo mi;
// mail not from player
if (mailType != MAIL_NORMAL)
{
if(has_items)
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE mail_id = '%u'", mail_id);
continue;
}
MailDraft draft(subject, itemTextId);
if (mailTemplateId)
draft = MailDraft(mailTemplateId,false); // itesm already included
if(has_items)
{
// data needs to be at first place for Item::LoadFromDB
@@ -4180,7 +4195,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
continue;
}
mi.AddItem(item_guidlow, item_template, pItem);
draft.AddItem(pItem);
}
while (resultItems->NextRow());
@@ -4192,7 +4207,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
uint32 pl_account = objmgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER));
WorldSession::SendReturnToSender(MAIL_NORMAL, pl_account, guid, sender, subject, itemTextId, &mi, money, mailTemplateId);
draft.AddMoney(money).SendReturnToSender(pl_account, guid, sender);
}
while (resultMail->NextRow());
@@ -7853,7 +7868,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
{
sLog.outDebug(" if(lootid)");
loot->clear();
loot->FillLoot(lootid, LootTemplates_Gameobject, this, false, go->GetLootMode());
loot->FillLoot(lootid, LootTemplates_Gameobject, this, false, false, go->GetLootMode());
}
if (loot_type == LOOT_FISHING)
@@ -7982,7 +7997,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
loot->clear();
if (uint32 lootid = creature->GetCreatureInfo()->lootid)
loot->FillLoot(lootid, LootTemplates_Creature, recipient, false, creature->GetLootMode());
loot->FillLoot(lootid, LootTemplates_Creature, recipient, false, false, creature->GetLootMode());
loot->generateMoneyLoot(creature->GetCreatureInfo()->mingold,creature->GetCreatureInfo()->maxgold);
@@ -13267,56 +13282,8 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
}
// Send reward mail
if (pQuest->GetRewMailTemplateId())
{
MailMessageType mailType;
uint32 senderGuidOrEntry;
switch(questGiver->GetTypeId())
{
case TYPEID_UNIT:
mailType = MAIL_CREATURE;
senderGuidOrEntry = questGiver->GetEntry();
break;
case TYPEID_GAMEOBJECT:
mailType = MAIL_GAMEOBJECT;
senderGuidOrEntry = questGiver->GetEntry();
break;
case TYPEID_ITEM:
mailType = MAIL_ITEM;
senderGuidOrEntry = questGiver->GetEntry();
break;
case TYPEID_PLAYER:
mailType = MAIL_NORMAL;
senderGuidOrEntry = questGiver->GetGUIDLow();
break;
default:
mailType = MAIL_NORMAL;
senderGuidOrEntry = GetGUIDLow();
break;
}
Loot questMailLoot;
questMailLoot.FillLoot(pQuest->GetQuestId(), LootTemplates_QuestMail, this,true);
// fill mail
MailItemsInfo mi; // item list preparing
uint32 max_slot = questMailLoot.GetMaxSlotInLootFor(this);
for (uint32 i = 0; mi.size() < MAX_MAIL_ITEMS && i < max_slot; ++i)
{
if (LootItem* lootitem = questMailLoot.LootItemInSlot(i,this))
{
if (Item* item = Item::CreateItem(lootitem->itemid,lootitem->count,this))
{
item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
}
}
}
WorldSession::SendMailTo(this, mailType, MAIL_STATIONERY_NORMAL, senderGuidOrEntry, GetGUIDLow(), "", 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE,pQuest->GetRewMailDelaySecs(),pQuest->GetRewMailTemplateId());
}
if (uint32 mail_template_id = pQuest->GetRewMailTemplateId())
MailDraft(mail_template_id).SendMailTo(this, questGiver, MAIL_CHECK_MASK_NONE, pQuest->GetRewMailDelaySecs());
if (pQuest->IsDaily())
{
@@ -15641,20 +15608,20 @@ void Player::_LoadInventory(QueryResult *result, uint32 timediff)
// send by mail problematic items
while (!problematicItems.empty())
{
std::string subject = GetSession()->GetMangosString(LANG_NOT_EQUIPPED_ITEM);
// fill mail
MailItemsInfo mi; // item list preparing
MailDraft draft(subject);
for (uint8 i = 0; !problematicItems.empty() && i < MAX_MAIL_ITEMS; ++i)
{
Item* item = problematicItems.front();
problematicItems.pop_front();
mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
draft.AddItem(item);
}
std::string subject = GetSession()->GetTrinityString(LANG_NOT_EQUIPPED_ITEM);
WorldSession::SendMailTo(this, MAIL_NORMAL, MAIL_STATIONERY_GM, GetGUIDLow(), GetGUIDLow(), subject, 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
draft.SendMailTo(this, MailSender(this, MAIL_STATIONERY_GM));
}
}
//if(isAlive())
@@ -20026,8 +19993,6 @@ void Player::AutoUnequipOffhandIfNeed(bool force /*= false*/)
}
else
{
MailItemsInfo mi;
mi.AddItem(offItem->GetGUIDLow(), offItem->GetEntry(), offItem);
MoveItemFromInventory(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND, true);
CharacterDatabase.BeginTransaction();
offItem->DeleteFromInventoryDB(); // deletes item from character's inventory
@@ -20035,7 +20000,7 @@ void Player::AutoUnequipOffhandIfNeed(bool force /*= false*/)
CharacterDatabase.CommitTransaction();
std::string subject = GetSession()->GetMangosString(LANG_NOT_EQUIPPED_ITEM);
WorldSession::SendMailTo(this, MAIL_NORMAL, MAIL_STATIONERY_GM, GetGUIDLow(), GetGUIDLow(), subject, 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
MailDraft(subject).AddItem(offItem).SendMailTo(this, MailSender(this, MAIL_STATIONERY_GM));
}
}
+2 -2
View File
@@ -1428,8 +1428,8 @@ class MANGOS_DLL_SPEC Player : public Unit
uint32 GetMailSize() { return m_mail.size();};
Mail* GetMail(uint32 id);
PlayerMails::iterator GetmailBegin() { return m_mail.begin();};
PlayerMails::iterator GetmailEnd() { return m_mail.end();};
PlayerMails::iterator GetMailBegin() { return m_mail.begin();};
PlayerMails::iterator GetMailEnd() { return m_mail.end();};
/*********************************************************/
/*** MAILED ITEMS SYSTEM ***/
+3
View File
@@ -1477,6 +1477,9 @@ void World::SetInitialWorldSettings()
sLog.outString("Loading Player Corpses...");
objmgr.LoadCorpses();
sLog.outString( "Loading Player level dependent mail rewards..." );
objmgr.LoadMailLevelRewards();
sLog.outString("Loading Disabled Spells...");
objmgr.LoadSpellDisabledEntrys();
+1 -7
View File
@@ -28,7 +28,6 @@
#include "Common.h"
#include "SharedDefines.h"
class MailItemsInfo;
struct ItemPrototype;
struct AuctionEntry;
struct DeclinedName;
@@ -42,7 +41,6 @@ class Unit;
class GameObject;
class WorldPacket;
class WorldSocket;
class WorldSession;
class QueryResult;
class LoginQueryHolder;
class CharacterHandler;
@@ -223,12 +221,8 @@ class TRINITY_DLL_SPEC WorldSession
m_TutorialsChanged = true;
}
}
//mail
//used with item_page table
//used with item_page table
bool SendItemInfo( uint32 itemid, WorldPacket data );
static void SendReturnToSender(uint8 messageType, uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid, const std::string& subject, uint32 itemTextId, MailItemsInfo *mi, uint32 money, uint16 mailTemplateId = 0);
static void SendMailTo(Player* receiver, uint8 messageType, uint8 stationery, uint32 sender_guidlow_or_entry, uint32 received_guidlow, std::string subject, uint32 itemTextId, MailItemsInfo* mi, uint32 money, uint32 COD, uint32 checked, uint32 deliver_delay = 0, uint16 mailTemplateId = 0);
//auction
void SendAuctionHello( uint64 guid, Creature * unit );