Implement support of Timed Achievement. Thanks Shauren.

Fixes issue #1431.

--HG--
branch : trunk
This commit is contained in:
Trazom62
2010-04-27 22:22:13 +02:00
parent 90f38341f0
commit 36ebd58b37
8 changed files with 152 additions and 26 deletions
+118 -17
View File
@@ -611,6 +611,10 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement)
if (GetPlayer()->GetSession()->PlayerLoading()) if (GetPlayer()->GetSession()->PlayerLoading())
return; return;
// Don't send for achievements with ACHIEVEMENT_FLAG_TRACKING
if (achievement->flags & ACHIEVEMENT_FLAG_TRACKING)
return;
#ifdef TRINITY_DEBUG #ifdef TRINITY_DEBUG
if ((sLog.getLogFilter() & LOG_FILTER_ACHIEVEMENT_UPDATES) == 0) if ((sLog.getLogFilter() & LOG_FILTER_ACHIEVEMENT_UPDATES) == 0)
sLog.outDebug("AchievementMgr::SendAchievementEarned(%u)", achievement->ID); sLog.outDebug("AchievementMgr::SendAchievementEarned(%u)", achievement->ID);
@@ -657,19 +661,22 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement)
GetPlayer()->SendMessageToSetInRange(&data, sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY), true); GetPlayer()->SendMessageToSetInRange(&data, sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY), true);
} }
void AchievementMgr::SendCriteriaUpdate(uint32 id, CriteriaProgress const* progress) void AchievementMgr::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted)
{ {
WorldPacket data(SMSG_CRITERIA_UPDATE, 8+4+8); WorldPacket data(SMSG_CRITERIA_UPDATE, 8+4+8);
data << uint32(id); data << uint32(entry->ID);
// the counter is packed like a packed Guid // the counter is packed like a packed Guid
data.appendPackGUID(progress->counter); data.appendPackGUID(progress->counter);
data.append(GetPlayer()->GetPackGUID()); data.append(GetPlayer()->GetPackGUID());
data << uint32(0); if (!entry->timeLimit)
data << uint32(0);
else
data << uint32(timedCompleted ? 0 : 1); // this are some flags, 1 is for keeping the counter at 0 in client
data << uint32(secsToTimeBitFields(progress->date)); data << uint32(secsToTimeBitFields(progress->date));
data << uint32(0); // timer 1 data << uint32(timeElapsed); // time elapsed in seconds
data << uint32(0); // timer 2 data << uint32(0); // unk
GetPlayer()->SendDirectMessage(&data); GetPlayer()->SendDirectMessage(&data);
} }
@@ -711,9 +718,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
{ {
AchievementCriteriaEntry const *achievementCriteria = (*i); AchievementCriteriaEntry const *achievementCriteria = (*i);
if (achievementCriteria->groupFlag & ACHIEVEMENT_CRITERIA_GROUP_NOT_IN_GROUP && GetPlayer()->GetGroup())
continue;
AchievementEntry const *achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement); AchievementEntry const *achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement);
if (!achievement) if (!achievement)
continue; continue;
@@ -1695,6 +1699,11 @@ bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry)
void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype) void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype)
{ {
// Don't allow to cheat - doing timed achievements without timer active
TimedAchievementMap::iterator timedIter = m_timedAchievements.find(entry->ID);
if (entry->timeLimit && timedIter == m_timedAchievements.end())
return;
if ((sLog.getLogFilter() & LOG_FILTER_ACHIEVEMENT_UPDATES) == 0) if ((sLog.getLogFilter() & LOG_FILTER_ACHIEVEMENT_UPDATES) == 0)
sLog.outDetail("AchievementMgr::SetCriteriaProgress(%u, %u) for (GUID:%u)", entry->ID, changeValue, m_player->GetGUIDLow()); sLog.outDetail("AchievementMgr::SetCriteriaProgress(%u, %u) for (GUID:%u)", entry->ID, changeValue, m_player->GetGUIDLow());
@@ -1704,8 +1713,9 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry,
if (iter == m_criteriaProgress.end()) if (iter == m_criteriaProgress.end())
{ {
// not create record for 0 counter // not create record for 0 counter but allow it for timed achievements
if (changeValue == 0) // we will need to send 0 progress to client to start the timer
if (changeValue == 0 && !entry->timeLimit)
return; return;
progress = &m_criteriaProgress[entry->ID]; progress = &m_criteriaProgress[entry->ID];
@@ -1735,7 +1745,7 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry,
} }
// not update (not mark as changed) if counter will have same value // not update (not mark as changed) if counter will have same value
if (progress->counter == newValue) if (progress->counter == newValue && !entry->timeLimit)
return; return;
progress->counter = newValue; progress->counter = newValue;
@@ -1743,16 +1753,85 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry,
progress->changed = true; progress->changed = true;
uint32 timeElapsed = 0;
bool timedCompleted = false;
if (entry->timeLimit) if (entry->timeLimit)
{ {
time_t now = time(NULL); //has to exist else we wouldn't be here
if (time_t(progress->date + entry->timeLimit) < now) timedCompleted = IsCompletedCriteria(entry, sAchievementStore.LookupEntry(entry->referredAchievement));
progress->counter = 1; // Client expects this in packet
timeElapsed = entry->timeLimit - (timedIter->second/IN_MILISECONDS);
// also it seems illogical, the timeframe will be extended at every criteria update // Remove the timer, we wont need it anymore
progress->date = now; if (timedCompleted)
m_timedAchievements.erase(timedIter);
}
SendCriteriaUpdate(entry, progress, timeElapsed, timedCompleted);
}
void AchievementMgr::UpdateTimedAchievements(uint32 timeDiff)
{
if (!m_timedAchievements.empty())
{
for (TimedAchievementMap::iterator itr = m_timedAchievements.begin(); itr != m_timedAchievements.end();)
{
// Time is up, remove timer and reset progress
if (itr->second <= timeDiff)
{
AchievementCriteriaEntry const *entry = sAchievementCriteriaStore.LookupEntry(itr->first);
SetCriteriaProgress(entry, 0, PROGRESS_SET);
m_timedAchievements.erase(itr++);
}
else
{
itr->second -= timeDiff;
++itr;
}
}
}
}
void AchievementMgr::StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry)
{
AchievementCriteriaEntryList const& achievementCriteriaList = achievementmgr.GetTimedAchievementCriteriaByType(type);
for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i != achievementCriteriaList.end(); ++i)
{
if ((*i)->timerStartEvent != entry)
continue;
AchievementEntry const *achievement = sAchievementStore.LookupEntry((*i)->referredAchievement);
if (m_timedAchievements.find((*i)->ID) == m_timedAchievements.end() && !IsCompletedCriteria(*i, achievement))
{
// Start the timer
m_timedAchievements[(*i)->ID] = (*i)->timeLimit * IN_MILISECONDS;
// and at client too
SetCriteriaProgress(*i, 0, PROGRESS_SET);
}
}
}
void AchievementMgr::RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry)
{
AchievementCriteriaEntryList const& achievementCriteriaList = achievementmgr.GetTimedAchievementCriteriaByType(type);
for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i!=achievementCriteriaList.end(); ++i)
{
if ((*i)->timerStartEvent != entry)
continue;
TimedAchievementMap::iterator timedIter = m_timedAchievements.find((*i)->ID);
// We don't have timer for this achievement
if (timedIter == m_timedAchievements.end())
continue;
// 0 the progress to avoid saving to db
SetCriteriaProgress(*i, 0, PROGRESS_SET);
// Remove the timer
m_timedAchievements.erase(timedIter);
} }
SendCriteriaUpdate(entry->ID,progress);
} }
void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
@@ -1847,8 +1926,14 @@ void AchievementMgr::SendRespondInspectAchievements(Player* player)
*/ */
void AchievementMgr::BuildAllDataPacket(WorldPacket *data) void AchievementMgr::BuildAllDataPacket(WorldPacket *data)
{ {
AchievementEntry const *achievement;
for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter) for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter)
{ {
// Skip tracking - they bug client UI
achievement = sAchievementStore.LookupEntry(iter->first);
if (achievement->flags & ACHIEVEMENT_FLAG_TRACKING)
continue;
*data << uint32(iter->first); *data << uint32(iter->first);
*data << uint32(secsToTimeBitFields(iter->second.date)); *data << uint32(secsToTimeBitFields(iter->second.date));
} }
@@ -1879,6 +1964,11 @@ AchievementCriteriaEntryList const& AchievementGlobalMgr::GetAchievementCriteria
return m_AchievementCriteriasByType[type]; return m_AchievementCriteriasByType[type];
} }
AchievementCriteriaEntryList const& AchievementGlobalMgr::GetTimedAchievementCriteriaByType(AchievementCriteriaTimedTypes type)
{
return m_AchievementCriteriasByTimedType[type];
}
void AchievementGlobalMgr::LoadAchievementCriteriaList() void AchievementGlobalMgr::LoadAchievementCriteriaList()
{ {
if (sAchievementCriteriaStore.GetNumRows() == 0) if (sAchievementCriteriaStore.GetNumRows() == 0)
@@ -1902,6 +1992,9 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList()
m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria); m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria);
m_AchievementCriteriaListByAchievement[criteria->referredAchievement].push_back(criteria); m_AchievementCriteriaListByAchievement[criteria->referredAchievement].push_back(criteria);
if(criteria->timeLimit)
m_AchievementCriteriasByTimedType[criteria->timedType].push_back(criteria);
} }
sLog.outString(); sLog.outString();
@@ -2030,6 +2123,8 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
} }
case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING: case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING:
break; // any cases break; // any cases
case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET: // any cases
break;
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL: // any cases case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL: // any cases
break; break;
case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA: // need skip generic cases case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA: // need skip generic cases
@@ -2038,10 +2133,16 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
break; break;
case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM: // any cases case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM: // any cases
break; break;
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
break; // any cases
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT:
break; // any cases
case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE: // need skip generic cases case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE: // need skip generic cases
if (criteria->do_emote.count == 0) if (criteria->do_emote.count == 0)
continue; continue;
break; break;
case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2:
break; // any cases
case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL: // skip statistics case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL: // skip statistics
if (criteria->win_duel.duelCount == 0) if (criteria->win_duel.duelCount == 0)
continue; continue;
+9 -2
View File
@@ -249,12 +249,15 @@ class AchievementMgr
void SendAllAchievementData(); void SendAllAchievementData();
void SendRespondInspectAchievements(Player* player); void SendRespondInspectAchievements(Player* player);
bool HasAchieved(AchievementEntry const* achievement) const; bool HasAchieved(AchievementEntry const* achievement) const;
Player* GetPlayer() { return m_player;} Player* GetPlayer() { return m_player; }
void UpdateTimedAchievements(uint32 timeDiff);
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry);
void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry); // used for quest and scripted timed achievements
private: private:
enum ProgressType { PROGRESS_SET, PROGRESS_ACCUMULATE, PROGRESS_HIGHEST }; enum ProgressType { PROGRESS_SET, PROGRESS_ACCUMULATE, PROGRESS_HIGHEST };
void SendAchievementEarned(AchievementEntry const* achievement); void SendAchievementEarned(AchievementEntry const* achievement);
void SendCriteriaUpdate(uint32 id, CriteriaProgress const* progress); void SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted);
void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype = PROGRESS_SET); void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype = PROGRESS_SET);
void CompletedCriteriaFor(AchievementEntry const* achievement); void CompletedCriteriaFor(AchievementEntry const* achievement);
bool IsCompletedCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement); bool IsCompletedCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement);
@@ -265,12 +268,15 @@ class AchievementMgr
Player* m_player; Player* m_player;
CriteriaProgressMap m_criteriaProgress; CriteriaProgressMap m_criteriaProgress;
CompletedAchievementMap m_completedAchievements; CompletedAchievementMap m_completedAchievements;
typedef std::map<uint32, uint32> TimedAchievementMap;
TimedAchievementMap m_timedAchievements; // Criteria id/time left in MS
}; };
class AchievementGlobalMgr class AchievementGlobalMgr
{ {
public: public:
AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type); AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type);
AchievementCriteriaEntryList const& GetTimedAchievementCriteriaByType(AchievementCriteriaTimedTypes type);
AchievementCriteriaEntryList const* GetAchievementCriteriaByAchievement(uint32 id) AchievementCriteriaEntryList const* GetAchievementCriteriaByAchievement(uint32 id)
{ {
AchievementCriteriaListByAchievement::const_iterator itr = m_AchievementCriteriaListByAchievement.find(id); AchievementCriteriaListByAchievement::const_iterator itr = m_AchievementCriteriaListByAchievement.find(id);
@@ -322,6 +328,7 @@ class AchievementGlobalMgr
// store achievement criterias by type to speed up lookup // store achievement criterias by type to speed up lookup
AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL]; AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL];
AchievementCriteriaEntryList m_AchievementCriteriasByTimedType[ACHIEVEMENT_TIMED_TYPE_MAX];
// store achievement criterias by achievement to speed up lookup // store achievement criterias by achievement to speed up lookup
AchievementCriteriaListByAchievement m_AchievementCriteriaListByAchievement; AchievementCriteriaListByAchievement m_AchievementCriteriaListByAchievement;
// store achievements by referenced achievement id to speed up lookup // store achievements by referenced achievement id to speed up lookup
+10 -4
View File
@@ -58,7 +58,7 @@ enum AchievementFaction
enum AchievementFlags enum AchievementFlags
{ {
ACHIEVEMENT_FLAG_COUNTER = 0x00000001, // Just count statistic (never stop and complete) ACHIEVEMENT_FLAG_COUNTER = 0x00000001, // Just count statistic (never stop and complete)
ACHIEVEMENT_FLAG_UNK2 = 0x00000002, // not used ACHIEVEMENT_FLAG_TRACKING = 0x00000002, // Not sent to client - internal use only
ACHIEVEMENT_FLAG_STORE_MAX_VALUE = 0x00000004, // Store only max value? used only in "Reach level xx" ACHIEVEMENT_FLAG_STORE_MAX_VALUE = 0x00000004, // Store only max value? used only in "Reach level xx"
ACHIEVEMENT_FLAG_SUMM = 0x00000008, // Use summ criteria value from all reqirements (and calculate max value) ACHIEVEMENT_FLAG_SUMM = 0x00000008, // Use summ criteria value from all reqirements (and calculate max value)
ACHIEVEMENT_FLAG_MAX_USED = 0x00000010, // Show max criteria (and calculate max value ??) ACHIEVEMENT_FLAG_MAX_USED = 0x00000010, // Show max criteria (and calculate max value ??)
@@ -90,10 +90,16 @@ enum AchievementCriteriaCompletionFlags
ACHIEVEMENT_CRITERIA_FLAG_MONEY_COUNTER = 0x00000020, // Displays counter as money ACHIEVEMENT_CRITERIA_FLAG_MONEY_COUNTER = 0x00000020, // Displays counter as money
}; };
enum AchievementCriteriaGroupFlags enum AchievementCriteriaTimedTypes
{ {
// you mustn't be in a group while fulfilling this achievement ACHIEVEMENT_TIMED_TYPE_EVENT = 1, // Timer is started by internal event with id in timerStartEvent
ACHIEVEMENT_CRITERIA_GROUP_NOT_IN_GROUP = 2, ACHIEVEMENT_TIMED_TYPE_QUEST = 2, // Timer is started by acceting quest with entry in timerStartEvent
ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER = 5, // Timer is started by casting a spell with entry in timerStartEvent
ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET = 6, // Timer is started by being target of spell with entry in timerStartEvent
ACHIEVEMENT_TIMED_TYPE_CREATURE = 7, // Timer is started by killing creature with entry in timerStartEvent
ACHIEVEMENT_TIMED_TYPE_ITEM = 9, // Timer is started by using item with entry in timerStartEvent
ACHIEVEMENT_TIMED_TYPE_MAX,
}; };
enum AchievementCriteriaTypes enum AchievementCriteriaTypes
+2 -2
View File
@@ -492,8 +492,8 @@ struct AchievementCriteriaEntry
//char* name[16]; // 9-24 //char* name[16]; // 9-24
//uint32 name_flags; // 25 //uint32 name_flags; // 25
uint32 completionFlag; // 26 uint32 completionFlag; // 26
uint32 groupFlag; // 27 uint32 timedType; // 27
//uint32 unk1; // 28 Alway appears with timed events uint32 timerStartEvent; // 28 Alway appears with timed events
// for timed spells it is spell id for // for timed spells it is spell id for
// timed kills it is creature id // timed kills it is creature id
uint32 timeLimit; // 29 time limit in seconds uint32 timeLimit; // 29 time limit in seconds
+1 -1
View File
@@ -22,7 +22,7 @@
#define TRINITY_DBCSFRM_H #define TRINITY_DBCSFRM_H
const char Achievementfmt[]="niixssssssssssssssssxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxii"; const char Achievementfmt[]="niixssssssssssssssssxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxii";
const char AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiixix"; const char AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiiiix";
const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxxx"; const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxxx";
const char AreaGroupEntryfmt[]="niiiiiii"; const char AreaGroupEntryfmt[]="niiiiiii";
const char AreaPOIEntryfmt[]="niiiiiiiiiiifffixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxix"; const char AreaPOIEntryfmt[]="niiiiiiiiiiifffixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxix";
+6
View File
@@ -1218,6 +1218,8 @@ void Player::Update(uint32 p_time)
} }
} }
GetAchievementMgr().UpdateTimedAchievements(p_time);
if (hasUnitState(UNIT_STAT_MELEE_ATTACKING) && !hasUnitState(UNIT_STAT_CASTING)) if (hasUnitState(UNIT_STAT_MELEE_ATTACKING) && !hasUnitState(UNIT_STAT_CASTING))
{ {
if (Unit *pVictim = getVictim()) if (Unit *pVictim = getVictim())
@@ -13975,6 +13977,8 @@ void Player::AddQuest(Quest const *pQuest, Object *questGiver)
if (questStatusData.uState != QUEST_NEW) if (questStatusData.uState != QUEST_NEW)
questStatusData.uState = QUEST_CHANGED; questStatusData.uState = QUEST_CHANGED;
GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_QUEST, quest_id);
//starting initial quest script //starting initial quest script
if (questGiver && pQuest->GetQuestStartScript() != 0) if (questGiver && pQuest->GetQuestStartScript() != 0)
GetMap()->ScriptsStart(sQuestStartScripts, pQuest->GetQuestStartScript(), questGiver, this); GetMap()->ScriptsStart(sQuestStartScripts, pQuest->GetQuestStartScript(), questGiver, this);
@@ -14899,7 +14903,9 @@ void Player::KilledMonsterCredit(uint32 entry, uint64 guid)
real_entry = killed->GetEntry(); real_entry = killed->GetEntry();
} }
GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_CREATURE, real_entry); // MUST BE CALLED FIRST
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, real_entry, addkillcount); GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, real_entry, addkillcount);
for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i) for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i)
{ {
uint32 questid = GetQuestSlotQuestId(i); uint32 questid = GetQuestSlotQuestId(i);
+1
View File
@@ -392,6 +392,7 @@ void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recv_data)
_player->TakeQuestSourceItem(quest, true); // remove quest src item from player _player->TakeQuestSourceItem(quest, true); // remove quest src item from player
_player->SetQuestStatus(quest, QUEST_STATUS_NONE); _player->SetQuestStatus(quest, QUEST_STATUS_NONE);
_player->GetAchievementMgr().RemoveTimedAchievement(ACHIEVEMENT_TIMED_TYPE_QUEST, quest);
} }
_player->SetQuestSlot(slot, 0); _player->SetQuestSlot(slot, 0);
+5
View File
@@ -1266,12 +1266,14 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask, bool
if (unit->GetTypeId() == TYPEID_PLAYER) if (unit->GetTypeId() == TYPEID_PLAYER)
{ {
unit->ToPlayer()->GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, m_spellInfo->Id);
unit->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, m_spellInfo->Id); unit->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, m_spellInfo->Id);
unit->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, m_spellInfo->Id); unit->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, m_spellInfo->Id);
} }
if (m_caster->GetTypeId() == TYPEID_PLAYER) if (m_caster->GetTypeId() == TYPEID_PLAYER)
{ {
m_caster->ToPlayer()->GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER, m_spellInfo->Id);
m_caster->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, m_spellInfo->Id, 0, unit); m_caster->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, m_spellInfo->Id, 0, unit);
} }
@@ -2929,7 +2931,10 @@ void Spell::cast(bool skipCheck)
if (m_caster->GetTypeId() == TYPEID_PLAYER) if (m_caster->GetTypeId() == TYPEID_PLAYER)
{ {
if (!m_IsTriggeredSpell && m_CastItem) if (!m_IsTriggeredSpell && m_CastItem)
{
m_caster->ToPlayer()->GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_ITEM, m_CastItem->GetEntry());
m_caster->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, m_CastItem->GetEntry()); m_caster->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, m_CastItem->GetEntry());
}
m_caster->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, m_spellInfo->Id); m_caster->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, m_spellInfo->Id);
} }