diff options
author | Giuseppe Montesanto <montesanto.giuseppe@live.it> | 2012-01-01 04:34:14 +0100 |
---|---|---|
committer | Giuseppe Montesanto <montesanto.giuseppe@live.it> | 2012-01-01 04:34:14 +0100 |
commit | bf73409f4934754fcd8b85e70a16ceb2715e60d0 (patch) | |
tree | 400024ca6c866cc88d5bee7d9dac6ebfa725613f /src/server | |
parent | ea7b0b064da0b43086c12df4651649d6dfec76cb (diff) |
Fix 'The Undying' and 'The Immortal' achievements.
Diffstat (limited to 'src/server')
7 files changed, 148 insertions, 91 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index f97d01a42a4..aac7e55a4a7 100755 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -1507,9 +1507,6 @@ void Creature::setDeathState(DeathState s) if (m_formation && m_formation->getLeader() == this) m_formation->FormationReset(true); - if (ZoneScript* zoneScript = GetZoneScript()) - zoneScript->OnCreatureDeath(this); - if ((canFly() || IsFlying()) && FallGround()) return; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index fec9a13192c..981318fbdeb 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -12750,6 +12750,10 @@ void Unit::setDeathState(DeathState s) // do not why since in IncreaseMaxHealth currenthealth is checked SetHealth(0); SetPower(getPowerType(), 0); + + // players in instance don't have ZoneScript, but they have InstanceScript + if (ZoneScript* zoneScript = GetZoneScript() ? GetZoneScript() : (ZoneScript*)GetInstanceScript()) + zoneScript->OnUnitDeath(this); } else if (s == JUST_ALIVED) RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); // clear skinnable for creature and player (at battleground) diff --git a/src/server/game/Maps/ZoneScript.h b/src/server/game/Maps/ZoneScript.h index 58ba9ae2c43..70239baefaf 100755 --- a/src/server/game/Maps/ZoneScript.h +++ b/src/server/game/Maps/ZoneScript.h @@ -37,7 +37,7 @@ class ZoneScript virtual void OnGameObjectCreate(GameObject* /*go*/) {} virtual void OnGameObjectRemove(GameObject* /*go*/) {} - virtual void OnCreatureDeath(Creature* /*creature*/) {} + virtual void OnUnitDeath(Unit* /*unit*/) {} //All-purpose data storage 64 bit virtual uint64 GetData64(uint32 /*DataId*/) { return 0; } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index a7235e34f3a..c6dcf3d7e29 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -335,8 +335,12 @@ class instance_icecrown_citadel : public InstanceMapScript return entry; } - void OnCreatureDeath(Creature* creature) + void OnUnitDeath(Unit* unit) { + Creature* creature = unit->ToCreature(); + if (!creature) + return; + switch (creature->GetEntry()) { case NPC_YMIRJAR_BATTLE_MAIDEN: diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp index 077aa708e14..e42f6230ecf 100644 --- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp +++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp @@ -121,24 +121,24 @@ public: LoadMinionData(minionData); } - std::set<uint64> HeiganEruptionGUID[4]; - uint64 GothikGateGUID; - uint64 HorsemenChestGUID; - uint64 SapphironGUID; - uint64 uiFaerlina; - uint64 uiThane; - uint64 uiLady; - uint64 uiBaron; - uint64 uiSir; - - uint64 uiThaddius; - uint64 uiHeigan; - uint64 uiFeugen; - uint64 uiStalagg; - - uint64 uiKelthuzad; - uint64 uiKelthuzadTrigger; - uint64 uiPortals[4]; + std::set<uint64> heiganEruptionGUID[4]; + uint64 gothikGateGUID; + uint64 horsemenChestGUID; + uint64 sapphironGUID; + uint64 faerlinaGUID; + uint64 thaneGUID; + uint64 ladyGUID; + uint64 baronGUID; + uint64 sirGUID; + + uint64 thaddiusGUID; + uint64 heiganGUID; + uint64 feugenGUID; + uint64 stalaggGUID; + + uint64 kelthuzadGUID; + uint64 kelthuzadTriggerGUID; + uint64 portalsGUID[4]; uint32 AbominationCount; @@ -147,41 +147,46 @@ public: time_t minHorsemenDiedTime; time_t maxHorsemenDiedTime; + uint32 playerDied; + void Initialize() { - GothikGateGUID = 0; - HorsemenChestGUID = 0; - SapphironGUID = 0; - uiFaerlina = 0; - uiThane = 0; - uiLady = 0; - uiBaron = 0; - uiSir = 0; - uiThaddius = 0; - uiHeigan = 0; - uiFeugen = 0; - uiStalagg = 0; - uiKelthuzad = 0; - uiKelthuzadTrigger = 0; - - memset(uiPortals, 0, sizeof(uiPortals)); + gothikGateGUID = 0; + horsemenChestGUID = 0; + sapphironGUID = 0; + faerlinaGUID = 0; + thaneGUID = 0; + ladyGUID = 0; + baronGUID = 0; + sirGUID = 0; + thaddiusGUID = 0; + heiganGUID = 0; + feugenGUID = 0; + stalaggGUID = 0; + kelthuzadGUID = 0; + kelthuzadTriggerGUID = 0; + + playerDied = 0; + gothikDoorState = GO_STATE_ACTIVE; + + memset(portalsGUID, 0, sizeof(portalsGUID)); } void OnCreatureCreate(Creature* creature) { switch (creature->GetEntry()) { - case 15989: SapphironGUID = creature->GetGUID(); return; - case 15953: uiFaerlina = creature->GetGUID(); return; - case 16064: uiThane = creature->GetGUID(); return; - case 16065: uiLady = creature->GetGUID(); return; - case 30549: uiBaron = creature->GetGUID(); return; - case 16063: uiSir = creature->GetGUID(); return; - case 15928: uiThaddius = creature->GetGUID(); return; - case 15936: uiHeigan = creature->GetGUID(); return; - case 15930: uiFeugen = creature->GetGUID(); return; - case 15929: uiStalagg = creature->GetGUID(); return; - case 15990: uiKelthuzad = creature->GetGUID(); return; + case 15989: sapphironGUID = creature->GetGUID(); return; + case 15953: faerlinaGUID = creature->GetGUID(); return; + case 16064: thaneGUID = creature->GetGUID(); return; + case 16065: ladyGUID = creature->GetGUID(); return; + case 30549: baronGUID = creature->GetGUID(); return; + case 16063: sirGUID = creature->GetGUID(); return; + case 15928: thaddiusGUID = creature->GetGUID(); return; + case 15936: heiganGUID = creature->GetGUID(); return; + case 15930: feugenGUID = creature->GetGUID(); return; + case 15929: stalaggGUID = creature->GetGUID(); return; + case 15990: kelthuzadGUID = creature->GetGUID(); return; } AddMinion(creature, true); @@ -197,7 +202,7 @@ public: if (go->GetGOInfo()->displayId == 6785 || go->GetGOInfo()->displayId == 1287) { uint32 section = GetEruptionSection(go->GetPositionX(), go->GetPositionY()); - HeiganEruptionGUID[section].insert(go->GetGUID()); + heiganEruptionGUID[section].insert(go->GetGUID()); return; } @@ -205,29 +210,29 @@ public: switch (go->GetEntry()) { case GO_GOTHIK_GATE: - GothikGateGUID = go->GetGUID(); + gothikGateGUID = go->GetGUID(); go->SetGoState(gothikDoorState); break; case GO_HORSEMEN_CHEST: - HorsemenChestGUID = go->GetGUID(); + horsemenChestGUID = go->GetGUID(); break; case GO_HORSEMEN_CHEST_HERO: - HorsemenChestGUID = go->GetGUID(); + horsemenChestGUID = go->GetGUID(); break; case GO_KELTHUZAD_PORTAL01: - uiPortals[0] = go->GetGUID(); + portalsGUID[0] = go->GetGUID(); break; case GO_KELTHUZAD_PORTAL02: - uiPortals[1] = go->GetGUID(); + portalsGUID[1] = go->GetGUID(); break; case GO_KELTHUZAD_PORTAL03: - uiPortals[2] = go->GetGUID(); + portalsGUID[2] = go->GetGUID(); break; case GO_KELTHUZAD_PORTAL04: - uiPortals[3] = go->GetGUID(); + portalsGUID[3] = go->GetGUID(); break; case GO_KELTHUZAD_TRIGGER: - uiKelthuzadTrigger = go->GetGUID(); + kelthuzadTriggerGUID = go->GetGUID(); break; default: break; @@ -242,16 +247,16 @@ public: { uint32 section = GetEruptionSection(go->GetPositionX(), go->GetPositionY()); - HeiganEruptionGUID[section].erase(go->GetGUID()); + heiganEruptionGUID[section].erase(go->GetGUID()); return; } switch (go->GetEntry()) { case GO_BIRTH: - if (SapphironGUID) + if (sapphironGUID) { - if (Creature* pSapphiron = instance->GetCreature(SapphironGUID)) + if (Creature* pSapphiron = instance->GetCreature(sapphironGUID)) pSapphiron->AI()->DoAction(DATA_SAPPHIRON_BIRTH); return; } @@ -263,6 +268,15 @@ public: AddDoor(go, false); } + void OnUnitDeath(Unit* unit) + { + if (unit->GetTypeId() == TYPEID_PLAYER && IsEncounterInProgress()) + { + playerDied = 1; + SaveToDB(); + } + } + void SetData(uint32 id, uint32 value) { switch (id) @@ -271,11 +285,10 @@ public: HeiganErupt(value); break; case DATA_GOTHIK_GATE: - if (GameObject* gothikGate = instance->GetGameObject(GothikGateGUID)) + if (GameObject* gothikGate = instance->GetGameObject(gothikGateGUID)) gothikGate->SetGoState(GOState(value)); gothikDoorState = GOState(value); break; - case DATA_HORSEMEN0: case DATA_HORSEMEN1: case DATA_HORSEMEN2: @@ -319,35 +332,35 @@ public: switch (id) { case DATA_FAERLINA: - return uiFaerlina; + return faerlinaGUID; case DATA_THANE: - return uiThane; + return thaneGUID; case DATA_LADY: - return uiLady; + return ladyGUID; case DATA_BARON: - return uiBaron; + return baronGUID; case DATA_SIR: - return uiSir; + return sirGUID; case DATA_THADDIUS: - return uiThaddius; + return thaddiusGUID; case DATA_HEIGAN: - return uiHeigan; + return heiganGUID; case DATA_FEUGEN: - return uiFeugen; + return feugenGUID; case DATA_STALAGG: - return uiStalagg; + return stalaggGUID; case DATA_KELTHUZAD: - return uiKelthuzad; + return kelthuzadGUID; case DATA_KELTHUZAD_PORTAL01: - return uiPortals[0]; + return portalsGUID[0]; case DATA_KELTHUZAD_PORTAL02: - return uiPortals[1]; + return portalsGUID[1]; case DATA_KELTHUZAD_PORTAL03: - return uiPortals[2]; + return portalsGUID[2]; case DATA_KELTHUZAD_PORTAL04: - return uiPortals[3]; + return portalsGUID[3]; case DATA_KELTHUZAD_TRIGGER: - return uiKelthuzadTrigger; + return kelthuzadTriggerGUID; } return 0; } @@ -359,7 +372,7 @@ public: if (id == BOSS_HORSEMEN && state == DONE) { - if (GameObject* pHorsemenChest = instance->GetGameObject(HorsemenChestGUID)) + if (GameObject* pHorsemenChest = instance->GetGameObject(horsemenChestGUID)) pHorsemenChest->SetRespawnTime(pHorsemenChest->GetRespawnDelay()); } @@ -373,7 +386,7 @@ public: if (i == section) continue; - for (std::set<uint64>::const_iterator itr = HeiganEruptionGUID[i].begin(); itr != HeiganEruptionGUID[i].end(); ++itr) + for (std::set<uint64>::const_iterator itr = heiganEruptionGUID[i].begin(); itr != heiganEruptionGUID[i].end(); ++itr) { if (GameObject* pHeiganEruption = instance->GetGameObject(*itr)) { @@ -384,6 +397,21 @@ public: } } + // This Function is called in CheckAchievementCriteriaMeet and CheckAchievementCriteriaMeet is called before SetBossState(bossId, DONE), + // so to check if all bosses are done the checker must exclude 1 boss, the last done, if there is at most 1 encouter in progress when is + // called this function then all bosses are done. The one boss that check is the boss that calls this function, so it is dead. + bool AreAllEncoutersDone() + { + uint32 numBossAlive = 0; + for (uint32 i = 0; i < MAX_BOSS_NUMBER; ++i) + if (GetBossState(i) != DONE) + numBossAlive++; + + if (numBossAlive > 1) + return false; + return true; + } + bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target = NULL*/, uint32 /*miscvalue1 = 0*/) { switch (criteria_id) @@ -396,12 +424,22 @@ public: if (Difficulty(instance->GetSpawnMode()) == RAID_DIFFICULTY_25MAN_NORMAL && (maxHorsemenDiedTime - minHorsemenDiedTime) < 15) return true; return false; - case 13233: // Criteria for achievement 2186: The Immortal (25-man) - // TODO. - break; - case 13237: // Criteria for achievement 2187: The Undying (10-man) - // TODO. - break; + // Difficulty checks are done on DB. + // Criteria for achievement 2186: The Immortal (25-man) + case 13233: // The Four Horsemen + case 13234: // Maexxna + case 13235: // Thaddius + case 13236: // Loatheb + case 7616: // Kel'Thuzad + // Criteria for achievement 2187: The Undying (10-man) + case 13237: // The Four Horsemen + case 13238: // Maexxna + case 13239: // Loatheb + case 13240: // Thaddius + case 7617: // Kel'Thuzad + if (AreAllEncoutersDone() && !playerDied) + return true; + return false; } return false; } @@ -409,16 +447,22 @@ public: std::string GetSaveData() { std::ostringstream saveStream; - saveStream << GetBossSaveData() << ' ' << gothikDoorState; + saveStream << GetBossSaveData() << gothikDoorState << ' ' << playerDied; return saveStream.str(); } void Load(const char * data) { std::istringstream loadStream(LoadBossState(data)); - uint32 buff; + uint32 temp, buff, buff2; + + for (uint32 i = 0; i < MAX_BOSS_NUMBER; ++i) + loadStream >> temp; + loadStream >> buff; gothikDoorState = GOState(buff); + loadStream >> buff2; + playerDied = buff2; } }; diff --git a/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp index e6b3416b89c..ebc19b723d8 100644 --- a/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp +++ b/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp @@ -58,8 +58,12 @@ public: gameObjectList.clear(); } - void OnCreatureDeath(Creature* creature) + void OnUnitDeath(Unit* unit) { + Creature* creature = unit->ToCreature(); + if (!creature) + return; + if (creature->GetEntry() != NPC_CENTRIFUGE_CONSTRUCT) return; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp index 3c5697a7995..232c0ad6ffe 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp @@ -358,8 +358,12 @@ class instance_ulduar : public InstanceMapScript } } - void OnCreatureDeath(Creature* creature) + void OnUnitDeath(Unit* unit) { + Creature* creature = unit->ToCreature(); + if (!creature) + return; + switch (creature->GetEntry()) { case NPC_CORRUPTED_SERVITOR: |