diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index 9f331ba51..bf65393a4 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -24,6 +24,7 @@ #include "ObjectMgr.h" #include "Guild.h" #include "Database/DatabaseEnv.h" +#include "GameEvent.h" AchievementMgr::AchievementMgr(Player *player) { @@ -246,7 +247,50 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if(GetPlayer()->HasSpell(achievementCriteria->learn_spell.spellID)) SetCriteriaProgress(achievementCriteria, 1); break; - + case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP: + // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case + if(!miscvalue1) + continue; + if(GetPlayer()->GetMapId() != achievementCriteria->death_at_map.mapID) + continue; + SetCriteriaProgress(achievementCriteria, 1, true); + break; + case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE: + // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case + if(!miscvalue1) + continue; + if(miscvalue1 != achievementCriteria->killed_by_creature.creatureEntry) + continue; + SetCriteriaProgress(achievementCriteria, 1, true); + break; + case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER: + // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case + if(!miscvalue1) + continue; + SetCriteriaProgress(achievementCriteria, 1, true); + break; + case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING: + { + // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case + if(!miscvalue1) + continue; + if(achievement->ID == 1260) + { + if(Player::GetDrunkenstateByValue(GetPlayer()->GetDrunkValue()) != DRUNKEN_SMASHED) + continue; + // TODO: hardcoding eventid is bad, it can differ from DB to DB - maye implement something using HolidayNames.dbc? + if(!gameeventmgr.IsActiveEvent(26)) + continue; + } + // miscvalue1 is falltime, calculate to fall height format given in dbc + uint32 fallHeight = uint32(0.06f*miscvalue1-91.5)*100; + SetCriteriaProgress(achievementCriteria, fallHeight); + break; + } + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: + if(GetPlayer()->GetQuestRewardStatus(achievementCriteria->complete_quest.questID)) + SetCriteriaProgress(achievementCriteria, 1); + break; } if(IsCompletedCriteria(achievementCriteria)) CompletedCriteria(achievementCriteria); @@ -313,11 +357,19 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve return progress->counter >= achievementCriteria->complete_quests_in_zone.questCount; case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST: return progress->counter >= achievementCriteria->complete_daily_quest.questCount; - case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND: - // just used as a counter - return false - return false; case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL: return progress->counter >= 1; + case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING: + return progress->counter >= achievementCriteria->fall_without_dying.fallHeight; + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: + return progress->counter >= 1; + + // handle all statistic-only criteria here + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND: + case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP: + case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE: + case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER: + return false; } return false; } diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index a2ec545f0..d1cf3a9ed 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -322,6 +322,9 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) damage = target->GetMaxHealth()/2; target->EnvironmentalDamage(target->GetGUID(), DAMAGE_FALL, damage); + + if(target->isAlive()) + target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING, movementInfo.fallTime); } //Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 1f5a6865b..cb6a895cf 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1250,6 +1250,7 @@ void Player::setDeathState(DeathState s) // passive spell if(!ressSpellId) ressSpellId = GetResurrectionSpellId(); + GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP, 1); } Unit::setDeathState(s); @@ -12451,6 +12452,7 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED; GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT); + GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST); } void Player::FailQuest( uint32 quest_id ) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 26ae65eb8..5860d8261 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -690,6 +690,15 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->AI()) ((Creature*)this)->AI()->KilledUnit(pVictim); + // achievement stuff + if ( pVictim->GetTypeId() == TYPEID_PLAYER) + { + if(GetTypeId() == TYPEID_UNIT) + ((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE, GetEntry()); + else if(GetTypeId() == TYPEID_PLAYER) + ((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER, 1); + } + // 10% durability loss on death // clean InHateListOf if (pVictim->GetTypeId() == TYPEID_PLAYER)