aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShocker <shocker@freakz.ro>2012-01-04 13:11:34 -0800
committerShocker <shocker@freakz.ro>2012-01-04 13:11:34 -0800
commit8d7f77eb00000cb1c83b246214672f6b04a23d0f (patch)
tree2e4175a7125bae58f29007751171e24372202346 /src
parentde2bcb1caa8a8de77e5b14eae66622f57f6ac98b (diff)
parent46fb199ee1c5d27ea79f65d63f6fd8dbe29612c6 (diff)
Merge pull request #4616 from kandera/fix_seasonal_quest_reset
Core/Quests: Add implementation of seasonal quest reset
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp125
-rwxr-xr-xsrc/server/game/Entities/Player/Player.h12
-rwxr-xr-xsrc/server/game/Events/GameEventMgr.cpp43
-rwxr-xr-xsrc/server/game/Globals/ObjectMgr.h5
-rwxr-xr-xsrc/server/game/Quests/QuestDef.cpp1
-rwxr-xr-xsrc/server/game/Quests/QuestDef.h5
-rw-r--r--[-rwxr-xr-x]src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp8
-rwxr-xr-xsrc/server/game/World/World.cpp11
-rwxr-xr-xsrc/server/game/World/World.h1
-rw-r--r--[-rwxr-xr-x]src/server/shared/Database/Implementation/CharacterDatabase.cpp10
-rw-r--r--[-rwxr-xr-x]src/server/shared/Database/Implementation/CharacterDatabase.h10
11 files changed, 213 insertions, 18 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index c5c025c96df..6d6a8fd5071 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -14529,7 +14529,7 @@ bool Player::CanSeeStartQuest(Quest const* quest)
SatisfyQuestExclusiveGroup(quest, false) && SatisfyQuestReputation(quest, false) &&
SatisfyQuestPreviousQuest(quest, false) && SatisfyQuestNextChain(quest, false) &&
SatisfyQuestPrevChain(quest, false) && SatisfyQuestDay(quest, false) && SatisfyQuestWeek(quest, false) &&
- !DisableMgr::IsDisabledFor(DISABLE_TYPE_QUEST, quest->GetQuestId(), this))
+ SatisfyQuestSeasonal(quest, false) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_QUEST, quest->GetQuestId(), this))
{
return getLevel() + sWorld->getIntConfig(CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF) >= quest->GetMinLevel();
}
@@ -14545,7 +14545,7 @@ bool Player::CanTakeQuest(Quest const* quest, bool msg)
&& SatisfyQuestPreviousQuest(quest, msg) && SatisfyQuestTimed(quest, msg)
&& SatisfyQuestNextChain(quest, msg) && SatisfyQuestPrevChain(quest, msg)
&& SatisfyQuestDay(quest, msg) && SatisfyQuestWeek(quest, msg)
- && !DisableMgr::IsDisabledFor(DISABLE_TYPE_QUEST, quest->GetQuestId(), this)
+ && SatisfyQuestSeasonal(quest,msg) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_QUEST, quest->GetQuestId(), this)
&& SatisfyQuestConditions(quest, msg);
}
@@ -14669,7 +14669,7 @@ bool Player::CanRewardQuest(Quest const* quest, bool msg)
return false;
// daily quest can't be rewarded (25 daily quest already completed)
- if (!SatisfyQuestDay(quest, true) || !SatisfyQuestWeek(quest, true))
+ if (!SatisfyQuestDay(quest, true) || !SatisfyQuestWeek(quest, true) || !SatisfyQuestSeasonal(quest,true))
return false;
// rewarded and not repeatable quest (only cheating case, then ignore without message)
@@ -14978,6 +14978,8 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
}
else if (quest->IsWeekly())
SetWeeklyQuestStatus(quest_id);
+ else if (quest->IsSeasonal())
+ SetSeasonalQuestStatus(quest_id);
RemoveActiveQuest(quest_id);
m_RewardedQuests.insert(quest_id);
@@ -15333,7 +15335,7 @@ bool Player::SatisfyQuestExclusiveGroup(Quest const* qInfo, bool msg)
// not allow have daily quest if daily quest from exclusive group already recently completed
Quest const* Nquest = sObjectMgr->GetQuestTemplate(exclude_Id);
- if (!SatisfyQuestDay(Nquest, false) || !SatisfyQuestWeek(Nquest, false))
+ if (!SatisfyQuestDay(Nquest, false) || !SatisfyQuestWeek(Nquest, false) || !SatisfyQuestSeasonal(Nquest,false))
{
if (msg)
SendCanTakeQuestResponse(INVALIDREASON_DONT_HAVE_REQ);
@@ -15342,7 +15344,7 @@ bool Player::SatisfyQuestExclusiveGroup(Quest const* qInfo, bool msg)
}
// alternative quest already started or completed - but don't check rewarded states if both are repeatable
- if (GetQuestStatus(exclude_Id) != QUEST_STATUS_NONE || (!(qInfo->IsRepeatable() && Nquest->IsRepeatable()) && m_RewardedQuests.find(exclude_Id) != m_RewardedQuests.end()))
+ if (GetQuestStatus(exclude_Id) != QUEST_STATUS_NONE || (!(qInfo->IsRepeatable() && Nquest->IsRepeatable()) && (m_RewardedQuests.find(exclude_Id) != m_RewardedQuests.end())))
{
if (msg)
SendCanTakeQuestResponse(INVALIDREASON_DONT_HAVE_REQ);
@@ -15443,6 +15445,15 @@ bool Player::SatisfyQuestWeek(Quest const* qInfo, bool /*msg*/)
return m_weeklyquests.find(qInfo->GetQuestId()) == m_weeklyquests.end();
}
+bool Player::SatisfyQuestSeasonal(Quest const* qInfo, bool /*msg*/)
+{
+ if (!qInfo->IsSeasonal() || m_seasonalquests.empty())
+ return true;
+ if (m_seasonalquests.find(qInfo->GetSeasonalQuestEvent()) == m_seasonalquests.end()) return false;
+ // if not found in cooldown list
+ return m_seasonalquests[qInfo->GetSeasonalQuestEvent()].find(qInfo->GetQuestId()) == m_seasonalquests[qInfo->GetSeasonalQuestEvent()].end();
+}
+
bool Player::GiveQuestSourceItem(Quest const* quest)
{
uint32 srcitem = quest->GetSrcItemId();
@@ -16980,7 +16991,8 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
_LoadQuestStatus(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS));
_LoadQuestStatusRewarded(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADQUESTSTATUSREW));
_LoadDailyQuestStatus(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS));
- _LoadWeeklyQuestStatus(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADWEKLYQUESTSTATUS));
+ _LoadWeeklyQuestStatus(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADWEEKLYQUESTSTATUS));
+ _LoadSeasonalQuestStatus(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADSEASONALQUESTSTATUS));
_LoadRandomBGStatus(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADRANDOMBG));
// after spell and quest load
@@ -17846,6 +17858,29 @@ void Player::_LoadWeeklyQuestStatus(PreparedQueryResult result)
m_WeeklyQuestChanged = false;
}
+void Player::_LoadSeasonalQuestStatus(PreparedQueryResult result)
+{
+ m_seasonalquests.clear();
+
+ if (result)
+ {
+ do
+ {
+ uint32 quest_id = (*result)[0].GetUInt32();
+ uint16 event_id = (*result)[1].GetUInt16();
+ Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
+ if (!quest)
+ continue;
+
+ m_seasonalquests[event_id].insert(quest_id);
+ sLog->outDebug(LOG_FILTER_PLAYER_LOADING, "Seasonal quest {%u} cooldown for player (GUID: %u)", quest_id, GetGUIDLow());
+ }
+ while (result->NextRow());
+ }
+
+ m_SeasonalQuestChanged = false;
+}
+
void Player::_LoadSpells(PreparedQueryResult result)
{
//QueryResult* result = CharacterDatabase.PQuery("SELECT spell, active, disabled FROM character_spell WHERE guid = '%u'", GetGUIDLow());
@@ -18572,6 +18607,7 @@ void Player::SaveToDB(bool create /*=false*/)
_SaveQuestStatus(trans);
_SaveDailyQuestStatus(trans);
_SaveWeeklyQuestStatus(trans);
+ _SaveSeasonalQuestStatus(trans);
_SaveTalents(trans);
_SaveSpells(trans);
_SaveSpellCooldowns(trans);
@@ -18910,18 +18946,28 @@ void Player::_SaveDailyQuestStatus(SQLTransaction& trans)
// save last daily quest time for all quests: we need only mostly reset time for reset check anyway
// we don't need transactions here.
- trans->PAppend("DELETE FROM character_queststatus_daily WHERE guid = '%u'", GetGUIDLow());
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_QUEST_STATUS_DAILY_CHAR);
+ stmt->setUInt32(0, GetGUIDLow());
+ trans->Append(stmt);
for (uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx)
if (GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx))
- trans->PAppend("INSERT INTO character_queststatus_daily (guid, quest, time) VALUES ('%u', '%u', '" UI64FMTD "')",
- GetGUIDLow(), GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx), uint64(m_lastDailyQuestTime));
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_DAILYQUESTSTATUS);
+ stmt->setUInt32(0, GetGUIDLow());
+ stmt->setUInt32(1, GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx));
+ stmt->setUInt64(2, uint64(m_lastDailyQuestTime));
+ trans->Append(stmt);
+ }
if (!m_DFQuests.empty())
{
for (DFQuestsDoneList::iterator itr = m_DFQuests.begin(); itr != m_DFQuests.end(); ++itr)
{
- trans->PAppend("INSERT INTO character_queststatus_daily (guid, quest, time) VALUES ('%u', '%u', '" UI64FMTD "')",
- GetGUIDLow(), (*itr), uint64(m_lastDailyQuestTime));
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_DAILYQUESTSTATUS);
+ stmt->setUInt32(0, GetGUIDLow());
+ stmt->setUInt32(1, (*itr));
+ stmt->setUInt64(2, uint64(m_lastDailyQuestTime));
+ trans->Append(stmt);
}
}
}
@@ -18932,18 +18978,51 @@ void Player::_SaveWeeklyQuestStatus(SQLTransaction& trans)
return;
// we don't need transactions here.
- trans->PAppend("DELETE FROM character_queststatus_weekly WHERE guid = '%u'", GetGUIDLow());
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_QUEST_STATUS_WEEKLY_CHAR);
+ stmt->setUInt32(0, GetGUIDLow());
+ trans->Append(stmt);
for (QuestSet::const_iterator iter = m_weeklyquests.begin(); iter != m_weeklyquests.end(); ++iter)
{
uint32 quest_id = *iter;
- trans->PAppend("INSERT INTO character_queststatus_weekly (guid, quest) VALUES ('%u', '%u')", GetGUIDLow(), quest_id);
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_WEEKLYQUESTSTATUS);
+ stmt->setUInt32(0, GetGUIDLow());
+ stmt->setUInt32(1, quest_id);
+ trans->Append(stmt);
}
m_WeeklyQuestChanged = false;
}
+void Player::_SaveSeasonalQuestStatus(SQLTransaction& trans)
+{
+ if (!m_SeasonalQuestChanged || m_seasonalquests.empty())
+ return;
+
+ // we don't need transactions here.
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_QUEST_STATUS_SEASONAL_CHAR);
+ stmt->setUInt32(0, GetGUIDLow());
+ trans->Append(stmt);
+
+ for (SeasonalEventQuestMap::const_iterator iter = m_seasonalquests.begin(); iter != m_seasonalquests.end(); ++iter)
+ {
+ uint16 event_id = iter->first;
+ for (SeasonalQuestSet::const_iterator itr = (iter->second).begin(); itr != (iter->second).end(); ++itr)
+ {
+ uint32 quest_id = (*itr);
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_SEASONALQUESTSTATUS);
+ stmt->setUInt32(0,GetGUIDLow());
+ stmt->setUInt32(1,quest_id);
+ stmt->setUInt16(1,event_id);
+ trans->Append(stmt);
+ }
+ }
+
+ m_SeasonalQuestChanged = false;
+}
+
void Player::_SaveSkills(SQLTransaction& trans)
{
// we don't need transactions here.
@@ -22036,6 +22115,16 @@ void Player::SetWeeklyQuestStatus(uint32 quest_id)
m_WeeklyQuestChanged = true;
}
+void Player::SetSeasonalQuestStatus(uint32 quest_id)
+{
+ Quest const* q = sObjectMgr->GetQuestTemplate(quest_id);
+ if (!q)
+ return;
+
+ m_seasonalquests[q->GetSeasonalQuestEvent()].insert(quest_id);
+ m_SeasonalQuestChanged = true;
+}
+
void Player::ResetDailyQuestStatus()
{
for (uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx)
@@ -22058,6 +22147,16 @@ void Player::ResetWeeklyQuestStatus()
m_WeeklyQuestChanged = false;
}
+void Player::ResetSeasonalQuestStatus(uint16 event_id)
+{
+ if (m_seasonalquests.empty() || m_seasonalquests[event_id].empty())
+ return;
+
+ m_seasonalquests.erase(event_id);
+ // DB data deleted in caller
+ m_SeasonalQuestChanged = false;
+}
+
Battleground* Player::GetBattleground() const
{
if (GetBattlegroundId() == 0)
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 7da008d597b..21c87a993dc 100755
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -815,11 +815,12 @@ enum PlayerLoginQueryIndex
PLAYER_LOGIN_QUERY_LOADTALENTS = 23,
PLAYER_LOGIN_QUERY_LOADACCOUNTDATA = 24,
PLAYER_LOGIN_QUERY_LOADSKILLS = 25,
- PLAYER_LOGIN_QUERY_LOADWEKLYQUESTSTATUS = 26,
+ PLAYER_LOGIN_QUERY_LOADWEEKLYQUESTSTATUS = 26,
PLAYER_LOGIN_QUERY_LOADRANDOMBG = 27,
PLAYER_LOGIN_QUERY_LOADBANNED = 28,
PLAYER_LOGIN_QUERY_LOADQUESTSTATUSREW = 29,
PLAYER_LOGIN_QUERY_LOADINSTANCELOCKTIMES = 30,
+ PLAYER_LOGIN_QUERY_LOADSEASONALQUESTSTATUS = 31,
MAX_PLAYER_LOGIN_QUERY,
};
@@ -1422,6 +1423,7 @@ class Player : public Unit, public GridObject<Player>
bool SatisfyQuestPrevChain(Quest const* qInfo, bool msg);
bool SatisfyQuestDay(Quest const* qInfo, bool msg);
bool SatisfyQuestWeek(Quest const* qInfo, bool msg);
+ bool SatisfyQuestSeasonal(Quest const* qInfo, bool msg);
bool GiveQuestSourceItem(Quest const* quest);
bool TakeQuestSourceItem(uint32 questId, bool msg);
bool GetQuestRewardStatus(uint32 quest_id) const;
@@ -1432,8 +1434,10 @@ class Player : public Unit, public GridObject<Player>
void SetDailyQuestStatus(uint32 quest_id);
void SetWeeklyQuestStatus(uint32 quest_id);
+ void SetSeasonalQuestStatus(uint32 quest_id);
void ResetDailyQuestStatus();
void ResetWeeklyQuestStatus();
+ void ResetSeasonalQuestStatus(uint16 event_id);
uint16 FindQuestSlot(uint32 quest_id) const;
uint32 GetQuestSlotQuestId(uint16 slot) const { return GetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_ID_OFFSET); }
@@ -2558,8 +2562,11 @@ class Player : public Unit, public GridObject<Player>
//We allow only one timed quest active at the same time. Below can then be simple value instead of set.
typedef std::set<uint32> QuestSet;
+ typedef std::set<uint32> SeasonalQuestSet;
+ typedef UNORDERED_MAP<uint32,SeasonalQuestSet> SeasonalEventQuestMap;
QuestSet m_timedquests;
QuestSet m_weeklyquests;
+ SeasonalEventQuestMap m_seasonalquests;
uint64 m_divider;
uint32 m_ingametime;
@@ -2580,6 +2587,7 @@ class Player : public Unit, public GridObject<Player>
void _LoadQuestStatusRewarded(PreparedQueryResult result);
void _LoadDailyQuestStatus(PreparedQueryResult result);
void _LoadWeeklyQuestStatus(PreparedQueryResult result);
+ void _LoadSeasonalQuestStatus(PreparedQueryResult result);
void _LoadRandomBGStatus(PreparedQueryResult result);
void _LoadGroup(PreparedQueryResult result);
void _LoadSkills(PreparedQueryResult result);
@@ -2605,6 +2613,7 @@ class Player : public Unit, public GridObject<Player>
void _SaveQuestStatus(SQLTransaction& trans);
void _SaveDailyQuestStatus(SQLTransaction& trans);
void _SaveWeeklyQuestStatus(SQLTransaction& trans);
+ void _SaveSeasonalQuestStatus(SQLTransaction& trans);
void _SaveSkills(SQLTransaction& trans);
void _SaveSpells(SQLTransaction& trans);
void _SaveEquipmentSets(SQLTransaction& trans);
@@ -2716,6 +2725,7 @@ class Player : public Unit, public GridObject<Player>
bool m_DailyQuestChanged;
bool m_WeeklyQuestChanged;
+ bool m_SeasonalQuestChanged;
time_t m_lastDailyQuestTime;
uint32 m_drunkTimer;
diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp
index 8b9e2fe047b..e1900c6c994 100755
--- a/src/server/game/Events/GameEventMgr.cpp
+++ b/src/server/game/Events/GameEventMgr.cpp
@@ -759,6 +759,47 @@ void GameEventMgr::LoadFromDB()
}
}
+ sLog->outString("Loading Game Event Seasonal Quest Relations...");
+ {
+ uint32 oldMSTime = getMSTime();
+
+ // 0 1
+ QueryResult result = WorldDatabase.Query("SELECT quest, event FROM game_event_seasonal_questrelation");
+
+ if (!result)
+ {
+ sLog->outString(">> Loaded 0 seasonal quests additions in game events. DB table `game_event_seasonal_questrelation` is empty.");
+ sLog->outString();
+ }
+ else
+ {
+ uint32 count = 0;
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint32 quest = fields[0].GetUInt32();
+ uint16 event_id = fields[1].GetUInt16();
+
+ if (event_id >= mGameEvent.size())
+ {
+ sLog->outErrorDb("`game_event_seasonal_questrelation` event id (%u) is out of range compared to max event in `game_event`", event_id);
+ continue;
+ }
+
+ Quest * qInfo = sObjectMgr->GetQuestTemplate(quest);
+ if (qInfo)
+ qInfo->SetSeasonalQuestEvent(event_id);
+
+ ++count;
+ }
+ while (result->NextRow());
+
+ sLog->outString(">> Loaded %u quests additions in game events in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ sLog->outString();
+ }
+ }
+
sLog->outString("Loading Game Event Vendor Additions Data...");
{
uint32 oldMSTime = getMSTime();
@@ -1079,6 +1120,8 @@ void GameEventMgr::UnApplyEvent(uint16 event_id)
UpdateEventNPCVendor(event_id, false);
// update bg holiday
UpdateBattlegroundSettings();
+ // check for seasonal quest reset.
+ sWorld->ResetEventSeasonalQuests(event_id);
}
void GameEventMgr::ApplyNewEvent(uint16 event_id)
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index 57c6fe1ad2f..1b6d90da0a6 100755
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -687,6 +687,11 @@ class ObjectMgr
QuestMap::const_iterator itr = mQuestTemplates.find(quest_id);
return itr != mQuestTemplates.end() ? itr->second : NULL;
}
+ Quest * GetQuestTemplate(uint32 quest_id)
+ {
+ QuestMap::const_iterator itr = mQuestTemplates.find(quest_id);
+ return itr != mQuestTemplates.end() ? itr->second : NULL;
+ }
QuestMap const& GetQuestTemplates() const { return mQuestTemplates; }
uint32 GetQuestForAreaTrigger(uint32 Trigger_ID) const
diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp
index 14a6577b1b5..674f54d07a8 100755
--- a/src/server/game/Quests/QuestDef.cpp
+++ b/src/server/game/Quests/QuestDef.cpp
@@ -65,6 +65,7 @@ Quest::Quest(Field* questRecord)
RequiredPlayerKills = questRecord[40].GetUInt32();
RewardTalents = questRecord[41].GetUInt32();
RewardArenaPoints = questRecord[42].GetInt32();
+ SeasonalQuestEvent = 0;
for (int i = 0; i < QUEST_REWARDS_COUNT; ++i)
RewardItemId[i] = questRecord[43+i].GetUInt32();
diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h
index 90905f2fa34..4fbfcd176f4 100755
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -187,6 +187,7 @@ class Quest
bool HasFlag(uint32 flag) const { return (Flags & flag) != 0; }
void SetFlag(uint32 flag) { Flags |= flag; }
+ void SetSeasonalQuestEvent(uint16 event_id) { SeasonalQuestEvent = event_id; }
// table data accessors:
uint32 GetQuestId() const { return Id; }
@@ -246,11 +247,13 @@ class Quest
uint32 GetCompleteEmote() const { return EmoteOnComplete; }
uint32 GetQuestStartScript() const { return StartScript; }
uint32 GetQuestCompleteScript() const { return CompleteScript; }
+ uint16 GetSeasonalQuestEvent() const {return SeasonalQuestEvent; }
bool IsRepeatable() const { return Flags & QUEST_TRINITY_FLAGS_REPEATABLE; }
bool IsAutoComplete() const;
uint32 GetFlags() const { return Flags; }
bool IsDaily() const { return Flags & QUEST_FLAGS_DAILY; }
bool IsWeekly() const { return Flags & QUEST_FLAGS_WEEKLY; }
+ bool IsSeasonal() const { return ZoneOrSort == -22; }
bool IsDailyOrWeekly() const { return Flags & (QUEST_FLAGS_DAILY | QUEST_FLAGS_WEEKLY); }
bool IsAutoAccept() const { return Flags & QUEST_FLAGS_AUTO_ACCEPT; }
bool IsRaidQuest() const { return Type == QUEST_TYPE_RAID || Type == QUEST_TYPE_RAID_10 || Type == QUEST_TYPE_RAID_25; }
@@ -295,6 +298,8 @@ class Quest
uint32 m_reqCreatureOrGOcount;
uint32 m_rewchoiceitemscount;
uint32 m_rewitemscount;
+ //additional data needed for seasonal quest events
+ uint16 SeasonalQuestEvent;
// table data
protected:
diff --git a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
index 11de2c68ca1..47af8c9bc1e 100755..100644
--- a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
@@ -93,9 +93,13 @@ bool LoginQueryHolder::Initialize()
stmt->setUInt32(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS, stmt);
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_WEKLYQUESTSTATUS);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_WEEKLYQUESTSTATUS);
stmt->setUInt32(0, lowGuid);
- res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOADWEKLYQUESTSTATUS, stmt);
+ res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOADWEEKLYQUESTSTATUS, stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_SEASONALQUESTSTATUS);
+ stmt->setUInt32(0, lowGuid);
+ res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOADSEASONALQUESTSTATUS, stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_REPUTATION);
stmt->setUInt32(0, lowGuid);
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 388bafc503d..426a93fda57 100755
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -2748,6 +2748,17 @@ void World::ResetWeeklyQuests()
sPoolMgr->ChangeWeeklyQuests();
}
+void World::ResetEventSeasonalQuests(uint16 event_id)
+{
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_QUEST_STATUS_SEASONAL);
+ stmt->setUInt16(0,event_id);
+ CharacterDatabase.Execute(stmt);
+
+ for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
+ if (itr->second->GetPlayer())
+ itr->second->GetPlayer()->ResetSeasonalQuestStatus(event_id);
+}
+
void World::ResetRandomBG()
{
sLog->outDetail("Random BG status reset for all characters.");
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 02438375058..bedd8a87b20 100755
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -746,6 +746,7 @@ class World
uint32 GetCleaningFlags() const { return m_CleaningFlags; }
void SetCleaningFlags(uint32 flags) { m_CleaningFlags = flags; }
+ void ResetEventSeasonalQuests(uint16 event_id);
protected:
void _UpdateGameTime();
// callback for UpdateRealmCharacters
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index b5b174a19eb..31fd5f66375 100755..100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
@@ -46,6 +46,10 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PREPARE_STATEMENT(CHAR_SEL_GUID_RACE_ACC_BY_NAME, "SELECT guid, race, account FROM characters WHERE name = ?", CONNECTION_ASYNC);
PREPARE_STATEMENT(CHAR_DEL_QUEST_STATUS_DAILY, "DELETE FROM character_queststatus_daily", CONNECTION_ASYNC);
PREPARE_STATEMENT(CHAR_DEL_QUEST_STATUS_WEEKLY, "DELETE FROM character_queststatus_weekly", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_DEL_QUEST_STATUS_SEASONAL, "DELETE FROM character_queststatus_seasonal WHERE event = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_DEL_QUEST_STATUS_DAILY_CHAR, "DELETE FROM character_queststatus_daily WHERE guid = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_DEL_QUEST_STATUS_WEEKLY_CHAR, "DELETE FROM character_queststatus_weekly WHERE guid = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_DEL_QUEST_STATUS_SEASONAL_CHAR, "DELETE FROM character_queststatus_seasonal WHERE guid = ?", CONNECTION_ASYNC);
PREPARE_STATEMENT(CHAR_DEL_BATTLEGROUND_RANDOM, "DELETE FROM character_battleground_random", CONNECTION_ASYNC);
PREPARE_STATEMENT(CHAR_INS_BATTLEGROUND_RANDOM, "INSERT INTO character_battleground_random (guid) VALUES (?)", CONNECTION_ASYNC);
@@ -63,7 +67,11 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PREPARE_STATEMENT(CHAR_SEL_CHARACTER_QUESTSTATUS, "SELECT quest, status, explored, timer, mobcount1, mobcount2, mobcount3, mobcount4, "
"itemcount1, itemcount2, itemcount3, itemcount4, playercount FROM character_queststatus WHERE guid = ?", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_SEL_CHARACTER_DAILYQUESTSTATUS, "SELECT quest, time FROM character_queststatus_daily WHERE guid = ?", CONNECTION_ASYNC)
- PREPARE_STATEMENT(CHAR_SEL_CHARACTER_WEKLYQUESTSTATUS, "SELECT quest FROM character_queststatus_weekly WHERE guid = ?", CONNECTION_ASYNC)
+ PREPARE_STATEMENT(CHAR_SEL_CHARACTER_WEEKLYQUESTSTATUS, "SELECT quest FROM character_queststatus_weekly WHERE guid = ?", CONNECTION_ASYNC)
+ PREPARE_STATEMENT(CHAR_SEL_CHARACTER_SEASONALQUESTSTATUS, "SELECT quest FROM character_queststatus_seasonal WHERE guid = ?", CONNECTION_ASYNC)
+ PREPARE_STATEMENT(CHAR_INS_CHARACTER_DAILYQUESTSTATUS, "INSERT INTO character_queststatus_daily (guid, quest, time) VALUES (?, ?, ?)", CONNECTION_ASYNC)
+ PREPARE_STATEMENT(CHAR_INS_CHARACTER_WEEKLYQUESTSTATUS, "INSERT INTO character_queststatus_weekly (guid, quest) VALUES (?, ?)", CONNECTION_ASYNC)
+ PREPARE_STATEMENT(CHAR_INS_CHARACTER_SEASONALQUESTSTATUS, "INSERT INTO character_queststatus_seasonal (guid, quest, event) VALUES (?, ?, ?)", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_SEL_CHARACTER_REPUTATION, "SELECT faction, standing, flags FROM character_reputation WHERE guid = ?", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_SEL_CHARACTER_INVENTORY, "SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, bag, slot, "
"item, itemEntry FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid WHERE ci.guid = ? ORDER BY bag, slot", CONNECTION_ASYNC)
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h
index a0f5b9a9954..a239e274a54 100755..100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.h
@@ -66,6 +66,10 @@ enum CharacterDatabaseStatements
CHAR_SEL_GUID_RACE_ACC_BY_NAME,
CHAR_DEL_QUEST_STATUS_DAILY,
CHAR_DEL_QUEST_STATUS_WEEKLY,
+ CHAR_DEL_QUEST_STATUS_SEASONAL,
+ CHAR_DEL_QUEST_STATUS_DAILY_CHAR,
+ CHAR_DEL_QUEST_STATUS_WEEKLY_CHAR,
+ CHAR_DEL_QUEST_STATUS_SEASONAL_CHAR,
CHAR_DEL_BATTLEGROUND_RANDOM,
CHAR_INS_BATTLEGROUND_RANDOM,
@@ -76,7 +80,11 @@ enum CharacterDatabaseStatements
CHAR_SEL_CHARACTER_SPELL,
CHAR_SEL_CHARACTER_QUESTSTATUS,
CHAR_SEL_CHARACTER_DAILYQUESTSTATUS,
- CHAR_SEL_CHARACTER_WEKLYQUESTSTATUS,
+ CHAR_SEL_CHARACTER_WEEKLYQUESTSTATUS,
+ CHAR_SEL_CHARACTER_SEASONALQUESTSTATUS,
+ CHAR_INS_CHARACTER_DAILYQUESTSTATUS,
+ CHAR_INS_CHARACTER_WEEKLYQUESTSTATUS,
+ CHAR_INS_CHARACTER_SEASONALQUESTSTATUS,
CHAR_SEL_CHARACTER_REPUTATION,
CHAR_SEL_CHARACTER_INVENTORY,
CHAR_SEL_CHARACTER_ACTIONS,