mirror of
https://github.com/mangosfour/server.git
synced 2025-12-16 04:37:00 +00:00
Merge remote branch 'origin/master' into 330
Conflicts: src/game/DBCfmt.h src/game/GossipDef.cpp src/game/Mail.cpp
This commit is contained in:
commit
2732c33465
48 changed files with 1023 additions and 786 deletions
|
|
@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
|
||||||
`version` varchar(120) default NULL,
|
`version` varchar(120) default NULL,
|
||||||
`creature_ai_version` varchar(120) default NULL,
|
`creature_ai_version` varchar(120) default NULL,
|
||||||
`cache_id` int(10) default '0',
|
`cache_id` int(10) default '0',
|
||||||
`required_8731_01_mangos_creature_template` bit(1) default NULL
|
`required_8770_01_mangos_quest_template` bit(1) default NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
@ -2711,6 +2711,55 @@ LOCK TABLES `locales_quest` WRITE;
|
||||||
/*!40000 ALTER TABLE `locales_quest` ENABLE KEYS */;
|
/*!40000 ALTER TABLE `locales_quest` ENABLE KEYS */;
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `mail_level_reward`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `mail_level_reward`;
|
||||||
|
CREATE TABLE `mail_level_reward` (
|
||||||
|
`level` mediumint(8) unsigned NOT NULL default '0',
|
||||||
|
`raceMask` mediumint(8) unsigned NOT NULL default '0',
|
||||||
|
`mailTemplateId` mediumint(8) unsigned NOT NULL default '0',
|
||||||
|
`senderEntry` mediumint(8) unsigned NOT NULL default '0',
|
||||||
|
PRIMARY KEY (`level`,`raceMask`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Mail System';
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Dumping data for table `mail_level_reward`
|
||||||
|
--
|
||||||
|
|
||||||
|
LOCK TABLES `mail_level_reward` WRITE;
|
||||||
|
/*!40000 ALTER TABLE `mail_level_reward` DISABLE KEYS */;
|
||||||
|
/*!40000 ALTER TABLE `mail_level_reward` ENABLE KEYS */;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `mail_loot_template`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `mail_loot_template`;
|
||||||
|
CREATE TABLE `mail_loot_template` (
|
||||||
|
`entry` mediumint(8) unsigned NOT NULL default '0',
|
||||||
|
`item` mediumint(8) unsigned NOT NULL default '0',
|
||||||
|
`ChanceOrQuestChance` float NOT NULL default '100',
|
||||||
|
`groupid` tinyint(3) unsigned NOT NULL default '0',
|
||||||
|
`mincountOrRef` mediumint(9) NOT NULL default '1',
|
||||||
|
`maxcount` tinyint(3) unsigned NOT NULL default '1',
|
||||||
|
`lootcondition` tinyint(3) unsigned NOT NULL default '0',
|
||||||
|
`condition_value1` mediumint(8) unsigned NOT NULL default '0',
|
||||||
|
`condition_value2` mediumint(8) unsigned NOT NULL default '0',
|
||||||
|
PRIMARY KEY (`entry`,`item`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System';
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Dumping data for table `mail_loot_template`
|
||||||
|
--
|
||||||
|
|
||||||
|
LOCK TABLES `mail_loot_template` WRITE;
|
||||||
|
/*!40000 ALTER TABLE `mail_loot_template` DISABLE KEYS */;
|
||||||
|
/*!40000 ALTER TABLE `mail_loot_template` ENABLE KEYS */;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Table structure for table `mangos_string`
|
-- Table structure for table `mangos_string`
|
||||||
--
|
--
|
||||||
|
|
@ -13561,33 +13610,6 @@ LOCK TABLES `quest_start_scripts` WRITE;
|
||||||
/*!40000 ALTER TABLE `quest_start_scripts` ENABLE KEYS */;
|
/*!40000 ALTER TABLE `quest_start_scripts` ENABLE KEYS */;
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
|
|
||||||
--
|
|
||||||
-- Table structure for table `quest_mail_loot_template`
|
|
||||||
--
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `quest_mail_loot_template`;
|
|
||||||
CREATE TABLE `quest_mail_loot_template` (
|
|
||||||
`entry` mediumint(8) unsigned NOT NULL default '0',
|
|
||||||
`item` mediumint(8) unsigned NOT NULL default '0',
|
|
||||||
`ChanceOrQuestChance` float NOT NULL default '100',
|
|
||||||
`groupid` tinyint(3) unsigned NOT NULL default '0',
|
|
||||||
`mincountOrRef` mediumint(9) NOT NULL default '1',
|
|
||||||
`maxcount` tinyint(3) unsigned NOT NULL default '1',
|
|
||||||
`lootcondition` tinyint(3) unsigned NOT NULL default '0',
|
|
||||||
`condition_value1` mediumint(8) unsigned NOT NULL default '0',
|
|
||||||
`condition_value2` mediumint(8) unsigned NOT NULL default '0',
|
|
||||||
PRIMARY KEY (`entry`,`item`)
|
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System';
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Dumping data for table `quest_mail_loot_template`
|
|
||||||
--
|
|
||||||
|
|
||||||
LOCK TABLES `quest_mail_loot_template` WRITE;
|
|
||||||
/*!40000 ALTER TABLE `quest_mail_loot_template` DISABLE KEYS */;
|
|
||||||
/*!40000 ALTER TABLE `quest_mail_loot_template` ENABLE KEYS */;
|
|
||||||
UNLOCK TABLES;
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Table structure for table `quest_template`
|
-- Table structure for table `quest_template`
|
||||||
--
|
--
|
||||||
|
|
@ -13599,7 +13621,7 @@ CREATE TABLE `quest_template` (
|
||||||
`ZoneOrSort` smallint(6) NOT NULL default '0',
|
`ZoneOrSort` smallint(6) NOT NULL default '0',
|
||||||
`SkillOrClass` smallint(6) NOT NULL default '0',
|
`SkillOrClass` smallint(6) NOT NULL default '0',
|
||||||
`MinLevel` tinyint(3) unsigned NOT NULL default '0',
|
`MinLevel` tinyint(3) unsigned NOT NULL default '0',
|
||||||
`QuestLevel` tinyint(3) unsigned NOT NULL default '0',
|
`QuestLevel` smallint(6) NOT NULL default '0',
|
||||||
`Type` smallint(5) unsigned NOT NULL default '0',
|
`Type` smallint(5) unsigned NOT NULL default '0',
|
||||||
`RequiredRaces` smallint(5) unsigned NOT NULL default '0',
|
`RequiredRaces` smallint(5) unsigned NOT NULL default '0',
|
||||||
`RequiredSkillValue` smallint(5) unsigned NOT NULL default '0',
|
`RequiredSkillValue` smallint(5) unsigned NOT NULL default '0',
|
||||||
|
|
|
||||||
6
sql/updates/8749_01_mangos_mail_loot_template.sql
Normal file
6
sql/updates/8749_01_mangos_mail_loot_template.sql
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_8731_01_mangos_creature_template required_8749_01_mangos_mail_loot_template bit;
|
||||||
|
|
||||||
|
RENAME TABLE quest_mail_loot_template TO mail_loot_template;
|
||||||
|
|
||||||
|
UPDATE mail_loot_template, quest_template
|
||||||
|
SET mail_loot_template.entry = quest_template.RewMailTemplateId WHERE mail_loot_template.entry = quest_template.entry;
|
||||||
10
sql/updates/8769_01_mangos_mail_level_reward.sql
Normal file
10
sql/updates/8769_01_mangos_mail_level_reward.sql
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_8749_01_mangos_mail_loot_template required_8769_01_mangos_mail_level_reward bit;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `mail_level_reward`;
|
||||||
|
CREATE TABLE `mail_level_reward` (
|
||||||
|
`level` tinyint(3) unsigned NOT NULL default '0',
|
||||||
|
`raceMask` mediumint(8) unsigned NOT NULL default '0',
|
||||||
|
`mailTemplateId` mediumint(8) unsigned NOT NULL default '0',
|
||||||
|
`senderEntry` mediumint(8) unsigned NOT NULL default '0',
|
||||||
|
PRIMARY KEY (`level`,`raceMask`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Mail System';
|
||||||
4
sql/updates/8770_01_mangos_quest_template.sql
Normal file
4
sql/updates/8770_01_mangos_quest_template.sql
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_8769_01_mangos_mail_level_reward required_8770_01_mangos_quest_template bit;
|
||||||
|
|
||||||
|
ALTER TABLE quest_template
|
||||||
|
CHANGE COLUMN QuestLevel QuestLevel smallint(6) NOT NULL DEFAULT 0;
|
||||||
|
|
@ -145,6 +145,9 @@ pkgdata_DATA = \
|
||||||
8726_01_mangos_spell_proc_event.sql \
|
8726_01_mangos_spell_proc_event.sql \
|
||||||
8728_01_realmd_account.sql \
|
8728_01_realmd_account.sql \
|
||||||
8731_01_mangos_creature_template.sql \
|
8731_01_mangos_creature_template.sql \
|
||||||
|
8749_01_mangos_mail_loot_template.sql \
|
||||||
|
8769_01_mangos_mail_level_reward.sql \
|
||||||
|
8770_01_mangos_quest_template.sql \
|
||||||
README
|
README
|
||||||
|
|
||||||
## Additional files to include when running 'make dist'
|
## Additional files to include when running 'make dist'
|
||||||
|
|
@ -270,4 +273,7 @@ EXTRA_DIST = \
|
||||||
8726_01_mangos_spell_proc_event.sql \
|
8726_01_mangos_spell_proc_event.sql \
|
||||||
8728_01_realmd_account.sql \
|
8728_01_realmd_account.sql \
|
||||||
8731_01_mangos_creature_template.sql \
|
8731_01_mangos_creature_template.sql \
|
||||||
|
8749_01_mangos_mail_loot_template.sql \
|
||||||
|
8769_01_mangos_mail_level_reward.sql \
|
||||||
|
8770_01_mangos_quest_template.sql \
|
||||||
README
|
README
|
||||||
|
|
|
||||||
|
|
@ -1706,16 +1706,6 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
|
||||||
{
|
{
|
||||||
Item* item = reward->itemId ? Item::CreateItem(reward->itemId,1,GetPlayer ()) : NULL;
|
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();
|
int loc_idx = GetPlayer()->GetSession()->GetSessionDbLocaleIndex();
|
||||||
|
|
||||||
// subject and text
|
// subject and text
|
||||||
|
|
@ -1734,7 +1724,18 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
|
||||||
|
|
||||||
uint32 itemTextId = objmgr.CreateItemText( text );
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -513,8 +513,8 @@ float ArenaTeam::GetChanceAgainst(uint32 own_rating, uint32 enemy_rating)
|
||||||
// ELO system
|
// ELO system
|
||||||
|
|
||||||
if (sWorld.getConfig(CONFIG_ARENA_SEASON_ID) >= 6)
|
if (sWorld.getConfig(CONFIG_ARENA_SEASON_ID) >= 6)
|
||||||
if (enemy_rating < 1300)
|
if (enemy_rating < 1500)
|
||||||
enemy_rating = 1300;
|
enemy_rating = 1500;
|
||||||
return 1.0f/(1.0f+exp(log(10.0f)*(float)((float)enemy_rating - (float)own_rating)/400.0f));
|
return 1.0f/(1.0f+exp(log(10.0f)*(float)((float)enemy_rating - (float)own_rating)/400.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,9 @@ void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction, uint32 newPri
|
||||||
if (oldBidder)
|
if (oldBidder)
|
||||||
oldBidder->GetSession()->SendAuctionBidderNotification( auction->GetHouseId(), auction->Id, _player->GetGUID(), newPrice, auction->GetAuctionOutBid(), auction->item_template);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -142,7 +144,9 @@ void WorldSession::SendAuctionCancelledToBidderMail( AuctionEntry* auction )
|
||||||
std::ostringstream msgAuctionCancelledSubject;
|
std::ostringstream msgAuctionCancelledSubject;
|
||||||
msgAuctionCancelledSubject << auction->item_template << ":0:" << AUCTION_CANCELLED_TO_BIDDER;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -443,11 +447,10 @@ void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data )
|
||||||
std::ostringstream msgAuctionCanceledOwner;
|
std::ostringstream msgAuctionCanceledOwner;
|
||||||
msgAuctionCanceledOwner << auction->item_template << ":0:" << AUCTION_CANCELED;
|
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
|
// 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
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -141,16 +141,15 @@ void AuctionHouseMgr::SendAuctionWonMail( AuctionEntry *auction )
|
||||||
CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'",auction->bidder,pItem->GetGUIDLow());
|
CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'",auction->bidder,pItem->GetGUIDLow());
|
||||||
CharacterDatabase.CommitTransaction();
|
CharacterDatabase.CommitTransaction();
|
||||||
|
|
||||||
MailItemsInfo mi;
|
|
||||||
mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
|
|
||||||
|
|
||||||
if (bidder)
|
if (bidder)
|
||||||
bidder->GetSession()->SendAuctionBidderNotification( auction->GetHouseId(), auction->Id, bidder_guid, 0, 0, auction->item_template);
|
bidder->GetSession()->SendAuctionBidderNotification( auction->GetHouseId(), auction->Id, bidder_guid, 0, 0, auction->item_template);
|
||||||
else
|
else
|
||||||
RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
|
RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
|
||||||
|
|
||||||
// will delete item or place to receiver mail list
|
// will delete item or place to receiver mail list
|
||||||
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);
|
||||||
}
|
}
|
||||||
// receiver not exist
|
// receiver not exist
|
||||||
else
|
else
|
||||||
|
|
@ -187,7 +186,8 @@ void AuctionHouseMgr::SendAuctionSalePendingMail( AuctionEntry * auction )
|
||||||
|
|
||||||
uint32 itemTextId = objmgr.CreateItemText( msgAuctionSalePendingBody.str() );
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -229,7 +229,9 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail( AuctionEntry * auction )
|
||||||
owner->GetSession()->SendAuctionOwnerNotification( auction );
|
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, HOUR);
|
MailDraft(msgAuctionSuccessfulSubject.str(), itemTextId)
|
||||||
|
.AddMoney(profit)
|
||||||
|
.SendMailTo(MailReceiver(owner,auction->owner), auction, MAIL_CHECK_MASK_AUCTION, HOUR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -261,11 +263,10 @@ void AuctionHouseMgr::SendAuctionExpiredMail( AuctionEntry * auction )
|
||||||
else
|
else
|
||||||
RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
|
RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
|
||||||
|
|
||||||
MailItemsInfo mi;
|
|
||||||
mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
|
|
||||||
|
|
||||||
// will delete item or place to receiver mail list
|
// will delete item or place to receiver mail list
|
||||||
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);
|
||||||
}
|
}
|
||||||
// owner not found
|
// owner not found
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -933,10 +933,6 @@ void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count)
|
||||||
// save new item before send
|
// save new item before send
|
||||||
markItem->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
|
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
|
// subject: item name
|
||||||
std::string subject = markProto->Name1;
|
std::string subject = markProto->Name1;
|
||||||
int loc_idx = plr->GetSession()->GetSessionDbLocaleIndex();
|
int loc_idx = plr->GetSession()->GetSessionDbLocaleIndex();
|
||||||
|
|
@ -951,7 +947,9 @@ void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count)
|
||||||
snprintf(textBuf,300,textFormat.c_str(),GetName(),GetName());
|
snprintf(textBuf,300,textFormat.c_str(),GetName(),GetName());
|
||||||
uint32 itemTextId = objmgr.CreateItemText( textBuf );
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -431,6 +431,8 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||||
{ "locales_page_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesPageTextCommand, "", NULL },
|
{ "locales_page_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesPageTextCommand, "", NULL },
|
||||||
{ "locales_points_of_interest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesPointsOfInterestCommand, "", NULL },
|
{ "locales_points_of_interest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesPointsOfInterestCommand, "", NULL },
|
||||||
{ "locales_quest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesQuestCommand, "", NULL },
|
{ "locales_quest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesQuestCommand, "", NULL },
|
||||||
|
{ "mail_level_reward", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadMailLevelRewardCommand, "", NULL },
|
||||||
|
{ "mail_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesMailCommand, "", NULL },
|
||||||
{ "mangos_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadMangosStringCommand, "", NULL },
|
{ "mangos_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadMangosStringCommand, "", NULL },
|
||||||
{ "milling_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesMillingCommand, "", NULL },
|
{ "milling_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesMillingCommand, "", NULL },
|
||||||
{ "npc_gossip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcGossipCommand, "", NULL },
|
{ "npc_gossip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcGossipCommand, "", NULL },
|
||||||
|
|
@ -443,7 +445,6 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||||
{ "points_of_interest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadPointsOfInterestCommand, "",NULL},
|
{ "points_of_interest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadPointsOfInterestCommand, "",NULL},
|
||||||
{ "prospecting_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesProspectingCommand,"", NULL },
|
{ "prospecting_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesProspectingCommand,"", NULL },
|
||||||
{ "quest_end_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestEndScriptsCommand, "", 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_start_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestStartScriptsCommand, "", NULL },
|
||||||
{ "quest_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestTemplateCommand, "", NULL },
|
{ "quest_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestTemplateCommand, "", NULL },
|
||||||
{ "reference_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesReferenceCommand, "", NULL },
|
{ "reference_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesReferenceCommand, "", NULL },
|
||||||
|
|
|
||||||
|
|
@ -351,13 +351,14 @@ class ChatHandler
|
||||||
bool HandleReloadLootTemplatesFishingCommand(const char* args);
|
bool HandleReloadLootTemplatesFishingCommand(const char* args);
|
||||||
bool HandleReloadLootTemplatesGameobjectCommand(const char* args);
|
bool HandleReloadLootTemplatesGameobjectCommand(const char* args);
|
||||||
bool HandleReloadLootTemplatesItemCommand(const char* args);
|
bool HandleReloadLootTemplatesItemCommand(const char* args);
|
||||||
|
bool HandleReloadLootTemplatesMailCommand(const char* args);
|
||||||
bool HandleReloadLootTemplatesMillingCommand(const char* args);
|
bool HandleReloadLootTemplatesMillingCommand(const char* args);
|
||||||
bool HandleReloadLootTemplatesPickpocketingCommand(const char* args);
|
bool HandleReloadLootTemplatesPickpocketingCommand(const char* args);
|
||||||
bool HandleReloadLootTemplatesProspectingCommand(const char* args);
|
bool HandleReloadLootTemplatesProspectingCommand(const char* args);
|
||||||
bool HandleReloadLootTemplatesReferenceCommand(const char* args);
|
bool HandleReloadLootTemplatesReferenceCommand(const char* args);
|
||||||
bool HandleReloadLootTemplatesQuestMailCommand(const char* args);
|
|
||||||
bool HandleReloadLootTemplatesSkinningCommand(const char* args);
|
bool HandleReloadLootTemplatesSkinningCommand(const char* args);
|
||||||
bool HandleReloadLootTemplatesSpellCommand(const char* args);
|
bool HandleReloadLootTemplatesSpellCommand(const char* args);
|
||||||
|
bool HandleReloadMailLevelRewardCommand(const char* args);
|
||||||
bool HandleReloadMangosStringCommand(const char* args);
|
bool HandleReloadMangosStringCommand(const char* args);
|
||||||
bool HandleReloadNpcGossipCommand(const char* args);
|
bool HandleReloadNpcGossipCommand(const char* args);
|
||||||
bool HandleReloadNpcOptionCommand(const char* args);
|
bool HandleReloadNpcOptionCommand(const char* args);
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ Creature::~Creature()
|
||||||
void Creature::AddToWorld()
|
void Creature::AddToWorld()
|
||||||
{
|
{
|
||||||
///- Register the creature for guid lookup
|
///- Register the creature for guid lookup
|
||||||
if(!IsInWorld())
|
if(!IsInWorld() && GetGUIDHigh()==HIGHGUID_UNIT)
|
||||||
GetMap()->GetObjectsStore().insert<Creature>(GetGUID(), (Creature*)this);
|
GetMap()->GetObjectsStore().insert<Creature>(GetGUID(), (Creature*)this);
|
||||||
|
|
||||||
Unit::AddToWorld();
|
Unit::AddToWorld();
|
||||||
|
|
@ -150,7 +150,7 @@ void Creature::AddToWorld()
|
||||||
void Creature::RemoveFromWorld()
|
void Creature::RemoveFromWorld()
|
||||||
{
|
{
|
||||||
///- Remove the creature from the accessor
|
///- Remove the creature from the accessor
|
||||||
if(IsInWorld())
|
if(IsInWorld() && GetGUIDHigh()==HIGHGUID_UNIT)
|
||||||
GetMap()->GetObjectsStore().erase<Creature>(GetGUID(), (Creature*)NULL);
|
GetMap()->GetObjectsStore().erase<Creature>(GetGUID(), (Creature*)NULL);
|
||||||
|
|
||||||
Unit::RemoveFromWorld();
|
Unit::RemoveFromWorld();
|
||||||
|
|
@ -1353,7 +1353,17 @@ bool Creature::LoadFromDB(uint32 guid, Map *map)
|
||||||
}
|
}
|
||||||
|
|
||||||
m_DBTableGuid = guid;
|
m_DBTableGuid = guid;
|
||||||
if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_UNIT);
|
if (map->GetInstanceId() == 0)
|
||||||
|
{
|
||||||
|
// Creature can be loaded already in map if grid has been unloaded while creature walk to another grid
|
||||||
|
// FIXME: until creature guids is global and for instances used dynamic generated guids
|
||||||
|
// in instance possible load creature duplicates with same DB guid but different in game guids
|
||||||
|
// This will be until implementing per-map creature guids
|
||||||
|
if (map->GetCreature(MAKE_NEW_GUID(guid,data->id,HIGHGUID_UNIT)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
guid = objmgr.GenerateLowGuid(HIGHGUID_UNIT);
|
||||||
|
|
||||||
uint16 team = 0;
|
uint16 team = 0;
|
||||||
if(!Create(guid,map,data->phaseMask,data->id,team,data))
|
if(!Create(guid,map,data->phaseMask,data->id,team,data))
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,11 @@ uint32 GetTalentSpellCost(uint32 spellId);
|
||||||
TalentSpellPos const* GetTalentSpellPos(uint32 spellId);
|
TalentSpellPos const* GetTalentSpellPos(uint32 spellId);
|
||||||
|
|
||||||
int32 GetAreaFlagByAreaID(uint32 area_id); // -1 if not found
|
int32 GetAreaFlagByAreaID(uint32 area_id); // -1 if not found
|
||||||
AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id);
|
|
||||||
AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag,uint32 map_id);
|
|
||||||
uint32 GetAreaFlagByMapId(uint32 mapid);
|
uint32 GetAreaFlagByMapId(uint32 mapid);
|
||||||
|
|
||||||
|
MANGOS_DLL_SPEC AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id);
|
||||||
|
MANGOS_DLL_SPEC AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag,uint32 map_id);
|
||||||
|
|
||||||
uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId);
|
uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId);
|
||||||
|
|
||||||
enum ContentLevels
|
enum ContentLevels
|
||||||
|
|
|
||||||
|
|
@ -1069,7 +1069,7 @@ struct MailTemplateEntry
|
||||||
uint32 ID; // 0
|
uint32 ID; // 0
|
||||||
//char* subject[16]; // 1-16
|
//char* subject[16]; // 1-16
|
||||||
// 17 name flags, unused
|
// 17 name flags, unused
|
||||||
//char* content[16]; // 18-33
|
char* content[16]; // 18-33
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MapEntry
|
struct MapEntry
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ const char ItemRandomPropertiesfmt[]="nxiiiiissssssssssssssssx";
|
||||||
const char ItemRandomSuffixfmt[]="nssssssssssssssssxxiiiiiiiiii";
|
const char ItemRandomSuffixfmt[]="nssssssssssssssssxxiiiiiiiiii";
|
||||||
const char ItemSetEntryfmt[]="dssssssssssssssssxxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiiiii";
|
const char ItemSetEntryfmt[]="dssssssssssssssssxxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiiiii";
|
||||||
const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";
|
const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";
|
||||||
const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxssssssssssssssssx";
|
||||||
const char MapEntryfmt[]="nxixxssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixiffxixx";
|
const char MapEntryfmt[]="nxixxssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixiffxixx";
|
||||||
const char MapDifficultyEntryfmt[]="diixxxxxxxxxxxxxxxxxiix";
|
const char MapDifficultyEntryfmt[]="diixxxxxxxxxxxxxxxxxiix";
|
||||||
const char MovieEntryfmt[]="nxx";
|
const char MovieEntryfmt[]="nxx";
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ void PlayerMenu::SendGossipMenu( uint32 TitleTextId, uint64 npcGUID )
|
||||||
|
|
||||||
data << uint32(questID);
|
data << uint32(questID);
|
||||||
data << uint32(qItem.m_qIcon);
|
data << uint32(qItem.m_qIcon);
|
||||||
data << uint32(pSession->GetPlayer()->GetQuestLevel(pQuest));
|
data << int32(pQuest->GetQuestLevel());
|
||||||
std::string Title = pQuest->GetTitle();
|
std::string Title = pQuest->GetTitle();
|
||||||
|
|
||||||
int loc_idx = pSession->GetSessionDbLocaleIndex();
|
int loc_idx = pSession->GetSessionDbLocaleIndex();
|
||||||
|
|
@ -400,7 +400,7 @@ void PlayerMenu::SendQuestGiverQuestList( QEmote eEmote, const std::string& Titl
|
||||||
|
|
||||||
data << uint32(questID);
|
data << uint32(questID);
|
||||||
data << uint32(qmi.m_qIcon);
|
data << uint32(qmi.m_qIcon);
|
||||||
data << uint32(pSession->GetPlayer()->GetQuestLevel(pQuest));
|
data << int32(pQuest->GetQuestLevel());
|
||||||
data << title;
|
data << title;
|
||||||
}
|
}
|
||||||
pSession->SendPacket( &data );
|
pSession->SendPacket( &data );
|
||||||
|
|
@ -560,7 +560,7 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
|
||||||
|
|
||||||
data << uint32(pQuest->GetQuestId()); // quest id
|
data << uint32(pQuest->GetQuestId()); // quest id
|
||||||
data << uint32(pQuest->GetQuestMethod()); // Accepted values: 0, 1 or 2. 0==IsAutoComplete() (skip objectives/details)
|
data << uint32(pQuest->GetQuestMethod()); // Accepted values: 0, 1 or 2. 0==IsAutoComplete() (skip objectives/details)
|
||||||
data << uint32(pQuest->GetQuestLevel()); // may be 0, static data, in other cases must be used dynamic level: Player::GetQuestLevel
|
data << int32(pQuest->GetQuestLevel()); // may be -1, static data, in other cases must be used dynamic level: Player::GetQuestLevelForPlayer (0 is not known, but assuming this is no longer valid for quest intended for client)
|
||||||
data << uint32(0); // min level
|
data << uint32(0); // min level
|
||||||
data << uint32(pQuest->GetZoneOrSort()); // zone or sort to display in quest log
|
data << uint32(pQuest->GetZoneOrSort()); // zone or sort to display in quest log
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -951,15 +951,13 @@ void Guild::LogGuildEvent(uint8 EventType, uint32 PlayerGuid1, uint32 PlayerGuid
|
||||||
// Bank content related
|
// Bank content related
|
||||||
void Guild::DisplayGuildBankContent(WorldSession *session, uint8 TabId)
|
void Guild::DisplayGuildBankContent(WorldSession *session, uint8 TabId)
|
||||||
{
|
{
|
||||||
WorldPacket data(SMSG_GUILD_BANK_LIST,1200);
|
GuildBankTab const* tab = m_TabListMap[TabId];
|
||||||
|
|
||||||
GuildBankTab const* tab = GetBankTab(TabId);
|
|
||||||
if (!tab)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!IsMemberHaveRights(session->GetPlayer()->GetGUIDLow(),TabId,GUILD_BANK_RIGHT_VIEW_TAB))
|
if (!IsMemberHaveRights(session->GetPlayer()->GetGUIDLow(),TabId,GUILD_BANK_RIGHT_VIEW_TAB))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
WorldPacket data(SMSG_GUILD_BANK_LIST,1200);
|
||||||
|
|
||||||
data << uint64(GetGuildBankMoney());
|
data << uint64(GetGuildBankMoney());
|
||||||
data << uint8(TabId);
|
data << uint8(TabId);
|
||||||
// remaining slots for today
|
// remaining slots for today
|
||||||
|
|
@ -992,9 +990,7 @@ void Guild::DisplayGuildBankMoneyUpdate()
|
||||||
|
|
||||||
void Guild::DisplayGuildBankContentUpdate(uint8 TabId, int32 slot1, int32 slot2)
|
void Guild::DisplayGuildBankContentUpdate(uint8 TabId, int32 slot1, int32 slot2)
|
||||||
{
|
{
|
||||||
GuildBankTab const* tab = GetBankTab(TabId);
|
GuildBankTab const* tab = m_TabListMap[TabId];
|
||||||
if (!tab)
|
|
||||||
return;
|
|
||||||
|
|
||||||
WorldPacket data(SMSG_GUILD_BANK_LIST,1200);
|
WorldPacket data(SMSG_GUILD_BANK_LIST,1200);
|
||||||
|
|
||||||
|
|
@ -1042,9 +1038,7 @@ void Guild::DisplayGuildBankContentUpdate(uint8 TabId, int32 slot1, int32 slot2)
|
||||||
|
|
||||||
void Guild::DisplayGuildBankContentUpdate(uint8 TabId, GuildItemPosCountVec const& slots)
|
void Guild::DisplayGuildBankContentUpdate(uint8 TabId, GuildItemPosCountVec const& slots)
|
||||||
{
|
{
|
||||||
GuildBankTab const* tab = GetBankTab(TabId);
|
GuildBankTab const* tab = m_TabListMap[TabId];
|
||||||
if (!tab)
|
|
||||||
return;
|
|
||||||
|
|
||||||
WorldPacket data(SMSG_GUILD_BANK_LIST,1200);
|
WorldPacket data(SMSG_GUILD_BANK_LIST,1200);
|
||||||
|
|
||||||
|
|
@ -1134,14 +1128,6 @@ void Guild::CreateNewBankTab()
|
||||||
|
|
||||||
void Guild::SetGuildBankTabInfo(uint8 TabId, std::string Name, std::string Icon)
|
void Guild::SetGuildBankTabInfo(uint8 TabId, std::string Name, std::string Icon)
|
||||||
{
|
{
|
||||||
if (TabId >= GUILD_BANK_MAX_TABS)
|
|
||||||
return;
|
|
||||||
if (TabId >= m_TabListMap.size())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!m_TabListMap[TabId])
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_TabListMap[TabId]->Name == Name && m_TabListMap[TabId]->Icon == Icon)
|
if (m_TabListMap[TabId]->Name == Name && m_TabListMap[TabId]->Icon == Icon)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -1993,12 +1979,7 @@ void Guild::SetGuildBankTabText(uint8 TabId, std::string text)
|
||||||
|
|
||||||
void Guild::SendGuildBankTabText(WorldSession *session, uint8 TabId)
|
void Guild::SendGuildBankTabText(WorldSession *session, uint8 TabId)
|
||||||
{
|
{
|
||||||
if (TabId > GUILD_BANK_MAX_TABS)
|
GuildBankTab const* tab = m_TabListMap[TabId];
|
||||||
return;
|
|
||||||
|
|
||||||
GuildBankTab const *tab = GetBankTab(TabId);
|
|
||||||
if (!tab)
|
|
||||||
return;
|
|
||||||
|
|
||||||
WorldPacket data(MSG_QUERY_GUILD_BANK_TEXT, 1+tab->Text.size()+1);
|
WorldPacket data(MSG_QUERY_GUILD_BANK_TEXT, 1+tab->Text.size()+1);
|
||||||
data << uint8(TabId);
|
data << uint8(TabId);
|
||||||
|
|
|
||||||
|
|
@ -400,7 +400,6 @@ class Guild
|
||||||
void SetGuildBankTabText(uint8 TabId, std::string text);
|
void SetGuildBankTabText(uint8 TabId, std::string text);
|
||||||
void SendGuildBankTabText(WorldSession *session, uint8 TabId);
|
void SendGuildBankTabText(WorldSession *session, uint8 TabId);
|
||||||
void SetGuildBankTabInfo(uint8 TabId, std::string name, std::string icon);
|
void SetGuildBankTabInfo(uint8 TabId, std::string name, std::string icon);
|
||||||
const GuildBankTab *GetBankTab(uint8 index) { if(index >= m_TabListMap.size()) return NULL; return m_TabListMap[index]; }
|
|
||||||
uint8 GetPurchasedTabs() const { return m_PurchasedTabs; }
|
uint8 GetPurchasedTabs() const { return m_PurchasedTabs; }
|
||||||
uint32 GetBankRights(uint32 rankId, uint8 TabId) const;
|
uint32 GetBankRights(uint32 rankId, uint8 TabId) const;
|
||||||
bool IsMemberHaveRights(uint32 LowGuid, uint8 TabId,uint32 rights) const;
|
bool IsMemberHaveRights(uint32 LowGuid, uint8 TabId,uint32 rights) const;
|
||||||
|
|
@ -408,6 +407,7 @@ class Guild
|
||||||
// Load/unload
|
// Load/unload
|
||||||
void LoadGuildBankFromDB();
|
void LoadGuildBankFromDB();
|
||||||
void UnloadGuildBank();
|
void UnloadGuildBank();
|
||||||
|
bool IsGuildBankLoaded() const { return m_GuildBankLoaded; }
|
||||||
void IncOnlineMemberCount() { ++m_OnlineMembers; }
|
void IncOnlineMemberCount() { ++m_OnlineMembers; }
|
||||||
// Money deposit/withdraw
|
// Money deposit/withdraw
|
||||||
void SendMoneyInfo(WorldSession *session, uint32 LowGuid);
|
void SendMoneyInfo(WorldSession *session, uint32 LowGuid);
|
||||||
|
|
|
||||||
|
|
@ -859,7 +859,7 @@ void WorldSession::HandleGuildBankerActivate( WorldPacket & recv_data )
|
||||||
{
|
{
|
||||||
if(Guild *pGuild = objmgr.GetGuildById(GuildId))
|
if(Guild *pGuild = objmgr.GetGuildById(GuildId))
|
||||||
{
|
{
|
||||||
pGuild->DisplayGuildBankTabsInfo(this);
|
pGuild->DisplayGuildBankTabsInfo(this); // this also will load guild bank if not yet
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -879,18 +879,22 @@ void WorldSession::HandleGuildBankQueryTab( WorldPacket & recv_data )
|
||||||
if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
|
if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(uint32 GuildId = GetPlayer()->GetGuildId())
|
uint32 GuildId = GetPlayer()->GetGuildId();
|
||||||
{
|
if (!GuildId)
|
||||||
if(Guild *pGuild = objmgr.GetGuildById(GuildId))
|
return;
|
||||||
{
|
|
||||||
|
Guild *pGuild = objmgr.GetGuildById(GuildId);
|
||||||
|
if (!pGuild)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!pGuild->IsGuildBankLoaded() || TabId >= pGuild->GetPurchasedTabs())
|
||||||
|
return;
|
||||||
|
|
||||||
// Let's update the amount of gold the player can withdraw before displaying the content
|
// Let's update the amount of gold the player can withdraw before displaying the content
|
||||||
// This is useful if money withdraw right has changed
|
// This is useful if money withdraw right has changed
|
||||||
pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
|
pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
|
||||||
|
|
||||||
pGuild->DisplayGuildBankContent(this, TabId);
|
pGuild->DisplayGuildBankContent(this, TabId);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WorldSession::HandleGuildBankDepositMoney( WorldPacket & recv_data )
|
void WorldSession::HandleGuildBankDepositMoney( WorldPacket & recv_data )
|
||||||
{
|
{
|
||||||
|
|
@ -909,10 +913,17 @@ void WorldSession::HandleGuildBankDepositMoney( WorldPacket & recv_data )
|
||||||
if (GetPlayer()->GetMoney() < money)
|
if (GetPlayer()->GetMoney() < money)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(uint32 GuildId = GetPlayer()->GetGuildId())
|
uint32 GuildId = GetPlayer()->GetGuildId();
|
||||||
{
|
if (!GuildId)
|
||||||
if(Guild *pGuild = objmgr.GetGuildById(GuildId))
|
return;
|
||||||
{
|
|
||||||
|
Guild *pGuild = objmgr.GetGuildById(GuildId);
|
||||||
|
if (!pGuild)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!pGuild->IsGuildBankLoaded() || !pGuild->GetPurchasedTabs())
|
||||||
|
return;
|
||||||
|
|
||||||
CharacterDatabase.BeginTransaction();
|
CharacterDatabase.BeginTransaction();
|
||||||
|
|
||||||
pGuild->SetBankMoney(pGuild->GetGuildBankMoney()+money);
|
pGuild->SetBankMoney(pGuild->GetGuildBankMoney()+money);
|
||||||
|
|
@ -935,8 +946,6 @@ void WorldSession::HandleGuildBankDepositMoney( WorldPacket & recv_data )
|
||||||
pGuild->DisplayGuildBankContent(this, 0);
|
pGuild->DisplayGuildBankContent(this, 0);
|
||||||
pGuild->DisplayGuildBankMoneyUpdate();
|
pGuild->DisplayGuildBankMoneyUpdate();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WorldSession::HandleGuildBankWithdrawMoney( WorldPacket & recv_data )
|
void WorldSession::HandleGuildBankWithdrawMoney( WorldPacket & recv_data )
|
||||||
{
|
{
|
||||||
|
|
@ -960,6 +969,9 @@ void WorldSession::HandleGuildBankWithdrawMoney( WorldPacket & recv_data )
|
||||||
if(!pGuild)
|
if(!pGuild)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!pGuild->IsGuildBankLoaded() || !pGuild->GetPurchasedTabs())
|
||||||
|
return;
|
||||||
|
|
||||||
if (pGuild->GetGuildBankMoney()<money) // not enough money in bank
|
if (pGuild->GetGuildBankMoney()<money) // not enough money in bank
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -1005,6 +1017,21 @@ void WorldSession::HandleGuildBankSwapItems( WorldPacket & recv_data )
|
||||||
uint32 SplitedAmount = 0;
|
uint32 SplitedAmount = 0;
|
||||||
|
|
||||||
recv_data >> GoGuid >> BankToBank;
|
recv_data >> GoGuid >> BankToBank;
|
||||||
|
|
||||||
|
uint32 GuildId = GetPlayer()->GetGuildId();
|
||||||
|
if (!GuildId)
|
||||||
|
{
|
||||||
|
recv_data.rpos(recv_data.wpos()); // prevent additional spam at rejected packet
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Guild *pGuild = objmgr.GetGuildById(GuildId);
|
||||||
|
if (!pGuild || !pGuild->IsGuildBankLoaded())
|
||||||
|
{
|
||||||
|
recv_data.rpos(recv_data.wpos()); // prevent additional spam at rejected packet
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (BankToBank)
|
if (BankToBank)
|
||||||
{
|
{
|
||||||
recv_data >> BankTabDst;
|
recv_data >> BankTabDst;
|
||||||
|
|
@ -1016,7 +1043,10 @@ void WorldSession::HandleGuildBankSwapItems( WorldPacket & recv_data )
|
||||||
recv_data >> unk2; // always 0
|
recv_data >> unk2; // always 0
|
||||||
recv_data >> SplitedAmount;
|
recv_data >> SplitedAmount;
|
||||||
|
|
||||||
if (BankTabSlotDst >= GUILD_BANK_MAX_SLOTS || (BankTabDst == BankTab && BankTabSlotDst == BankTabSlot))
|
if (BankTabSlotDst >= GUILD_BANK_MAX_SLOTS ||
|
||||||
|
(BankTabDst == BankTab && BankTabSlotDst == BankTabSlot) ||
|
||||||
|
BankTab >= pGuild->GetPurchasedTabs() ||
|
||||||
|
BankTabDst >= pGuild->GetPurchasedTabs())
|
||||||
{
|
{
|
||||||
recv_data.rpos(recv_data.wpos()); // prevent additional spam at rejected packet
|
recv_data.rpos(recv_data.wpos()); // prevent additional spam at rejected packet
|
||||||
return;
|
return;
|
||||||
|
|
@ -1042,7 +1072,8 @@ void WorldSession::HandleGuildBankSwapItems( WorldPacket & recv_data )
|
||||||
recv_data >> SplitedAmount;
|
recv_data >> SplitedAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BankTabSlot >= GUILD_BANK_MAX_SLOTS && BankTabSlot != 0xFF)
|
if (BankTabSlot >= GUILD_BANK_MAX_SLOTS && BankTabSlot != 0xFF ||
|
||||||
|
BankTab >= pGuild->GetPurchasedTabs())
|
||||||
{
|
{
|
||||||
recv_data.rpos(recv_data.wpos()); // prevent additional spam at rejected packet
|
recv_data.rpos(recv_data.wpos()); // prevent additional spam at rejected packet
|
||||||
return;
|
return;
|
||||||
|
|
@ -1052,10 +1083,6 @@ void WorldSession::HandleGuildBankSwapItems( WorldPacket & recv_data )
|
||||||
if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
|
if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(uint32 GuildId = GetPlayer()->GetGuildId())
|
|
||||||
{
|
|
||||||
if(Guild *pGuild = objmgr.GetGuildById(GuildId))
|
|
||||||
{
|
|
||||||
// Bank <-> Bank
|
// Bank <-> Bank
|
||||||
if (BankToBank)
|
if (BankToBank)
|
||||||
{
|
{
|
||||||
|
|
@ -1078,8 +1105,6 @@ void WorldSession::HandleGuildBankSwapItems( WorldPacket & recv_data )
|
||||||
else // Char -> Bank cases
|
else // Char -> Bank cases
|
||||||
pGuild->MoveFromCharToBank(_player, PlayerBag, PlayerSlot, BankTab, BankTabSlot, SplitedAmount);
|
pGuild->MoveFromCharToBank(_player, PlayerBag, PlayerSlot, BankTab, BankTabSlot, SplitedAmount);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WorldSession::HandleGuildBankBuyTab( WorldPacket & recv_data )
|
void WorldSession::HandleGuildBankBuyTab( WorldPacket & recv_data )
|
||||||
{
|
{
|
||||||
|
|
@ -1095,26 +1120,21 @@ void WorldSession::HandleGuildBankBuyTab( WorldPacket & recv_data )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint32 GuildId = GetPlayer()->GetGuildId();
|
uint32 GuildId = GetPlayer()->GetGuildId();
|
||||||
if (GuildId==0)
|
if (!GuildId)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Guild *pGuild = objmgr.GetGuildById(GuildId);
|
Guild *pGuild = objmgr.GetGuildById(GuildId);
|
||||||
if(!pGuild)
|
if(!pGuild)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// m_PurchasedTabs = 0 when buying Tab 0, that is why this check can be made
|
||||||
|
if (!pGuild->IsGuildBankLoaded() || TabId != pGuild->GetPurchasedTabs())
|
||||||
|
return;
|
||||||
|
|
||||||
uint32 TabCost = GetGuildBankTabPrice(TabId) * GOLD;
|
uint32 TabCost = GetGuildBankTabPrice(TabId) * GOLD;
|
||||||
if (!TabCost)
|
if (!TabCost)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (pGuild->GetPurchasedTabs() >= GUILD_BANK_MAX_TABS)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (TabId != pGuild->GetPurchasedTabs()) // m_PurchasedTabs = 0 when buying Tab 0, that is why this check can be made
|
|
||||||
{
|
|
||||||
sLog.outError("Error: trying to buy a tab non contiguous to owned ones");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetPlayer()->GetMoney() < TabCost) // Should not happen, this is checked by client
|
if (GetPlayer()->GetMoney() < TabCost) // Should not happen, this is checked by client
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -1149,16 +1169,21 @@ void WorldSession::HandleGuildBankUpdateTab( WorldPacket & recv_data )
|
||||||
if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
|
if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(uint32 GuildId = GetPlayer()->GetGuildId())
|
uint32 GuildId = GetPlayer()->GetGuildId();
|
||||||
{
|
if (!GuildId)
|
||||||
if(Guild *pGuild = objmgr.GetGuildById(GuildId))
|
return;
|
||||||
{
|
|
||||||
|
Guild *pGuild = objmgr.GetGuildById(GuildId);
|
||||||
|
if (!pGuild)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!pGuild->IsGuildBankLoaded() || TabId >= pGuild->GetPurchasedTabs())
|
||||||
|
return;
|
||||||
|
|
||||||
pGuild->SetGuildBankTabInfo(TabId, Name, IconIndex);
|
pGuild->SetGuildBankTabInfo(TabId, Name, IconIndex);
|
||||||
pGuild->DisplayGuildBankTabsInfo(this);
|
pGuild->DisplayGuildBankTabsInfo(this);
|
||||||
pGuild->DisplayGuildBankContent(this, TabId);
|
pGuild->DisplayGuildBankContent(this, TabId);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WorldSession::HandleGuildBankLogQuery( WorldPacket & recv_data )
|
void WorldSession::HandleGuildBankLogQuery( WorldPacket & recv_data )
|
||||||
{
|
{
|
||||||
|
|
@ -1167,8 +1192,21 @@ void WorldSession::HandleGuildBankLogQuery( WorldPacket & recv_data )
|
||||||
uint8 TabId;
|
uint8 TabId;
|
||||||
recv_data >> TabId;
|
recv_data >> TabId;
|
||||||
|
|
||||||
if(uint32 GuildId = GetPlayer()->GetGuildId())
|
uint32 GuildId = GetPlayer()->GetGuildId();
|
||||||
if(Guild *pGuild = objmgr.GetGuildById(GuildId))
|
if (!GuildId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Guild *pGuild = objmgr.GetGuildById(GuildId);
|
||||||
|
if (!pGuild)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!pGuild->IsGuildBankLoaded())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// GUILD_BANK_MAX_TABS send by client for money log
|
||||||
|
if (TabId >= pGuild->GetPurchasedTabs() && TabId != GUILD_BANK_MAX_TABS)
|
||||||
|
return;
|
||||||
|
|
||||||
pGuild->DisplayGuildBankLogs(this, TabId);
|
pGuild->DisplayGuildBankLogs(this, TabId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1179,8 +1217,17 @@ void WorldSession::HandleQueryGuildBankTabText(WorldPacket &recv_data)
|
||||||
uint8 TabId;
|
uint8 TabId;
|
||||||
recv_data >> TabId;
|
recv_data >> TabId;
|
||||||
|
|
||||||
if(uint32 GuildId = GetPlayer()->GetGuildId())
|
uint32 GuildId = GetPlayer()->GetGuildId();
|
||||||
if(Guild *pGuild = objmgr.GetGuildById(GuildId))
|
if (!GuildId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Guild *pGuild = objmgr.GetGuildById(GuildId);
|
||||||
|
if (!pGuild)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!pGuild->IsGuildBankLoaded() || TabId >= pGuild->GetPurchasedTabs())
|
||||||
|
return;
|
||||||
|
|
||||||
pGuild->SendGuildBankTabText(this, TabId);
|
pGuild->SendGuildBankTabText(this, TabId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1193,8 +1240,17 @@ void WorldSession::HandleSetGuildBankTabText(WorldPacket &recv_data)
|
||||||
recv_data >> TabId;
|
recv_data >> TabId;
|
||||||
recv_data >> Text;
|
recv_data >> Text;
|
||||||
|
|
||||||
if(uint32 GuildId = GetPlayer()->GetGuildId())
|
uint32 GuildId = GetPlayer()->GetGuildId();
|
||||||
if(Guild *pGuild = objmgr.GetGuildById(GuildId))
|
if (!GuildId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Guild *pGuild = objmgr.GetGuildById(GuildId);
|
||||||
|
if (!pGuild)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!pGuild->IsGuildBankLoaded() || TabId >= pGuild->GetPurchasedTabs())
|
||||||
|
return;
|
||||||
|
|
||||||
pGuild->SetGuildBankTabText(TabId, Text);
|
pGuild->SetGuildBankTabText(TabId, Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2003,13 +2003,12 @@ bool ChatHandler::HandleSendMailCommand(const char* args)
|
||||||
std::string text = msgText;
|
std::string text = msgText;
|
||||||
|
|
||||||
// from console show not existed sender
|
// 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;
|
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);
|
std::string nameLink = playerLink(target_name);
|
||||||
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
|
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ bool ChatHandler::HandleReloadAllCommand(const char*)
|
||||||
HandleReloadAllItemCommand("");
|
HandleReloadAllItemCommand("");
|
||||||
HandleReloadAllLocalesCommand("");
|
HandleReloadAllLocalesCommand("");
|
||||||
|
|
||||||
|
HandleReloadMailLevelRewardCommand("");
|
||||||
HandleReloadCommandCommand("");
|
HandleReloadCommandCommand("");
|
||||||
HandleReloadReservedNameCommand("");
|
HandleReloadReservedNameCommand("");
|
||||||
HandleReloadMangosStringCommand("");
|
HandleReloadMangosStringCommand("");
|
||||||
|
|
@ -360,12 +361,12 @@ bool ChatHandler::HandleReloadLootTemplatesProspectingCommand(const char*)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChatHandler::HandleReloadLootTemplatesQuestMailCommand(const char*)
|
bool ChatHandler::HandleReloadLootTemplatesMailCommand(const char*)
|
||||||
{
|
{
|
||||||
sLog.outString( "Re-Loading Loot Tables... (`quest_mail_loot_template`)" );
|
sLog.outString( "Re-Loading Loot Tables... (`mail_loot_template`)" );
|
||||||
LoadLootTemplates_QuestMail();
|
LoadLootTemplates_Mail();
|
||||||
LootTemplates_QuestMail.CheckLootRefs();
|
LootTemplates_Mail.CheckLootRefs();
|
||||||
SendGlobalSysMessage("DB table `quest_mail_loot_template` reloaded.");
|
SendGlobalSysMessage("DB table `mail_loot_template` reloaded.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -822,6 +823,14 @@ bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/)
|
||||||
return true;
|
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)
|
bool ChatHandler::HandleLoadScriptsCommand(const char* args)
|
||||||
{
|
{
|
||||||
if(!LoadScriptingModule(args)) return true;
|
if(!LoadScriptingModule(args)) return true;
|
||||||
|
|
@ -6216,25 +6225,23 @@ bool ChatHandler::HandleSendItemsCommand(const char* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
// from console show not existed sender
|
// 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;
|
uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
|
||||||
|
|
||||||
// fill mail
|
// fill mail
|
||||||
MailItemsInfo mi; // item list preparing
|
MailDraft draft(subject, itemTextId);
|
||||||
|
|
||||||
for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
|
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))
|
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
|
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);
|
std::string nameLink = playerLink(receiver_name);
|
||||||
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
|
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
|
||||||
|
|
@ -6278,13 +6285,13 @@ bool ChatHandler::HandleSendMoneyCommand(const char* args)
|
||||||
std::string text = msgText;
|
std::string text = msgText;
|
||||||
|
|
||||||
// from console show not existed sender
|
// 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;
|
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);
|
std::string nameLink = playerLink(receiver_name);
|
||||||
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
|
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
|
||||||
|
|
|
||||||
|
|
@ -40,10 +40,10 @@ LootStore LootTemplates_Disenchant( "disenchant_loot_template", "item disenc
|
||||||
LootStore LootTemplates_Fishing( "fishing_loot_template", "area id", true);
|
LootStore LootTemplates_Fishing( "fishing_loot_template", "area id", true);
|
||||||
LootStore LootTemplates_Gameobject( "gameobject_loot_template", "gameobject entry", true);
|
LootStore LootTemplates_Gameobject( "gameobject_loot_template", "gameobject entry", true);
|
||||||
LootStore LootTemplates_Item( "item_loot_template", "item 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_Milling( "milling_loot_template", "item entry (herb)", true);
|
||||||
LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template","creature pickpocket lootid", true);
|
LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template","creature pickpocket lootid", true);
|
||||||
LootStore LootTemplates_Prospecting( "prospecting_loot_template", "item entry (ore)", 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_Reference( "reference_loot_template", "reference id", false);
|
||||||
LootStore LootTemplates_Skinning( "skinning_loot_template", "creature skinning id", true);
|
LootStore LootTemplates_Skinning( "skinning_loot_template", "creature skinning id", true);
|
||||||
LootStore LootTemplates_Spell( "spell_loot_template", "spell id (random item creating)",false);
|
LootStore LootTemplates_Spell( "spell_loot_template", "spell id (random item creating)",false);
|
||||||
|
|
@ -1256,28 +1256,19 @@ void LoadLootTemplates_Prospecting()
|
||||||
LootTemplates_Prospecting.ReportUnusedIds(ids_set);
|
LootTemplates_Prospecting.ReportUnusedIds(ids_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadLootTemplates_QuestMail()
|
void LoadLootTemplates_Mail()
|
||||||
{
|
{
|
||||||
LootIdSet ids_set;
|
LootIdSet ids_set;
|
||||||
LootTemplates_QuestMail.LoadAndCollectLootIds(ids_set);
|
LootTemplates_Mail.LoadAndCollectLootIds(ids_set);
|
||||||
|
|
||||||
// remove real entries and check existence loot
|
// remove real entries and check existence loot
|
||||||
ObjectMgr::QuestMap const& questMap = objmgr.GetQuestTemplates();
|
for(uint32 i = 1; i < sMailTemplateStore.GetNumRows(); ++i )
|
||||||
for(ObjectMgr::QuestMap::const_iterator itr = questMap.begin(); itr != questMap.end(); ++itr )
|
if(sMailTemplateStore.LookupEntry(i))
|
||||||
{
|
if(ids_set.count(i))
|
||||||
if(!itr->second->GetRewMailTemplateId())
|
ids_set.erase(i);
|
||||||
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);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
// output error for any still listed (not referenced from appropriate table) ids
|
// 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()
|
void LoadLootTemplates_Skinning()
|
||||||
|
|
@ -1354,7 +1345,7 @@ void LoadLootTemplates_Reference()
|
||||||
LootTemplates_Skinning.CheckLootRefs(&ids_set);
|
LootTemplates_Skinning.CheckLootRefs(&ids_set);
|
||||||
LootTemplates_Disenchant.CheckLootRefs(&ids_set);
|
LootTemplates_Disenchant.CheckLootRefs(&ids_set);
|
||||||
LootTemplates_Prospecting.CheckLootRefs(&ids_set);
|
LootTemplates_Prospecting.CheckLootRefs(&ids_set);
|
||||||
LootTemplates_QuestMail.CheckLootRefs(&ids_set);
|
LootTemplates_Mail.CheckLootRefs(&ids_set);
|
||||||
LootTemplates_Reference.CheckLootRefs(&ids_set);
|
LootTemplates_Reference.CheckLootRefs(&ids_set);
|
||||||
|
|
||||||
// output error for any still listed ids (not referenced from any loot table)
|
// output error for any still listed ids (not referenced from any loot table)
|
||||||
|
|
|
||||||
|
|
@ -324,24 +324,24 @@ extern LootStore LootTemplates_Creature;
|
||||||
extern LootStore LootTemplates_Fishing;
|
extern LootStore LootTemplates_Fishing;
|
||||||
extern LootStore LootTemplates_Gameobject;
|
extern LootStore LootTemplates_Gameobject;
|
||||||
extern LootStore LootTemplates_Item;
|
extern LootStore LootTemplates_Item;
|
||||||
|
extern LootStore LootTemplates_Mail;
|
||||||
extern LootStore LootTemplates_Milling;
|
extern LootStore LootTemplates_Milling;
|
||||||
extern LootStore LootTemplates_Pickpocketing;
|
extern LootStore LootTemplates_Pickpocketing;
|
||||||
extern LootStore LootTemplates_Skinning;
|
extern LootStore LootTemplates_Skinning;
|
||||||
extern LootStore LootTemplates_Disenchant;
|
extern LootStore LootTemplates_Disenchant;
|
||||||
extern LootStore LootTemplates_Prospecting;
|
extern LootStore LootTemplates_Prospecting;
|
||||||
extern LootStore LootTemplates_QuestMail;
|
|
||||||
extern LootStore LootTemplates_Spell;
|
extern LootStore LootTemplates_Spell;
|
||||||
|
|
||||||
void LoadLootTemplates_Creature();
|
void LoadLootTemplates_Creature();
|
||||||
void LoadLootTemplates_Fishing();
|
void LoadLootTemplates_Fishing();
|
||||||
void LoadLootTemplates_Gameobject();
|
void LoadLootTemplates_Gameobject();
|
||||||
void LoadLootTemplates_Item();
|
void LoadLootTemplates_Item();
|
||||||
|
void LoadLootTemplates_Mail();
|
||||||
void LoadLootTemplates_Milling();
|
void LoadLootTemplates_Milling();
|
||||||
void LoadLootTemplates_Pickpocketing();
|
void LoadLootTemplates_Pickpocketing();
|
||||||
void LoadLootTemplates_Skinning();
|
void LoadLootTemplates_Skinning();
|
||||||
void LoadLootTemplates_Disenchant();
|
void LoadLootTemplates_Disenchant();
|
||||||
void LoadLootTemplates_Prospecting();
|
void LoadLootTemplates_Prospecting();
|
||||||
void LoadLootTemplates_QuestMail();
|
|
||||||
|
|
||||||
void LoadLootTemplates_Spell();
|
void LoadLootTemplates_Spell();
|
||||||
void LoadLootTemplates_Reference();
|
void LoadLootTemplates_Reference();
|
||||||
|
|
@ -352,12 +352,12 @@ inline void LoadLootTables()
|
||||||
LoadLootTemplates_Fishing();
|
LoadLootTemplates_Fishing();
|
||||||
LoadLootTemplates_Gameobject();
|
LoadLootTemplates_Gameobject();
|
||||||
LoadLootTemplates_Item();
|
LoadLootTemplates_Item();
|
||||||
|
LoadLootTemplates_Mail();
|
||||||
LoadLootTemplates_Milling();
|
LoadLootTemplates_Milling();
|
||||||
LoadLootTemplates_Pickpocketing();
|
LoadLootTemplates_Pickpocketing();
|
||||||
LoadLootTemplates_Skinning();
|
LoadLootTemplates_Skinning();
|
||||||
LoadLootTemplates_Disenchant();
|
LoadLootTemplates_Disenchant();
|
||||||
LoadLootTemplates_Prospecting();
|
LoadLootTemplates_Prospecting();
|
||||||
LoadLootTemplates_QuestMail();
|
|
||||||
LoadLootTemplates_Spell();
|
LoadLootTemplates_Spell();
|
||||||
|
|
||||||
LoadLootTemplates_Reference();
|
LoadLootTemplates_Reference();
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@
|
||||||
#include "Language.h"
|
#include "Language.h"
|
||||||
#include "DBCStores.h"
|
#include "DBCStores.h"
|
||||||
#include "BattleGroundMgr.h"
|
#include "BattleGroundMgr.h"
|
||||||
|
#include "Item.h"
|
||||||
|
#include "AuctionHouseMgr.h"
|
||||||
|
|
||||||
enum MailShowFlags
|
enum MailShowFlags
|
||||||
{
|
{
|
||||||
|
|
@ -39,18 +41,6 @@ enum MailShowFlags
|
||||||
MAIL_SHOW_RETURN = 0x0010,
|
MAIL_SHOW_RETURN = 0x0010,
|
||||||
};
|
};
|
||||||
|
|
||||||
void MailItem::deleteItem( bool inDB )
|
|
||||||
{
|
|
||||||
if(item)
|
|
||||||
{
|
|
||||||
if(inDB)
|
|
||||||
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'", item->GetGUIDLow());
|
|
||||||
|
|
||||||
delete item;
|
|
||||||
item = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||||
{
|
{
|
||||||
uint64 mailbox, unk3;
|
uint64 mailbox, unk3;
|
||||||
|
|
@ -60,9 +50,6 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||||
recv_data >> mailbox;
|
recv_data >> mailbox;
|
||||||
recv_data >> receiver;
|
recv_data >> receiver;
|
||||||
|
|
||||||
if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
|
|
||||||
return;
|
|
||||||
|
|
||||||
recv_data >> subject;
|
recv_data >> subject;
|
||||||
|
|
||||||
recv_data >> body;
|
recv_data >> body;
|
||||||
|
|
@ -70,34 +57,32 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||||
recv_data >> unk1; // stationery?
|
recv_data >> unk1; // stationery?
|
||||||
recv_data >> unk2; // 0x00000000
|
recv_data >> unk2; // 0x00000000
|
||||||
|
|
||||||
MailItemsInfo mi;
|
|
||||||
|
|
||||||
uint8 items_count;
|
uint8 items_count;
|
||||||
recv_data >> items_count; // attached items count
|
recv_data >> items_count; // attached items count
|
||||||
|
|
||||||
if(items_count > 12) // client limit
|
if (items_count > MAX_MAIL_ITEMS) // client limit
|
||||||
{
|
{
|
||||||
GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_TOO_MANY_ATTACHMENTS);
|
GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_TOO_MANY_ATTACHMENTS);
|
||||||
|
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(items_count)
|
uint64 itemGUIDs[MAX_MAIL_ITEMS];
|
||||||
{
|
|
||||||
for(uint8 i = 0; i < items_count; ++i)
|
for(uint8 i = 0; i < items_count; ++i)
|
||||||
{
|
{
|
||||||
uint8 item_slot;
|
recv_data.read_skip<uint8>(); // item slot in mail, not used
|
||||||
uint64 item_guid;
|
recv_data >> itemGUIDs[i];
|
||||||
recv_data >> item_slot;
|
|
||||||
recv_data >> item_guid;
|
|
||||||
mi.AddItem(GUID_LOPART(item_guid), item_slot);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
recv_data >> money >> COD; // money and cod
|
recv_data >> money >> COD; // money and cod
|
||||||
recv_data >> unk3; // const 0
|
recv_data >> unk3; // const 0
|
||||||
recv_data >> unk4; // const 0
|
recv_data >> unk4; // const 0
|
||||||
|
|
||||||
items_count = mi.size(); // this is the real size after the duplicates have been removed
|
// packet read complete, now do check
|
||||||
|
|
||||||
|
if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
|
||||||
|
return;
|
||||||
|
|
||||||
if (receiver.empty())
|
if (receiver.empty())
|
||||||
return;
|
return;
|
||||||
|
|
@ -147,8 +132,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rc_team = objmgr.GetPlayerTeamByGUID(rc);
|
rc_team = objmgr.GetPlayerTeamByGUID(rc);
|
||||||
QueryResult* result = CharacterDatabase.PQuery("SELECT COUNT(*) FROM mail WHERE receiver = '%u'", GUID_LOPART(rc));
|
if (QueryResult* result = CharacterDatabase.PQuery("SELECT COUNT(*) FROM mail WHERE receiver = '%u'", GUID_LOPART(rc)))
|
||||||
if(result)
|
|
||||||
{
|
{
|
||||||
Field *fields = result->Fetch();
|
Field *fields = result->Fetch();
|
||||||
mails_count = fields[0].GetUInt32();
|
mails_count = fields[0].GetUInt32();
|
||||||
|
|
@ -170,95 +154,89 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 rc_account = 0;
|
uint32 rc_account = receive
|
||||||
if(receive)
|
? receive->GetSession()->GetAccountId()
|
||||||
rc_account = receive->GetSession()->GetAccountId();
|
: objmgr.GetPlayerAccountIdByGUID(rc);
|
||||||
else
|
|
||||||
rc_account = objmgr.GetPlayerAccountIdByGUID(rc);
|
|
||||||
|
|
||||||
if (items_count)
|
Item* items[MAX_MAIL_ITEMS];
|
||||||
{
|
|
||||||
for(MailItemMap::iterator mailItemIter = mi.begin(); mailItemIter != mi.end(); ++mailItemIter)
|
|
||||||
{
|
|
||||||
MailItem& mailItem = mailItemIter->second;
|
|
||||||
|
|
||||||
if(!mailItem.item_guidlow)
|
for(uint8 i = 0; i < items_count; ++i)
|
||||||
|
{
|
||||||
|
if (!itemGUIDs[i])
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mailItem.item = pl->GetItemByGuid(MAKE_NEW_GUID(mailItem.item_guidlow, 0, HIGHGUID_ITEM));
|
Item* item = pl->GetItemByGuid(itemGUIDs[i]);
|
||||||
|
|
||||||
// prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail)
|
// prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail)
|
||||||
if(!mailItem.item)
|
if(!item)
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!mailItem.item->CanBeTraded(true))
|
if (!item->CanBeTraded(true))
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mailItem.item->IsBoundAccountWide() && mailItem.item->IsSoulBound() && pl->GetSession()->GetAccountId() != rc_account)
|
if (item->IsBoundAccountWide() && item->IsSoulBound() && pl->GetSession()->GetAccountId() != rc_account)
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mailItem.item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED) || mailItem.item->GetUInt32Value(ITEM_FIELD_DURATION))
|
if (item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED) || item->GetUInt32Value(ITEM_FIELD_DURATION))
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(COD && mailItem.item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED))
|
if (COD && item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED))
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANT_SEND_WRAPPED_COD);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANT_SEND_WRAPPED_COD);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
items[i] = item;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
pl->SendMailResult(0, MAIL_SEND, MAIL_OK);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_OK);
|
||||||
|
|
||||||
uint32 itemTextId = 0;
|
uint32 itemTextId = !body.empty() ? objmgr.CreateItemText( body ) : 0;
|
||||||
if (!body.empty())
|
|
||||||
{
|
|
||||||
itemTextId = objmgr.CreateItemText( body );
|
|
||||||
}
|
|
||||||
|
|
||||||
pl->ModifyMoney( -int32(reqmoney) );
|
pl->ModifyMoney( -int32(reqmoney) );
|
||||||
pl->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost);
|
pl->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost);
|
||||||
|
|
||||||
bool needItemDelay = false;
|
bool needItemDelay = false;
|
||||||
|
|
||||||
|
MailDraft draft(subject, itemTextId);
|
||||||
|
|
||||||
if (items_count > 0 || money > 0)
|
if (items_count > 0 || money > 0)
|
||||||
{
|
{
|
||||||
if (items_count > 0)
|
if (items_count > 0)
|
||||||
{
|
{
|
||||||
for(MailItemMap::iterator mailItemIter = mi.begin(); mailItemIter != mi.end(); ++mailItemIter)
|
for(uint8 i = 0; i < items_count; ++i)
|
||||||
{
|
{
|
||||||
MailItem& mailItem = mailItemIter->second;
|
Item* item = items[i];
|
||||||
if(!mailItem.item)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
mailItem.item_template = mailItem.item ? mailItem.item->GetEntry() : 0;
|
|
||||||
|
|
||||||
if (GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
|
if (GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
|
||||||
{
|
{
|
||||||
sLog.outCommand(GetAccountId(), "GM %s (Account: %u) mail item: %s (Entry: %u Count: %u) to player: %s (Account: %u)",
|
sLog.outCommand(GetAccountId(), "GM %s (Account: %u) mail item: %s (Entry: %u Count: %u) to player: %s (Account: %u)",
|
||||||
GetPlayerName(), GetAccountId(), mailItem.item->GetProto()->Name1, mailItem.item->GetEntry(), mailItem.item->GetCount(), receiver.c_str(), rc_account);
|
GetPlayerName(), GetAccountId(), item->GetProto()->Name1, item->GetEntry(), item->GetCount(), receiver.c_str(), rc_account);
|
||||||
}
|
}
|
||||||
|
|
||||||
pl->MoveItemFromInventory(mailItem.item->GetBagSlot(), mailItem.item->GetSlot(), true);
|
pl->MoveItemFromInventory(items[i]->GetBagSlot(), item->GetSlot(), true);
|
||||||
CharacterDatabase.BeginTransaction();
|
CharacterDatabase.BeginTransaction();
|
||||||
mailItem.item->DeleteFromInventoryDB(); // deletes item from character's inventory
|
item->DeleteFromInventoryDB(); // deletes item from character's inventory
|
||||||
mailItem.item->SaveToDB(); // recursive and not have transaction guard into self, item not in inventory and can be save standalone
|
item->SaveToDB(); // recursive and not have transaction guard into self, item not in inventory and can be save standalone
|
||||||
// owner in data will set at mail receive and item extracting
|
// owner in data will set at mail receive and item extracting
|
||||||
CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", GUID_LOPART(rc), mailItem.item->GetGUIDLow());
|
CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", GUID_LOPART(rc), item->GetGUIDLow());
|
||||||
CharacterDatabase.CommitTransaction();
|
CharacterDatabase.CommitTransaction();
|
||||||
|
|
||||||
|
draft.AddItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if item send to character at another account, then apply item delivery delay
|
// if item send to character at another account, then apply item delivery delay
|
||||||
|
|
@ -276,7 +254,10 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||||
uint32 deliver_delay = needItemDelay ? sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0;
|
uint32 deliver_delay = needItemDelay ? sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0;
|
||||||
|
|
||||||
// will delete item or place to receiver mail list
|
// will delete item or place to receiver mail list
|
||||||
WorldSession::SendMailTo(receive, MAIL_NORMAL, MAIL_STATIONERY_NORMAL, pl->GetGUIDLow(), GUID_LOPART(rc), subject, itemTextId, &mi, money, COD, MAIL_CHECK_MASK_NONE, deliver_delay);
|
draft
|
||||||
|
.AddMoney(money)
|
||||||
|
.AddCOD(COD)
|
||||||
|
.SendMailTo(MailReceiver(receive, GUID_LOPART(rc)), pl, MAIL_CHECK_MASK_NONE, deliver_delay);
|
||||||
|
|
||||||
CharacterDatabase.BeginTransaction();
|
CharacterDatabase.BeginTransaction();
|
||||||
pl->SaveInventoryAndGoldToDB();
|
pl->SaveInventoryAndGoldToDB();
|
||||||
|
|
@ -314,7 +295,7 @@ void WorldSession::HandleMailDelete(WorldPacket & recv_data )
|
||||||
uint32 mailId;
|
uint32 mailId;
|
||||||
recv_data >> mailbox;
|
recv_data >> mailbox;
|
||||||
recv_data >> mailId;
|
recv_data >> mailId;
|
||||||
recv_data.read_skip<uint32>(); // 3.3.0
|
recv_data.read_skip<uint32>(); // mailTemplateId
|
||||||
|
|
||||||
if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
|
if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
|
||||||
return;
|
return;
|
||||||
|
|
@ -341,11 +322,12 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data )
|
||||||
uint64 mailbox;
|
uint64 mailbox;
|
||||||
uint32 mailId;
|
uint32 mailId;
|
||||||
recv_data >> mailbox;
|
recv_data >> mailbox;
|
||||||
|
recv_data >> mailId;
|
||||||
|
recv_data.read_skip<uint64>(); // original sender GUID for return to, not used
|
||||||
|
|
||||||
if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
|
if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
recv_data >> mailId;
|
|
||||||
Player *pl = _player;
|
Player *pl = _player;
|
||||||
Mail *m = pl->GetMail(mailId);
|
Mail *m = pl->GetMail(mailId);
|
||||||
if(!m || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL))
|
if(!m || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL))
|
||||||
|
|
@ -362,7 +344,12 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data )
|
||||||
CharacterDatabase.CommitTransaction();
|
CharacterDatabase.CommitTransaction();
|
||||||
pl->RemoveMail(mailId);
|
pl->RemoveMail(mailId);
|
||||||
|
|
||||||
MailItemsInfo mi;
|
// send back only to players and simple drop for other cases
|
||||||
|
if (m->messageType == MAIL_NORMAL)
|
||||||
|
{
|
||||||
|
MailDraft draft(m->subject, m->itemTextId);
|
||||||
|
if (m->mailTemplateId)
|
||||||
|
draft = MailDraft(m->mailTemplateId,false); // items already included
|
||||||
|
|
||||||
if(m->HasItems())
|
if(m->HasItems())
|
||||||
{
|
{
|
||||||
|
|
@ -370,7 +357,7 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data )
|
||||||
{
|
{
|
||||||
Item *item = pl->GetMItem(itr2->item_guid);
|
Item *item = pl->GetMItem(itr2->item_guid);
|
||||||
if(item)
|
if(item)
|
||||||
mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
|
draft.AddItem(item);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//WTF?
|
//WTF?
|
||||||
|
|
@ -380,59 +367,13 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SendReturnToSender(MAIL_NORMAL, GetAccountId(), m->receiver, m->sender, m->subject, m->itemTextId, &mi, m->money, m->mailTemplateId);
|
draft.AddMoney(m->money).SendReturnToSender(GetAccountId(), m->receiver, m->sender);
|
||||||
|
}
|
||||||
|
|
||||||
delete m; // we can deallocate old mail
|
delete m; // we can deallocate old mail
|
||||||
pl->SendMailResult(mailId, MAIL_RETURNED_TO_SENDER, MAIL_OK);
|
pl->SendMailResult(mailId, MAIL_RETURNED_TO_SENDER, MAIL_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::SendReturnToSender(uint8 messageType, uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid, const std::string& subject, uint32 itemTextId, MailItemsInfo *mi, uint32 money, uint16 mailTemplateId )
|
|
||||||
{
|
|
||||||
if(messageType != MAIL_NORMAL) // return only to players
|
|
||||||
{
|
|
||||||
mi->deleteIncludedItems(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Player *receiver = objmgr.GetPlayer(MAKE_NEW_GUID(receiver_guid, 0, HIGHGUID_PLAYER));
|
|
||||||
|
|
||||||
uint32 rc_account = 0;
|
|
||||||
if(!receiver)
|
|
||||||
rc_account = objmgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(receiver_guid, 0, HIGHGUID_PLAYER));
|
|
||||||
|
|
||||||
if(!receiver && !rc_account) // sender not exist
|
|
||||||
{
|
|
||||||
mi->deleteIncludedItems(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepare mail and send in other case
|
|
||||||
bool needItemDelay = false;
|
|
||||||
|
|
||||||
if(mi && !mi->empty())
|
|
||||||
{
|
|
||||||
// if item send to character at another account, then apply item delivery delay
|
|
||||||
needItemDelay = sender_acc != rc_account;
|
|
||||||
|
|
||||||
// set owner to new receiver (to prevent delete item with sender char deleting)
|
|
||||||
CharacterDatabase.BeginTransaction();
|
|
||||||
for(MailItemMap::iterator mailItemIter = mi->begin(); mailItemIter != mi->end(); ++mailItemIter)
|
|
||||||
{
|
|
||||||
MailItem& mailItem = mailItemIter->second;
|
|
||||||
mailItem.item->SaveToDB(); // item not in inventory and can be save standalone
|
|
||||||
// owner in data will set at mail receive and item extracting
|
|
||||||
CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", receiver_guid, mailItem.item->GetGUIDLow());
|
|
||||||
}
|
|
||||||
CharacterDatabase.CommitTransaction();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If theres is an item, there is a one hour delivery delay.
|
|
||||||
uint32 deliver_delay = needItemDelay ? sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0;
|
|
||||||
|
|
||||||
// will delete item or place to receiver mail list
|
|
||||||
WorldSession::SendMailTo(receiver, MAIL_NORMAL, MAIL_STATIONERY_NORMAL, sender_guid, receiver_guid, subject, itemTextId, mi, money, 0, MAIL_CHECK_MASK_RETURNED, deliver_delay, mailTemplateId);
|
|
||||||
}
|
|
||||||
|
|
||||||
//called when player takes item attached in mail
|
//called when player takes item attached in mail
|
||||||
void WorldSession::HandleMailTakeItem(WorldPacket & recv_data )
|
void WorldSession::HandleMailTakeItem(WorldPacket & recv_data )
|
||||||
{
|
{
|
||||||
|
|
@ -503,7 +444,9 @@ void WorldSession::HandleMailTakeItem(WorldPacket & recv_data )
|
||||||
// check player existence
|
// check player existence
|
||||||
if(receive || sender_accId)
|
if(receive || sender_accId)
|
||||||
{
|
{
|
||||||
WorldSession::SendMailTo(receive, MAIL_NORMAL, MAIL_STATIONERY_NORMAL, m->receiver, m->sender, m->subject, 0, NULL, m->COD, 0, MAIL_CHECK_MASK_COD_PAYMENT);
|
MailDraft(m->subject)
|
||||||
|
.AddMoney(m->COD)
|
||||||
|
.SendMailTo(MailReceiver(receive,m->sender),MailSender(MAIL_NORMAL,m->receiver), MAIL_CHECK_MASK_COD_PAYMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
pl->ModifyMoney( -int32(m->COD) );
|
pl->ModifyMoney( -int32(m->COD) );
|
||||||
|
|
@ -608,7 +551,7 @@ void WorldSession::HandleGetMailList(WorldPacket & recv_data )
|
||||||
if ((*itr)->HasItems() && (*itr)->messageType == MAIL_NORMAL)
|
if ((*itr)->HasItems() && (*itr)->messageType == MAIL_NORMAL)
|
||||||
show_flags |= MAIL_SHOW_RETURN;
|
show_flags |= MAIL_SHOW_RETURN;
|
||||||
|
|
||||||
data << uint16(0x0040); // unknown 2.3.0, different values
|
data << uint16(next_mail_size); // Message size
|
||||||
data << uint32((*itr)->messageID); // Message ID
|
data << uint32((*itr)->messageID); // Message ID
|
||||||
data << uint8((*itr)->messageType); // Message Type
|
data << uint8((*itr)->messageType); // Message Type
|
||||||
|
|
||||||
|
|
@ -710,7 +653,9 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket & recv_data )
|
||||||
uint64 mailbox;
|
uint64 mailbox;
|
||||||
uint32 mailId;
|
uint32 mailId;
|
||||||
|
|
||||||
recv_data >> mailbox >> mailId;
|
recv_data >> mailbox;
|
||||||
|
recv_data >> mailId;
|
||||||
|
recv_data.read_skip<uint32>(); // mailTemplateId, non need, Mail store own 100% correct value anyway
|
||||||
|
|
||||||
if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
|
if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
|
||||||
return;
|
return;
|
||||||
|
|
@ -718,12 +663,27 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket & recv_data )
|
||||||
Player *pl = _player;
|
Player *pl = _player;
|
||||||
|
|
||||||
Mail* m = pl->GetMail(mailId);
|
Mail* m = pl->GetMail(mailId);
|
||||||
if(!m || !m->itemTextId || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL))
|
if(!m || !m->itemTextId && !m->mailTemplateId || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL))
|
||||||
{
|
{
|
||||||
pl->SendMailResult(mailId, MAIL_MADE_PERMANENT, MAIL_ERR_INTERNAL_ERROR);
|
pl->SendMailResult(mailId, MAIL_MADE_PERMANENT, MAIL_ERR_INTERNAL_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 itemTextId = m->itemTextId;
|
||||||
|
|
||||||
|
// in mail template case we need create new text id
|
||||||
|
if(!itemTextId)
|
||||||
|
{
|
||||||
|
MailTemplateEntry const* mailTemplateEntry = sMailTemplateStore.LookupEntry(m->mailTemplateId);
|
||||||
|
if(!mailTemplateEntry)
|
||||||
|
{
|
||||||
|
pl->SendMailResult(mailId, MAIL_MADE_PERMANENT, MAIL_ERR_INTERNAL_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
itemTextId = objmgr.CreateItemText(mailTemplateEntry->content[GetSessionDbcLocale()]);
|
||||||
|
}
|
||||||
|
|
||||||
Item *bodyItem = new Item; // This is not bag and then can be used new Item.
|
Item *bodyItem = new Item; // This is not bag and then can be used new Item.
|
||||||
if(!bodyItem->Create(objmgr.GenerateLowGuid(HIGHGUID_ITEM), MAIL_BODY_ITEM_TEMPLATE, pl))
|
if(!bodyItem->Create(objmgr.GenerateLowGuid(HIGHGUID_ITEM), MAIL_BODY_ITEM_TEMPLATE, pl))
|
||||||
{
|
{
|
||||||
|
|
@ -731,7 +691,7 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket & recv_data )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bodyItem->SetUInt32Value( ITEM_FIELD_ITEM_TEXT_ID, m->itemTextId );
|
bodyItem->SetUInt32Value( ITEM_FIELD_ITEM_TEXT_ID, itemTextId );
|
||||||
bodyItem->SetUInt32Value( ITEM_FIELD_CREATOR, m->sender);
|
bodyItem->SetUInt32Value( ITEM_FIELD_CREATOR, m->sender);
|
||||||
|
|
||||||
sLog.outDetail("HandleMailCreateTextItem mailid=%u",mailId);
|
sLog.outDetail("HandleMailCreateTextItem mailid=%u",mailId);
|
||||||
|
|
@ -813,90 +773,217 @@ void WorldSession::HandleQueryNextMailTime(WorldPacket & /*recv_data*/ )
|
||||||
SendPacket(&data);
|
SendPacket(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::SendMailTo(Player* receiver, uint8 messageType, uint8 stationery, uint32 sender_guidlow_or_entry, uint32 receiver_guidlow, std::string subject, uint32 itemTextId, MailItemsInfo* mi, uint32 money, uint32 COD, uint32 checked, uint32 deliver_delay, uint16 mailTemplateId)
|
MailSender::MailSender( Object* sender, MailStationery stationery ) : m_stationery(stationery)
|
||||||
{
|
{
|
||||||
|
switch(sender->GetTypeId())
|
||||||
|
{
|
||||||
|
case TYPEID_UNIT:
|
||||||
|
m_messageType = MAIL_CREATURE;
|
||||||
|
m_senderId = sender->GetEntry();
|
||||||
|
break;
|
||||||
|
case TYPEID_GAMEOBJECT:
|
||||||
|
m_messageType = MAIL_GAMEOBJECT;
|
||||||
|
m_senderId = sender->GetEntry();
|
||||||
|
break;
|
||||||
|
case TYPEID_ITEM:
|
||||||
|
m_messageType = MAIL_ITEM;
|
||||||
|
m_senderId = sender->GetEntry();
|
||||||
|
break;
|
||||||
|
case TYPEID_PLAYER:
|
||||||
|
m_messageType = MAIL_NORMAL;
|
||||||
|
m_senderId = sender->GetGUIDLow();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
m_messageType = MAIL_NORMAL;
|
||||||
|
m_senderId = 0; // will show mail from not existed player
|
||||||
|
sLog.outError( "MailSender::MailSender - Mail have unexpected sender typeid (%u)", sender->GetTypeId());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MailSender::MailSender( AuctionEntry* sender )
|
||||||
|
: m_messageType(MAIL_AUCTION), m_senderId(sender->GetHouseId()), m_stationery(MAIL_STATIONERY_AUCTION)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MailReceiver::MailReceiver( Player* receiver ) : m_receiver(receiver), m_receiver_lowguid(receiver->GetGUIDLow())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MailReceiver::MailReceiver( Player* receiver,uint32 receiver_lowguid ) : m_receiver(receiver), m_receiver_lowguid(receiver_lowguid)
|
||||||
|
{
|
||||||
|
ASSERT(!receiver || receiver->GetGUIDLow() == receiver_lowguid);
|
||||||
|
}
|
||||||
|
|
||||||
|
MailDraft& MailDraft::AddItem( Item* item )
|
||||||
|
{
|
||||||
|
m_items[item->GetGUIDLow()] = item; return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MailDraft::prepareItems(Player* receiver)
|
||||||
|
{
|
||||||
|
if (!m_mailTemplateId || !m_mailTemplateItemsNeed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_mailTemplateItemsNeed = false;
|
||||||
|
|
||||||
|
Loot mailLoot;
|
||||||
|
|
||||||
|
mailLoot.FillLoot(m_mailTemplateId, LootTemplates_Mail, receiver,true);
|
||||||
|
|
||||||
|
uint32 max_slot = mailLoot.GetMaxSlotInLootFor(receiver);
|
||||||
|
for(uint32 i = 0; m_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(); // save for prevent lost at next mail load, if send fail then item will deleted
|
||||||
|
AddItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MailDraft::deleteIncludedItems( bool inDB /*= false*/ )
|
||||||
|
{
|
||||||
|
for(MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
|
||||||
|
{
|
||||||
|
Item* item = mailItemIter->second;
|
||||||
|
|
||||||
|
if(inDB)
|
||||||
|
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'", item->GetGUIDLow());
|
||||||
|
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_items.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MailDraft::SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid )
|
||||||
|
{
|
||||||
|
Player *receiver = objmgr.GetPlayer(MAKE_NEW_GUID(receiver_guid, 0, HIGHGUID_PLAYER));
|
||||||
|
|
||||||
|
uint32 rc_account = 0;
|
||||||
|
if(!receiver)
|
||||||
|
rc_account = objmgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(receiver_guid, 0, HIGHGUID_PLAYER));
|
||||||
|
|
||||||
|
if(!receiver && !rc_account) // sender not exist
|
||||||
|
{
|
||||||
|
deleteIncludedItems(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare mail and send in other case
|
||||||
|
bool needItemDelay = false;
|
||||||
|
|
||||||
|
if(!m_items.empty())
|
||||||
|
{
|
||||||
|
// if item send to character at another account, then apply item delivery delay
|
||||||
|
needItemDelay = sender_acc != rc_account;
|
||||||
|
|
||||||
|
// set owner to new receiver (to prevent delete item with sender char deleting)
|
||||||
|
CharacterDatabase.BeginTransaction();
|
||||||
|
for(MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
|
||||||
|
{
|
||||||
|
Item* item = mailItemIter->second;
|
||||||
|
item->SaveToDB(); // item not in inventory and can be save standalone
|
||||||
|
// owner in data will set at mail receive and item extracting
|
||||||
|
CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", receiver_guid, item->GetGUIDLow());
|
||||||
|
}
|
||||||
|
CharacterDatabase.CommitTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If theres is an item, there is a one hour delivery delay.
|
||||||
|
uint32 deliver_delay = needItemDelay ? sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0;
|
||||||
|
|
||||||
|
// will delete item or place to receiver mail list
|
||||||
|
SendMailTo(MailReceiver(receiver,receiver_guid), MailSender(MAIL_NORMAL, sender_guid), MAIL_CHECK_MASK_RETURNED, deliver_delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MailDraft::SendMailTo(MailReceiver const& receiver, MailSender const& sender, MailCheckMask checked, uint32 deliver_delay)
|
||||||
|
{
|
||||||
|
Player* pReceiver = receiver.GetPlayer(); // can be NULL
|
||||||
|
|
||||||
|
if (pReceiver)
|
||||||
|
prepareItems(pReceiver); // generate mail template items
|
||||||
|
|
||||||
|
|
||||||
uint32 mailId = objmgr.GenerateMailID();
|
uint32 mailId = objmgr.GenerateMailID();
|
||||||
|
|
||||||
time_t deliver_time = time(NULL) + deliver_delay;
|
time_t deliver_time = time(NULL) + deliver_delay;
|
||||||
|
|
||||||
uint32 expire_delay;
|
uint32 expire_delay;
|
||||||
// auction mail without any items and money (auction sale note) pending 1 hour
|
// auction mail without any items and money (auction sale note) pending 1 hour
|
||||||
if (messageType == MAIL_AUCTION && !mi && !money)
|
if (sender.GetMailMessageType() == MAIL_AUCTION && m_items.empty() && !m_money)
|
||||||
expire_delay = HOUR;
|
expire_delay = HOUR;
|
||||||
// mail from battlemaster (rewardmarks) should last only one day
|
// mail from battlemaster (rewardmarks) should last only one day
|
||||||
else if (messageType == MAIL_CREATURE && sBattleGroundMgr.GetBattleMasterBG(sender_guidlow_or_entry) != BATTLEGROUND_TYPE_NONE)
|
else if (sender.GetMailMessageType() == MAIL_CREATURE && sBattleGroundMgr.GetBattleMasterBG(sender.GetSenderId()) != BATTLEGROUND_TYPE_NONE)
|
||||||
expire_delay = DAY;
|
expire_delay = DAY;
|
||||||
// default case: expire time if COD 3 days, if no COD 30 days
|
// default case: expire time if COD 3 days, if no COD 30 days
|
||||||
else
|
else
|
||||||
expire_delay = (COD > 0) ? 3 * DAY : 30 * DAY;
|
expire_delay = (m_COD > 0) ? 3 * DAY : 30 * DAY;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
time_t expire_time = deliver_time + expire_delay;
|
time_t expire_time = deliver_time + expire_delay;
|
||||||
|
|
||||||
if (mailTemplateId && !sMailTemplateStore.LookupEntry(mailTemplateId))
|
// Add to DB
|
||||||
|
std::string safe_subject = GetSubject();
|
||||||
|
|
||||||
|
CharacterDatabase.BeginTransaction();
|
||||||
|
CharacterDatabase.escape_string(safe_subject);
|
||||||
|
CharacterDatabase.PExecute("INSERT INTO mail (id,messageType,stationery,mailTemplateId,sender,receiver,subject,itemTextId,has_items,expire_time,deliver_time,money,cod,checked) "
|
||||||
|
"VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%s', '%u', '%u', '" UI64FMTD "','" UI64FMTD "', '%u', '%u', '%d')",
|
||||||
|
mailId, sender.GetMailMessageType(), sender.GetStationery(), GetMailTemplateId(), sender.GetSenderId(), receiver.GetPlayerGUIDLow(), safe_subject.c_str(), GetBodyId(), (m_items.empty() ? 0 : 1), (uint64)expire_time, (uint64)deliver_time, m_money, m_COD, checked);
|
||||||
|
|
||||||
|
for(MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
|
||||||
{
|
{
|
||||||
sLog.outError( "WorldSession::SendMailTo - Mail have not existed MailTemplateId (%u), remove at send", mailTemplateId);
|
Item* item = mailItemIter->second;
|
||||||
mailTemplateId = 0;
|
CharacterDatabase.PExecute("INSERT INTO mail_items (mail_id,item_guid,item_template,receiver) VALUES ('%u', '%u', '%u','%u')", mailId, item->GetGUIDLow(), item->GetEntry(), receiver.GetPlayerGUIDLow());
|
||||||
}
|
}
|
||||||
|
CharacterDatabase.CommitTransaction();
|
||||||
|
|
||||||
if (receiver)
|
// For online receiver update in game mail status and data
|
||||||
|
if (pReceiver)
|
||||||
{
|
{
|
||||||
receiver->AddNewMailDeliverTime(deliver_time);
|
pReceiver->AddNewMailDeliverTime(deliver_time);
|
||||||
|
|
||||||
if (receiver->IsMailsLoaded())
|
if (pReceiver->IsMailsLoaded())
|
||||||
{
|
{
|
||||||
Mail *m = new Mail;
|
Mail *m = new Mail;
|
||||||
m->messageID = mailId;
|
m->messageID = mailId;
|
||||||
m->messageType = messageType;
|
m->mailTemplateId = GetMailTemplateId();
|
||||||
m->stationery = stationery;
|
m->subject = GetSubject();
|
||||||
m->mailTemplateId = mailTemplateId;
|
m->itemTextId = GetBodyId();
|
||||||
m->sender = sender_guidlow_or_entry;
|
m->money = GetMoney();
|
||||||
m->receiver = receiver->GetGUIDLow();
|
m->COD = GetCOD();
|
||||||
m->subject = subject;
|
|
||||||
m->itemTextId = itemTextId;
|
|
||||||
|
|
||||||
if (mi)
|
for(MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
|
||||||
m->AddAllItems(*mi);
|
{
|
||||||
|
Item* item = mailItemIter->second;
|
||||||
|
m->AddItem(item->GetGUIDLow(), item->GetEntry());
|
||||||
|
}
|
||||||
|
|
||||||
|
m->messageType = sender.GetMailMessageType();
|
||||||
|
m->stationery = sender.GetStationery();
|
||||||
|
m->sender = sender.GetSenderId();
|
||||||
|
m->receiver = receiver.GetPlayerGUIDLow();
|
||||||
m->expire_time = expire_time;
|
m->expire_time = expire_time;
|
||||||
m->deliver_time = deliver_time;
|
m->deliver_time = deliver_time;
|
||||||
m->money = money;
|
|
||||||
m->COD = COD;
|
|
||||||
m->checked = checked;
|
m->checked = checked;
|
||||||
m->state = MAIL_STATE_UNCHANGED;
|
m->state = MAIL_STATE_UNCHANGED;
|
||||||
|
|
||||||
receiver->AddMail(m); // to insert new mail to beginning of maillist
|
pReceiver->AddMail(m); // to insert new mail to beginning of maillist
|
||||||
|
|
||||||
if (mi)
|
if (!m_items.empty())
|
||||||
{
|
{
|
||||||
for(MailItemMap::iterator mailItemIter = mi->begin(); mailItemIter != mi->end(); ++mailItemIter)
|
for(MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
|
||||||
{
|
pReceiver->AddMItem(mailItemIter->second);
|
||||||
MailItem& mailItem = mailItemIter->second;
|
|
||||||
if (mailItem.item)
|
|
||||||
receiver->AddMItem(mailItem.item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (!m_items.empty())
|
||||||
|
deleteIncludedItems();
|
||||||
}
|
}
|
||||||
else if (mi)
|
else if (!m_items.empty())
|
||||||
mi->deleteIncludedItems();
|
deleteIncludedItems();
|
||||||
}
|
|
||||||
else if (mi)
|
|
||||||
mi->deleteIncludedItems();
|
|
||||||
|
|
||||||
CharacterDatabase.BeginTransaction();
|
|
||||||
CharacterDatabase.escape_string(subject);
|
|
||||||
CharacterDatabase.PExecute("INSERT INTO mail (id,messageType,stationery,mailTemplateId,sender,receiver,subject,itemTextId,has_items,expire_time,deliver_time,money,cod,checked) "
|
|
||||||
"VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%s', '%u', '%u', '" UI64FMTD "','" UI64FMTD "', '%u', '%u', '%d')",
|
|
||||||
mailId, messageType, stationery, mailTemplateId, sender_guidlow_or_entry, receiver_guidlow, subject.c_str(), itemTextId, (mi && !mi->empty() ? 1 : 0), (uint64)expire_time, (uint64)deliver_time, money, COD, checked);
|
|
||||||
|
|
||||||
if (mi)
|
|
||||||
{
|
|
||||||
for(MailItemMap::const_iterator mailItemIter = mi->begin(); mailItemIter != mi->end(); ++mailItemIter)
|
|
||||||
{
|
|
||||||
MailItem const& mailItem = mailItemIter->second;
|
|
||||||
CharacterDatabase.PExecute("INSERT INTO mail_items (mail_id,item_guid,item_template,receiver) VALUES ('%u', '%u', '%u','%u')", mailId, mailItem.item_guidlow, mailItem.item_template, receiver_guidlow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CharacterDatabase.CommitTransaction();
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
152
src/game/Mail.h
152
src/game/Mail.h
|
|
@ -21,20 +21,12 @@
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
struct AuctionEntry;
|
||||||
class Item;
|
class Item;
|
||||||
|
|
||||||
#define MAIL_BODY_ITEM_TEMPLATE 8383 // - plain letter, A Dusty Unsent Letter: 889
|
#define MAIL_BODY_ITEM_TEMPLATE 8383 // - plain letter, A Dusty Unsent Letter: 889
|
||||||
#define MAX_MAIL_ITEMS 12
|
#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
|
enum MailMessageType
|
||||||
{
|
{
|
||||||
MAIL_NORMAL = 0,
|
MAIL_NORMAL = 0,
|
||||||
|
|
@ -62,16 +54,75 @@ enum MailAuctionAnswers
|
||||||
AUCTION_SALE_PENDING = 6
|
AUCTION_SALE_PENDING = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
// gathered from Stationery.dbc
|
class MailSender
|
||||||
enum MailStationery
|
|
||||||
{
|
{
|
||||||
MAIL_STATIONERY_UNKNOWN = 1,
|
public: // Constructors
|
||||||
MAIL_STATIONERY_NORMAL = 41,
|
MailSender(MailMessageType messageType, uint32 sender_guidlow_or_entry, MailStationery stationery = MAIL_STATIONERY_NORMAL)
|
||||||
MAIL_STATIONERY_GM = 61,
|
: m_messageType(messageType), m_senderId(sender_guidlow_or_entry), m_stationery(stationery)
|
||||||
MAIL_STATIONERY_AUCTION = 62,
|
{
|
||||||
MAIL_STATIONERY_VAL = 64,
|
}
|
||||||
MAIL_STATIONERY_CHR = 65,
|
MailSender(Object* sender, MailStationery stationery = MAIL_STATIONERY_NORMAL);
|
||||||
MAIL_STATIONERY_ORP = 67, // new in 3.2.2
|
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
|
struct MailItemInfo
|
||||||
|
|
@ -80,61 +131,6 @@ struct MailItemInfo
|
||||||
uint32 item_template;
|
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
|
struct Mail
|
||||||
{
|
{
|
||||||
uint32 messageID;
|
uint32 messageID;
|
||||||
|
|
@ -162,15 +158,6 @@ struct Mail
|
||||||
items.push_back(mii);
|
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)
|
bool RemoveItem(uint32 item_guid)
|
||||||
{
|
{
|
||||||
for(std::vector<MailItemInfo>::iterator itr = items.begin(); itr != items.end(); ++itr)
|
for(std::vector<MailItemInfo>::iterator itr = items.begin(); itr != items.end(); ++itr)
|
||||||
|
|
@ -186,4 +173,5 @@ struct Mail
|
||||||
|
|
||||||
bool HasItems() const { return !items.empty(); }
|
bool HasItems() const { return !items.empty(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -182,22 +182,19 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave *save,
|
||||||
Guard guard(*this);
|
Guard guard(*this);
|
||||||
|
|
||||||
// make sure we have a valid map id
|
// make sure we have a valid map id
|
||||||
const MapEntry* entry = sMapStore.LookupEntry(GetId());
|
if (!sMapStore.LookupEntry(GetId()))
|
||||||
if(!entry)
|
|
||||||
{
|
{
|
||||||
sLog.outError("CreateInstance: no entry for map %d", GetId());
|
sLog.outError("CreateInstance: no entry for map %d", GetId());
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
const InstanceTemplate * iTemplate = objmgr.GetInstanceTemplate(GetId());
|
if (!objmgr.GetInstanceTemplate(GetId()))
|
||||||
if(!iTemplate)
|
|
||||||
{
|
{
|
||||||
sLog.outError("CreateInstance: no instance template for map %d", GetId());
|
sLog.outError("CreateInstance: no instance template for map %d", GetId());
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// some instances only have one difficulty
|
// some instances only have one difficulty
|
||||||
MapDifficulty const* mapDiff = GetMapDifficultyData(GetId(),difficulty);
|
if (!GetMapDifficultyData(GetId(),difficulty))
|
||||||
if (!mapDiff)
|
|
||||||
difficulty = DUNGEON_DIFFICULTY_NORMAL;
|
difficulty = DUNGEON_DIFFICULTY_NORMAL;
|
||||||
|
|
||||||
sLog.outDebug("MapInstanced::CreateInstance: %s map instance %d for %d created with difficulty %s", save?"":"new ", InstanceId, GetId(), difficulty?"heroic":"normal");
|
sLog.outDebug("MapInstanced::CreateInstance: %s map instance %d for %d created with difficulty %s", save?"":"new ", InstanceId, GetId(), difficulty?"heroic":"normal");
|
||||||
|
|
|
||||||
|
|
@ -104,17 +104,6 @@ template<> void addUnitState(Creature *obj, CellPair const& cell_pair)
|
||||||
obj->SetCurrentCell(cell);
|
obj->SetCurrentCell(cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> bool alreadyLoaded(Map* /*map*/, uint32 /*guid*/)
|
|
||||||
{
|
|
||||||
// Non creature objects not walk by grids
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> bool alreadyLoaded<Creature>(Map* map, uint32 guid)
|
|
||||||
{
|
|
||||||
return map->GetObjectsStore().find<Creature>(guid,(Creature*)NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager<T> &m, uint32 &count, Map* map)
|
void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager<T> &m, uint32 &count, Map* map)
|
||||||
{
|
{
|
||||||
|
|
@ -124,13 +113,6 @@ void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager<T> &
|
||||||
{
|
{
|
||||||
uint32 guid = *i_guid;
|
uint32 guid = *i_guid;
|
||||||
|
|
||||||
// Note: this will fully correct work only at non-instanced maps,
|
|
||||||
// at instanced maps will use dynamic selected guid
|
|
||||||
// and then duplicate just will not detected and will be 2 creature with identical DB guid
|
|
||||||
// with some chance
|
|
||||||
if (alreadyLoaded<T>(map,guid))
|
|
||||||
continue; // still loaded in another grid (move from respawn [this] grid early), we not need second copy
|
|
||||||
|
|
||||||
T* obj = new T;
|
T* obj = new T;
|
||||||
//sLog.outString("DEBUG: LoadHelper from table: %s for (guid: %u) Loading",table,guid);
|
//sLog.outString("DEBUG: LoadHelper from table: %s for (guid: %u) Loading",table,guid);
|
||||||
if(!obj->LoadFromDB(guid, map))
|
if(!obj->LoadFromDB(guid, map))
|
||||||
|
|
|
||||||
|
|
@ -2163,6 +2163,7 @@ void ObjectMgr::LoadPetLevelInfo()
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
barGoLink bar( 1 );
|
barGoLink bar( 1 );
|
||||||
|
bar.step();
|
||||||
|
|
||||||
sLog.outString();
|
sLog.outString();
|
||||||
sLog.outString(">> Loaded %u level pet stats definitions", count);
|
sLog.outString(">> Loaded %u level pet stats definitions", count);
|
||||||
|
|
@ -3278,6 +3279,9 @@ void ObjectMgr::LoadQuests()
|
||||||
delete result;
|
delete result;
|
||||||
|
|
||||||
// Post processing
|
// Post processing
|
||||||
|
|
||||||
|
std::map<uint32,uint32> usedMailTemplates;
|
||||||
|
|
||||||
for (QuestMap::iterator iter = mQuestTemplates.begin(); iter != mQuestTemplates.end(); ++iter)
|
for (QuestMap::iterator iter = mQuestTemplates.begin(); iter != mQuestTemplates.end(); ++iter)
|
||||||
{
|
{
|
||||||
Quest * qinfo = iter->second;
|
Quest * qinfo = iter->second;
|
||||||
|
|
@ -3775,6 +3779,16 @@ void ObjectMgr::LoadQuests()
|
||||||
qinfo->RewMailTemplateId = 0; // no mail will send to player
|
qinfo->RewMailTemplateId = 0; // no mail will send to player
|
||||||
qinfo->RewMailDelaySecs = 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)
|
||||||
|
|
@ -7504,6 +7518,72 @@ bool ObjectMgr::DeleteGameTele(const std::string& name)
|
||||||
return false;
|
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()
|
void ObjectMgr::LoadTrainerSpell()
|
||||||
{
|
{
|
||||||
// For reload case
|
// For reload case
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,19 @@ struct PetLevelInfo
|
||||||
uint16 armor;
|
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
|
struct ReputationOnKillEntry
|
||||||
{
|
{
|
||||||
uint32 repfaction1;
|
uint32 repfaction1;
|
||||||
|
|
@ -515,6 +528,7 @@ class ObjectMgr
|
||||||
void LoadNpcOptionLocales();
|
void LoadNpcOptionLocales();
|
||||||
void LoadPointOfInterestLocales();
|
void LoadPointOfInterestLocales();
|
||||||
void LoadInstanceTemplate();
|
void LoadInstanceTemplate();
|
||||||
|
void LoadMailLevelRewards();
|
||||||
|
|
||||||
void LoadGossipText();
|
void LoadGossipText();
|
||||||
|
|
||||||
|
|
@ -584,6 +598,19 @@ class ObjectMgr
|
||||||
typedef std::multimap<int32, uint32> ExclusiveQuestGroups;
|
typedef std::multimap<int32, uint32> ExclusiveQuestGroups;
|
||||||
ExclusiveQuestGroups mExclusiveQuestGroups;
|
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
|
WeatherZoneChances const* GetWeatherChances(uint32 zone_id) const
|
||||||
{
|
{
|
||||||
WeatherZoneMap::const_iterator itr = mWeatherZoneMap.find(zone_id);
|
WeatherZoneMap::const_iterator itr = mWeatherZoneMap.find(zone_id);
|
||||||
|
|
@ -844,6 +871,8 @@ class ObjectMgr
|
||||||
void ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr);
|
void ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr);
|
||||||
void LoadQuestRelationsHelper(QuestRelations& map,char const* table);
|
void LoadQuestRelationsHelper(QuestRelations& map,char const* table);
|
||||||
|
|
||||||
|
MailLevelRewardMap m_mailLevelRewardMap;
|
||||||
|
|
||||||
typedef std::map<uint32,PetLevelInfo*> PetLevelInfoMap;
|
typedef std::map<uint32,PetLevelInfo*> PetLevelInfoMap;
|
||||||
// PetLevelInfoMap[creature_id][level]
|
// PetLevelInfoMap[creature_id][level]
|
||||||
PetLevelInfoMap petInfo; // [creature_id][level]
|
PetLevelInfoMap petInfo; // [creature_id][level]
|
||||||
|
|
|
||||||
|
|
@ -2452,6 +2452,9 @@ void Player::GiveLevel(uint32 level)
|
||||||
if (Pet* pet = GetPet())
|
if (Pet* pet = GetPet())
|
||||||
pet->SynchronizeLevelWithOwner();
|
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);
|
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3914,8 +3917,8 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
|
||||||
// remove signs from petitions (also remove petitions if owner);
|
// remove signs from petitions (also remove petitions if owner);
|
||||||
RemovePetitionsAndSigns(playerguid, 10);
|
RemovePetitionsAndSigns(playerguid, 10);
|
||||||
|
|
||||||
// return back all mails with COD and Item 0 1 2 3 4 5 6
|
// return back all mails with COD and Item 0 1 2 3 4 5 6 7
|
||||||
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);
|
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)
|
if(resultMail)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
|
|
@ -3923,18 +3926,30 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
|
||||||
Field *fields = resultMail->Fetch();
|
Field *fields = resultMail->Fetch();
|
||||||
|
|
||||||
uint32 mail_id = fields[0].GetUInt32();
|
uint32 mail_id = fields[0].GetUInt32();
|
||||||
uint16 mailTemplateId= fields[1].GetUInt16();
|
uint16 mailType = fields[1].GetUInt16();
|
||||||
uint32 sender = fields[2].GetUInt32();
|
uint16 mailTemplateId= fields[2].GetUInt16();
|
||||||
std::string subject = fields[3].GetCppString();
|
uint32 sender = fields[3].GetUInt32();
|
||||||
uint32 itemTextId = fields[4].GetUInt32();
|
std::string subject = fields[4].GetCppString();
|
||||||
uint32 money = fields[5].GetUInt32();
|
uint32 itemTextId = fields[5].GetUInt32();
|
||||||
bool has_items = fields[6].GetBool();
|
uint32 money = fields[6].GetUInt32();
|
||||||
|
bool has_items = fields[7].GetBool();
|
||||||
|
|
||||||
//we can return mail now
|
//we can return mail now
|
||||||
//so firstly delete the old one
|
//so firstly delete the old one
|
||||||
CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", mail_id);
|
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)
|
if(has_items)
|
||||||
{
|
{
|
||||||
// data needs to be at first place for Item::LoadFromDB
|
// data needs to be at first place for Item::LoadFromDB
|
||||||
|
|
@ -3963,7 +3978,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
mi.AddItem(item_guidlow, item_template, pItem);
|
draft.AddItem(pItem);
|
||||||
}
|
}
|
||||||
while (resultItems->NextRow());
|
while (resultItems->NextRow());
|
||||||
|
|
||||||
|
|
@ -3975,7 +3990,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
|
||||||
|
|
||||||
uint32 pl_account = objmgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER));
|
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());
|
while (resultMail->NextRow());
|
||||||
|
|
||||||
|
|
@ -4816,56 +4831,6 @@ float Player::GetRatingBonusValue(CombatRating cr) const
|
||||||
return float(GetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr)) / GetRatingCoefficient(cr);
|
return float(GetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr)) / GetRatingCoefficient(cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Player::GetMeleeCritDamageReduction(uint32 damage) const
|
|
||||||
{
|
|
||||||
float melee = GetRatingBonusValue(CR_CRIT_TAKEN_MELEE)*2.2f;
|
|
||||||
if (melee>33.0f) melee = 33.0f;
|
|
||||||
return uint32 (melee * damage /100.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 Player::GetMeleeDamageReduction(uint32 damage) const
|
|
||||||
{
|
|
||||||
float rate = GetRatingBonusValue(CR_CRIT_TAKEN_MELEE);
|
|
||||||
// Resilience not limited (limit it by 100%)
|
|
||||||
if (rate > 100.0f)
|
|
||||||
rate = 100.0f;
|
|
||||||
return uint32 (rate * damage / 100.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 Player::GetRangedCritDamageReduction(uint32 damage) const
|
|
||||||
{
|
|
||||||
float ranged = GetRatingBonusValue(CR_CRIT_TAKEN_RANGED)*2.2f;
|
|
||||||
if (ranged>33.0f) ranged=33.0f;
|
|
||||||
return uint32 (ranged * damage /100.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 Player::GetRangedDamageReduction(uint32 damage) const
|
|
||||||
{
|
|
||||||
float rate = GetRatingBonusValue(CR_CRIT_TAKEN_RANGED);
|
|
||||||
// Resilience not limited (limit it by 100%)
|
|
||||||
if (rate > 100.0f)
|
|
||||||
rate = 100.0f;
|
|
||||||
return uint32 (rate * damage / 100.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 Player::GetSpellCritDamageReduction(uint32 damage) const
|
|
||||||
{
|
|
||||||
float spell = GetRatingBonusValue(CR_CRIT_TAKEN_SPELL)*2.2f;
|
|
||||||
// In wow script resilience limited to 33%
|
|
||||||
if (spell>33.0f)
|
|
||||||
spell = 33.0f;
|
|
||||||
return uint32 (spell * damage / 100.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 Player::GetSpellDamageReduction(uint32 damage) const
|
|
||||||
{
|
|
||||||
float rate = GetRatingBonusValue(CR_CRIT_TAKEN_SPELL);
|
|
||||||
// Resilience not limited (limit it by 100%)
|
|
||||||
if (rate > 100.0f)
|
|
||||||
rate = 100.0f;
|
|
||||||
return uint32 (rate * damage / 100.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
float Player::GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const
|
float Player::GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const
|
||||||
{
|
{
|
||||||
switch (attType)
|
switch (attType)
|
||||||
|
|
@ -5952,7 +5917,7 @@ void Player::RewardReputation(Quest const *pQuest)
|
||||||
{
|
{
|
||||||
if(pQuest->RewRepFaction[i] && pQuest->RewRepValue[i] )
|
if(pQuest->RewRepFaction[i] && pQuest->RewRepValue[i] )
|
||||||
{
|
{
|
||||||
int32 rep = CalculateReputationGain(GetQuestLevel(pQuest), pQuest->RewRepValue[i], pQuest->RewRepFaction[i], true);
|
int32 rep = CalculateReputationGain(GetQuestLevelForPlayer(pQuest), pQuest->RewRepValue[i], pQuest->RewRepFaction[i], true);
|
||||||
FactionEntry const* factionEntry = sFactionStore.LookupEntry(pQuest->RewRepFaction[i]);
|
FactionEntry const* factionEntry = sFactionStore.LookupEntry(pQuest->RewRepFaction[i]);
|
||||||
if(factionEntry)
|
if(factionEntry)
|
||||||
GetReputationMgr().ModifyReputation(factionEntry, rep);
|
GetReputationMgr().ModifyReputation(factionEntry, rep);
|
||||||
|
|
@ -12764,56 +12729,8 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send reward mail
|
// Send reward mail
|
||||||
if (pQuest->GetRewMailTemplateId())
|
if (uint32 mail_template_id = pQuest->GetRewMailTemplateId())
|
||||||
{
|
MailDraft(mail_template_id).SendMailTo(this, questGiver, MAIL_CHECK_MASK_NONE, pQuest->GetRewMailDelaySecs());
|
||||||
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 (pQuest->IsDaily())
|
if (pQuest->IsDaily())
|
||||||
{
|
{
|
||||||
|
|
@ -15040,20 +14957,20 @@ void Player::_LoadInventory(QueryResult *result, uint32 timediff)
|
||||||
// send by mail problematic items
|
// send by mail problematic items
|
||||||
while(!problematicItems.empty())
|
while(!problematicItems.empty())
|
||||||
{
|
{
|
||||||
|
std::string subject = GetSession()->GetMangosString(LANG_NOT_EQUIPPED_ITEM);
|
||||||
|
|
||||||
// fill mail
|
// fill mail
|
||||||
MailItemsInfo mi; // item list preparing
|
MailDraft draft(subject);
|
||||||
|
|
||||||
for(int i = 0; !problematicItems.empty() && i < MAX_MAIL_ITEMS; ++i)
|
for(int i = 0; !problematicItems.empty() && i < MAX_MAIL_ITEMS; ++i)
|
||||||
{
|
{
|
||||||
Item* item = problematicItems.front();
|
Item* item = problematicItems.front();
|
||||||
problematicItems.pop_front();
|
problematicItems.pop_front();
|
||||||
|
|
||||||
mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
|
draft.AddItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string subject = GetSession()->GetMangosString(LANG_NOT_EQUIPPED_ITEM);
|
draft.SendMailTo(this, MailSender(this, MAIL_STATIONERY_GM));
|
||||||
|
|
||||||
WorldSession::SendMailTo(this, MAIL_NORMAL, MAIL_STATIONERY_GM, GetGUIDLow(), GetGUIDLow(), subject, 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if(isAlive())
|
//if(isAlive())
|
||||||
|
|
@ -18921,8 +18838,6 @@ void Player::AutoUnequipOffhandIfNeed()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MailItemsInfo mi;
|
|
||||||
mi.AddItem(offItem->GetGUIDLow(), offItem->GetEntry(), offItem);
|
|
||||||
MoveItemFromInventory(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND, true);
|
MoveItemFromInventory(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND, true);
|
||||||
CharacterDatabase.BeginTransaction();
|
CharacterDatabase.BeginTransaction();
|
||||||
offItem->DeleteFromInventoryDB(); // deletes item from character's inventory
|
offItem->DeleteFromInventoryDB(); // deletes item from character's inventory
|
||||||
|
|
@ -18930,7 +18845,7 @@ void Player::AutoUnequipOffhandIfNeed()
|
||||||
CharacterDatabase.CommitTransaction();
|
CharacterDatabase.CommitTransaction();
|
||||||
|
|
||||||
std::string subject = GetSession()->GetMangosString(LANG_NOT_EQUIPPED_ITEM);
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1281,7 +1281,8 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
/*** QUEST SYSTEM ***/
|
/*** QUEST SYSTEM ***/
|
||||||
/*********************************************************/
|
/*********************************************************/
|
||||||
|
|
||||||
uint32 GetQuestLevel( Quest const* pQuest ) const { return pQuest && pQuest->GetQuestLevel() ? pQuest->GetQuestLevel() : getLevel(); }
|
// Return player level when QuestLevel is dynamic (-1)
|
||||||
|
uint32 GetQuestLevelForPlayer(Quest const* pQuest) const { return pQuest && (pQuest->GetQuestLevel() > 0) ? (uint32)pQuest->GetQuestLevel() : getLevel(); }
|
||||||
|
|
||||||
void PrepareQuestMenu( uint64 guid );
|
void PrepareQuestMenu( uint64 guid );
|
||||||
void SendPreparedQuest( uint64 guid );
|
void SendPreparedQuest( uint64 guid );
|
||||||
|
|
@ -1298,6 +1299,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
void CompleteQuest( uint32 quest_id );
|
void CompleteQuest( uint32 quest_id );
|
||||||
void IncompleteQuest( uint32 quest_id );
|
void IncompleteQuest( uint32 quest_id );
|
||||||
void RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver, bool announce = true );
|
void RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver, bool announce = true );
|
||||||
|
|
||||||
void FailQuest( uint32 quest_id );
|
void FailQuest( uint32 quest_id );
|
||||||
bool SatisfyQuestSkillOrClass( Quest const* qInfo, bool msg );
|
bool SatisfyQuestSkillOrClass( Quest const* qInfo, bool msg );
|
||||||
bool SatisfyQuestLevel( Quest const* qInfo, bool msg );
|
bool SatisfyQuestLevel( Quest const* qInfo, bool msg );
|
||||||
|
|
@ -1731,12 +1733,6 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
float OCTRegenMPPerSpirit();
|
float OCTRegenMPPerSpirit();
|
||||||
float GetRatingCoefficient(CombatRating cr) const;
|
float GetRatingCoefficient(CombatRating cr) const;
|
||||||
float GetRatingBonusValue(CombatRating cr) const;
|
float GetRatingBonusValue(CombatRating cr) const;
|
||||||
uint32 GetMeleeCritDamageReduction(uint32 damage) const;
|
|
||||||
uint32 GetMeleeDamageReduction(uint32 damage) const;
|
|
||||||
uint32 GetRangedCritDamageReduction(uint32 damage) const;
|
|
||||||
uint32 GetRangedDamageReduction(uint32 damage) const;
|
|
||||||
uint32 GetSpellCritDamageReduction(uint32 damage) const;
|
|
||||||
uint32 GetSpellDamageReduction(uint32 damage) const;
|
|
||||||
uint32 GetBaseSpellPowerBonus() { return m_baseSpellPower; }
|
uint32 GetBaseSpellPowerBonus() { return m_baseSpellPower; }
|
||||||
|
|
||||||
float GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const;
|
float GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const;
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ Quest::Quest(Field * questRecord)
|
||||||
ZoneOrSort = questRecord[2].GetInt32();
|
ZoneOrSort = questRecord[2].GetInt32();
|
||||||
SkillOrClass = questRecord[3].GetInt32();
|
SkillOrClass = questRecord[3].GetInt32();
|
||||||
MinLevel = questRecord[4].GetUInt32();
|
MinLevel = questRecord[4].GetUInt32();
|
||||||
QuestLevel = questRecord[5].GetUInt32();
|
QuestLevel = questRecord[5].GetInt32();
|
||||||
Type = questRecord[6].GetUInt32();
|
Type = questRecord[6].GetUInt32();
|
||||||
RequiredRaces = questRecord[7].GetUInt32();
|
RequiredRaces = questRecord[7].GetUInt32();
|
||||||
RequiredSkillValue = questRecord[8].GetUInt32();
|
RequiredSkillValue = questRecord[8].GetUInt32();
|
||||||
|
|
@ -169,7 +169,7 @@ uint32 Quest::XPValue( Player *pPlayer ) const
|
||||||
if( RewMoneyMaxLevel > 0 )
|
if( RewMoneyMaxLevel > 0 )
|
||||||
{
|
{
|
||||||
uint32 pLevel = pPlayer->getLevel();
|
uint32 pLevel = pPlayer->getLevel();
|
||||||
uint32 qLevel = QuestLevel;
|
uint32 qLevel = QuestLevel > 0 ? (uint32)QuestLevel : 0;
|
||||||
float fullxp = 0;
|
float fullxp = 0;
|
||||||
if (qLevel >= 15)
|
if (qLevel >= 15)
|
||||||
fullxp = RewMoneyMaxLevel / 6.0f;
|
fullxp = RewMoneyMaxLevel / 6.0f;
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ class Quest
|
||||||
int32 GetZoneOrSort() const { return ZoneOrSort; }
|
int32 GetZoneOrSort() const { return ZoneOrSort; }
|
||||||
int32 GetSkillOrClass() const { return SkillOrClass; }
|
int32 GetSkillOrClass() const { return SkillOrClass; }
|
||||||
uint32 GetMinLevel() const { return MinLevel; }
|
uint32 GetMinLevel() const { return MinLevel; }
|
||||||
uint32 GetQuestLevel() const { return QuestLevel; }
|
int32 GetQuestLevel() const { return QuestLevel; }
|
||||||
uint32 GetType() const { return Type; }
|
uint32 GetType() const { return Type; }
|
||||||
uint32 GetRequiredRaces() const { return RequiredRaces; }
|
uint32 GetRequiredRaces() const { return RequiredRaces; }
|
||||||
uint32 GetRequiredSkillValue() const { return RequiredSkillValue; }
|
uint32 GetRequiredSkillValue() const { return RequiredSkillValue; }
|
||||||
|
|
@ -274,7 +274,7 @@ class Quest
|
||||||
int32 ZoneOrSort;
|
int32 ZoneOrSort;
|
||||||
int32 SkillOrClass;
|
int32 SkillOrClass;
|
||||||
uint32 MinLevel;
|
uint32 MinLevel;
|
||||||
uint32 QuestLevel;
|
int32 QuestLevel;
|
||||||
uint32 Type;
|
uint32 Type;
|
||||||
uint32 RequiredRaces;
|
uint32 RequiredRaces;
|
||||||
uint32 RequiredSkillValue;
|
uint32 RequiredSkillValue;
|
||||||
|
|
|
||||||
|
|
@ -606,7 +606,7 @@ uint32 WorldSession::getDialogStatus(Player *pPlayer, Object* questgiver, uint32
|
||||||
{
|
{
|
||||||
if ( pQuest->IsAutoComplete() || (pQuest->IsRepeatable() && pPlayer->getQuestStatusMap()[quest_id].m_rewarded))
|
if ( pQuest->IsAutoComplete() || (pQuest->IsRepeatable() && pPlayer->getQuestStatusMap()[quest_id].m_rewarded))
|
||||||
result2 = DIALOG_STATUS_REWARD_REP;
|
result2 = DIALOG_STATUS_REWARD_REP;
|
||||||
else if (pPlayer->getLevel() <= pPlayer->GetQuestLevel(pQuest) + sWorld.getConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF) )
|
else if (pPlayer->getLevel() <= pPlayer->GetQuestLevelForPlayer(pQuest) + sWorld.getConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF) )
|
||||||
{
|
{
|
||||||
if (pQuest->HasFlag(QUEST_FLAGS_DAILY))
|
if (pQuest->HasFlag(QUEST_FLAGS_DAILY))
|
||||||
result2 = DIALOG_STATUS_AVAILABLE_REP;
|
result2 = DIALOG_STATUS_AVAILABLE_REP;
|
||||||
|
|
|
||||||
|
|
@ -2387,10 +2387,10 @@ enum PetDiet
|
||||||
#define CHAIN_SPELL_JUMP_RADIUS 10
|
#define CHAIN_SPELL_JUMP_RADIUS 10
|
||||||
|
|
||||||
// Max values for Guild & Guild Bank
|
// Max values for Guild & Guild Bank
|
||||||
#define GUILD_BANK_MAX_TABS 6
|
#define GUILD_BANK_MAX_TABS 6 // send by client for money log also
|
||||||
#define GUILD_BANK_MAX_SLOTS 98
|
#define GUILD_BANK_MAX_SLOTS 98
|
||||||
#define GUILD_BANK_MAX_LOGS 25
|
#define GUILD_BANK_MAX_LOGS 25
|
||||||
#define GUILD_BANK_MONEY_LOGS_TAB 100
|
#define GUILD_BANK_MONEY_LOGS_TAB 100 // used for money log in DB
|
||||||
#define GUILD_EVENTLOG_MAX_RECORDS 100
|
#define GUILD_EVENTLOG_MAX_RECORDS 100
|
||||||
#define GUILD_RANKS_MIN_COUNT 5
|
#define GUILD_RANKS_MIN_COUNT 5
|
||||||
#define GUILD_RANKS_MAX_COUNT 10
|
#define GUILD_RANKS_MAX_COUNT 10
|
||||||
|
|
@ -2620,6 +2620,27 @@ enum BattleGroundTypeId
|
||||||
};
|
};
|
||||||
#define MAX_BATTLEGROUND_TYPE_ID 33
|
#define MAX_BATTLEGROUND_TYPE_ID 33
|
||||||
|
|
||||||
|
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,
|
||||||
|
MAIL_STATIONERY_ORP = 67, // new in 3.2.2
|
||||||
|
};
|
||||||
|
|
||||||
enum MailResponseType
|
enum MailResponseType
|
||||||
{
|
{
|
||||||
MAIL_SEND = 0,
|
MAIL_SEND = 0,
|
||||||
|
|
|
||||||
|
|
@ -6382,12 +6382,12 @@ void Aura::PeriodicTick()
|
||||||
if (isCrit)
|
if (isCrit)
|
||||||
cleanDamage.hitOutCome = MELEE_HIT_CRIT;
|
cleanDamage.hitOutCome = MELEE_HIT_CRIT;
|
||||||
|
|
||||||
// Reduce dot damage from resilience for players.
|
// only from players
|
||||||
// FIXME: need use SpellDamageBonus instead?
|
// FIXME: need use SpellDamageBonus instead?
|
||||||
if (m_target->GetTypeId() == TYPEID_PLAYER)
|
if (IS_PLAYER_GUID(m_caster_guid))
|
||||||
pdamage-=((Player*)m_target)->GetSpellDamageReduction(pdamage);
|
pdamage -= m_target->GetSpellDamageReduction(pdamage);
|
||||||
|
|
||||||
pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist);
|
pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist, !(GetSpellProto()->AttributesEx2 & SPELL_ATTR_EX2_CANT_REFLECTED));
|
||||||
|
|
||||||
sLog.outDetail("PeriodicTick: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
|
sLog.outDetail("PeriodicTick: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
|
||||||
GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb);
|
GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb);
|
||||||
|
|
@ -6442,7 +6442,7 @@ void Aura::PeriodicTick()
|
||||||
|
|
||||||
pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount());
|
pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount());
|
||||||
|
|
||||||
pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist);
|
pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist, !(GetSpellProto()->AttributesEx2 & SPELL_ATTR_EX2_CANT_REFLECTED));
|
||||||
|
|
||||||
if(m_target->GetHealth() < pdamage)
|
if(m_target->GetHealth() < pdamage)
|
||||||
pdamage = uint32(m_target->GetHealth());
|
pdamage = uint32(m_target->GetHealth());
|
||||||
|
|
@ -6609,8 +6609,8 @@ void Aura::PeriodicTick()
|
||||||
int32 drain_amount = m_target->GetPower(power) > pdamage ? pdamage : m_target->GetPower(power);
|
int32 drain_amount = m_target->GetPower(power) > pdamage ? pdamage : m_target->GetPower(power);
|
||||||
|
|
||||||
// resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
|
// resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
|
||||||
if (power == POWER_MANA && m_target->GetTypeId() == TYPEID_PLAYER)
|
if (power == POWER_MANA)
|
||||||
drain_amount -= ((Player*)m_target)->GetSpellCritDamageReduction(drain_amount);
|
drain_amount -= m_target->GetSpellCritDamageReduction(drain_amount);
|
||||||
|
|
||||||
m_target->ModifyPower(power, -drain_amount);
|
m_target->ModifyPower(power, -drain_amount);
|
||||||
|
|
||||||
|
|
@ -6701,8 +6701,8 @@ void Aura::PeriodicTick()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
|
// resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
|
||||||
if (powerType == POWER_MANA && m_target->GetTypeId() == TYPEID_PLAYER)
|
if (powerType == POWER_MANA)
|
||||||
pdamage -= ((Player*)m_target)->GetSpellCritDamageReduction(pdamage);
|
pdamage -= m_target->GetSpellCritDamageReduction(pdamage);
|
||||||
|
|
||||||
uint32 gain = uint32(-m_target->ModifyPower(powerType, -pdamage));
|
uint32 gain = uint32(-m_target->ModifyPower(powerType, -pdamage));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2486,8 +2486,8 @@ void Spell::EffectPowerDrain(uint32 i)
|
||||||
|
|
||||||
// resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
|
// resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
|
||||||
uint32 power = damage;
|
uint32 power = damage;
|
||||||
if ( drain_power == POWER_MANA && unitTarget->GetTypeId() == TYPEID_PLAYER )
|
if (drain_power == POWER_MANA)
|
||||||
power -= ((Player*)unitTarget)->GetSpellCritDamageReduction(power);
|
power -= unitTarget->GetSpellCritDamageReduction(power);
|
||||||
|
|
||||||
int32 new_damage;
|
int32 new_damage;
|
||||||
if(curPower < power)
|
if(curPower < power)
|
||||||
|
|
@ -2550,8 +2550,8 @@ void Spell::EffectPowerBurn(uint32 i)
|
||||||
|
|
||||||
// resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
|
// resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
|
||||||
uint32 power = damage;
|
uint32 power = damage;
|
||||||
if (powertype == POWER_MANA && unitTarget->GetTypeId() == TYPEID_PLAYER)
|
if (powertype == POWER_MANA)
|
||||||
power -= ((Player*)unitTarget)->GetSpellCritDamageReduction(power);
|
power -= unitTarget->GetSpellCritDamageReduction(power);
|
||||||
|
|
||||||
int32 new_damage = (curPower < power) ? curPower : power;
|
int32 new_damage = (curPower < power) ? curPower : power;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1060,11 +1060,11 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, S
|
||||||
damageInfo->HitInfo|= SPELL_HIT_TYPE_CRIT;
|
damageInfo->HitInfo|= SPELL_HIT_TYPE_CRIT;
|
||||||
damage = SpellCriticalDamageBonus(spellInfo, damage, pVictim);
|
damage = SpellCriticalDamageBonus(spellInfo, damage, pVictim);
|
||||||
// Resilience - reduce crit damage
|
// Resilience - reduce crit damage
|
||||||
if (pVictim->GetTypeId()==TYPEID_PLAYER)
|
|
||||||
{
|
|
||||||
uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageSchoolMask);
|
uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageSchoolMask);
|
||||||
damage -= ((Player*)pVictim)->GetMeleeCritDamageReduction(redunction_affected_damage);
|
if (attackType != RANGED_ATTACK)
|
||||||
}
|
damage -= pVictim->GetMeleeCritDamageReduction(redunction_affected_damage);
|
||||||
|
else
|
||||||
|
damage -= pVictim->GetRangedCritDamageReduction(redunction_affected_damage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -1080,20 +1080,18 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, S
|
||||||
damageInfo->HitInfo|= SPELL_HIT_TYPE_CRIT;
|
damageInfo->HitInfo|= SPELL_HIT_TYPE_CRIT;
|
||||||
damage = SpellCriticalDamageBonus(spellInfo, damage, pVictim);
|
damage = SpellCriticalDamageBonus(spellInfo, damage, pVictim);
|
||||||
// Resilience - reduce crit damage
|
// Resilience - reduce crit damage
|
||||||
if (pVictim->GetTypeId()==TYPEID_PLAYER)
|
|
||||||
{
|
|
||||||
uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageSchoolMask);
|
uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageSchoolMask);
|
||||||
damage -= ((Player*)pVictim)->GetSpellCritDamageReduction(redunction_affected_damage);
|
damage -= pVictim->GetSpellCritDamageReduction(redunction_affected_damage);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER)
|
// only from players
|
||||||
|
if (GetTypeId() == TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageSchoolMask);
|
uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageSchoolMask);
|
||||||
damage -= ((Player*)pVictim)->GetSpellDamageReduction(redunction_affected_damage);
|
damage -= pVictim->GetSpellDamageReduction(redunction_affected_damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// damage mitigation
|
// damage mitigation
|
||||||
|
|
@ -1116,7 +1114,7 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, S
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 absorb_affected_damage = CalcNotIgnoreAbsorbDamage(damage,damageSchoolMask,spellInfo);
|
uint32 absorb_affected_damage = CalcNotIgnoreAbsorbDamage(damage,damageSchoolMask,spellInfo);
|
||||||
CalcAbsorbResist(pVictim, damageSchoolMask, SPELL_DIRECT_DAMAGE, absorb_affected_damage, &damageInfo->absorb, &damageInfo->resist);
|
CalcAbsorbResist(pVictim, damageSchoolMask, SPELL_DIRECT_DAMAGE, absorb_affected_damage, &damageInfo->absorb, &damageInfo->resist, !(spellInfo->AttributesEx2 & SPELL_ATTR_EX2_CANT_REFLECTED));
|
||||||
damage-= damageInfo->absorb + damageInfo->resist;
|
damage-= damageInfo->absorb + damageInfo->resist;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -1286,13 +1284,15 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da
|
||||||
damageInfo->damage = int32((damageInfo->damage) * float((100.0f + mod)/100.0f));
|
damageInfo->damage = int32((damageInfo->damage) * float((100.0f + mod)/100.0f));
|
||||||
|
|
||||||
// Resilience - reduce crit damage
|
// Resilience - reduce crit damage
|
||||||
if (pVictim->GetTypeId()==TYPEID_PLAYER)
|
|
||||||
{
|
|
||||||
uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damageInfo->damage,damageInfo->damageSchoolMask);
|
uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damageInfo->damage,damageInfo->damageSchoolMask);
|
||||||
uint32 resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(redunction_affected_damage);
|
uint32 resilienceReduction;
|
||||||
|
if (attackType != RANGED_ATTACK)
|
||||||
|
resilienceReduction = pVictim->GetMeleeCritDamageReduction(redunction_affected_damage);
|
||||||
|
else
|
||||||
|
resilienceReduction = pVictim->GetRangedCritDamageReduction(redunction_affected_damage);
|
||||||
|
|
||||||
damageInfo->damage -= resilienceReduction;
|
damageInfo->damage -= resilienceReduction;
|
||||||
damageInfo->cleanDamage += resilienceReduction;
|
damageInfo->cleanDamage += resilienceReduction;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MELEE_HIT_PARRY:
|
case MELEE_HIT_PARRY:
|
||||||
|
|
@ -1391,13 +1391,14 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER)
|
// only from players
|
||||||
|
if (GetTypeId() == TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageInfo->damageSchoolMask);
|
uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageInfo->damageSchoolMask);
|
||||||
if (attackType != RANGED_ATTACK)
|
if (attackType != RANGED_ATTACK)
|
||||||
damage-=((Player*)pVictim)->GetMeleeDamageReduction(redunction_affected_damage);
|
damage -= pVictim->GetMeleeDamageReduction(redunction_affected_damage);
|
||||||
else
|
else
|
||||||
damage-=((Player*)pVictim)->GetRangedDamageReduction(redunction_affected_damage);
|
damage -= pVictim->GetRangedDamageReduction(redunction_affected_damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate absorb resist
|
// Calculate absorb resist
|
||||||
|
|
@ -1407,7 +1408,7 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da
|
||||||
|
|
||||||
// Calculate absorb & resists
|
// Calculate absorb & resists
|
||||||
uint32 absorb_affected_damage = CalcNotIgnoreAbsorbDamage(damageInfo->damage,damageInfo->damageSchoolMask);
|
uint32 absorb_affected_damage = CalcNotIgnoreAbsorbDamage(damageInfo->damage,damageInfo->damageSchoolMask);
|
||||||
CalcAbsorbResist(damageInfo->target, damageInfo->damageSchoolMask, DIRECT_DAMAGE, absorb_affected_damage, &damageInfo->absorb, &damageInfo->resist);
|
CalcAbsorbResist(damageInfo->target, damageInfo->damageSchoolMask, DIRECT_DAMAGE, absorb_affected_damage, &damageInfo->absorb, &damageInfo->resist, true);
|
||||||
damageInfo->damage-=damageInfo->absorb + damageInfo->resist;
|
damageInfo->damage-=damageInfo->absorb + damageInfo->resist;
|
||||||
if (damageInfo->absorb)
|
if (damageInfo->absorb)
|
||||||
{
|
{
|
||||||
|
|
@ -1627,7 +1628,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit* pVictim, const uint32 damage)
|
||||||
return (newdamage > 1) ? newdamage : 1;
|
return (newdamage > 1) ? newdamage : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist)
|
void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist, bool canReflect)
|
||||||
{
|
{
|
||||||
if(!pVictim || !pVictim->isAlive() || !damage)
|
if(!pVictim || !pVictim->isAlive() || !damage)
|
||||||
return;
|
return;
|
||||||
|
|
@ -1731,7 +1732,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Reflective Shield (Lady Malande boss)
|
// Reflective Shield (Lady Malande boss)
|
||||||
if (spellProto->Id == 41475)
|
if (spellProto->Id == 41475 && canReflect)
|
||||||
{
|
{
|
||||||
if(RemainingDamage < currentAbsorb)
|
if(RemainingDamage < currentAbsorb)
|
||||||
reflectDamage = RemainingDamage / 2;
|
reflectDamage = RemainingDamage / 2;
|
||||||
|
|
@ -1789,7 +1790,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reflective Shield
|
// Reflective Shield
|
||||||
if (spellProto->SpellFamilyFlags == 0x1)
|
if (spellProto->SpellFamilyFlags == 0x1 && canReflect)
|
||||||
{
|
{
|
||||||
if (pVictim == this)
|
if (pVictim == this)
|
||||||
break;
|
break;
|
||||||
|
|
@ -1911,7 +1912,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cast back reflect damage spell
|
// Cast back reflect damage spell
|
||||||
if (reflectSpell)
|
if (canReflect && reflectSpell)
|
||||||
pVictim->CastCustomSpell(this, reflectSpell, &reflectDamage, NULL, NULL, true, NULL, reflectTriggeredBy);
|
pVictim->CastCustomSpell(this, reflectSpell, &reflectDamage, NULL, NULL, true, NULL, reflectTriggeredBy);
|
||||||
|
|
||||||
// absorb by mana cost
|
// absorb by mana cost
|
||||||
|
|
@ -2941,13 +2942,10 @@ float Unit::GetUnitCriticalChance(WeaponAttackType attackType, const Unit *pVict
|
||||||
crit += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE);
|
crit += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE);
|
||||||
|
|
||||||
// reduce crit chance from Rating for players
|
// reduce crit chance from Rating for players
|
||||||
if (pVictim->GetTypeId()==TYPEID_PLAYER)
|
if (attackType != RANGED_ATTACK)
|
||||||
{
|
crit -= pVictim->GetMeleeCritChanceReduction();
|
||||||
if (attackType==RANGED_ATTACK)
|
|
||||||
crit -= ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_RANGED);
|
|
||||||
else
|
else
|
||||||
crit -= ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_MELEE);
|
crit -= pVictim->GetRangedCritChanceReduction();
|
||||||
}
|
|
||||||
|
|
||||||
// Apply crit chance from defence skill
|
// Apply crit chance from defence skill
|
||||||
crit += (int32(GetMaxSkillValueForLevel(pVictim)) - int32(pVictim->GetDefenseSkillValue(this))) * 0.04f;
|
crit += (int32(GetMaxSkillValueForLevel(pVictim)) - int32(pVictim->GetDefenseSkillValue(this))) * 0.04f;
|
||||||
|
|
@ -8622,8 +8620,7 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
|
||||||
// Modify critical chance by victim SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE
|
// Modify critical chance by victim SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE
|
||||||
crit_chance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE);
|
crit_chance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE);
|
||||||
// Modify by player victim resilience
|
// Modify by player victim resilience
|
||||||
if (pVictim->GetTypeId() == TYPEID_PLAYER)
|
crit_chance -= pVictim->GetSpellCritChanceReduction();
|
||||||
crit_chance -= ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_SPELL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// scripted (increase crit chance ... against ... target by x%)
|
// scripted (increase crit chance ... against ... target by x%)
|
||||||
|
|
@ -9626,7 +9623,8 @@ bool Unit::isTargetableForAttack(bool inverseAlive /*=false*/) const
|
||||||
if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE))
|
if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ((isAlive() && !isInvisibleForAlive()) == inverseAlive)
|
// inversealive is needed for some spells which need to be casted at dead targets (aoe)
|
||||||
|
if (isAlive() == inverseAlive)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return IsInWorld() && !hasUnitState(UNIT_STAT_DIED) && !isInFlight();
|
return IsInWorld() && !hasUnitState(UNIT_STAT_DIED) && !isInFlight();
|
||||||
|
|
@ -9788,8 +9786,11 @@ bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u->isAlive() && isInvisibleForAlive())
|
// isInvisibleForAlive() those units can only be seen by dead or if other
|
||||||
if (u->GetTypeId() == TYPEID_PLAYER && !((Player *)u)->isGameMaster())
|
// unit is also invisible for alive.. if an isinvisibleforalive unit dies we
|
||||||
|
// should be able to see it too
|
||||||
|
if (u->isAlive() && isAlive() && isInvisibleForAlive() != u->isInvisibleForAlive())
|
||||||
|
if (u->GetTypeId() != TYPEID_PLAYER || !((Player *)u)->isGameMaster())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Visible units, always are visible for all units, except for units under invisibility and phases
|
// Visible units, always are visible for all units, except for units under invisibility and phases
|
||||||
|
|
@ -12631,3 +12632,26 @@ void Unit::KnockBackFrom(Unit* target, float horizintalSpeed, float verticalSpee
|
||||||
NearTeleportTo(fx, fy, fz, GetOrientation(), this == target);
|
NearTeleportTo(fx, fy, fz, GetOrientation(), this == target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Unit::GetCombatRatingReduction(CombatRating cr) const
|
||||||
|
{
|
||||||
|
if (GetTypeId() == TYPEID_PLAYER)
|
||||||
|
return ((Player const*)this)->GetRatingBonusValue(cr);
|
||||||
|
else if (((Creature const*)this)->isPet())
|
||||||
|
{
|
||||||
|
// Player's pet have 0.4 resilience from owner
|
||||||
|
if (Unit* owner = GetOwner())
|
||||||
|
if(owner->GetTypeId() == TYPEID_PLAYER)
|
||||||
|
return ((Player*)owner)->GetRatingBonusValue(cr) * 0.4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Unit::GetCombatRatingDamageReduction(CombatRating cr, float rate, float cap, uint32 damage) const
|
||||||
|
{
|
||||||
|
float percent = GetCombatRatingReduction(cr) * rate;
|
||||||
|
if (percent > cap)
|
||||||
|
percent = cap;
|
||||||
|
return uint32 (percent * damage / 100.0f);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1034,6 +1034,21 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||||
void CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType = BASE_ATTACK);
|
void CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType = BASE_ATTACK);
|
||||||
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss);
|
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss);
|
||||||
|
|
||||||
|
// player or player's pet resilience (-1%)
|
||||||
|
float GetMeleeCritChanceReduction() const { return GetCombatRatingReduction(CR_CRIT_TAKEN_MELEE); }
|
||||||
|
float GetRangedCritChanceReduction() const { return GetCombatRatingReduction(CR_CRIT_TAKEN_RANGED); }
|
||||||
|
float GetSpellCritChanceReduction() const { return GetCombatRatingReduction(CR_CRIT_TAKEN_SPELL); }
|
||||||
|
|
||||||
|
// player or player's pet resilience (-1%)
|
||||||
|
uint32 GetMeleeCritDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_MELEE, 2.2f, 33.0f, damage); }
|
||||||
|
uint32 GetRangedCritDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_RANGED, 2.2f, 33.0f, damage); }
|
||||||
|
uint32 GetSpellCritDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_SPELL, 2.2f, 33.0f, damage); }
|
||||||
|
|
||||||
|
// player or player's pet resilience (-1%), cap 100%
|
||||||
|
uint32 GetMeleeDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_MELEE, 1.0f, 100.0f, damage); }
|
||||||
|
uint32 GetRangedDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_MELEE, 1.0f, 100.0f, damage); }
|
||||||
|
uint32 GetSpellDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_MELEE, 1.0f, 100.0f, damage); }
|
||||||
|
|
||||||
float MeleeSpellMissChance(Unit *pVictim, WeaponAttackType attType, int32 skillDiff, SpellEntry const *spell);
|
float MeleeSpellMissChance(Unit *pVictim, WeaponAttackType attType, int32 skillDiff, SpellEntry const *spell);
|
||||||
SpellMissInfo MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell);
|
SpellMissInfo MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell);
|
||||||
SpellMissInfo MagicSpellHitResult(Unit *pVictim, SpellEntry const *spell);
|
SpellMissInfo MagicSpellHitResult(Unit *pVictim, SpellEntry const *spell);
|
||||||
|
|
@ -1462,7 +1477,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||||
// redefined in Creature
|
// redefined in Creature
|
||||||
|
|
||||||
uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage);
|
uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage);
|
||||||
void CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist);
|
void CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist, bool canReflect = false);
|
||||||
|
|
||||||
void UpdateSpeed(UnitMoveType mtype, bool forced);
|
void UpdateSpeed(UnitMoveType mtype, bool forced);
|
||||||
float GetSpeed( UnitMoveType mtype ) const;
|
float GetSpeed( UnitMoveType mtype ) const;
|
||||||
|
|
@ -1583,6 +1598,10 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||||
bool HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 cooldown);
|
bool HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 cooldown);
|
||||||
bool HandleMendingAuraProc(Aura* triggeredByAura);
|
bool HandleMendingAuraProc(Aura* triggeredByAura);
|
||||||
|
|
||||||
|
// player or player's pet
|
||||||
|
float GetCombatRatingReduction(CombatRating cr) const;
|
||||||
|
uint32 GetCombatRatingDamageReduction(CombatRating cr, float rate, float cap, uint32 damage) const;
|
||||||
|
|
||||||
uint32 m_state; // Even derived shouldn't modify
|
uint32 m_state; // Even derived shouldn't modify
|
||||||
uint32 m_CombatTimer;
|
uint32 m_CombatTimer;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1106,6 +1106,9 @@ void World::SetInitialWorldSettings()
|
||||||
///- Initialize the random number generator
|
///- Initialize the random number generator
|
||||||
srand((unsigned int)time(NULL));
|
srand((unsigned int)time(NULL));
|
||||||
|
|
||||||
|
///- Time server startup
|
||||||
|
uint32 uStartTime = getMSTime();
|
||||||
|
|
||||||
///- Initialize config settings
|
///- Initialize config settings
|
||||||
LoadConfigSettings();
|
LoadConfigSettings();
|
||||||
|
|
||||||
|
|
@ -1335,6 +1338,9 @@ void World::SetInitialWorldSettings()
|
||||||
sLog.outString( "Loading Player Corpses..." );
|
sLog.outString( "Loading Player Corpses..." );
|
||||||
objmgr.LoadCorpses();
|
objmgr.LoadCorpses();
|
||||||
|
|
||||||
|
sLog.outString( "Loading Player level dependent mail rewards..." );
|
||||||
|
objmgr.LoadMailLevelRewards();
|
||||||
|
|
||||||
sLog.outString( "Loading Loot Tables..." );
|
sLog.outString( "Loading Loot Tables..." );
|
||||||
sLog.outString();
|
sLog.outString();
|
||||||
LoadLootTables();
|
LoadLootTables();
|
||||||
|
|
@ -1508,6 +1514,9 @@ void World::SetInitialWorldSettings()
|
||||||
m_timers[WUPDATE_EVENTS].SetInterval(nextGameEvent); //depend on next event
|
m_timers[WUPDATE_EVENTS].SetInterval(nextGameEvent); //depend on next event
|
||||||
|
|
||||||
sLog.outString( "WORLD: World initialized" );
|
sLog.outString( "WORLD: World initialized" );
|
||||||
|
|
||||||
|
uint32 uStartInterval = getMSTimeDiff(uStartTime, getMSTime());
|
||||||
|
sLog.outString( "SERVER STARTUP TIME: %i minutes %i seconds", uStartInterval / 60000, (uStartInterval % 60000) / 1000 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::DetectDBCLang()
|
void World::DetectDBCLang()
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "SharedDefines.h"
|
#include "SharedDefines.h"
|
||||||
|
|
||||||
class MailItemsInfo;
|
|
||||||
struct ItemPrototype;
|
struct ItemPrototype;
|
||||||
struct AuctionEntry;
|
struct AuctionEntry;
|
||||||
struct DeclinedName;
|
struct DeclinedName;
|
||||||
|
|
@ -39,7 +38,6 @@ class Player;
|
||||||
class Unit;
|
class Unit;
|
||||||
class WorldPacket;
|
class WorldPacket;
|
||||||
class WorldSocket;
|
class WorldSocket;
|
||||||
class WorldSession;
|
|
||||||
class QueryResult;
|
class QueryResult;
|
||||||
class LoginQueryHolder;
|
class LoginQueryHolder;
|
||||||
class CharacterHandler;
|
class CharacterHandler;
|
||||||
|
|
@ -220,12 +218,8 @@ class MANGOS_DLL_SPEC WorldSession
|
||||||
m_TutorialsChanged = true;
|
m_TutorialsChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//mail
|
|
||||||
//used with item_page table
|
//used with item_page table
|
||||||
bool SendItemInfo( uint32 itemid, WorldPacket data );
|
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
|
//auction
|
||||||
void SendAuctionHello( uint64 guid, Creature * unit );
|
void SendAuctionHello( uint64 guid, Creature * unit );
|
||||||
|
|
|
||||||
|
|
@ -43,10 +43,9 @@ mangos_worldd_LDADD = \
|
||||||
../shared/vmap/libmangosvmaps.a \
|
../shared/vmap/libmangosvmaps.a \
|
||||||
../framework/libmangosframework.a \
|
../framework/libmangosframework.a \
|
||||||
../../dep/src/sockets/libmangossockets.a \
|
../../dep/src/sockets/libmangossockets.a \
|
||||||
../../dep/src/g3dlite/libg3dlite.a \
|
../../dep/src/g3dlite/libg3dlite.a
|
||||||
../../dep/tbb/libtbbmalloc.so
|
|
||||||
|
|
||||||
mangos_worldd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/g3dlite -L../bindings/universal/ -L../../dep/tbb -L$(libdir) $(MANGOS_LIBS) -export-dynamic
|
mangos_worldd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/g3dlite -L../bindings/universal/ -L$(libdir) $(MANGOS_LIBS) -export-dynamic
|
||||||
|
|
||||||
## Additional files to include when running 'make dist'
|
## Additional files to include when running 'make dist'
|
||||||
# Include world daemon configuration
|
# Include world daemon configuration
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,9 @@ mangos_realmd_LDADD = \
|
||||||
../shared/Auth/libmangosauth.a \
|
../shared/Auth/libmangosauth.a \
|
||||||
../shared/libmangosshared.a \
|
../shared/libmangosshared.a \
|
||||||
../framework/libmangosframework.a \
|
../framework/libmangosframework.a \
|
||||||
../../dep/src/sockets/libmangossockets.a \
|
../../dep/src/sockets/libmangossockets.a
|
||||||
../../dep/tbb/libtbbmalloc.so
|
|
||||||
|
|
||||||
mangos_realmd_LDFLAGS = -L../../dep/src/sockets -L../../dep/tbb -L$(libdir) $(MANGOS_LIBS)
|
mangos_realmd_LDFLAGS = -L../../dep/src/sockets -L$(libdir) $(MANGOS_LIBS)
|
||||||
|
|
||||||
## Additional files to include when running 'make dist'
|
## Additional files to include when running 'make dist'
|
||||||
# Include realm list daemon configuration
|
# Include realm list daemon configuration
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "8745"
|
#define REVISION_NR "8770"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#ifndef __REVISION_SQL_H__
|
#ifndef __REVISION_SQL_H__
|
||||||
#define __REVISION_SQL_H__
|
#define __REVISION_SQL_H__
|
||||||
#define REVISION_DB_CHARACTERS "required_8721_01_characters_guild"
|
#define REVISION_DB_CHARACTERS "required_8721_01_characters_guild"
|
||||||
#define REVISION_DB_MANGOS "required_8731_01_mangos_creature_template"
|
#define REVISION_DB_MANGOS "required_8770_01_mangos_quest_template"
|
||||||
#define REVISION_DB_REALMD "required_8728_01_realmd_account"
|
#define REVISION_DB_REALMD "required_8728_01_realmd_account"
|
||||||
#endif // __REVISION_SQL_H__
|
#endif // __REVISION_SQL_H__
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@
|
||||||
<AdditionalOptions>/Zl /MP %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zl /MP %(AdditionalOptions)</AdditionalOptions>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\..\src\framework;..\..\dep\ACE_wrappers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..\src\framework;..\..\dep\ACE_wrappers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;USE_STANDARD_MALLOC;;_DEBUG;MANGOS_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;;_DEBUG;MANGOS_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<MinimalRebuild>false</MinimalRebuild>
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
|
@ -170,7 +170,7 @@
|
||||||
<AdditionalOptions>/Zl /MP %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zl /MP %(AdditionalOptions)</AdditionalOptions>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\..\src\framework;..\..\dep\ACE_wrappers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..\src\framework;..\..\dep\ACE_wrappers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;USE_STANDARD_MALLOC;;_DEBUG;MANGOS_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;;_DEBUG;MANGOS_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<MinimalRebuild>false</MinimalRebuild>
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
|
@ -194,7 +194,7 @@
|
||||||
<AdditionalOptions>/Zl /MP %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zl /MP %(AdditionalOptions)</AdditionalOptions>
|
||||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
<AdditionalIncludeDirectories>..\..\src\framework;..\..\dep\ACE_wrappers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..\src\framework;..\..\dep\ACE_wrappers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;USE_STANDARD_MALLOC;;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<MinimalRebuild>false</MinimalRebuild>
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
|
@ -221,7 +221,7 @@
|
||||||
<AdditionalOptions>/Zl /MP %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zl /MP %(AdditionalOptions)</AdditionalOptions>
|
||||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
<AdditionalIncludeDirectories>..\..\src\framework;..\..\dep\ACE_wrappers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..\src\framework;..\..\dep\ACE_wrappers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;USE_STANDARD_MALLOC;;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<MinimalRebuild>false</MinimalRebuild>
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
|
@ -245,7 +245,7 @@
|
||||||
<AdditionalOptions>/Zl /MP %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zl /MP %(AdditionalOptions)</AdditionalOptions>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\..\src\framework;..\..\dep\ACE_wrappers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..\src\framework;..\..\dep\ACE_wrappers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;USE_STANDARD_MALLOC;;_DEBUG;MANGOS_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;;_DEBUG;MANGOS_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<MinimalRebuild>false</MinimalRebuild>
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
|
@ -272,7 +272,7 @@
|
||||||
<AdditionalOptions>/Zl /MP %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zl /MP %(AdditionalOptions)</AdditionalOptions>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\..\src\framework;..\..\dep\ACE_wrappers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..\src\framework;..\..\dep\ACE_wrappers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;USE_STANDARD_MALLOC;;_DEBUG;MANGOS_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;;_DEBUG;MANGOS_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<MinimalRebuild>false</MinimalRebuild>
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue