mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 19:37:03 +00:00
[10655] Add support for monthly quests
Quest that can repeated each month are set by quest_template.SpecialFlags |0x04 flag Quest are reset at midnight the first day of each month. Note: for the time being, quest must also be set repeatable (SpecialFlags |0x01) Signed-off-by: NoFantasy <nofantasy@nf.no>
This commit is contained in:
parent
331a7e7f5b
commit
a38f97f71c
12 changed files with 218 additions and 13 deletions
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `character_db_version`;
|
DROP TABLE IF EXISTS `character_db_version`;
|
||||||
CREATE TABLE `character_db_version` (
|
CREATE TABLE `character_db_version` (
|
||||||
`required_10568_01_characters_character_tutorial` bit(1) default NULL
|
`required_10655_01_characters_character_queststatus_monthly` bit(1) default NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
@ -725,6 +725,27 @@ LOCK TABLES `character_queststatus_daily` WRITE;
|
||||||
/*!40000 ALTER TABLE `character_queststatus_daily` ENABLE KEYS */;
|
/*!40000 ALTER TABLE `character_queststatus_daily` ENABLE KEYS */;
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `character_queststatus_monthly`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `character_queststatus_monthly`;
|
||||||
|
CREATE TABLE `character_queststatus_monthly` (
|
||||||
|
`guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier',
|
||||||
|
`quest` int(11) unsigned NOT NULL default '0' COMMENT 'Quest Identifier',
|
||||||
|
PRIMARY KEY (`guid`,`quest`),
|
||||||
|
KEY `idx_guid` (`guid`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System';
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Dumping data for table `character_queststatus_monthly`
|
||||||
|
--
|
||||||
|
|
||||||
|
LOCK TABLES `character_queststatus_monthly` WRITE;
|
||||||
|
/*!40000 ALTER TABLE `character_queststatus_monthly` DISABLE KEYS */;
|
||||||
|
/*!40000 ALTER TABLE `character_queststatus_monthly` ENABLE KEYS */;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Table structure for table `character_queststatus_weekly`
|
-- Table structure for table `character_queststatus_weekly`
|
||||||
--
|
--
|
||||||
|
|
@ -1624,6 +1645,7 @@ CREATE TABLE `saved_variables` (
|
||||||
`NextArenaPointDistributionTime` bigint(40) UNSIGNED NOT NULL DEFAULT '0',
|
`NextArenaPointDistributionTime` bigint(40) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
`NextDailyQuestResetTime` bigint(40) unsigned NOT NULL default '0',
|
`NextDailyQuestResetTime` bigint(40) unsigned NOT NULL default '0',
|
||||||
`NextWeeklyQuestResetTime` bigint(40) unsigned NOT NULL default '0',
|
`NextWeeklyQuestResetTime` bigint(40) unsigned NOT NULL default '0',
|
||||||
|
`NextMonthlyQuestResetTime` bigint(40) unsigned NOT NULL default '0',
|
||||||
`cleaning_flags` int(11) unsigned NOT NULL default '0'
|
`cleaning_flags` int(11) unsigned NOT NULL default '0'
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Variable Saves';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Variable Saves';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
ALTER TABLE character_db_version CHANGE COLUMN required_10568_01_characters_character_tutorial required_10655_01_characters_character_queststatus_monthly bit;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS character_queststatus_monthly;
|
||||||
|
CREATE TABLE character_queststatus_monthly (
|
||||||
|
guid int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier',
|
||||||
|
quest int(11) unsigned NOT NULL default '0' COMMENT 'Quest Identifier',
|
||||||
|
PRIMARY KEY (guid,quest),
|
||||||
|
KEY idx_guid (guid)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System';
|
||||||
|
|
||||||
|
ALTER TABLE saved_variables
|
||||||
|
ADD COLUMN NextMonthlyQuestResetTime bigint(40) unsigned NOT NULL default '0' AFTER NextWeeklyQuestResetTime;
|
||||||
|
|
@ -110,6 +110,7 @@ pkgdata_DATA = \
|
||||||
10628_01_mangos_mangos_string.sql \
|
10628_01_mangos_mangos_string.sql \
|
||||||
10629_01_mangos_mangos_string.sql \
|
10629_01_mangos_mangos_string.sql \
|
||||||
10654_01_mangos_game_event_creature_quest.sql \
|
10654_01_mangos_game_event_creature_quest.sql \
|
||||||
|
10655_01_characters_character_queststatus_monthly.sql \
|
||||||
README
|
README
|
||||||
|
|
||||||
## Additional files to include when running 'make dist'
|
## Additional files to include when running 'make dist'
|
||||||
|
|
@ -200,4 +201,5 @@ EXTRA_DIST = \
|
||||||
10628_01_mangos_mangos_string.sql \
|
10628_01_mangos_mangos_string.sql \
|
||||||
10629_01_mangos_mangos_string.sql \
|
10629_01_mangos_mangos_string.sql \
|
||||||
10654_01_mangos_game_event_creature_quest.sql \
|
10654_01_mangos_game_event_creature_quest.sql \
|
||||||
|
10655_01_characters_character_queststatus_monthly.sql \
|
||||||
README
|
README
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,7 @@ bool LoginQueryHolder::Initialize()
|
||||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS, "SELECT quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4 FROM character_queststatus WHERE guid = '%u'", GUID_LOPART(m_guid));
|
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS, "SELECT quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4 FROM character_queststatus WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS,"SELECT quest FROM character_queststatus_daily WHERE guid = '%u'", GUID_LOPART(m_guid));
|
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS,"SELECT quest FROM character_queststatus_daily WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADWEEKLYQUESTSTATUS,"SELECT quest FROM character_queststatus_weekly WHERE guid = '%u'", GUID_LOPART(m_guid));
|
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADWEEKLYQUESTSTATUS,"SELECT quest FROM character_queststatus_weekly WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||||
|
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMONTHLYQUESTSTATUS,"SELECT quest FROM character_queststatus_monthly WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADREPUTATION, "SELECT faction,standing,flags FROM character_reputation WHERE guid = '%u'", GUID_LOPART(m_guid));
|
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADREPUTATION, "SELECT faction,standing,flags FROM character_reputation WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADINVENTORY, "SELECT data,text,bag,slot,item,item_template FROM character_inventory JOIN item_instance ON character_inventory.item = item_instance.guid WHERE character_inventory.guid = '%u' ORDER BY bag,slot", GUID_LOPART(m_guid));
|
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADINVENTORY, "SELECT data,text,bag,slot,item,item_template FROM character_inventory JOIN item_instance ON character_inventory.item = item_instance.guid WHERE character_inventory.guid = '%u' ORDER BY bag,slot", GUID_LOPART(m_guid));
|
||||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACTIONS, "SELECT spec,button,action,type FROM character_action WHERE guid = '%u' ORDER BY button", GUID_LOPART(m_guid));
|
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACTIONS, "SELECT spec,button,action,type FROM character_action WHERE guid = '%u' ORDER BY button", GUID_LOPART(m_guid));
|
||||||
|
|
|
||||||
|
|
@ -3685,6 +3685,15 @@ void ObjectMgr::LoadQuests()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (qinfo->QuestFlags & QUEST_MANGOS_FLAGS_MONTHLY)
|
||||||
|
{
|
||||||
|
if (!(qinfo->QuestFlags & QUEST_MANGOS_FLAGS_REPEATABLE))
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("Monthly quest %u not marked as repeatable in `SpecialFlags`, added.", qinfo->GetQuestId());
|
||||||
|
qinfo->QuestFlags |= QUEST_MANGOS_FLAGS_REPEATABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (qinfo->QuestFlags & QUEST_FLAGS_AUTO_REWARDED)
|
if (qinfo->QuestFlags & QUEST_FLAGS_AUTO_REWARDED)
|
||||||
{
|
{
|
||||||
// at auto-reward can be rewarded only RewChoiceItemId[0]
|
// at auto-reward can be rewarded only RewChoiceItemId[0]
|
||||||
|
|
|
||||||
|
|
@ -13275,7 +13275,8 @@ bool Player::CanSeeStartQuest(Quest const *pQuest) const
|
||||||
if (SatisfyQuestClass(pQuest, false) && SatisfyQuestRace(pQuest, false) && SatisfyQuestSkill(pQuest, false) &&
|
if (SatisfyQuestClass(pQuest, false) && SatisfyQuestRace(pQuest, false) && SatisfyQuestSkill(pQuest, false) &&
|
||||||
SatisfyQuestExclusiveGroup(pQuest, false) && SatisfyQuestReputation(pQuest, false) &&
|
SatisfyQuestExclusiveGroup(pQuest, false) && SatisfyQuestReputation(pQuest, false) &&
|
||||||
SatisfyQuestPreviousQuest(pQuest, false) && SatisfyQuestNextChain(pQuest, false) &&
|
SatisfyQuestPreviousQuest(pQuest, false) && SatisfyQuestNextChain(pQuest, false) &&
|
||||||
SatisfyQuestPrevChain(pQuest, false) && SatisfyQuestDay(pQuest, false) && SatisfyQuestWeek(pQuest, false))
|
SatisfyQuestPrevChain(pQuest, false) && SatisfyQuestDay(pQuest, false) && SatisfyQuestWeek(pQuest, false) &&
|
||||||
|
SatisfyQuestMonth(pQuest, false))
|
||||||
{
|
{
|
||||||
return getLevel() + sWorld.getConfig(CONFIG_UINT32_QUEST_HIGH_LEVEL_HIDE_DIFF) >= pQuest->GetMinLevel();
|
return getLevel() + sWorld.getConfig(CONFIG_UINT32_QUEST_HIGH_LEVEL_HIDE_DIFF) >= pQuest->GetMinLevel();
|
||||||
}
|
}
|
||||||
|
|
@ -13290,7 +13291,7 @@ bool Player::CanTakeQuest(Quest const *pQuest, bool msg) const
|
||||||
SatisfyQuestSkill(pQuest, msg) && SatisfyQuestReputation(pQuest, msg) &&
|
SatisfyQuestSkill(pQuest, msg) && SatisfyQuestReputation(pQuest, msg) &&
|
||||||
SatisfyQuestPreviousQuest(pQuest, msg) && SatisfyQuestTimed(pQuest, msg) &&
|
SatisfyQuestPreviousQuest(pQuest, msg) && SatisfyQuestTimed(pQuest, msg) &&
|
||||||
SatisfyQuestNextChain(pQuest, msg) && SatisfyQuestPrevChain(pQuest, msg) &&
|
SatisfyQuestNextChain(pQuest, msg) && SatisfyQuestPrevChain(pQuest, msg) &&
|
||||||
SatisfyQuestDay(pQuest, msg) && SatisfyQuestWeek(pQuest, msg);
|
SatisfyQuestDay(pQuest, msg) && SatisfyQuestWeek(pQuest, msg) && SatisfyQuestMonth(pQuest, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Player::CanAddQuest(Quest const *pQuest, bool msg) const
|
bool Player::CanAddQuest(Quest const *pQuest, bool msg) const
|
||||||
|
|
@ -13409,7 +13410,7 @@ bool Player::CanRewardQuest(Quest const *pQuest, bool msg) const
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// daily quest can't be rewarded (25 daily quest already completed)
|
// daily quest can't be rewarded (25 daily quest already completed)
|
||||||
if (!SatisfyQuestDay(pQuest, true) || !SatisfyQuestWeek(pQuest, true))
|
if (!SatisfyQuestDay(pQuest, true) || !SatisfyQuestWeek(pQuest, true) || !SatisfyQuestMonth(pQuest, true))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// rewarded and not repeatable quest (only cheating case, then ignore without message)
|
// rewarded and not repeatable quest (only cheating case, then ignore without message)
|
||||||
|
|
@ -13695,6 +13696,9 @@ void Player::RewardQuest(Quest const *pQuest, uint32 reward, Object* questGiver,
|
||||||
if (pQuest->IsWeekly())
|
if (pQuest->IsWeekly())
|
||||||
SetWeeklyQuestStatus(quest_id);
|
SetWeeklyQuestStatus(quest_id);
|
||||||
|
|
||||||
|
if (pQuest->IsMonthly())
|
||||||
|
SetMonthlyQuestStatus(quest_id);
|
||||||
|
|
||||||
if (!pQuest->IsRepeatable())
|
if (!pQuest->IsRepeatable())
|
||||||
SetQuestStatus(quest_id, QUEST_STATUS_COMPLETE);
|
SetQuestStatus(quest_id, QUEST_STATUS_COMPLETE);
|
||||||
else
|
else
|
||||||
|
|
@ -14133,6 +14137,15 @@ bool Player::SatisfyQuestWeek(Quest const* qInfo, bool msg) const
|
||||||
return m_weeklyquests.find(qInfo->GetQuestId()) == m_weeklyquests.end();
|
return m_weeklyquests.find(qInfo->GetQuestId()) == m_weeklyquests.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Player::SatisfyQuestMonth(Quest const* qInfo, bool msg) const
|
||||||
|
{
|
||||||
|
if (!qInfo->IsMonthly() || m_monthlyquests.empty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// if not found in cooldown list
|
||||||
|
return m_monthlyquests.find(qInfo->GetQuestId()) == m_monthlyquests.end();
|
||||||
|
}
|
||||||
|
|
||||||
bool Player::CanGiveQuestSourceItem( Quest const *pQuest, ItemPosCountVec* dest ) const
|
bool Player::CanGiveQuestSourceItem( Quest const *pQuest, ItemPosCountVec* dest ) const
|
||||||
{
|
{
|
||||||
uint32 srcitem = pQuest->GetSrcItemId();
|
uint32 srcitem = pQuest->GetSrcItemId();
|
||||||
|
|
@ -15458,6 +15471,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||||
_LoadQuestStatus(holder->GetResult(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS));
|
_LoadQuestStatus(holder->GetResult(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS));
|
||||||
_LoadDailyQuestStatus(holder->GetResult(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS));
|
_LoadDailyQuestStatus(holder->GetResult(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS));
|
||||||
_LoadWeeklyQuestStatus(holder->GetResult(PLAYER_LOGIN_QUERY_LOADWEEKLYQUESTSTATUS));
|
_LoadWeeklyQuestStatus(holder->GetResult(PLAYER_LOGIN_QUERY_LOADWEEKLYQUESTSTATUS));
|
||||||
|
_LoadMonthlyQuestStatus(holder->GetResult(PLAYER_LOGIN_QUERY_LOADMONTHLYQUESTSTATUS));
|
||||||
|
|
||||||
_LoadTalents(holder->GetResult(PLAYER_LOGIN_QUERY_LOADTALENTS));
|
_LoadTalents(holder->GetResult(PLAYER_LOGIN_QUERY_LOADTALENTS));
|
||||||
|
|
||||||
|
|
@ -16291,6 +16305,36 @@ void Player::_LoadWeeklyQuestStatus(QueryResult *result)
|
||||||
m_WeeklyQuestChanged = false;
|
m_WeeklyQuestChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::_LoadMonthlyQuestStatus(QueryResult *result)
|
||||||
|
{
|
||||||
|
m_monthlyquests.clear();
|
||||||
|
|
||||||
|
//QueryResult *result = CharacterDatabase.PQuery("SELECT quest FROM character_queststatus_weekly WHERE guid = '%u'", GetGUIDLow());
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Field *fields = result->Fetch();
|
||||||
|
|
||||||
|
uint32 quest_id = fields[0].GetUInt32();
|
||||||
|
|
||||||
|
Quest const* pQuest = sObjectMgr.GetQuestTemplate(quest_id);
|
||||||
|
if (!pQuest)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
m_monthlyquests.insert(quest_id);
|
||||||
|
|
||||||
|
DEBUG_LOG("Monthly quest {%u} cooldown for player (GUID: %u)", quest_id, GetGUIDLow());
|
||||||
|
}
|
||||||
|
while( result->NextRow() );
|
||||||
|
|
||||||
|
delete result;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_MonthlyQuestChanged = false;
|
||||||
|
}
|
||||||
|
|
||||||
void Player::_LoadSpells(QueryResult *result)
|
void Player::_LoadSpells(QueryResult *result)
|
||||||
{
|
{
|
||||||
//QueryResult *result = CharacterDatabase.PQuery("SELECT spell,active,disabled FROM character_spell WHERE guid = '%u'",GetGUIDLow());
|
//QueryResult *result = CharacterDatabase.PQuery("SELECT spell,active,disabled FROM character_spell WHERE guid = '%u'",GetGUIDLow());
|
||||||
|
|
@ -16911,6 +16955,7 @@ void Player::SaveToDB()
|
||||||
_SaveQuestStatus();
|
_SaveQuestStatus();
|
||||||
_SaveDailyQuestStatus();
|
_SaveDailyQuestStatus();
|
||||||
_SaveWeeklyQuestStatus();
|
_SaveWeeklyQuestStatus();
|
||||||
|
_SaveMonthlyQuestStatus();
|
||||||
_SaveSpells();
|
_SaveSpells();
|
||||||
_SaveSpellCooldowns();
|
_SaveSpellCooldowns();
|
||||||
_SaveActions();
|
_SaveActions();
|
||||||
|
|
@ -17239,6 +17284,24 @@ void Player::_SaveWeeklyQuestStatus()
|
||||||
m_WeeklyQuestChanged = false;
|
m_WeeklyQuestChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::_SaveMonthlyQuestStatus()
|
||||||
|
{
|
||||||
|
if (!m_MonthlyQuestChanged || m_monthlyquests.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// we don't need transactions here.
|
||||||
|
CharacterDatabase.PExecute("DELETE FROM character_queststatus_monthly WHERE guid = '%u'", GetGUIDLow());
|
||||||
|
|
||||||
|
for (QuestSet::const_iterator iter = m_monthlyquests.begin(); iter != m_monthlyquests.end(); ++iter)
|
||||||
|
{
|
||||||
|
uint32 quest_id = *iter;
|
||||||
|
|
||||||
|
CharacterDatabase.PExecute("INSERT INTO character_queststatus_monthly (guid, quest) VALUES ('%u', '%u')", GetGUIDLow(), quest_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_MonthlyQuestChanged = false;
|
||||||
|
}
|
||||||
|
|
||||||
void Player::_SaveSkills()
|
void Player::_SaveSkills()
|
||||||
{
|
{
|
||||||
// we don't need transactions here.
|
// we don't need transactions here.
|
||||||
|
|
@ -19941,6 +20004,12 @@ void Player::SetWeeklyQuestStatus( uint32 quest_id )
|
||||||
m_WeeklyQuestChanged = true;
|
m_WeeklyQuestChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::SetMonthlyQuestStatus(uint32 quest_id)
|
||||||
|
{
|
||||||
|
m_monthlyquests.insert(quest_id);
|
||||||
|
m_MonthlyQuestChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
void Player::ResetDailyQuestStatus()
|
void Player::ResetDailyQuestStatus()
|
||||||
{
|
{
|
||||||
for(uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx)
|
for(uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx)
|
||||||
|
|
@ -19960,6 +20029,16 @@ void Player::ResetWeeklyQuestStatus()
|
||||||
m_WeeklyQuestChanged = false;
|
m_WeeklyQuestChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::ResetMonthlyQuestStatus()
|
||||||
|
{
|
||||||
|
if (m_monthlyquests.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_monthlyquests.clear();
|
||||||
|
// DB data deleted in caller
|
||||||
|
m_MonthlyQuestChanged = false;
|
||||||
|
}
|
||||||
|
|
||||||
BattleGround* Player::GetBattleGround() const
|
BattleGround* Player::GetBattleGround() const
|
||||||
{
|
{
|
||||||
if(GetBattleGroundId()==0)
|
if(GetBattleGroundId()==0)
|
||||||
|
|
|
||||||
|
|
@ -914,6 +914,7 @@ enum PlayerLoginQueryIndex
|
||||||
PLAYER_LOGIN_QUERY_LOADMAILEDITEMS,
|
PLAYER_LOGIN_QUERY_LOADMAILEDITEMS,
|
||||||
PLAYER_LOGIN_QUERY_LOADTALENTS,
|
PLAYER_LOGIN_QUERY_LOADTALENTS,
|
||||||
PLAYER_LOGIN_QUERY_LOADWEEKLYQUESTSTATUS,
|
PLAYER_LOGIN_QUERY_LOADWEEKLYQUESTSTATUS,
|
||||||
|
PLAYER_LOGIN_QUERY_LOADMONTHLYQUESTSTATUS,
|
||||||
|
|
||||||
MAX_PLAYER_LOGIN_QUERY
|
MAX_PLAYER_LOGIN_QUERY
|
||||||
};
|
};
|
||||||
|
|
@ -1435,6 +1436,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
bool SatisfyQuestPrevChain( Quest const* qInfo, bool msg ) const;
|
bool SatisfyQuestPrevChain( Quest const* qInfo, bool msg ) const;
|
||||||
bool SatisfyQuestDay( Quest const* qInfo, bool msg ) const;
|
bool SatisfyQuestDay( Quest const* qInfo, bool msg ) const;
|
||||||
bool SatisfyQuestWeek( Quest const* qInfo, bool msg ) const;
|
bool SatisfyQuestWeek( Quest const* qInfo, bool msg ) const;
|
||||||
|
bool SatisfyQuestMonth(Quest const* qInfo, bool msg) const;
|
||||||
bool CanGiveQuestSourceItem( Quest const *pQuest, ItemPosCountVec* dest = NULL) const;
|
bool CanGiveQuestSourceItem( Quest const *pQuest, ItemPosCountVec* dest = NULL) const;
|
||||||
void GiveQuestSourceItem( Quest const *pQuest );
|
void GiveQuestSourceItem( Quest const *pQuest );
|
||||||
bool TakeQuestSourceItem( uint32 quest_id, bool msg );
|
bool TakeQuestSourceItem( uint32 quest_id, bool msg );
|
||||||
|
|
@ -1444,8 +1446,10 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
|
|
||||||
void SetDailyQuestStatus( uint32 quest_id );
|
void SetDailyQuestStatus( uint32 quest_id );
|
||||||
void SetWeeklyQuestStatus( uint32 quest_id );
|
void SetWeeklyQuestStatus( uint32 quest_id );
|
||||||
|
void SetMonthlyQuestStatus(uint32 quest_id);
|
||||||
void ResetDailyQuestStatus();
|
void ResetDailyQuestStatus();
|
||||||
void ResetWeeklyQuestStatus();
|
void ResetWeeklyQuestStatus();
|
||||||
|
void ResetMonthlyQuestStatus();
|
||||||
|
|
||||||
uint16 FindQuestSlot( uint32 quest_id ) const;
|
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); }
|
uint32 GetQuestSlotQuestId(uint16 slot) const { return GetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_ID_OFFSET); }
|
||||||
|
|
@ -2425,6 +2429,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
typedef std::set<uint32> QuestSet;
|
typedef std::set<uint32> QuestSet;
|
||||||
QuestSet m_timedquests;
|
QuestSet m_timedquests;
|
||||||
QuestSet m_weeklyquests;
|
QuestSet m_weeklyquests;
|
||||||
|
QuestSet m_monthlyquests;
|
||||||
|
|
||||||
uint64 m_divider;
|
uint64 m_divider;
|
||||||
uint32 m_ingametime;
|
uint32 m_ingametime;
|
||||||
|
|
@ -2442,6 +2447,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
void _LoadQuestStatus(QueryResult *result);
|
void _LoadQuestStatus(QueryResult *result);
|
||||||
void _LoadDailyQuestStatus(QueryResult *result);
|
void _LoadDailyQuestStatus(QueryResult *result);
|
||||||
void _LoadWeeklyQuestStatus(QueryResult *result);
|
void _LoadWeeklyQuestStatus(QueryResult *result);
|
||||||
|
void _LoadMonthlyQuestStatus(QueryResult *result);
|
||||||
void _LoadGroup(QueryResult *result);
|
void _LoadGroup(QueryResult *result);
|
||||||
void _LoadSkills(QueryResult *result);
|
void _LoadSkills(QueryResult *result);
|
||||||
void _LoadSpells(QueryResult *result);
|
void _LoadSpells(QueryResult *result);
|
||||||
|
|
@ -2466,6 +2472,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
void _SaveQuestStatus();
|
void _SaveQuestStatus();
|
||||||
void _SaveDailyQuestStatus();
|
void _SaveDailyQuestStatus();
|
||||||
void _SaveWeeklyQuestStatus();
|
void _SaveWeeklyQuestStatus();
|
||||||
|
void _SaveMonthlyQuestStatus();
|
||||||
void _SaveSkills();
|
void _SaveSkills();
|
||||||
void _SaveSpells();
|
void _SaveSpells();
|
||||||
void _SaveEquipmentSets();
|
void _SaveEquipmentSets();
|
||||||
|
|
@ -2565,6 +2572,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
|
|
||||||
bool m_DailyQuestChanged;
|
bool m_DailyQuestChanged;
|
||||||
bool m_WeeklyQuestChanged;
|
bool m_WeeklyQuestChanged;
|
||||||
|
bool m_MonthlyQuestChanged;
|
||||||
|
|
||||||
uint32 m_drunkTimer;
|
uint32 m_drunkTimer;
|
||||||
uint16 m_drunk;
|
uint16 m_drunk;
|
||||||
|
|
|
||||||
|
|
@ -160,15 +160,17 @@ enum __QuestFlags
|
||||||
QUEST_FLAGS_AUTO_ACCEPT = 0x00080000, // quests in starting areas
|
QUEST_FLAGS_AUTO_ACCEPT = 0x00080000, // quests in starting areas
|
||||||
|
|
||||||
// Mangos flags for set SpecialFlags in DB if required but used only at server
|
// Mangos flags for set SpecialFlags in DB if required but used only at server
|
||||||
QUEST_MANGOS_FLAGS_REPEATABLE = 0x01000000, // Set by 1 in SpecialFlags from DB
|
QUEST_MANGOS_FLAGS_REPEATABLE = 0x001000000, // Set by 1 in SpecialFlags from DB
|
||||||
QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT = 0x02000000, // Set by 2 in SpecialFlags from DB (if required area explore, spell SPELL_EFFECT_QUEST_COMPLETE casting, table `*_script` command SCRIPT_COMMAND_QUEST_EXPLORED use, set from script DLL)
|
QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT = 0x002000000, // Set by 2 in SpecialFlags from DB (if required area explore, spell SPELL_EFFECT_QUEST_COMPLETE casting, table `*_script` command SCRIPT_COMMAND_QUEST_EXPLORED use, set from script DLL)
|
||||||
QUEST_MANGOS_FLAGS_DB_ALLOWED = 0xFFFFFF | QUEST_MANGOS_FLAGS_REPEATABLE | QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT,
|
QUEST_MANGOS_FLAGS_MONTHLY = 0x004000000, // 4 in SpecialFlags. Quest reset for player at beginning of month.
|
||||||
|
QUEST_MANGOS_FLAGS_DB_ALLOWED = 0xFFFFFF |
|
||||||
|
QUEST_MANGOS_FLAGS_REPEATABLE | QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT | QUEST_MANGOS_FLAGS_MONTHLY,
|
||||||
|
|
||||||
// Mangos flags for internal use only
|
// Mangos flags for internal use only
|
||||||
QUEST_MANGOS_FLAGS_DELIVER = 0x04000000, // Internal flag computed only
|
QUEST_MANGOS_FLAGS_DELIVER = 0x008000000, // Internal flag computed only
|
||||||
QUEST_MANGOS_FLAGS_SPEAKTO = 0x08000000, // Internal flag computed only
|
QUEST_MANGOS_FLAGS_SPEAKTO = 0x010000000, // Internal flag computed only
|
||||||
QUEST_MANGOS_FLAGS_KILL_OR_CAST = 0x10000000, // Internal flag computed only
|
QUEST_MANGOS_FLAGS_KILL_OR_CAST = 0x020000000, // Internal flag computed only
|
||||||
QUEST_MANGOS_FLAGS_TIMED = 0x20000000, // Internal flag computed only
|
QUEST_MANGOS_FLAGS_TIMED = 0x040000000, // Internal flag computed only
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QuestLocale
|
struct QuestLocale
|
||||||
|
|
@ -257,6 +259,7 @@ class Quest
|
||||||
uint32 GetFlags() const { return QuestFlags; }
|
uint32 GetFlags() const { return QuestFlags; }
|
||||||
bool IsDaily() const { return QuestFlags & QUEST_FLAGS_DAILY; }
|
bool IsDaily() const { return QuestFlags & QUEST_FLAGS_DAILY; }
|
||||||
bool IsWeekly() const { return QuestFlags & QUEST_FLAGS_WEEKLY; }
|
bool IsWeekly() const { return QuestFlags & QUEST_FLAGS_WEEKLY; }
|
||||||
|
bool IsMonthly() const { return QuestFlags & QUEST_MANGOS_FLAGS_MONTHLY; }
|
||||||
bool IsDailyOrWeekly() const { return QuestFlags & (QUEST_FLAGS_DAILY | QUEST_FLAGS_WEEKLY); }
|
bool IsDailyOrWeekly() const { return QuestFlags & (QUEST_FLAGS_DAILY | QUEST_FLAGS_WEEKLY); }
|
||||||
bool IsAutoAccept() const { return QuestFlags & QUEST_FLAGS_AUTO_ACCEPT; }
|
bool IsAutoAccept() const { return QuestFlags & QUEST_FLAGS_AUTO_ACCEPT; }
|
||||||
bool IsAllowedInRaid() const;
|
bool IsAllowedInRaid() const;
|
||||||
|
|
|
||||||
|
|
@ -1311,6 +1311,9 @@ void World::SetInitialWorldSettings()
|
||||||
sLog.outString("Calculate next weekly quest reset time..." );
|
sLog.outString("Calculate next weekly quest reset time..." );
|
||||||
InitWeeklyQuestResetTime();
|
InitWeeklyQuestResetTime();
|
||||||
|
|
||||||
|
sLog.outString("Calculate next monthly quest reset time..." );
|
||||||
|
SetMonthlyQuestResetTime();
|
||||||
|
|
||||||
sLog.outString("Starting objects Pooling system..." );
|
sLog.outString("Starting objects Pooling system..." );
|
||||||
sPoolMgr.Initialize();
|
sPoolMgr.Initialize();
|
||||||
|
|
||||||
|
|
@ -1395,6 +1398,10 @@ void World::Update(uint32 diff)
|
||||||
if (m_gameTime > m_NextWeeklyQuestReset)
|
if (m_gameTime > m_NextWeeklyQuestReset)
|
||||||
ResetWeeklyQuests();
|
ResetWeeklyQuests();
|
||||||
|
|
||||||
|
/// Handle monthly quests reset time
|
||||||
|
if (m_gameTime > m_NextMonthlyQuestReset)
|
||||||
|
ResetMonthlyQuests();
|
||||||
|
|
||||||
/// <ul><li> Handle auctions when the timer has passed
|
/// <ul><li> Handle auctions when the timer has passed
|
||||||
if (m_timers[WUPDATE_AUCTIONS].Passed())
|
if (m_timers[WUPDATE_AUCTIONS].Passed())
|
||||||
{
|
{
|
||||||
|
|
@ -1994,6 +2001,52 @@ void World::InitDailyQuestResetTime()
|
||||||
delete result;
|
delete result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void World::SetMonthlyQuestResetTime(bool initialize)
|
||||||
|
{
|
||||||
|
if (initialize)
|
||||||
|
{
|
||||||
|
QueryResult * result = CharacterDatabase.Query("SELECT NextMonthlyQuestResetTime FROM saved_variables");
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
m_NextMonthlyQuestReset = time_t(time(NULL));
|
||||||
|
else
|
||||||
|
m_NextMonthlyQuestReset = time_t((*result)[0].GetUInt64());
|
||||||
|
|
||||||
|
delete result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate time
|
||||||
|
time_t currentTime = time(NULL);
|
||||||
|
tm localTm = *localtime(¤tTime);
|
||||||
|
|
||||||
|
int month = localTm.tm_mon;
|
||||||
|
int year = localTm.tm_year;
|
||||||
|
|
||||||
|
++month;
|
||||||
|
|
||||||
|
// month 11 is december, next is january (0)
|
||||||
|
if (month > 11)
|
||||||
|
{
|
||||||
|
month = 0;
|
||||||
|
year += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset time for next month
|
||||||
|
localTm.tm_year = year;
|
||||||
|
localTm.tm_mon = month;
|
||||||
|
localTm.tm_mday = 1; // don't know if we really need config option for day/hour
|
||||||
|
localTm.tm_hour = 0;
|
||||||
|
localTm.tm_min = 0;
|
||||||
|
localTm.tm_sec = 0;
|
||||||
|
|
||||||
|
time_t nextMonthResetTime = mktime(&localTm);
|
||||||
|
|
||||||
|
m_NextMonthlyQuestReset = (initialize && m_NextMonthlyQuestReset < nextMonthResetTime) ? m_NextMonthlyQuestReset : nextMonthResetTime;
|
||||||
|
|
||||||
|
// Row must exist for this to work. Currently row is added by InitDailyQuestResetTime(), called before this function
|
||||||
|
CharacterDatabase.PExecute("UPDATE saved_variables SET NextMonthlyQuestResetTime = '"UI64FMTD"'", uint64(m_NextMonthlyQuestReset));
|
||||||
|
}
|
||||||
|
|
||||||
void World::ResetDailyQuests()
|
void World::ResetDailyQuests()
|
||||||
{
|
{
|
||||||
DETAIL_LOG("Daily quests reset for all characters.");
|
DETAIL_LOG("Daily quests reset for all characters.");
|
||||||
|
|
@ -2018,6 +2071,18 @@ void World::ResetWeeklyQuests()
|
||||||
CharacterDatabase.PExecute("UPDATE saved_variables SET NextWeeklyQuestResetTime = '"UI64FMTD"'", uint64(m_NextWeeklyQuestReset));
|
CharacterDatabase.PExecute("UPDATE saved_variables SET NextWeeklyQuestResetTime = '"UI64FMTD"'", uint64(m_NextWeeklyQuestReset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void World::ResetMonthlyQuests()
|
||||||
|
{
|
||||||
|
DETAIL_LOG("Monthly quests reset for all characters.");
|
||||||
|
CharacterDatabase.Execute("TRUNCATE character_queststatus_monthly");
|
||||||
|
|
||||||
|
for(SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
|
||||||
|
if (itr->second->GetPlayer())
|
||||||
|
itr->second->GetPlayer()->ResetMonthlyQuestStatus();
|
||||||
|
|
||||||
|
SetMonthlyQuestResetTime(false);
|
||||||
|
}
|
||||||
|
|
||||||
void World::SetPlayerLimit( int32 limit, bool needUpdate )
|
void World::SetPlayerLimit( int32 limit, bool needUpdate )
|
||||||
{
|
{
|
||||||
if (limit < -SEC_ADMINISTRATOR)
|
if (limit < -SEC_ADMINISTRATOR)
|
||||||
|
|
|
||||||
|
|
@ -583,8 +583,11 @@ class World
|
||||||
|
|
||||||
void InitDailyQuestResetTime();
|
void InitDailyQuestResetTime();
|
||||||
void InitWeeklyQuestResetTime();
|
void InitWeeklyQuestResetTime();
|
||||||
|
void SetMonthlyQuestResetTime(bool initialize = true);
|
||||||
void ResetDailyQuests();
|
void ResetDailyQuests();
|
||||||
void ResetWeeklyQuests();
|
void ResetWeeklyQuests();
|
||||||
|
void ResetMonthlyQuests();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setConfig(eConfigUInt32Values index, char const* fieldname, uint32 defvalue);
|
void setConfig(eConfigUInt32Values index, char const* fieldname, uint32 defvalue);
|
||||||
void setConfig(eConfigInt32Values index, char const* fieldname, int32 defvalue);
|
void setConfig(eConfigInt32Values index, char const* fieldname, int32 defvalue);
|
||||||
|
|
@ -655,6 +658,7 @@ class World
|
||||||
// next daily quests reset time
|
// next daily quests reset time
|
||||||
time_t m_NextDailyQuestReset;
|
time_t m_NextDailyQuestReset;
|
||||||
time_t m_NextWeeklyQuestReset;
|
time_t m_NextWeeklyQuestReset;
|
||||||
|
time_t m_NextMonthlyQuestReset;
|
||||||
|
|
||||||
//Player Queue
|
//Player Queue
|
||||||
Queue m_QueuedPlayer;
|
Queue m_QueuedPlayer;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "10654"
|
#define REVISION_NR "10655"
|
||||||
#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_10568_01_characters_character_tutorial"
|
#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_10654_01_mangos_game_event_creature_quest"
|
||||||
#define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version"
|
#define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version"
|
||||||
#endif // __REVISION_SQL_H__
|
#endif // __REVISION_SQL_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue