[10660] Make quest for game event be independent of source

Create new table and convert existing data.
Simplify how game event quests are activated during event by adding generic function to set quest active/inactive.
Any quest in game_event_quest are disabled until event start (and deactivated once stopped)

Signed-off-by: NoFantasy <nofantasy@nf.no>
This commit is contained in:
NoFantasy 2010-10-31 11:34:25 +01:00
parent 1370ead743
commit 449a708728
12 changed files with 97 additions and 67 deletions

View file

@ -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`
--

View file

@ -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;

View file

@ -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

View file

@ -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<Quest*>(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<QuestRelationsMap::iterator, QuestRelationsMap::iterator> 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<Quest*>(pQuest)->SetQuestActiveState(Activate);
}
}

View file

@ -87,10 +87,11 @@ class GameEventMgr
typedef std::pair<uint32, ModelEquip> ModelEquipPair;
typedef std::list<ModelEquipPair> ModelEquipList;
typedef std::vector<ModelEquipList> GameEventModelEquipMap;
typedef std::pair<uint32, uint32> QuestRelation;
typedef std::list<QuestRelation> QuestRelList;
typedef std::vector<QuestRelList> GameEventQuestMap;
typedef std::list<uint32> QuestList;
typedef std::vector<QuestList> GameEventQuestMap;
GameEventQuestMap mGameEventQuests; // events*2-1
GameEventModelEquipMap mGameEventModelEquip; // events*2-1
GameEventGuidMap mGameEventCreatureGuids; // events*2-1
GameEventGuidMap mGameEventGameobjectGuids; // events*2-1

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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();

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "10659"
#define REVISION_NR "10660"
#endif // __REVISION_NR_H__

View file

@ -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__