mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-30 00:53:46 +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
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user