diff --git a/sql/mangos.sql b/sql/mangos.sql index 41efdb7a8..c1dd16597 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -24,7 +24,7 @@ CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, `cache_id` int(10) default '0', - `required_8749_01_mangos_mail_loot_template` bit(1) default NULL + `required_8769_01_mangos_mail_level_reward` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -2711,6 +2711,28 @@ LOCK TABLES `locales_quest` WRITE; /*!40000 ALTER TABLE `locales_quest` ENABLE KEYS */; 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` -- diff --git a/sql/updates/8769_01_mangos_mail_level_reward.sql b/sql/updates/8769_01_mangos_mail_level_reward.sql new file mode 100644 index 000000000..30e5e2d50 --- /dev/null +++ b/sql/updates/8769_01_mangos_mail_level_reward.sql @@ -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'; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 36fc7b84b..cec131ce7 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -146,6 +146,7 @@ pkgdata_DATA = \ 8728_01_realmd_account.sql \ 8731_01_mangos_creature_template.sql \ 8749_01_mangos_mail_loot_template.sql \ + 8769_01_mangos_mail_level_reward.sql \ README ## Additional files to include when running 'make dist' @@ -272,4 +273,5 @@ EXTRA_DIST = \ 8728_01_realmd_account.sql \ 8731_01_mangos_creature_template.sql \ 8749_01_mangos_mail_loot_template.sql \ + 8769_01_mangos_mail_level_reward.sql \ README diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index ef0984b61..2e738bd7f 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -431,6 +431,7 @@ ChatCommand * ChatHandler::getCommandTable() { "locales_page_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesPageTextCommand, "", NULL }, { "locales_points_of_interest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesPointsOfInterestCommand, "", 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 }, { "milling_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesMillingCommand, "", NULL }, diff --git a/src/game/Chat.h b/src/game/Chat.h index 880d5b335..b12f06f06 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -358,6 +358,7 @@ class ChatHandler bool HandleReloadLootTemplatesReferenceCommand(const char* args); bool HandleReloadLootTemplatesSkinningCommand(const char* args); bool HandleReloadLootTemplatesSpellCommand(const char* args); + bool HandleReloadMailLevelRewardCommand(const char* args); bool HandleReloadMangosStringCommand(const char* args); bool HandleReloadNpcGossipCommand(const char* args); bool HandleReloadNpcOptionCommand(const char* args); diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 7e447aaa4..c4d65f6bb 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -67,6 +67,7 @@ bool ChatHandler::HandleReloadAllCommand(const char*) HandleReloadAllItemCommand(""); HandleReloadAllLocalesCommand(""); + HandleReloadMailLevelRewardCommand(""); HandleReloadCommandCommand(""); HandleReloadReservedNameCommand(""); HandleReloadMangosStringCommand(""); @@ -822,6 +823,14 @@ bool ChatHandler::HandleReloadLocalesQuestCommand(const char* /*arg*/) return true; } +bool ChatHandler::HandleReloadMailLevelRewardCommand(const char* /*arg*/) +{ + sLog.outString( "Re-Loading Player level dependent mail rewards..." ); + objmgr.LoadMailLevelRewards(); + SendGlobalSysMessage("DB table `mail_level_reward` reloaded."); + return true; +} + bool ChatHandler::HandleLoadScriptsCommand(const char* args) { if(!LoadScriptingModule(args)) return true; diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 0475f2bb5..f8f087ab1 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -7518,6 +7518,72 @@ bool ObjectMgr::DeleteGameTele(const std::string& name) return false; } +void ObjectMgr::LoadMailLevelRewards() +{ + m_mailLevelRewardMap.clear(); // for reload case + + uint32 count = 0; + QueryResult *result = WorldDatabase.Query("SELECT level, raceMask, mailTemplateId, senderEntry FROM mail_level_reward"); + + if( !result ) + { + barGoLink bar( 1 ); + + bar.step(); + + sLog.outString(); + sLog.outErrorDb(">> Loaded `mail_level_reward`, table is empty!"); + return; + } + + barGoLink bar( result->GetRowCount() ); + + do + { + bar.step(); + + Field *fields = result->Fetch(); + + uint8 level = fields[0].GetUInt8(); + uint32 raceMask = fields[1].GetUInt32(); + uint32 mailTemplateId = fields[2].GetUInt32(); + uint32 senderEntry = fields[3].GetUInt32(); + + if(level > MAX_LEVEL) + { + sLog.outErrorDb("Table `mail_level_reward` have data for level %u that more supported by client (%u), ignoring.",level,MAX_LEVEL); + continue; + } + + if(!(raceMask & RACEMASK_ALL_PLAYABLE)) + { + sLog.outErrorDb("Table `mail_level_reward` have raceMask (%u) for level %u that not include any player races, ignoring.",raceMask,level); + continue; + } + + if(!sMailTemplateStore.LookupEntry(mailTemplateId)) + { + sLog.outErrorDb("Table `mail_level_reward` have invalid mailTemplateId (%u) for level %u that invalid not include any player races, ignoring.",mailTemplateId,level); + continue; + } + + if(!GetCreatureTemplateStore(senderEntry)) + { + sLog.outErrorDb("Table `mail_level_reward` have not existed sender creature entry (%u) for level %u that invalid not include any player races, ignoring.",senderEntry,level); + continue; + } + + m_mailLevelRewardMap[level].push_back(MailLevelReward(raceMask,mailTemplateId,senderEntry)); + + ++count; + } + while (result->NextRow()); + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u level dependent mail rewards,", count ); +} + void ObjectMgr::LoadTrainerSpell() { // For reload case diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index c58f196ec..b888e39b8 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -179,6 +179,19 @@ struct PetLevelInfo uint16 armor; }; +struct MailLevelReward +{ + MailLevelReward() : raceMask(0), mailTemplateId(0), senderEntry(0) {} + MailLevelReward(uint32 _raceMask, uint32 _mailTemplateId, uint32 _senderEntry) : raceMask(_raceMask), mailTemplateId(_mailTemplateId), senderEntry(_senderEntry) {} + + uint32 raceMask; + uint32 mailTemplateId; + uint32 senderEntry; +}; + +typedef std::list MailLevelRewardList; +typedef UNORDERED_MAP MailLevelRewardMap; + struct ReputationOnKillEntry { uint32 repfaction1; @@ -515,6 +528,7 @@ class ObjectMgr void LoadNpcOptionLocales(); void LoadPointOfInterestLocales(); void LoadInstanceTemplate(); + void LoadMailLevelRewards(); void LoadGossipText(); @@ -584,6 +598,19 @@ class ObjectMgr typedef std::multimap ExclusiveQuestGroups; ExclusiveQuestGroups mExclusiveQuestGroups; + MailLevelReward const* GetMailLevelReward(uint32 level,uint32 raceMask) + { + MailLevelRewardMap::const_iterator map_itr = m_mailLevelRewardMap.find(level); + if (map_itr == m_mailLevelRewardMap.end()) + return NULL; + + for(MailLevelRewardList::const_iterator set_itr = map_itr->second.begin(); set_itr != map_itr->second.end(); ++set_itr) + if (set_itr->raceMask & raceMask) + return &*set_itr; + + return NULL; + } + WeatherZoneChances const* GetWeatherChances(uint32 zone_id) const { WeatherZoneMap::const_iterator itr = mWeatherZoneMap.find(zone_id); @@ -844,6 +871,8 @@ class ObjectMgr void ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr); void LoadQuestRelationsHelper(QuestRelations& map,char const* table); + MailLevelRewardMap m_mailLevelRewardMap; + typedef std::map PetLevelInfoMap; // PetLevelInfoMap[creature_id][level] PetLevelInfoMap petInfo; // [creature_id][level] diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 69a1b5c77..5a4fee0ee 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2452,6 +2452,9 @@ void Player::GiveLevel(uint32 level) if (Pet* pet = GetPet()) pet->SynchronizeLevelWithOwner(); + if (MailLevelReward const* mailReward = objmgr.GetMailLevelReward(level,getRaceMask())) + MailDraft(mailReward->mailTemplateId).SendMailTo(this,MailSender(MAIL_CREATURE,mailReward->senderEntry)); + GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL); } diff --git a/src/game/World.cpp b/src/game/World.cpp index 47a3ede3e..8efd7bf0f 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1338,6 +1338,9 @@ void World::SetInitialWorldSettings() sLog.outString( "Loading Player Corpses..." ); objmgr.LoadCorpses(); + sLog.outString( "Loading Player level dependent mail rewards..." ); + objmgr.LoadMailLevelRewards(); + sLog.outString( "Loading Loot Tables..." ); sLog.outString(); LoadLootTables(); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 40d7c75c6..807515154 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8768" + #define REVISION_NR "8769" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index c562c32e9..9caee023d 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_8721_01_characters_guild" - #define REVISION_DB_MANGOS "required_8749_01_mangos_mail_loot_template" + #define REVISION_DB_MANGOS "required_8769_01_mangos_mail_level_reward" #define REVISION_DB_REALMD "required_8728_01_realmd_account" #endif // __REVISION_SQL_H__