Core/LFG: implement weekly reward counter to limit the first dungeon rewards

* all default random rewards can be rewarded 7 times per week
* raid finder first reward can be rewarded once per week
* if completionsPerWeek = 0 the currency caps will limit the first rewards otherwise first rewards can be always rewarded
* random Cataclysm normal dungeons will now reward 140 Justice points instead of 150
* second reward for random Cataclysm normal dungeons will now reward gold only (need to verify this)
This commit is contained in:
Ovahlord
2018-04-18 15:09:49 +02:00
parent 3abbefeaf5
commit d9b12217c4
12 changed files with 195 additions and 74 deletions

View File

@@ -0,0 +1,7 @@
DROP TABLE IF EXISTS `character_rewardstatus_lfg`;
CREATE TABLE `character_rewardstatus_lfg`(
`guid` INT(10) NOT NULL DEFAULT 0 COMMENT 'Global Unique Identifier',
`dungeonId` SMALLINT(3) NOT NULL DEFAULT 0 COMMENT 'Dungeon ID Identifier',
`rewardCount` TINYINT(3) UNSIGNED DEFAULT 0 COMMENT 'Dungeon First Reward Count Identifier',
PRIMARY KEY (`dungeonId`)
);

View File

@@ -0,0 +1,8 @@
ALTER TABLE `lfg_dungeon_rewards` ADD COLUMN `completionsPerWeek` TINYINT(3) UNSIGNED DEFAULT 0 NULL COMMENT 'Maximum amount that the first quest may be rewarded' AFTER `otherQuestId`;
UPDATE `quest_template` SET `RewardCurrencyId1`= 0, `RewardCurrencyCount1`= 0 WHERE `ID` = 28908;
UPDATE `quest_template` SET `RewardCurrencyCount1`= 14000 WHERE `ID` = 28907;
UPDATE `quest_template` SET `Flags`= 0 WHERE `ID`= 30110;
UPDATE `lfg_dungeon_rewards` SET `completionsPerWeek`= 7 WHERE `dungeonId` NOT IN (417, 416, 434, 301);
UPDATE `lfg_dungeon_rewards` SET `completionsPerWeek`= 1 WHERE `dungeonId` IN (417, 416);

View File

@@ -93,6 +93,11 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_MONTHLY, "DELETE FROM character_queststatus_monthly", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_SEASONAL_BY_EVENT, "DELETE FROM character_queststatus_seasonal WHERE event = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_REWARDSTATUS_LFG, "SELECT dungeonId, rewardCount FROM character_rewardstatus_lfg WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHARACTER_REWARDSTATUS_LFG, "DELETE FROM character_rewardstatus_lfg WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHARACTER_REWARDSTATUS_LFG, "INSERT INTO character_rewardstatus_lfg (guid, dungeonId, rewardCount) VALUES (?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_RESET_CHARACTER_REWARDSTATUS_LFG, "DELETE FROM character_rewardstatus_lfg", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_REPUTATION, "SELECT faction, standing, flags FROM character_reputation WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(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);

View File

@@ -82,6 +82,11 @@ enum CharacterDatabaseStatements : uint32
CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_MONTHLY,
CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_SEASONAL_BY_EVENT,
CHAR_SEL_CHARACTER_REWARDSTATUS_LFG,
CHAR_DEL_CHARACTER_REWARDSTATUS_LFG,
CHAR_INS_CHARACTER_REWARDSTATUS_LFG,
CHAR_DEL_RESET_CHARACTER_REWARDSTATUS_LFG,
CHAR_SEL_CHARACTER_REPUTATION,
CHAR_SEL_CHARACTER_INVENTORY,
CHAR_SEL_CHARACTER_ACTIONS,

View File

@@ -124,7 +124,7 @@ void LFGMgr::LoadRewards()
RewardMapStore.clear();
// ORDER BY is very important for GetRandomDungeonReward!
QueryResult result = WorldDatabase.Query("SELECT dungeonId, maxLevel, firstQuestId, otherQuestId FROM lfg_dungeon_rewards ORDER BY dungeonId, maxLevel ASC");
QueryResult result = WorldDatabase.Query("SELECT dungeonId, maxLevel, firstQuestId, otherQuestId, completionsPerWeek FROM lfg_dungeon_rewards ORDER BY dungeonId, maxLevel ASC");
if (!result)
{
@@ -142,6 +142,7 @@ void LFGMgr::LoadRewards()
uint32 maxLevel = fields[1].GetUInt8();
uint32 firstQuestId = fields[2].GetUInt32();
uint32 otherQuestId = fields[3].GetUInt32();
uint32 completionsPerWeek = fields[4].GetUInt8();
if (!GetLFGDungeonEntry(dungeonId))
{
@@ -167,7 +168,7 @@ void LFGMgr::LoadRewards()
otherQuestId = 0;
}
RewardMapStore.insert(LfgRewardContainer::value_type(dungeonId, new LfgReward(maxLevel, firstQuestId, otherQuestId)));
RewardMapStore.insert(LfgRewardContainer::value_type(dungeonId, new LfgReward(maxLevel, firstQuestId, otherQuestId, completionsPerWeek)));
++count;
}
while (result->NextRow());
@@ -1492,17 +1493,22 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId, Map const*
if (!reward)
continue;
bool done = false;
bool firstReward = true;
Quest const* quest = sObjectMgr->GetQuestTemplate(reward->firstQuest);
if (!quest)
continue;
// if we can take the quest, means that we haven't done this kind of "run", IE: First Heroic Random of Day.
if (player->CanRewardQuest(quest, false))
// CanRewardQuest to check currency caps, SatisfyFirstLFGReward to check weekly reward caps for first quest
if (player->CanRewardQuest(quest, false) && player->SatisfyFirstLFGReward(rDungeonId, reward->completionsPerWeek))
{
if (reward->completionsPerWeek)
player->SetLFGRewardStatus(rDungeonId);
player->RewardQuest(quest, 0, nullptr, false);
}
else
{
done = true;
firstReward = false;
quest = sObjectMgr->GetQuestTemplate(reward->otherQuest);
if (!quest)
continue;
@@ -1514,20 +1520,16 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId, Map const*
if (Group *group = player->GetGroup())
tmpRole = group->GetLfgRoles(player->GetGUID());
if (IsCallToArmsEligible(player->getLevel(), rDungeonId & 0x00FFFFFF))
{
if (IsCallToArmsEligible(player->getLevel(), rDungeonId))
if (player->GetCallToArmsTempRoles() & tmpRole)
{
const Quest* q = sObjectMgr->GetQuestTemplate(LFG_CALL_TO_ARMS_QUEST);
player->RewardQuest(q, 0, nullptr, false);
}
}
if (Quest const* callToArmsQuest = sObjectMgr->GetQuestTemplate(LFG_CALL_TO_ARMS_QUEST))
player->RewardQuest(callToArmsQuest, 0, nullptr, false);
player->SetTempCallToArmsRoles(0);
// Give rewards
TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s, Player: %s done dungeon %u, %s previously done.", gguid.ToString().c_str(), guid.ToString().c_str(), GetDungeon(gguid), done ? " " : " not");
LfgPlayerRewardData data = LfgPlayerRewardData(dungeon->Entry(), GetDungeon(gguid, false), done, quest);
TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s, Player: %s done dungeon %u, %s previously done.", gguid.ToString().c_str(), guid.ToString().c_str(), GetDungeon(gguid), !firstReward ? " " : " not");
LfgPlayerRewardData data = LfgPlayerRewardData(dungeon->Entry(), GetDungeon(gguid, false), !firstReward, quest);
player->GetSession()->SendLfgPlayerReward(data);
}
}

View File

@@ -210,6 +210,7 @@ struct LfgPlayerRewardData
{
LfgPlayerRewardData(uint32 random, uint32 current, bool _done, Quest const* _quest):
rdungeonEntry(random), sdungeonEntry(current), done(_done), quest(_quest) { }
uint32 rdungeonEntry;
uint32 sdungeonEntry;
bool done;
@@ -219,12 +220,13 @@ struct LfgPlayerRewardData
/// Reward info
struct LfgReward
{
LfgReward(uint32 _maxLevel = 0, uint32 _firstQuest = 0, uint32 _otherQuest = 0):
maxLevel(_maxLevel), firstQuest(_firstQuest), otherQuest(_otherQuest) { }
LfgReward(uint32 _maxLevel = 0, uint32 _firstQuest = 0, uint32 _otherQuest = 0, uint8 _completionsPerWeek = 0):
maxLevel(_maxLevel), firstQuest(_firstQuest), otherQuest(_otherQuest), completionsPerWeek(_completionsPerWeek) { }
uint32 maxLevel;
uint32 firstQuest;
uint32 otherQuest;
uint8 completionsPerWeek;
};
/// Stores player data related to proposal to join

View File

@@ -395,6 +395,8 @@ Player::Player(WorldSession* session): Unit(true)
m_SeasonalQuestChanged = false;
m_LFGRewardStatusChanged = false;
SetPendingBind(0, 0);
_activeCheats = CHEAT_NONE;
@@ -4498,6 +4500,10 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe
stmt->setUInt32(0, guid);
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_REWARDSTATUS_LFG);
stmt->setUInt32(0, guid);
trans->Append(stmt);
Corpse::DeleteFromDB(playerguid, trans);
break;
}
@@ -15311,7 +15317,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
CharacterDatabase.CommitTransaction(trans);
}
if ((quest->IsDaily() || (quest->IsDFQuest()) && !quest->IsRepeatable()) && !quest->IsWeekly())
if (quest->IsDaily() && !quest->IsDFQuest())
{
SetDailyQuestStatus(quest_id);
if (quest->IsDaily())
@@ -15866,14 +15872,6 @@ bool Player::SatisfyQuestDay(Quest const* qInfo, bool msg) const
if (!qInfo->IsDaily() && !qInfo->IsDFQuest())
return true;
if (qInfo->IsDFQuest() && !qInfo->IsRepeatable())
{
if (m_DFQuests.find(qInfo->GetQuestId()) != m_DFQuests.end())
return false;
return true;
}
bool have_slot = false;
for (uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx)
{
@@ -16105,6 +16103,24 @@ void Player::SendQuestUpdate(uint32 questId)
PhasingHandler::OnConditionChange(this);
}
bool Player::SatisfyFirstLFGReward(uint32 dungeonId, uint8 maxRewCount) const
{
LFGRewardStatusMap::const_iterator lfgdungeon = m_lfgrewardstatus.find(dungeonId);
if (lfgdungeon != m_lfgrewardstatus.end())
return lfgdungeon->second && lfgdungeon->second < maxRewCount;
return true;
}
uint8 Player::GetFirstRewardCountForDungeonId(uint32 dungeonId)
{
LFGRewardStatusMap::const_iterator lfgdungeon = m_lfgrewardstatus.find(dungeonId);
if (lfgdungeon != m_lfgrewardstatus.end())
return lfgdungeon->second;
return 0;
}
QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver)
{
QuestRelationBounds qr;
@@ -17804,6 +17820,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder* holder)
_LoadWeeklyQuestStatus(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_WEEKLY_QUEST_STATUS));
_LoadSeasonalQuestStatus(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SEASONAL_QUEST_STATUS));
_LoadMonthlyQuestStatus(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_MONTHLY_QUEST_STATUS));
_LoadLFGRewardStatus(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_LFG_REWARD_STATUS));
_LoadRandomBGStatus(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_RANDOM_BG));
// after spell and quest load
@@ -18895,8 +18912,6 @@ void Player::_LoadDailyQuestStatus(PreparedQueryResult result)
for (uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx)
SetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx, 0);
m_DFQuests.clear();
//QueryResult* result = CharacterDatabase.PQuery("SELECT quest, time FROM character_queststatus_daily WHERE guid = '%u'", GetGUID().GetCounter());
if (result)
@@ -18906,15 +18921,6 @@ void Player::_LoadDailyQuestStatus(PreparedQueryResult result)
do
{
Field* fields = result->Fetch();
if (Quest const* qQuest = sObjectMgr->GetQuestTemplate(fields[0].GetUInt32()))
{
if (qQuest->IsDFQuest())
{
m_DFQuests.insert(qQuest->GetQuestId());
m_lastDailyQuestTime = time_t(fields[1].GetUInt32());
continue;
}
}
if (quest_daily_idx >= PLAYER_MAX_DAILY_QUESTS) // max amount with exist data in query
{
@@ -19017,6 +19023,27 @@ void Player::_LoadMonthlyQuestStatus(PreparedQueryResult result)
m_MonthlyQuestChanged = false;
}
void Player::_LoadLFGRewardStatus(PreparedQueryResult result)
{
m_lfgrewardstatus.clear();
if (result)
{
do
{
Field* fields = result->Fetch();
uint32 dungeon_id = fields[0].GetUInt16();
uint8 reward_count = fields[1].GetUInt8();
m_lfgrewardstatus[dungeon_id] = reward_count;
TC_LOG_DEBUG("entities.player.loading", "Player::_LFGQuestStatus: Loaded LFG quest first reward cooldown (DungeonID: %u) for player '%s' (%s)",
dungeon_id, GetName().c_str(), GetGUID().ToString().c_str());
} while (result->NextRow());
}
m_LFGRewardStatusChanged = false;
}
void Player::_LoadSpells(PreparedQueryResult result)
{
//QueryResult* result = CharacterDatabase.PQuery("SELECT spell, active, disabled FROM character_spell WHERE guid = '%u'", GetGUID().GetCounter());
@@ -19906,6 +19933,7 @@ void Player::SaveToDB(bool create /*=false*/)
_SaveWeeklyQuestStatus(trans);
_SaveSeasonalQuestStatus(trans);
_SaveMonthlyQuestStatus(trans);
_SaveLFGRewardStatus(trans);
_SaveTalents(trans);
_SaveSpells(trans);
GetSpellHistory()->SaveToDB<Player>(trans);
@@ -20436,18 +20464,6 @@ void Player::_SaveDailyQuestStatus(SQLTransaction& trans)
trans->Append(stmt);
}
}
if (!m_DFQuests.empty())
{
for (DFQuestsDoneList::iterator itr = m_DFQuests.begin(); itr != m_DFQuests.end(); ++itr)
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_QUESTSTATUS_DAILY);
stmt->setUInt32(0, GetGUID().GetCounter());
stmt->setUInt32(1, (*itr));
stmt->setUInt64(2, uint64(m_lastDailyQuestTime));
trans->Append(stmt);
}
}
}
void Player::_SaveWeeklyQuestStatus(SQLTransaction& trans)
@@ -20525,6 +20541,31 @@ void Player::_SaveMonthlyQuestStatus(SQLTransaction& trans)
m_MonthlyQuestChanged = false;
}
void Player::_SaveLFGRewardStatus(SQLTransaction& trans)
{
if (!m_LFGRewardStatusChanged || m_lfgrewardstatus.empty())
return;
// we don't need transactions here.
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_REWARDSTATUS_LFG);
stmt->setUInt32(0, GetGUID().GetCounter());
trans->Append(stmt);
for (LFGRewardStatusMap::const_iterator itr = m_lfgrewardstatus.begin(); itr != m_lfgrewardstatus.end(); ++itr)
{
uint32 dungeonId = itr->first;
uint8 rewardCount = itr->second;
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_REWARDSTATUS_LFG);
stmt->setUInt32(0, GetGUID().GetCounter());
stmt->setUInt32(1, dungeonId);
stmt->setUInt32(2, rewardCount);
trans->Append(stmt);
}
m_LFGRewardStatusChanged = false;
}
void Player::_SaveSkills(SQLTransaction& trans)
{
PreparedStatement* stmt;
@@ -24061,23 +24102,15 @@ void Player::SetDailyQuestStatus(uint32 quest_id)
{
if (Quest const* qQuest = sObjectMgr->GetQuestTemplate(quest_id))
{
if (!qQuest->IsDFQuest())
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)
if (!GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1 + quest_daily_idx))
{
if (!GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx))
{
SetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx, quest_id);
m_lastDailyQuestTime = time(nullptr); // last daily quest time
m_DailyQuestChanged = true;
break;
}
SetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1 + quest_daily_idx, quest_id);
m_lastDailyQuestTime = time(nullptr); // last daily quest time
m_DailyQuestChanged = true;
break;
}
} else
{
m_DFQuests.insert(quest_id);
m_lastDailyQuestTime = time(nullptr);
m_DailyQuestChanged = true;
}
}
}
@@ -24122,13 +24155,23 @@ void Player::SetMonthlyQuestStatus(uint32 quest_id)
m_MonthlyQuestChanged = true;
}
void Player::SetLFGRewardStatus(uint32 dungeon_id)
{
LFGRewardStatusMap::iterator lfgdungeon = m_lfgrewardstatus.find(dungeon_id);
if (lfgdungeon != m_lfgrewardstatus.end())
lfgdungeon->second++;
else
m_lfgrewardstatus[dungeon_id] = 1;
m_LFGRewardStatusChanged = true;
}
void Player::ResetDailyQuestStatus()
{
for (uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx)
SetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx, 0);
m_DFQuests.clear(); // Dungeon Finder Quests.
// DB data deleted in caller
m_DailyQuestChanged = false;
m_lastDailyQuestTime = 0;
@@ -24165,6 +24208,16 @@ void Player::ResetMonthlyQuestStatus()
m_MonthlyQuestChanged = false;
}
void Player::ResetLFGRewardStatus()
{
if (!m_lfgrewardstatus.empty())
return;
m_lfgrewardstatus.clear();
// DB data deleted in caller
m_LFGRewardStatusChanged = false;
}
Battleground* Player::GetBattleground() const
{
if (GetBattlegroundId() == 0)

View File

@@ -784,6 +784,7 @@ enum PlayerLoginQueryIndex
PLAYER_LOGIN_QUERY_LOAD_CUF_PROFILES = 35,
PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION = 36,
PLAYER_LOGIN_QUERY_LOAD_ALL_PETS = 37,
PLAYER_LOGIN_QUERY_LOAD_LFG_REWARD_STATUS = 38,
MAX_PLAYER_LOGIN_QUERY
};
@@ -1385,16 +1386,20 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void RemoveRewardedQuest(uint32 questId, bool update = true);
void SendQuestUpdate(uint32 questId);
QuestGiverStatus GetQuestDialogStatus(Object* questGiver);
bool SatisfyFirstLFGReward(uint32 dungeonId, uint8 maxRewCount) const;
uint8 GetFirstRewardCountForDungeonId(uint32 dungeon);
void SetDailyQuestStatus(uint32 quest_id);
bool IsDailyQuestDone(uint32 quest_id);
void SetWeeklyQuestStatus(uint32 quest_id);
void SetMonthlyQuestStatus(uint32 quest_id);
void SetSeasonalQuestStatus(uint32 quest_id);
void SetLFGRewardStatus(uint32 dungeon_id);
void ResetDailyQuestStatus();
void ResetWeeklyQuestStatus();
void ResetMonthlyQuestStatus();
void ResetSeasonalQuestStatus(uint16 event_id);
void ResetLFGRewardStatus();
uint16 FindQuestSlot(uint32 quest_id) const;
uint32 GetQuestSlotQuestId(uint16 slot) const;
@@ -2186,9 +2191,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
bool HasValidLFGLeavePoint(uint32 mapid);
void SetLFGLeavePoint();
typedef std::set<uint32> DFQuestsDoneList;
DFQuestsDoneList m_DFQuests;
// Temporarily removed pet cache
uint32 GetTemporaryUnsummonedPetNumber() const { return m_temporaryUnsummonedPetNumber; }
void SetTemporaryUnsummonedPetNumber(uint32 petnumber) { m_temporaryUnsummonedPetNumber = petnumber; }
@@ -2400,10 +2402,13 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
typedef std::set<uint32> QuestSet;
typedef std::set<uint32> SeasonalQuestSet;
typedef std::unordered_map<uint32, SeasonalQuestSet> SeasonalEventQuestMap;
typedef std::unordered_map<uint32, uint8> LFGRewardStatusMap;
QuestSet m_timedquests;
QuestSet m_weeklyquests;
QuestSet m_monthlyquests;
SeasonalEventQuestMap m_seasonalquests;
LFGRewardStatusMap m_lfgrewardstatus;
ObjectGuid m_playerSharingQuest;
uint32 m_sharedQuestId;
@@ -2442,6 +2447,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void _LoadInstanceTimeRestrictions(PreparedQueryResult result);
void _LoadCurrency(PreparedQueryResult result);
void _LoadCUFProfiles(PreparedQueryResult result);
void _LoadLFGRewardStatus(PreparedQueryResult result);
/*********************************************************/
/*** SAVE SYSTEM ***/
@@ -2467,6 +2473,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void _SaveInstanceTimeRestrictions(SQLTransaction& trans);
void _SaveCurrency(SQLTransaction& trans);
void _SaveCUFProfiles(SQLTransaction& trans);
void _SaveLFGRewardStatus(SQLTransaction& trans);
/*********************************************************/
/*** ENVIRONMENTAL SYSTEM ***/
@@ -2577,6 +2584,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
bool m_WeeklyQuestChanged;
bool m_MonthlyQuestChanged;
bool m_SeasonalQuestChanged;
bool m_LFGRewardStatusChanged;
time_t m_lastDailyQuestTime;
uint32 m_hostileReferenceCheckTimer;

View File

@@ -230,6 +230,10 @@ bool LoginQueryHolder::Initialize()
stmt->setUInt64(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_ALL_PETS, stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_REWARDSTATUS_LFG);
stmt->setUInt32(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_LFG_REWARD_STATUS, stmt);
return res;
}

View File

@@ -323,6 +323,9 @@ void WorldSession::SendLfgPlayerLockInfo()
if (quest)
{
firstCompletion = player->CanRewardQuest(quest, false);
if (reward->completionsPerWeek)
firstCompletion = player->SatisfyFirstLFGReward(dungeonId & 0x00FFFFFF, reward->completionsPerWeek);
if (!firstCompletion)
quest = sObjectMgr->GetQuestTemplate(reward->otherQuest);
}
@@ -337,7 +340,7 @@ void WorldSession::SendLfgPlayerLockInfo()
CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(CURRENCY_TYPE_VALOR_POINTS);
if (currency && rewValorPoints && !quest->IsWeekly())
if (currency && rewValorPoints && !reward->completionsPerWeek)
{
data << uint32(rewValorPoints); // currencyQuantity (valor points from selected dungeon)
data << uint32(player->GetCurrencyWeekCap(currency)); // some sort of overall cap/weekly cap
@@ -352,6 +355,21 @@ void WorldSession::SendLfgPlayerLockInfo()
data << uint32(0); // purseLimit
data << uint32(rewValorPoints); // some sort of reward for completion
}
else if (firstCompletion && reward && reward->completionsPerWeek)
{
data << uint32(1); // currencyQuantity
data << uint32(reward->completionsPerWeek); // some sort of overall cap/weekly cap
data << uint32(0); // currencyID
data << uint32(0); // tier1Quantity
data << uint32(reward->completionsPerWeek); // tier1Limit
data << uint32(player->GetFirstRewardCountForDungeonId(dungeonId & 0x00FFFFFF)); // overallQuantity
data << uint32(reward->completionsPerWeek); // overallLimit
data << uint32(0); // periodPurseQuantity
data << uint32(0); // periodPurseLimit
data << uint32(0); // purseQuantity
data << uint32(0); // purseLimit
data << uint32(1); // some sort of reward for completion
}
else
{
data << uint32(0); // currencyQuantity
@@ -762,7 +780,6 @@ void WorldSession::SendLfgPlayerReward(lfg::LfgPlayerRewardData const& rewardDat
GetPlayerInfo().c_str(), rewardData.rdungeonEntry, rewardData.sdungeonEntry, rewardData.done);
uint8 itemNum = rewardData.quest->GetRewItemsCount() + rewardData.quest->GetRewCurrencyCount();
WorldPacket data(SMSG_LFG_PLAYER_REWARD, 4 + 4 + 1 + 4 + 4 + 4 + 4 + 4 + 1 + itemNum * (4 + 4 + 4));
data << uint32(rewardData.rdungeonEntry); // Random Dungeon Finished
data << uint32(rewardData.sdungeonEntry); // Dungeon Finished

View File

@@ -2200,7 +2200,7 @@ void World::Update(uint32 diff)
/// Handle weekly quests reset time
if (currentGameTime > m_NextWeeklyQuestReset)
ResetWeeklyQuests();
ResetWeeklyQuestsAndRewards();
/// Handle monthly quests reset time
if (currentGameTime > m_NextMonthlyQuestReset)
@@ -3204,16 +3204,26 @@ void World::SetPlayerSecurityLimit(AccountTypes _sec)
KickAllLess(m_allowedSecurityLevel);
}
void World::ResetWeeklyQuests()
void World::ResetWeeklyQuestsAndRewards()
{
TC_LOG_INFO("misc", "Weekly quests reset for all characters.");
TC_LOG_INFO("misc", "Weekly quests and rewards reset for all characters.");
// Reset Weekly quests
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_WEEKLY);
CharacterDatabase.Execute(stmt);
// Reset Weekly lfg rewards
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_RESET_CHARACTER_REWARDSTATUS_LFG);
CharacterDatabase.Execute(stmt);
for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
{
if (itr->second->GetPlayer())
{
itr->second->GetPlayer()->ResetWeeklyQuestStatus();
itr->second->GetPlayer()->ResetLFGRewardStatus();
}
}
m_NextWeeklyQuestReset = time_t(m_NextWeeklyQuestReset + WEEK);
sWorld->setWorldState(WS_WEEKLY_QUEST_RESET_TIME, uint64(m_NextWeeklyQuestReset));

View File

@@ -822,7 +822,7 @@ class TC_GAME_API World
void InitGuildResetTime();
void InitCurrencyResetTime();
void ResetDailyQuests();
void ResetWeeklyQuests();
void ResetWeeklyQuestsAndRewards();
void ResetMonthlyQuests();
void ResetRandomBG();
void ResetGuildCap();