diff --git a/sql/mangos.sql b/sql/mangos.sql index 232b37bce..950cd0a3b 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_10654_01_mangos_game_event_creature_quest` bit(1) default NULL + `required_10660_01_mangos_game_event_quest` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -1645,27 +1645,6 @@ LOCK TABLES `game_event_creature` WRITE; /*!40000 ALTER TABLE `game_event_creature` ENABLE KEYS */; UNLOCK TABLES; --- --- Table structure for table `game_event_creature_quest` --- - -DROP TABLE IF EXISTS `game_event_creature_quest`; -CREATE TABLE `game_event_creature_quest` ( - `id` mediumint(8) unsigned NOT NULL default '0', - `quest` mediumint(8) unsigned NOT NULL default '0', - `event` smallint(5) unsigned NOT NULL default '0', - PRIMARY KEY (`id`,`quest`,`event`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - --- --- Dumping data for table `game_event_creature_quest` --- - -LOCK TABLES `game_event_creature_quest` WRITE; -/*!40000 ALTER TABLE `game_event_creature_quest` DISABLE KEYS */; -/*!40000 ALTER TABLE `game_event_creature_quest` ENABLE KEYS */; -UNLOCK TABLES; - -- -- Table structure for table `game_event_gameobject` -- @@ -1708,6 +1687,26 @@ LOCK TABLES `game_event_model_equip` WRITE; /*!40000 ALTER TABLE `game_event_model_equip` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `game_event_quest` +-- + +DROP TABLE IF EXISTS `game_event_quest`; +CREATE TABLE `game_event_quest` ( + `quest` mediumint(8) unsigned NOT NULL default '0' COMMENT 'entry from quest_template', + `event` smallint(5) unsigned NOT NULL default '0' COMMENT 'entry from game_event', + PRIMARY KEY (`quest`,`event`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Game event system'; + +-- +-- Dumping data for table `game_event_quest` +-- + +LOCK TABLES `game_event_quest` WRITE; +/*!40000 ALTER TABLE `game_event_quest` DISABLE KEYS */; +/*!40000 ALTER TABLE `game_event_quest` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `game_graveyard_zone` -- diff --git a/sql/updates/10660_01_mangos_game_event_quest.sql b/sql/updates/10660_01_mangos_game_event_quest.sql new file mode 100644 index 000000000..0fd8343dd --- /dev/null +++ b/sql/updates/10660_01_mangos_game_event_quest.sql @@ -0,0 +1,12 @@ +ALTER TABLE db_version CHANGE COLUMN required_10654_01_mangos_game_event_creature_quest required_10660_01_mangos_game_event_quest bit; + +DROP TABLE IF EXISTS game_event_quest; +CREATE TABLE game_event_quest ( + quest mediumint(8) unsigned NOT NULL default '0' COMMENT 'entry from quest_template', + event smallint(5) unsigned NOT NULL default '0' COMMENT 'entry from game_event', + PRIMARY KEY (quest,event) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Game event system'; + +INSERT INTO game_event_quest SELECT DISTINCT quest, event FROM game_event_creature_quest; + +DROP TABLE game_event_creature_quest; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 17f5ab22f..f2cf46e35 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -111,6 +111,7 @@ pkgdata_DATA = \ 10629_01_mangos_mangos_string.sql \ 10654_01_mangos_game_event_creature_quest.sql \ 10655_01_characters_character_queststatus_monthly.sql \ + 10660_01_mangos_game_event_quest.sql \ README ## Additional files to include when running 'make dist' @@ -202,4 +203,5 @@ EXTRA_DIST = \ 10629_01_mangos_mangos_string.sql \ 10654_01_mangos_game_event_creature_quest.sql \ 10655_01_characters_character_queststatus_monthly.sql \ + 10660_01_mangos_game_event_quest.sql \ README diff --git a/src/game/GameEventMgr.cpp b/src/game/GameEventMgr.cpp index 1969c9e14..51719fe7a 100644 --- a/src/game/GameEventMgr.cpp +++ b/src/game/GameEventMgr.cpp @@ -404,8 +404,8 @@ void GameEventMgr::LoadFromDB() } mGameEventQuests.resize(mGameEvent.size()); - // 0 1 2 - result = WorldDatabase.Query("SELECT id, quest, event FROM game_event_creature_quest"); + + result = WorldDatabase.Query("SELECT quest, event FROM game_event_quest"); count = 0; if( !result ) @@ -425,25 +425,36 @@ void GameEventMgr::LoadFromDB() Field *fields = result->Fetch(); bar.step(); - uint32 id = fields[0].GetUInt32(); - uint32 quest = fields[1].GetUInt32(); - uint16 event_id = fields[2].GetUInt16(); + uint32 quest = fields[0].GetUInt32(); + uint16 event_id = fields[1].GetUInt16(); if(event_id >= mGameEventQuests.size()) { - sLog.outErrorDb("`game_event_creature_quest` game event id (%u) is out of range compared to max event id in `game_event`",event_id); + sLog.outErrorDb("`game_event_quest` game event id (%u) is out of range compared to max event id in `game_event`",event_id); continue; } + const Quest* pQuest = sObjectMgr.GetQuestTemplate(quest); + + if (!pQuest) + { + sLog.outErrorDb("Table `game_event_quest` contain entry for quest %u (event %u) but this quest does not exist. Skipping.", quest, event_id); + continue; + } + + // disable any event specific quest (for cases where creature is spawned, but event not active). + const_cast(pQuest)->SetQuestActiveState(false); + ++count; - QuestRelList& questlist = mGameEventQuests[event_id]; - questlist.push_back(QuestRelation(id, quest)); + + QuestList& questlist = mGameEventQuests[event_id]; + questlist.push_back(quest); } while( result->NextRow() ); delete result; sLog.outString(); - sLog.outString( ">> Loaded %u quests additions in game events", count ); + sLog.outString( ">> Loaded %u quest additions in game events", count ); } } @@ -481,9 +492,6 @@ uint32 GameEventMgr::Update() // return the next e int16 event_nid = (-1) * (itr); // spawn all negative ones for this event GameEventSpawn(event_nid); - - // disable any event specific quest (for cases where creature is spawned, but event not active). - UpdateEventQuests(itr, false); UpdateWorldStates(itr, false); } } @@ -792,26 +800,17 @@ void GameEventMgr::ChangeEquipOrModel(int16 event_id, bool activate) void GameEventMgr::UpdateEventQuests(uint16 event_id, bool Activate) { - QuestRelList::iterator itr; - for (itr = mGameEventQuests[event_id].begin();itr != mGameEventQuests[event_id].end();++itr) + QuestList::iterator itr; + for (itr = mGameEventQuests[event_id].begin(); itr != mGameEventQuests[event_id].end(); ++itr) { - QuestRelationsMap &CreatureQuestMap = sObjectMgr.GetCreatureQuestRelationsMap(); + const Quest *pQuest = sObjectMgr.GetQuestTemplate(*itr); - if (Activate) // Add the pair(id,quest) to the multimap - CreatureQuestMap.insert(QuestRelationsMap::value_type(itr->first, itr->second)); - else - { // Remove the pair(id,quest) from the multimap - std::pair bounds = CreatureQuestMap.equal_range(itr->first); + //if (Activate) + //{ + // TODO: implement way to reset quests when event begin. + //} - for(QuestRelationsMap::iterator qitr = bounds.first; qitr != bounds.second; ++qitr) - { - if (qitr->second == itr->second) - { - CreatureQuestMap.erase(qitr); // iterator is now no more valid - break; // but we can exit loop since the element is found - } - } - } + const_cast(pQuest)->SetQuestActiveState(Activate); } } diff --git a/src/game/GameEventMgr.h b/src/game/GameEventMgr.h index 661b6de79..a35d70166 100644 --- a/src/game/GameEventMgr.h +++ b/src/game/GameEventMgr.h @@ -87,10 +87,11 @@ class GameEventMgr typedef std::pair ModelEquipPair; typedef std::list ModelEquipList; typedef std::vector GameEventModelEquipMap; - typedef std::pair QuestRelation; - typedef std::list QuestRelList; - typedef std::vector GameEventQuestMap; + + typedef std::list QuestList; + typedef std::vector GameEventQuestMap; GameEventQuestMap mGameEventQuests; // events*2-1 + GameEventModelEquipMap mGameEventModelEquip; // events*2-1 GameEventGuidMap mGameEventCreatureGuids; // events*2-1 GameEventGuidMap mGameEventGameobjectGuids; // events*2-1 diff --git a/src/game/Player.cpp b/src/game/Player.cpp index f399d6d56..92bb3ca10 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -13102,6 +13102,12 @@ void Player::PrepareQuestMenu(ObjectGuid guid) for(QuestRelationsMap::const_iterator itr = irbounds.first; itr != irbounds.second; ++itr) { uint32 quest_id = itr->second; + + Quest const* pQuest = sObjectMgr.GetQuestTemplate(quest_id); + + if (!pQuest || !pQuest->IsActive()) + continue; + QuestStatus status = GetQuestStatus(quest_id); if (status == QUEST_STATUS_COMPLETE && !GetQuestRewardStatus(quest_id)) @@ -13115,9 +13121,10 @@ void Player::PrepareQuestMenu(ObjectGuid guid) for(QuestRelationsMap::const_iterator itr = rbounds.first; itr != rbounds.second; ++itr) { uint32 quest_id = itr->second; + Quest const* pQuest = sObjectMgr.GetQuestTemplate(quest_id); - if (!pQuest) + if (!pQuest || !pQuest->IsActive()) continue; QuestStatus status = GetQuestStatus(quest_id); @@ -13276,7 +13283,8 @@ bool Player::CanSeeStartQuest(Quest const *pQuest) const SatisfyQuestExclusiveGroup(pQuest, false) && SatisfyQuestReputation(pQuest, false) && SatisfyQuestPreviousQuest(pQuest, false) && SatisfyQuestNextChain(pQuest, false) && SatisfyQuestPrevChain(pQuest, false) && SatisfyQuestDay(pQuest, false) && SatisfyQuestWeek(pQuest, false) && - SatisfyQuestMonth(pQuest, false)) + SatisfyQuestMonth(pQuest, false) && + pQuest->IsActive()) { return getLevel() + sWorld.getConfig(CONFIG_UINT32_QUEST_HIGH_LEVEL_HIDE_DIFF) >= pQuest->GetMinLevel(); } @@ -13291,7 +13299,8 @@ bool Player::CanTakeQuest(Quest const *pQuest, bool msg) const SatisfyQuestSkill(pQuest, msg) && SatisfyQuestReputation(pQuest, msg) && SatisfyQuestPreviousQuest(pQuest, msg) && SatisfyQuestTimed(pQuest, msg) && SatisfyQuestNextChain(pQuest, msg) && SatisfyQuestPrevChain(pQuest, msg) && - SatisfyQuestDay(pQuest, msg) && SatisfyQuestWeek(pQuest, msg) && SatisfyQuestMonth(pQuest, msg); + SatisfyQuestDay(pQuest, msg) && SatisfyQuestWeek(pQuest, msg) && SatisfyQuestMonth(pQuest, msg) && + pQuest->IsActive(); } bool Player::CanAddQuest(Quest const *pQuest, bool msg) const diff --git a/src/game/QuestDef.cpp b/src/game/QuestDef.cpp index 03246eaf7..ab282ceca 100644 --- a/src/game/QuestDef.cpp +++ b/src/game/QuestDef.cpp @@ -137,6 +137,8 @@ Quest::Quest(Field * questRecord) QuestStartScript = questRecord[139].GetUInt32(); QuestCompleteScript = questRecord[140].GetUInt32(); + m_isActive = true; + m_reqitemscount = 0; m_reqCreatureOrGOcount = 0; m_rewitemscount = 0; diff --git a/src/game/QuestDef.h b/src/game/QuestDef.h index 5bedb346c..5eb7fef70 100644 --- a/src/game/QuestDef.h +++ b/src/game/QuestDef.h @@ -269,6 +269,10 @@ class Quest bool IsAutoAccept() const { return m_QuestFlags & QUEST_FLAGS_AUTO_ACCEPT; } bool IsAllowedInRaid() const; + // quest can be fully deactivated and will not be available for any player + void SetQuestActiveState(bool state) { m_isActive = state; } + bool IsActive() const { return m_isActive; } + // multiple values std::string ObjectiveText[QUEST_OBJECTIVES_COUNT]; uint32 ReqItemId[QUEST_ITEM_OBJECTIVES_COUNT]; @@ -307,6 +311,8 @@ class Quest uint32 m_rewchoiceitemscount; uint32 m_rewitemscount; + bool m_isActive; + // table data protected: uint32 QuestId; diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp index 35a7edfe2..cd0854438 100644 --- a/src/game/QuestHandler.cpp +++ b/src/game/QuestHandler.cpp @@ -576,7 +576,7 @@ uint32 WorldSession::getDialogStatus(Player *pPlayer, Object* questgiver, uint32 uint32 quest_id = itr->second; Quest const *pQuest = sObjectMgr.GetQuestTemplate(quest_id); - if (!pQuest) + if (!pQuest || !pQuest->IsActive()) continue; QuestStatus status = pPlayer->GetQuestStatus(quest_id); @@ -602,7 +602,7 @@ uint32 WorldSession::getDialogStatus(Player *pPlayer, Object* questgiver, uint32 uint32 quest_id = itr->second; Quest const *pQuest = sObjectMgr.GetQuestTemplate(quest_id); - if (!pQuest) + if (!pQuest || !pQuest->IsActive()) continue; QuestStatus status = pPlayer->GetQuestStatus(quest_id); diff --git a/src/game/World.cpp b/src/game/World.cpp index 1df858939..5032fb2eb 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1055,12 +1055,6 @@ void World::SetInitialWorldSettings() sLog.outString( "Loading Objects Pooling Data..."); sPoolMgr.LoadFromDB(); - sLog.outString( "Loading Game Event Data..."); // must be after sPoolMgr.LoadFromDB for proper load pool events - sLog.outString(); - sGameEventMgr.LoadFromDB(); - sLog.outString( ">>> Game Event Data loaded" ); - sLog.outString(); - sLog.outString( "Loading Weather Data..." ); sObjectMgr.LoadWeatherZoneChances(); @@ -1076,6 +1070,12 @@ void World::SetInitialWorldSettings() sLog.outString( ">>> Quests Relations loaded" ); sLog.outString(); + sLog.outString( "Loading Game Event Data..."); // must be after sPoolMgr.LoadFromDB and quests to properly load pool events and quests for events + sLog.outString(); + sGameEventMgr.LoadFromDB(); + sLog.outString( ">>> Game Event Data loaded" ); + sLog.outString(); + sLog.outString( "Loading UNIT_NPC_FLAG_SPELLCLICK Data..." ); sObjectMgr.LoadNPCSpellClickSpells(); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index bfc253827..39b138118 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 "10659" + #define REVISION_NR "10660" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 7617b1863..8533abe2f 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_10655_01_characters_character_queststatus_monthly" - #define REVISION_DB_MANGOS "required_10654_01_mangos_game_event_creature_quest" + #define REVISION_DB_MANGOS "required_10660_01_mangos_game_event_quest" #define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version" #endif // __REVISION_SQL_H__