aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiuseppe Montesanto <montesanto.giuseppe@live.it>2012-01-01 04:34:14 +0100
committerGiuseppe Montesanto <montesanto.giuseppe@live.it>2012-01-01 04:34:14 +0100
commitbf73409f4934754fcd8b85e70a16ceb2715e60d0 (patch)
tree400024ca6c866cc88d5bee7d9dac6ebfa725613f
parentea7b0b064da0b43086c12df4651649d6dfec76cb (diff)
Fix 'The Undying' and 'The Immortal' achievements.
-rw-r--r--sql/updates/world/2011_12_26_00_world_achievements.sql29
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.cpp3
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp4
-rwxr-xr-xsrc/server/game/Maps/ZoneScript.h2
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp6
-rw-r--r--src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp212
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp6
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp6
8 files changed, 177 insertions, 91 deletions
diff --git a/sql/updates/world/2011_12_26_00_world_achievements.sql b/sql/updates/world/2011_12_26_00_world_achievements.sql
new file mode 100644
index 00000000000..cbd5efa3cd6
--- /dev/null
+++ b/sql/updates/world/2011_12_26_00_world_achievements.sql
@@ -0,0 +1,29 @@
+-- The Undying
+DELETE FROM `disables` WHERE `sourceType` = 4 AND `entry` IN (13237, 13238, 13239, 13240, 7617); -- Enable criteria
+DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (13237, 13238, 13239, 13240, 7617); -- Enable instance script execution for achievement criteria
+INSERT INTO `achievement_criteria_data` VALUES
+(13237, 12, 0, 0, ''),
+(13237, 18, 0, 0, ''),
+(13238, 12, 0, 0, ''),
+(13238, 18, 0, 0, ''),
+(13239, 12, 0, 0, ''),
+(13239, 18, 0, 0, ''),
+(13240, 12, 0, 0, ''),
+(13240, 18, 0, 0, ''),
+(7617, 12, 0, 0, ''),
+(7617, 18, 0, 0, '');
+
+-- The Immortal
+DELETE FROM `disables` WHERE `sourceType` = 4 AND `entry` IN (13233, 13234, 13235, 13236, 7616); -- Enable criteria
+DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (13233, 13234, 13235, 13236, 7616); -- Enable instance script execution for achievement criteria
+INSERT INTO `achievement_criteria_data` VALUES
+(13233, 12, 1, 0, ''),
+(13233, 18, 0, 0, ''),
+(13234, 12, 1, 0, ''),
+(13234, 18, 0, 0, ''),
+(13235, 12, 1, 0, ''),
+(13235, 18, 0, 0, ''),
+(13236, 12, 1, 0, ''),
+(13236, 18, 0, 0, ''),
+(7616, 12, 1, 0, ''),
+(7616, 18, 0, 0, '');
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: