Fix 'The Undying' and 'The Immortal' achievements.

This commit is contained in:
Giuseppe Montesanto
2012-01-01 04:34:14 +01:00
parent ea7b0b064d
commit bf73409f49
8 changed files with 174 additions and 88 deletions

View File

@@ -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:

View File

@@ -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;
std::set<uint64> heiganEruptionGUID[4];
uint64 gothikGateGUID;
uint64 horsemenChestGUID;
uint64 sapphironGUID;
uint64 faerlinaGUID;
uint64 thaneGUID;
uint64 ladyGUID;
uint64 baronGUID;
uint64 sirGUID;
uint64 uiThaddius;
uint64 uiHeigan;
uint64 uiFeugen;
uint64 uiStalagg;
uint64 thaddiusGUID;
uint64 heiganGUID;
uint64 feugenGUID;
uint64 stalaggGUID;
uint64 uiKelthuzad;
uint64 uiKelthuzadTrigger;
uint64 uiPortals[4];
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;
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;
memset(uiPortals, 0, sizeof(uiPortals));
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;
}
};

View File

@@ -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;

View File

@@ -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: