diff options
| author | megamage <none@none> | 2009-03-06 15:21:44 -0600 |
|---|---|---|
| committer | megamage <none@none> | 2009-03-06 15:21:44 -0600 |
| commit | 50b3095312ef01dcc748011d740a8fadfaa04b6c (patch) | |
| tree | 2260ac10775016e7cc5ded834eb4754adc8aa3a2 /src/game | |
| parent | 2e0af6e37b17b76651e50b24a016b045f747b658 (diff) | |
Implement some death related achievements
* ACHIEVEMENT_CRITERIA_TYPE_DEATH (normal and arena types counting)
* ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON (instance types by man limit counting)
Note: need fixed for cases when max allowed players different from recommended count.
* ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM (environment damage sources by types)
Fixed:
* ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER
- self-kill counting as death from players
- same team player kill in opposition kills counter.
Also cleanup in Player::EnvironmentalDamage use DBCStructure.h comment.
Author: VladimirMangos
--HG--
branch : trunk
Diffstat (limited to 'src/game')
| -rw-r--r-- | src/game/AchievementMgr.cpp | 112 | ||||
| -rw-r--r-- | src/game/Player.cpp | 26 | ||||
| -rw-r--r-- | src/game/Unit.cpp | 25 |
3 files changed, 138 insertions, 25 deletions
diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index d4dd1faa840..b06a2f1c758 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -27,6 +27,7 @@ #include "GameEvent.h" #include "World.h" #include "SpellMgr.h" +#include "ArenaTeam.h" #include "ProgressBar.h" #include "GridNotifiersImpl.h" #include "CellImpl.h" @@ -374,6 +375,18 @@ void AchievementMgr::CheckAllAchievementCriteria() UpdateAchievementCriteria(AchievementCriteriaTypes(i)); } +static const uint32 achievIdByArenaSlot[MAX_ARENA_SLOT] = { 1057, 1107, 1108 }; +static const uint32 achievIdForDangeon[][4] = +{ + // ach_cr_id,is_dungeon,is_raid,is_heroic_dungeon + { 321, true, true, true }, + { 916, false, true, false }, + { 917, false, true, false }, + { 918, true, false, false }, + { 2219, false, false, true }, + { 0, false, false, false } +}; + /** * this function will be called whenever the user might have done a criteria relevant action */ @@ -408,7 +421,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui { // std. case: increment at 1 case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST: - case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER: // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case if(!miscvalue1) continue; @@ -493,6 +505,79 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui continue; SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); break; + case ACHIEVEMENT_CRITERIA_TYPE_DEATH: + { + // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case + if(!miscvalue1) + continue; + // skip wrong arena achievements, if not achievIdByArenaSlot then normal totla death counter + bool notfit = false; + for(int i = 0; i < MAX_ARENA_SLOT; ++i) + { + if(achievIdByArenaSlot[i] == achievement->ID) + { + BattleGround* bg = GetPlayer()->GetBattleGround(); + if(!bg || ArenaTeam::GetSlotByType(bg->GetArenaType())!=i) + notfit = true; + + break; + } + } + if(notfit) + continue; + + SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + break; + } + case ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON: + { + // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case + if(!miscvalue1) + continue; + + Map const* map = GetPlayer()->GetMap(); + if(!map->IsDungeon()) + continue; + + // search case + bool found = false; + for(int i = 0; achievIdForDangeon[i][0]; ++i) + { + if(achievIdForDangeon[i][0] == achievement->ID) + { + if(map->IsRaid()) + { + // if raid accepted (ignore difficulty) + if(!achievIdForDangeon[i][2]) + break; // for + } + else if(GetPlayer()->GetDifficulty()==DIFFICULTY_NORMAL) + { + // dungeon in normal mode accepted + if(!achievIdForDangeon[i][1]) + break; // for + } + else + { + // dungeon in heroic mode accepted + if(!achievIdForDangeon[i][3]) + break; // for + } + + found = true; + break; // for + } + } + if(!found) + continue; + + //FIXME: work only for instances where max==min for players + if(((InstanceMap*)map)->GetMaxPlayers() != achievementCriteria->death_in_dungeon.manLimit) + continue; + SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + break; + + } case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE: // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case if(!miscvalue1) @@ -501,6 +586,17 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui continue; SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); break; + case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER: + // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case + if(!miscvalue1) + continue; + + // if team check required: must kill by opposition faction + if(achievement->ID==318 && miscvalue2==GetPlayer()->GetTeam()) + continue; + + SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + break; case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING: { // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case @@ -518,6 +614,14 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui SetCriteriaProgress(achievementCriteria, miscvalue1); break; } + case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM: + // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case + if(!miscvalue1) + continue; + if(miscvalue2 != achievementCriteria->death_from.type) + continue; + SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + break; case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: if(GetPlayer()->GetQuestRewardStatus(achievementCriteria->complete_quest.questID)) SetCriteriaProgress(achievementCriteria, 1); @@ -680,10 +784,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY: case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE: - case ACHIEVEMENT_CRITERIA_TYPE_DEATH: - case ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON: case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID: - case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM: case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE: case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA: case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA: @@ -836,8 +937,11 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve // handle all statistic-only criteria here case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND: case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP: + case ACHIEVEMENT_CRITERIA_TYPE_DEATH: + case ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON: case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE: case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER: + case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM: case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS: case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER: case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL: diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 7bda4f64ed9..cf1e79e687b 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -898,6 +898,9 @@ void Player::StopMirrorTimer(MirrorTimerType Type) void Player::EnvironmentalDamage(uint64 guid, EnviromentalDamage type, uint32 damage) { + if(!isAlive() || isGameMaster()) + return; + WorldPacket data(SMSG_ENVIRONMENTALDAMAGELOG, (21)); data << (uint64)guid; data << (uint8)(type!=DAMAGE_FALL_TO_VOID ? type : DAMAGE_FALL); @@ -908,13 +911,18 @@ void Player::EnvironmentalDamage(uint64 guid, EnviromentalDamage type, uint32 da DealDamage(this, damage, NULL, SELF_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - if(type==DAMAGE_FALL && !isAlive()) // DealDamage not apply item durability loss at self damage + if(!isAlive()) { - DEBUG_LOG("We are fall to death, loosing 10 percents durability"); - DurabilityLossAll(0.10f,false); - // durability lost message - WorldPacket data(SMSG_DURABILITY_DAMAGE_DEATH, 0); - GetSession()->SendPacket(&data); + if(type==DAMAGE_FALL) // DealDamage not apply item durability loss at self damage + { + DEBUG_LOG("We are fall to death, loosing 10 percents durability"); + DurabilityLossAll(0.10f,false); + // durability lost message + WorldPacket data(SMSG_DURABILITY_DAMAGE_DEATH, 0); + GetSession()->SendPacket(&data); + } + + GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM, 1, type); } } @@ -998,9 +1006,7 @@ void Player::HandleLava() uint64 guid = GetGUID(); uint32 damage = urand(600, 700); // TODO: Get more detailed information about lava damage - // if not gamemaster then deal damage - if ( !isGameMaster() ) - EnvironmentalDamage(guid, DAMAGE_LAVA, damage); + EnvironmentalDamage(guid, DAMAGE_LAVA, damage); m_breathTimer = 1*IN_MILISECONDS; } @@ -1385,6 +1391,8 @@ void Player::setDeathState(DeathState s) if(!ressSpellId) ressSpellId = GetResurrectionSpellId(); GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP, 1); + GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH, 1); + GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON, 1); } Unit::setDeathState(s); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 60018a88a9c..da76612bec7 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -728,6 +728,7 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa if (pVictim->GetTypeId() == TYPEID_UNIT && !((Creature*)pVictim)->isPet() && !((Creature*)pVictim)->hasLootRecipient()) ((Creature*)pVictim)->SetLootRecipient(this); + if (health <= damage) { DEBUG_LOG("DealDamage: victim just died"); @@ -805,12 +806,12 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa ((Creature*)this)->AI()->KilledUnit(pVictim); // achievement stuff - if ( pVictim->GetTypeId() == TYPEID_PLAYER) + if (pVictim->GetTypeId() == TYPEID_PLAYER) { - if(GetTypeId() == TYPEID_UNIT) + 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); + else if(GetTypeId() == TYPEID_PLAYER && pVictim != this) + ((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER, 1, ((Player*)this)->GetTeam()); } // 10% durability loss on death @@ -12482,14 +12483,14 @@ void Unit::Kill(Unit *pVictim, bool durabilityLoss) } } - // 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); - } + // 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 && pVictim != this) + ((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER, 1, ((Player*)this)->GetTeam()); + } } void Unit::SetControlled(bool apply, UnitState state) |
