mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-29 08:33:47 +00:00
feat(Core/Achievements): Add possibility to complete achievements and update achievement criteria for offline players. (#19851)
This commit is contained in:
committed by
GitHub
parent
221dbd3fdb
commit
9999a80c96
@@ -0,0 +1,10 @@
|
||||
DROP TABLE IF EXISTS `character_achievement_offline_updates`;
|
||||
CREATE TABLE `character_achievement_offline_updates` (
|
||||
`guid` BIGINT UNSIGNED NOT NULL COMMENT 'Character\'s GUID',
|
||||
`update_type` TINYINT UNSIGNED NOT NULL COMMENT 'Supported types: 1 - COMPLETE_ACHIEVEMENT; 2 - UPDATE_CRITERIA',
|
||||
`arg1` INT UNSIGNED NOT NULL COMMENT 'For type 1: achievement ID; for type 2: ACHIEVEMENT_CRITERIA_TYPE',
|
||||
`arg2` INT UNSIGNED DEFAULT NULL COMMENT 'For type 2: miscValue1 for updating achievement criteria',
|
||||
`arg3` INT UNSIGNED DEFAULT NULL COMMENT 'For type 2: miscValue2 for updating achievement criteria',
|
||||
INDEX `idx_guid` (`guid`)
|
||||
)
|
||||
COMMENT = 'Stores updates to character achievements when the character was offline';
|
||||
@@ -43,7 +43,8 @@
|
||||
#define MAX_NETCLIENT_PACKET_SIZE (32767 - 1) // Client hardcap: int16 with trailing zero space otherwise crash on memory free
|
||||
|
||||
// TimeConstants
|
||||
constexpr auto MINUTE = 60;
|
||||
constexpr auto SECOND = 1;
|
||||
constexpr auto MINUTE = SECOND * 60;
|
||||
constexpr auto HOUR = MINUTE * 60;
|
||||
constexpr auto DAY = HOUR * 24;
|
||||
constexpr auto WEEK = DAY * 7;
|
||||
|
||||
@@ -441,6 +441,9 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_INS_CHAR_ACHIEVEMENT, "INSERT INTO character_achievement (guid, achievement, date) VALUES (?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS_BY_CRITERIA, "DELETE FROM character_achievement_progress WHERE guid = ? AND criteria = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_CHAR_ACHIEVEMENT_PROGRESS, "INSERT INTO character_achievement_progress (guid, criteria, counter, date) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_CHAR_ACHIEVEMENT_OFFLINE_UPDATES, "INSERT INTO character_achievement_offline_updates (guid, update_type, arg1, arg2, arg3) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES, "SELECT update_type, arg1, arg2, arg3 FROM character_achievement_offline_updates WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES, "DELETE FROM character_achievement_offline_updates WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_CHAR_REPUTATION_BY_FACTION, "DELETE FROM character_reputation WHERE guid = ? AND faction = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_CHAR_REPUTATION_BY_FACTION, "INSERT INTO character_reputation (guid, faction, standing, flags) VALUES (?, ?, ? , ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_CHAR_ARENA_POINTS, "UPDATE characters SET arenaPoints = (arenaPoints + ?) WHERE guid = ?", CONNECTION_ASYNC);
|
||||
|
||||
@@ -365,6 +365,9 @@ enum CharacterDatabaseStatements : uint32
|
||||
CHAR_INS_CHAR_ACHIEVEMENT,
|
||||
CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS_BY_CRITERIA,
|
||||
CHAR_INS_CHAR_ACHIEVEMENT_PROGRESS,
|
||||
CHAR_INS_CHAR_ACHIEVEMENT_OFFLINE_UPDATES,
|
||||
CHAR_SEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES,
|
||||
CHAR_DEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES,
|
||||
CHAR_DEL_CHAR_REPUTATION_BY_FACTION,
|
||||
CHAR_INS_CHAR_REPUTATION_BY_FACTION,
|
||||
CHAR_UPD_CHAR_ARENA_POINTS,
|
||||
|
||||
@@ -481,6 +481,7 @@ bool AchievementCriteriaDataSet::Meets(Player const* source, Unit const* target,
|
||||
AchievementMgr::AchievementMgr(Player* player)
|
||||
{
|
||||
_player = player;
|
||||
_offlineUpdatesDelayTimer = 0;
|
||||
}
|
||||
|
||||
AchievementMgr::~AchievementMgr()
|
||||
@@ -550,6 +551,10 @@ void AchievementMgr::DeleteFromDB(ObjectGuid::LowType lowguid)
|
||||
stmt->SetData(0, lowguid);
|
||||
trans->Append(stmt);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES);
|
||||
stmt->SetData(0, lowguid);
|
||||
trans->Append(stmt);
|
||||
|
||||
CharacterDatabase.CommitTransaction(trans);
|
||||
}
|
||||
|
||||
@@ -609,7 +614,7 @@ void AchievementMgr::SaveToDB(CharacterDatabaseTransaction trans)
|
||||
}
|
||||
}
|
||||
|
||||
void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult)
|
||||
void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult, PreparedQueryResult offlineUpdatesResult)
|
||||
{
|
||||
if (achievementResult)
|
||||
{
|
||||
@@ -669,6 +674,28 @@ void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQ
|
||||
progress.changed = false;
|
||||
} while (criteriaResult->NextRow());
|
||||
}
|
||||
|
||||
if (offlineUpdatesResult)
|
||||
{
|
||||
uint32 count = 0;
|
||||
do
|
||||
{
|
||||
Field* fields = offlineUpdatesResult->Fetch();
|
||||
|
||||
AchievementOfflinePlayerUpdate update;
|
||||
update.updateType = static_cast<AchievementOfflinePlayerUpdateType>(fields[0].Get<uint8>());
|
||||
update.arg1 = fields[1].Get<uint32>();
|
||||
update.arg2 = fields[2].Get<uint32>();
|
||||
update.arg3 = fields[3].Get<uint32>();
|
||||
|
||||
_offlineUpdatesQueue.push_back(update);
|
||||
|
||||
++count;
|
||||
} while (offlineUpdatesResult->NextRow());
|
||||
|
||||
if (count > 0)
|
||||
_offlineUpdatesDelayTimer = 5 * SECOND * IN_MILLISECONDS;
|
||||
}
|
||||
}
|
||||
|
||||
void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement) const
|
||||
@@ -884,7 +911,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS: /* FIXME: for online player only currently */
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_DISENCHANT:
|
||||
@@ -904,7 +931,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS:/* FIXME: for online player only currently */
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS:
|
||||
@@ -915,7 +942,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
||||
break;
|
||||
// std case: high value at miscvalue1
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD: /* FIXME: for online player only currently */
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED:
|
||||
@@ -2158,6 +2185,22 @@ void AchievementMgr::RemoveCriteriaProgress(const AchievementCriteriaEntry* entr
|
||||
_criteriaProgress.erase(criteriaProgress);
|
||||
}
|
||||
|
||||
void AchievementMgr::Update(uint32 timeDiff)
|
||||
{
|
||||
if (_offlineUpdatesDelayTimer > 0)
|
||||
{
|
||||
if (timeDiff >= _offlineUpdatesDelayTimer)
|
||||
{
|
||||
_offlineUpdatesDelayTimer = 0;
|
||||
ProcessOfflineUpdatesQueue();
|
||||
}
|
||||
else
|
||||
_offlineUpdatesDelayTimer -= timeDiff;
|
||||
}
|
||||
|
||||
UpdateTimedAchievements(timeDiff);
|
||||
}
|
||||
|
||||
void AchievementMgr::UpdateTimedAchievements(uint32 timeDiff)
|
||||
{
|
||||
if (!_timedAchievements.empty())
|
||||
@@ -2437,6 +2480,46 @@ CompletedAchievementMap const& AchievementMgr::GetCompletedAchievements()
|
||||
return _completedAchievements;
|
||||
}
|
||||
|
||||
void AchievementMgr::ProcessOfflineUpdatesQueue()
|
||||
{
|
||||
if (_offlineUpdatesQueue.empty())
|
||||
return;
|
||||
|
||||
for (auto const& update : _offlineUpdatesQueue)
|
||||
ProcessOfflineUpdate(update);
|
||||
|
||||
_offlineUpdatesQueue.clear();
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES);
|
||||
stmt->SetData(0, GetPlayer()->GetGUID().GetCounter());
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
void AchievementMgr::ProcessOfflineUpdate(AchievementOfflinePlayerUpdate const& update)
|
||||
{
|
||||
switch (update.updateType)
|
||||
{
|
||||
case ACHIEVEMENT_OFFLINE_PLAYER_UPDATE_TYPE_COMPLETE_ACHIEVEMENT:
|
||||
{
|
||||
AchievementEntry const* achievement = sAchievementStore.LookupEntry(update.arg1);
|
||||
|
||||
ASSERT(achievement != NULL, "Not found achievement to complete for offline achievements update. Wrong arg1 ({}) value?", update.arg1);
|
||||
|
||||
CompletedAchievement(achievement);
|
||||
break;
|
||||
}
|
||||
case ACHIEVEMENT_OFFLINE_PLAYER_UPDATE_TYPE_UPDATE_CRITERIA:
|
||||
{
|
||||
AchievementCriteriaTypes criteriaType = static_cast<AchievementCriteriaTypes>(update.arg1);
|
||||
UpdateAchievementCriteria(criteriaType, update.arg2, update.arg3);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ASSERT(false, "Unknown offline achievement update type ({}) for player - {}", update.updateType, GetPlayer()->GetGUID().GetCounter());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
AchievementGlobalMgr* AchievementGlobalMgr::instance()
|
||||
{
|
||||
static AchievementGlobalMgr instance;
|
||||
@@ -3054,3 +3137,25 @@ AchievementEntry const* AchievementGlobalMgr::GetAchievement(uint32 achievementI
|
||||
{
|
||||
return sAchievementStore.LookupEntry(achievementId);
|
||||
}
|
||||
|
||||
void AchievementGlobalMgr::CompletedAchievementForOfflinePlayer(ObjectGuid::LowType playerLowGuid, AchievementEntry const* entry)
|
||||
{
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_ACHIEVEMENT_OFFLINE_UPDATES);
|
||||
stmt->SetData(0, playerLowGuid);
|
||||
stmt->SetData(1, uint32(ACHIEVEMENT_OFFLINE_PLAYER_UPDATE_TYPE_COMPLETE_ACHIEVEMENT));
|
||||
stmt->SetData(2, entry->ID);
|
||||
stmt->SetData(3, 0);
|
||||
stmt->SetData(4, 0);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
void AchievementGlobalMgr::UpdateAchievementCriteriaForOfflinePlayer(ObjectGuid::LowType playerLowGuid, AchievementCriteriaTypes type, uint32 miscValue1, uint32 miscValue2)
|
||||
{
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_ACHIEVEMENT_OFFLINE_UPDATES);
|
||||
stmt->SetData(0, playerLowGuid);
|
||||
stmt->SetData(1, uint32(ACHIEVEMENT_OFFLINE_PLAYER_UPDATE_TYPE_UPDATE_CRITERIA));
|
||||
stmt->SetData(2, type);
|
||||
stmt->SetData(3, miscValue1);
|
||||
stmt->SetData(4, miscValue2);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,20 @@ typedef std::list<AchievementEntry const*> AchievementEntryList;
|
||||
typedef std::unordered_map<uint32, AchievementCriteriaEntryList> AchievementCriteriaListByAchievement;
|
||||
typedef std::map<uint32, AchievementEntryList> AchievementListByReferencedId;
|
||||
|
||||
enum AchievementOfflinePlayerUpdateType
|
||||
{
|
||||
ACHIEVEMENT_OFFLINE_PLAYER_UPDATE_TYPE_COMPLETE_ACHIEVEMENT = 1,
|
||||
ACHIEVEMENT_OFFLINE_PLAYER_UPDATE_TYPE_UPDATE_CRITERIA = 2
|
||||
};
|
||||
|
||||
struct AchievementOfflinePlayerUpdate
|
||||
{
|
||||
AchievementOfflinePlayerUpdateType updateType;
|
||||
uint32 arg1;
|
||||
uint32 arg2;
|
||||
uint32 arg3;
|
||||
};
|
||||
|
||||
struct CriteriaProgress
|
||||
{
|
||||
uint32 counter;
|
||||
@@ -284,7 +298,7 @@ public:
|
||||
|
||||
void Reset();
|
||||
static void DeleteFromDB(ObjectGuid::LowType lowguid);
|
||||
void LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult);
|
||||
void LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult, PreparedQueryResult offlineUpdatesResult);
|
||||
void SaveToDB(CharacterDatabaseTransaction trans);
|
||||
void ResetAchievementCriteria(AchievementCriteriaCondition condition, uint32 value, bool evenIfCriteriaComplete = false);
|
||||
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = nullptr);
|
||||
@@ -294,7 +308,8 @@ public:
|
||||
void SendRespondInspectAchievements(Player* player) const;
|
||||
[[nodiscard]] bool HasAchieved(uint32 achievementId) const;
|
||||
[[nodiscard]] Player* GetPlayer() const { return _player; }
|
||||
void UpdateTimedAchievements(uint32 timeDiff);
|
||||
|
||||
void Update(uint32 timeDiff);
|
||||
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost = 0);
|
||||
void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry); // used for quest and scripted timed achievements
|
||||
|
||||
@@ -313,11 +328,23 @@ private:
|
||||
bool CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement);
|
||||
void BuildAllDataPacket(WorldPacket* data) const;
|
||||
|
||||
void UpdateTimedAchievements(uint32 timeDiff);
|
||||
|
||||
// Handles updates when character was offline.
|
||||
void ProcessOfflineUpdate(AchievementOfflinePlayerUpdate const& update);
|
||||
void ProcessOfflineUpdatesQueue();
|
||||
|
||||
Player* _player;
|
||||
CriteriaProgressMap _criteriaProgress;
|
||||
CompletedAchievementMap _completedAchievements;
|
||||
typedef std::map<uint32, uint32> TimedAchievementMap;
|
||||
TimedAchievementMap _timedAchievements; // Criteria id/time left in MS
|
||||
|
||||
// Offline updates cannot be processed while players are loading,
|
||||
// as the player will not be notified of the changes.
|
||||
// To ensure proper notification, introduce a delay before processing.
|
||||
uint32 _offlineUpdatesDelayTimer;
|
||||
std::vector<AchievementOfflinePlayerUpdate> _offlineUpdatesQueue;
|
||||
};
|
||||
|
||||
class AchievementGlobalMgr
|
||||
@@ -398,6 +425,8 @@ public:
|
||||
|
||||
[[nodiscard]] AchievementEntry const* GetAchievement(uint32 achievementId) const;
|
||||
|
||||
void CompletedAchievementForOfflinePlayer(ObjectGuid::LowType playerLowGuid, AchievementEntry const* entry);
|
||||
void UpdateAchievementCriteriaForOfflinePlayer(ObjectGuid::LowType playerLowGuid, AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0);
|
||||
private:
|
||||
AchievementCriteriaDataMap _criteriaDataMap;
|
||||
|
||||
|
||||
@@ -318,10 +318,14 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, CharacterDatabas
|
||||
{
|
||||
if (sendNotification) // can be changed in the hook
|
||||
bidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, auction->bidder, 0, 0, auction->item_template);
|
||||
// FIXME: for offline player need also
|
||||
|
||||
if (updateAchievementCriteria) // can be changed in the hook
|
||||
bidder->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS, 1);
|
||||
}
|
||||
else if (updateAchievementCriteria)
|
||||
{
|
||||
sAchievementMgr->UpdateAchievementCriteriaForOfflinePlayer(auction->bidder.GetCounter(), ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS, 1);
|
||||
}
|
||||
|
||||
if (sendMail) // can be changed in the hook
|
||||
MailDraft(auction->BuildAuctionMailSubject(AUCTION_WON), AuctionEntry::BuildAuctionMailBody(auction->owner, auction->bid, auction->buyout))
|
||||
@@ -375,6 +379,11 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry* auction, Character
|
||||
if (sendNotification) // can be changed in the hook
|
||||
owner->GetSession()->SendAuctionOwnerNotification(auction);
|
||||
}
|
||||
else if (updateAchievementCriteria)
|
||||
{
|
||||
sAchievementMgr->UpdateAchievementCriteriaForOfflinePlayer(auction->owner.GetCounter(), ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS, profit);
|
||||
sAchievementMgr->UpdateAchievementCriteriaForOfflinePlayer(auction->owner.GetCounter(), ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD, auction->bid);
|
||||
}
|
||||
|
||||
if (sendMail) // can be changed in the hook
|
||||
MailDraft(auction->BuildAuctionMailSubject(AUCTION_SUCCESSFUL), AuctionEntry::BuildAuctionMailBody(auction->bidder, auction->bid, auction->buyout, auction->deposit, auction->GetAuctionCut()))
|
||||
|
||||
@@ -861,39 +861,40 @@ enum PlayedTimeIndex
|
||||
// used at player loading query list preparing, and later result selection
|
||||
enum PlayerLoginQueryIndex
|
||||
{
|
||||
PLAYER_LOGIN_QUERY_LOAD_FROM = 0,
|
||||
PLAYER_LOGIN_QUERY_LOAD_AURAS = 3,
|
||||
PLAYER_LOGIN_QUERY_LOAD_SPELLS = 4,
|
||||
PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS = 5,
|
||||
PLAYER_LOGIN_QUERY_LOAD_DAILY_QUEST_STATUS = 6,
|
||||
PLAYER_LOGIN_QUERY_LOAD_REPUTATION = 7,
|
||||
PLAYER_LOGIN_QUERY_LOAD_INVENTORY = 8,
|
||||
PLAYER_LOGIN_QUERY_LOAD_ACTIONS = 9,
|
||||
PLAYER_LOGIN_QUERY_LOAD_MAILS = 10,
|
||||
PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS = 11,
|
||||
PLAYER_LOGIN_QUERY_LOAD_SOCIAL_LIST = 13,
|
||||
PLAYER_LOGIN_QUERY_LOAD_HOME_BIND = 14,
|
||||
PLAYER_LOGIN_QUERY_LOAD_SPELL_COOLDOWNS = 15,
|
||||
PLAYER_LOGIN_QUERY_LOAD_DECLINED_NAMES = 16,
|
||||
PLAYER_LOGIN_QUERY_LOAD_ACHIEVEMENTS = 18,
|
||||
PLAYER_LOGIN_QUERY_LOAD_CRITERIA_PROGRESS = 19,
|
||||
PLAYER_LOGIN_QUERY_LOAD_EQUIPMENT_SETS = 20,
|
||||
PLAYER_LOGIN_QUERY_LOAD_ENTRY_POINT = 21,
|
||||
PLAYER_LOGIN_QUERY_LOAD_GLYPHS = 22,
|
||||
PLAYER_LOGIN_QUERY_LOAD_TALENTS = 23,
|
||||
PLAYER_LOGIN_QUERY_LOAD_ACCOUNT_DATA = 24,
|
||||
PLAYER_LOGIN_QUERY_LOAD_SKILLS = 25,
|
||||
PLAYER_LOGIN_QUERY_LOAD_WEEKLY_QUEST_STATUS = 26,
|
||||
PLAYER_LOGIN_QUERY_LOAD_RANDOM_BG = 27,
|
||||
PLAYER_LOGIN_QUERY_LOAD_BANNED = 28,
|
||||
PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_REW = 29,
|
||||
PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES = 30,
|
||||
PLAYER_LOGIN_QUERY_LOAD_SEASONAL_QUEST_STATUS = 31,
|
||||
PLAYER_LOGIN_QUERY_LOAD_MONTHLY_QUEST_STATUS = 32,
|
||||
PLAYER_LOGIN_QUERY_LOAD_BREW_OF_THE_MONTH = 34,
|
||||
PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION = 35,
|
||||
PLAYER_LOGIN_QUERY_LOAD_CHARACTER_SETTINGS = 36,
|
||||
PLAYER_LOGIN_QUERY_LOAD_PET_SLOTS = 37,
|
||||
PLAYER_LOGIN_QUERY_LOAD_FROM = 0,
|
||||
PLAYER_LOGIN_QUERY_LOAD_AURAS = 3,
|
||||
PLAYER_LOGIN_QUERY_LOAD_SPELLS = 4,
|
||||
PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS = 5,
|
||||
PLAYER_LOGIN_QUERY_LOAD_DAILY_QUEST_STATUS = 6,
|
||||
PLAYER_LOGIN_QUERY_LOAD_REPUTATION = 7,
|
||||
PLAYER_LOGIN_QUERY_LOAD_INVENTORY = 8,
|
||||
PLAYER_LOGIN_QUERY_LOAD_ACTIONS = 9,
|
||||
PLAYER_LOGIN_QUERY_LOAD_MAILS = 10,
|
||||
PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS = 11,
|
||||
PLAYER_LOGIN_QUERY_LOAD_SOCIAL_LIST = 13,
|
||||
PLAYER_LOGIN_QUERY_LOAD_HOME_BIND = 14,
|
||||
PLAYER_LOGIN_QUERY_LOAD_SPELL_COOLDOWNS = 15,
|
||||
PLAYER_LOGIN_QUERY_LOAD_DECLINED_NAMES = 16,
|
||||
PLAYER_LOGIN_QUERY_LOAD_ACHIEVEMENTS = 18,
|
||||
PLAYER_LOGIN_QUERY_LOAD_CRITERIA_PROGRESS = 19,
|
||||
PLAYER_LOGIN_QUERY_LOAD_EQUIPMENT_SETS = 20,
|
||||
PLAYER_LOGIN_QUERY_LOAD_ENTRY_POINT = 21,
|
||||
PLAYER_LOGIN_QUERY_LOAD_GLYPHS = 22,
|
||||
PLAYER_LOGIN_QUERY_LOAD_TALENTS = 23,
|
||||
PLAYER_LOGIN_QUERY_LOAD_ACCOUNT_DATA = 24,
|
||||
PLAYER_LOGIN_QUERY_LOAD_SKILLS = 25,
|
||||
PLAYER_LOGIN_QUERY_LOAD_WEEKLY_QUEST_STATUS = 26,
|
||||
PLAYER_LOGIN_QUERY_LOAD_RANDOM_BG = 27,
|
||||
PLAYER_LOGIN_QUERY_LOAD_BANNED = 28,
|
||||
PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_REW = 29,
|
||||
PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES = 30,
|
||||
PLAYER_LOGIN_QUERY_LOAD_SEASONAL_QUEST_STATUS = 31,
|
||||
PLAYER_LOGIN_QUERY_LOAD_MONTHLY_QUEST_STATUS = 32,
|
||||
PLAYER_LOGIN_QUERY_LOAD_BREW_OF_THE_MONTH = 34,
|
||||
PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION = 35,
|
||||
PLAYER_LOGIN_QUERY_LOAD_CHARACTER_SETTINGS = 36,
|
||||
PLAYER_LOGIN_QUERY_LOAD_PET_SLOTS = 37,
|
||||
PLAYER_LOGIN_QUERY_LOAD_OFFLINE_ACHIEVEMENTS_UPDATES = 38,
|
||||
MAX_PLAYER_LOGIN_QUERY
|
||||
};
|
||||
|
||||
|
||||
@@ -5023,7 +5023,7 @@ bool Player::LoadFromDB(ObjectGuid playerGuid, CharacterDatabaseQueryHolder cons
|
||||
SetCreationTime(fields[74].Get<Seconds>());
|
||||
|
||||
// load achievements before anything else to prevent multiple gains for the same achievement/criteria on every loading (as loading does call UpdateAchievementCriteria)
|
||||
m_achievementMgr->LoadFromDB(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ACHIEVEMENTS), holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CRITERIA_PROGRESS));
|
||||
m_achievementMgr->LoadFromDB(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ACHIEVEMENTS), holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CRITERIA_PROGRESS), holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_OFFLINE_ACHIEVEMENTS_UPDATES));
|
||||
|
||||
uint32 money = fields[8].Get<uint32>();
|
||||
if (money > MAX_MONEY_AMOUNT)
|
||||
|
||||
@@ -159,7 +159,7 @@ void Player::Update(uint32 p_time)
|
||||
}
|
||||
}
|
||||
|
||||
m_achievementMgr->UpdateTimedAchievements(p_time);
|
||||
m_achievementMgr->Update(p_time);
|
||||
|
||||
if (HasUnitState(UNIT_STATE_MELEE_ATTACKING) && !HasUnitState(UNIT_STATE_CASTING) && !HasUnitState(UNIT_STATE_CHARGING))
|
||||
{
|
||||
|
||||
@@ -216,6 +216,10 @@ bool LoginQueryHolder::Initialize()
|
||||
stmt->SetData(0, lowGuid);
|
||||
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_PET_SLOTS, stmt);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES);
|
||||
stmt->SetData(0, lowGuid);
|
||||
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_OFFLINE_ACHIEVEMENTS_UPDATES, stmt);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user