diff options
author | QAston <qaston@gmail.com> | 2011-06-26 00:29:36 +0200 |
---|---|---|
committer | QAston <qaston@gmail.com> | 2011-06-26 00:29:36 +0200 |
commit | 6dcee0c0ea23617849a6b04ae22d2b74fb04f097 (patch) | |
tree | eb68d1f2f1c8518263ffdf53cc01c292fe83ded8 /src | |
parent | 2bcf63d3879cdb7175b83e98f8cd37bacd6449b3 (diff) | |
parent | 9a5f8dc844be68fa239d9c5ac6b95b7a6b2dfcee (diff) |
Merge branch 'master' of https://github.com/TrinityCore/TrinityCore
Diffstat (limited to 'src')
43 files changed, 928 insertions, 543 deletions
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp index bd3125ff18d..d5fd8cca112 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp @@ -186,7 +186,7 @@ void BattlegroundIC::Update(uint32 diff) siege->Respawn(true); } - // we need to confirm this, i am not sure if this every 3 minutes + // we need to confirm if it is every 3 minutes for (uint8 u = (nodePoint[i].faction == TEAM_ALLIANCE ? BG_IC_NPC_DEMOLISHER_1_A : BG_IC_NPC_DEMOLISHER_1_H); u < (nodePoint[i].faction == TEAM_ALLIANCE ? BG_IC_NPC_DEMOLISHER_4_A : BG_IC_NPC_DEMOLISHER_4_H); u++) { if (Creature* demolisher = GetBGCreature(u)) @@ -200,7 +200,7 @@ void BattlegroundIC::Update(uint32 diff) } } - // the point is waiting for a change on his banner + // the point is waiting for a change on its banner if (nodePoint[i].needChange) { if (nodePoint[i].timer <= diff) diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 6634760fdfd..95be55e595e 100755 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -774,7 +774,7 @@ class GameObject : public WorldObject, public GridObject<GameObject> uint64 GetRotation() const { return m_rotation; } virtual uint32 GetScriptId() const { return GetGOInfo()->ScriptId; } - GameObjectAI* AI() const { return (GameObjectAI*)m_AI; } + GameObjectAI* AI() const { return m_AI; } std::string GetAIName() const; protected: diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index c5122b04d69..fd8be29c3e0 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -5704,7 +5704,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger { if (effIndex != 0) return false; - AuraEffect* counter = triggeredByAura->GetBase()->GetEffect(1); + AuraEffect* counter = triggeredByAura->GetBase()->GetEffect(EFFECT_1); if (!counter) return true; @@ -6040,7 +6040,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger // regen mana for caster CastCustomSpell(this, 59117, &basepoints0, NULL, NULL, true, castItem, triggeredByAura); // Get second aura of spell for replenishment effect on party - if (AuraEffect const* aurEff = (*i)->GetBase()->GetEffect(1)) + if (AuraEffect const* aurEff = (*i)->GetBase()->GetEffect(EFFECT_1)) { // Replenishment - roll chance if (roll_chance_i(aurEff->GetAmount())) @@ -6108,7 +6108,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger { // Multiple effects stack, so let's try to find this aura. int32 bonus = 0; - if (AuraEffect* aurEff = target->GetAuraEffect(47753, 0)) + if (AuraEffect const* aurEff = target->GetAuraEffect(47753, 0)) bonus = aurEff->GetAmount(); basepoints0 = CalculatePctN(int32(damage), triggerAmount) + bonus; @@ -6605,7 +6605,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger // This effect only from Rapid Killing (mana regen) if (!(procSpell->SpellFamilyFlags[1] & 0x01000000)) return false; - triggered_spell_id = 56654; target = this; @@ -6688,7 +6687,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger { if (procFlag & PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS) { - if ((procSpell->SpellFamilyName == SPELLFAMILY_PALADIN) && (procSpell->SpellFamilyFlags[0] & 0x40000000)) + if (procSpell->SpellFamilyName == SPELLFAMILY_PALADIN && (procSpell->SpellFamilyFlags[0] & 0x40000000)) { basepoints0 = damage / 12; @@ -6703,6 +6702,11 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger else if (damage > 0) triggered_spell_id = 58597; + // Item - Paladin T8 Holy 4P Bonus + if (Unit* caster = triggeredByAura->GetCaster()) + if (AuraEffect const* aurEff = caster->GetAuraEffect(64895, 0)) + cooldown = aurEff->GetAmount(); + target = this; break; } @@ -6710,7 +6714,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger if (dummySpell->SpellIconID == 3025) { // 4 damage tick - basepoints0 = triggerAmount*damage/400; + basepoints0 = triggerAmount * damage / 400; triggered_spell_id = 61840; // Add remaining ticks to damage done basepoints0 += pVictim->GetRemainingPeriodicAmount(GetGUID(), triggered_spell_id, SPELL_AURA_PERIODIC_DAMAGE); @@ -6720,7 +6724,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger if (dummySpell->SpellIconID == 3030) { // 4 healing tick - basepoints0 = triggerAmount*damage/400; + basepoints0 = triggerAmount * damage / 400; triggered_spell_id = 54203; break; } @@ -6808,7 +6812,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger // At melee attack or Hammer of the Righteous spell damage considered as melee attack bool stacker = !procSpell || procSpell->Id == 53595; - bool damager = procSpell && procSpell->EquippedItemClass == ITEM_CLASS_WEAPON; + // spells with SPELL_DAMAGE_CLASS_MELEE excluding Judgements + bool damager = procSpell && procSpell->EquippedItemClass != -1; if (!stacker && !damager) return false; @@ -6839,7 +6844,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger // At melee attack or Hammer of the Righteous spell damage considered as melee attack bool stacker = !procSpell || procSpell->Id == 53595; - bool damager = procSpell && procSpell->EquippedItemClass == ITEM_CLASS_WEAPON; + // spells with SPELL_DAMAGE_CLASS_MELEE excluding Judgements + bool damager = procSpell && procSpell->EquippedItemClass != -1; if (!stacker && !damager) return false; @@ -6913,6 +6919,13 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger basepoints0 = CalculatePctN(int32(damage), triggerAmount); break; } + // Item - Paladin T8 Holy 2P Bonus + case 64890: + { + triggered_spell_id = 64891; + basepoints0 = triggerAmount * damage / 300; + break; + } case 71406: // Tiny Abomination in a Jar case 71545: // Tiny Abomination in a Jar (Heroic) { @@ -7239,6 +7252,26 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger } return false; } + // Item - Shaman T10 Elemental 4P Bonus + case 70817: + { + // try to find spell Flame Shock on the target + if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_SHAMAN, 0x10000000, 0x0, 0x0, GetGUID())) + { + Aura* flameShock = aurEff->GetBase(); + int32 maxDuration = flameShock->GetMaxDuration(); + int32 newDuration = flameShock->GetDuration() + 2 * aurEff->GetAmplitude(); + + flameShock->SetDuration(newDuration); + // is it blizzlike to change max duration for FS? + if (newDuration > maxDuration) + flameShock->SetMaxDuration(newDuration); + + return true; + } + // if not found Flame Shock + return false; + } case 63280: // Glyph of Totem of Wrath { if (procSpell->SpellIconID != 2019) @@ -7942,6 +7975,9 @@ bool Unit::HandleAuraProc(Unit* pVictim, uint32 damage, Aura * triggeredByAura, if (pVictim->HasAura(53601)) { int32 bp0 = CalculatePctN(int32(damage / 12), SpellMgr::CalculateSpellEffectAmount(dummySpell, 2)); + // Item - Paladin T9 Holy 4P Bonus + if (AuraEffect const* aurEff = GetAuraEffect(67191, 0)) + AddPctN(bp0, aurEff->GetAmount()); CastCustomSpell(pVictim, 66922, &bp0, NULL, NULL, true); return true; } @@ -8014,7 +8050,7 @@ bool Unit::HandleAuraProc(Unit* pVictim, uint32 damage, Aura * triggeredByAura, return false; int32 bp0 = int32(CalculatePctN(GetCreateMana(), SpellMgr::CalculateSpellEffectAmount(spInfo, 0))); - CastCustomSpell(this, 67545, &bp0, NULL, NULL, true, NULL, triggeredByAura->GetEffect(0), GetGUID()); + CastCustomSpell(this, 67545, &bp0, NULL, NULL, true, NULL, triggeredByAura->GetEffect(EFFECT_0), GetGUID()); return true; } } @@ -8037,7 +8073,7 @@ bool Unit::HandleAuraProc(Unit* pVictim, uint32 damage, Aura * triggeredByAura, // can't proc from death rune use if (rune == RUNE_DEATH) return false; - AuraEffect* aurEff = triggeredByAura->GetEffect(0); + AuraEffect* aurEff = triggeredByAura->GetEffect(EFFECT_0); if (!aurEff) return false; // Reset amplitude - set death rune remove timer to 30s @@ -8786,7 +8822,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig } // Cast positive spell on enemy target case 7099: // Curse of Mending - case 39647: // Curse of Mending + case 39703: // Curse of Mending case 29494: // Temptation case 20233: // Improved Lay on Hands (cast on target) { @@ -10940,7 +10976,7 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM // Improved Faerie Fire if (pVictim->HasAuraState(AURA_STATE_FAERIE_FIRE)) if (AuraEffect const* aurEff = GetDummyAuraEffect(SPELLFAMILY_DRUID, 109, 0)) - crit_chance+=aurEff->GetAmount(); + crit_chance += aurEff->GetAmount(); // cumulative effect - don't break @@ -10950,7 +10986,7 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM // Improved Insect Swarm if (AuraEffect const* aurEff = GetDummyAuraEffect(SPELLFAMILY_DRUID, 1771, 0)) if (pVictim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x00000002, 0, 0)) - crit_chance+=aurEff->GetAmount(); + crit_chance += aurEff->GetAmount(); break; } break; @@ -10964,9 +11000,8 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM if (spellProto->SpellFamilyFlags[0] & 0x40000000) { // Sacred Shield - AuraEffect const* aura = pVictim->GetAuraEffect(58597, 1); - if (aura && aura->GetCasterGUID() == GetGUID()) - crit_chance+=aura->GetAmount(); + if (AuraEffect const* aura = pVictim->GetAuraEffect(58597, 1, GetGUID())) + crit_chance += aura->GetAmount(); break; } // Exorcism @@ -11839,7 +11874,7 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage, WeaponAttackType att case 6427: case 6428: // Dirty Deeds if (pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this)) { - AuraEffect* eff0 = (*i)->GetBase()->GetEffect(0); + AuraEffect* eff0 = (*i)->GetBase()->GetEffect(EFFECT_0); if (!eff0 || (*i)->GetEffIndex() != 1) { sLog->outError("Spell structure of DD (%u) changed.", (*i)->GetId()); diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index 2281caf4e74..c7800b0223c 100755 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -319,24 +319,6 @@ void InstanceScript::DoSendNotifyToInstance(const char *format, ...) } } -// Complete Achievement for all players in instance -void InstanceScript::DoCompleteAchievement(uint32 achievement) -{ - AchievementEntry const* pAE = GetAchievementStore()->LookupEntry(achievement); - Map::PlayerList const &PlayerList = instance->GetPlayers(); - - if (!pAE) - { - sLog->outError("TSCR: DoCompleteAchievement called for not existing achievement %u", achievement); - return; - } - - if (!PlayerList.isEmpty()) - for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) - if (Player *pPlayer = i->getSource()) - pPlayer->CompletedAchievement(pAE); -} - // Update Achievement Criteria for all players in instance void InstanceScript::DoUpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit* unit /*= NULL*/) { diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h index b3dcb9525c5..d2c98af0838 100755 --- a/src/server/game/Instances/InstanceScript.h +++ b/src/server/game/Instances/InstanceScript.h @@ -169,9 +169,6 @@ class InstanceScript : public ZoneScript // Send Notify to all players in instance void DoSendNotifyToInstance(char const* format, ...); - // Complete Achievement for all players in instance - DECLSPEC_DEPRECATED void DoCompleteAchievement(uint32 achievement) ATTR_DEPRECATED; - // Update Achievement Criteria for all players in instance void DoUpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = NULL); diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 41458ecaf55..bd2c34aef5c 100755 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -831,8 +831,8 @@ enum TrinityStrings LANG_BG_IC_REFINERY = 1222, LANG_BG_IC_QUARRY = 1223, LANG_BG_IC_HANGAR = 1224, - LANG_BG_IC_ALLIANCE = 1225, - LANG_BG_IC_HORDE = 1226, + LANG_BG_IC_ALLIANCE = 1300, + LANG_BG_IC_HORDE = 1301, // FREE IDS 1228-9999 diff --git a/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp b/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp index db2c76b422a..84f54786256 100755 --- a/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp @@ -718,14 +718,14 @@ void WorldSession::HandleListInventoryOpcode(WorldPacket & recv_data) SendListInventory(guid); } -void WorldSession::SendListInventory(uint64 vendorguid) +void WorldSession::SendListInventory(uint64 vendorGuid) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_LIST_INVENTORY"); - Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR); - if (!pCreature) + Creature* vendor = GetPlayer()->GetNPCIfCanInteractWith(vendorGuid, UNIT_NPC_FLAG_VENDOR); + if (!vendor) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: SendListInventory - Unit (GUID: %u) not found or you can not interact with him.", uint32(GUID_LOPART(vendorguid))); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: SendListInventory - Unit (GUID: %u) not found or you can not interact with him.", uint32(GUID_LOPART(vendorGuid))); _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, 0, 0); return; } @@ -735,56 +735,62 @@ void WorldSession::SendListInventory(uint64 vendorguid) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); // Stop the npc if moving - if (pCreature->HasUnitState(UNIT_STAT_MOVING)) - pCreature->StopMoving(); + if (vendor->HasUnitState(UNIT_STAT_MOVING)) + vendor->StopMoving(); - VendorItemData const* vItems = pCreature->GetVendorItems(); - if (!vItems) + VendorItemData const* items = vendor->GetVendorItems(); + if (!items) { - WorldPacket data(SMSG_LIST_INVENTORY, (8+1+1)); - data << uint64(vendorguid); - data << uint8(0); // count==0, next will be error code + WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + 1); + data << uint64(vendorGuid); + data << uint8(0); // count == 0, next will be error code data << uint8(0); // "Vendor has no inventory" SendPacket(&data); return; } - uint8 numitems = vItems->GetItemCount(); + uint8 itemCount = items->GetItemCount(); uint8 count = 0; - WorldPacket data(SMSG_LIST_INVENTORY, (8+1+numitems*8*4)); - data << uint64(vendorguid); + WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + itemCount * 8 * 4); + data << uint64(vendorGuid); - size_t count_pos = data.wpos(); + size_t countPos = data.wpos(); data << uint8(count); - float discountMod = _player->GetReputationPriceDiscount(pCreature); + float discountMod = _player->GetReputationPriceDiscount(vendor); - for (uint8 vendorslot = 0; vendorslot < numitems; ++vendorslot ) + for (uint8 slot = 0; slot < itemCount; ++slot) { - if (VendorItem const* crItem = vItems->GetItem(vendorslot)) + if (VendorItem const* item = items->GetItem(slot)) { - if (ItemTemplate const *pProto = sObjectMgr->GetItemTemplate(crItem->item)) + if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(item->item)) { - if ((pProto->AllowableClass & _player->getClassMask()) == 0 && pProto->Bonding == BIND_WHEN_PICKED_UP && !_player->isGameMaster()) + if (!(itemTemplate->AllowableClass & _player->getClassMask()) && itemTemplate->Bonding == BIND_WHEN_PICKED_UP && !_player->isGameMaster()) continue; // Only display items in vendor lists for the team the // player is on. If GM on, display all items. - if (!_player->isGameMaster() && ((pProto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && _player->GetTeam() == ALLIANCE) || (pProto->Flags2 == ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && _player->GetTeam() == HORDE))) + if (!_player->isGameMaster() && ((itemTemplate->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && _player->GetTeam() == ALLIANCE) || (itemTemplate->Flags2 == ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && _player->GetTeam() == HORDE))) continue; + + // Items sold out are not displayed in list + uint32 leftInStock = !item->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(item); + if (!_player->isGameMaster() && !leftInStock) + continue; + ++count; // reputation discount - int32 price = crItem->IsGoldRequired(pProto) ? uint32(floor(pProto->BuyPrice * discountMod)) : 0; + int32 price = item->IsGoldRequired(itemTemplate) ? uint32(floor(itemTemplate->BuyPrice * discountMod)) : 0; - data << uint32(vendorslot+1); // client expects counting to start at 1 - data << uint32(crItem->item); - data << uint32(pProto->DisplayInfoID); - data << int32(crItem->maxcount <= 0 ? 0xFFFFFFFF : pCreature->GetVendorItemCurrentCount(crItem)); + data << uint32(slot + 1); // client expects counting to start at 1 + data << uint32(item->item); + data << uint32(itemTemplate->DisplayInfoID); + data << int32(leftInStock); data << uint32(price); - data << uint32(pProto->MaxDurability); - data << uint32(pProto->BuyCount); - data << uint32(crItem->ExtendedCost); + data << uint32(itemTemplate->MaxDurability); + data << uint32(itemTemplate->BuyCount); + data << uint32(item->ExtendedCost); } } } @@ -796,7 +802,7 @@ void WorldSession::SendListInventory(uint64 vendorguid) return; } - data.put<uint8>(count_pos, count); + data.put<uint8>(countPos, count); SendPacket(&data); } diff --git a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp index b127831bad5..6193b0c6213 100755 --- a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp @@ -402,7 +402,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) spellInfo = actualSpellInfo; } - Spell* spell = new Spell(mover, spellInfo, false); + Spell* spell = new Spell(mover, spellInfo, false, 0, false, true); spell->m_cast_count = castCount; // set count of casts spell->prepare(&targets); } diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index eb1fd068bc3..f45ee79847c 100755 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -284,7 +284,7 @@ class WorldSession void SendTrainerList(uint64 guid); void SendTrainerList(uint64 guid, const std::string& strTitle); - void SendListInventory(uint64 guid); + void SendListInventory(uint64 vendorGuid); void SendShowBank(uint64 guid); void SendTabardVendorActivate(uint64 guid); void SendSpiritResurrect(); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index f52ce6461b3..17f8b246c83 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -439,7 +439,7 @@ void SpellCastTargets::OutDebug() const sLog->outString("elevation: %f", m_elevation); } -Spell::Spell(Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID, bool skipCheck): +Spell::Spell(Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID, bool skipCheck, bool castedClientside): m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, Caster)), m_caster(Caster), m_spellValue(new SpellValue(m_spellInfo)) { @@ -502,6 +502,7 @@ m_caster(Caster), m_spellValue(new SpellValue(m_spellInfo)) m_spellState = SPELL_STATE_NULL; + m_castedClientside = castedClientside; m_IsTriggeredSpell = bool(triggered || (info->AttributesEx4 & SPELL_ATTR4_TRIGGERED)); m_CastItem = NULL; diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index a05ad331776..57fbf815a9d 100755 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -386,7 +386,7 @@ class Spell typedef std::set<Aura*> UsedSpellMods; - Spell(Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID = 0, bool skipCheck = false); + Spell(Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID = 0, bool skipCheck = false, bool castedClientside = false); ~Spell(); void prepare(SpellCastTargets const* targets, AuraEffect const* triggeredByAura = NULL); @@ -684,6 +684,7 @@ class Spell uint32 m_timer; bool m_IsTriggeredSpell; + bool m_castedClientside; // if need this can be replaced by Aura copy // we can't store original aura link to prevent access to deleted auras diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 4167b9e1516..d6a447bd75f 100755 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3823,7 +3823,6 @@ void SpellMgr::LoadSpellCustomAttr() case 45641: // Fire Bloom case 55665: // Life Drain - Sapphiron (H) case 28796: // Poison Bolt Volly - Faerlina - case 5484: // Howl Of Terror (Warlock) spellInfo->MaxAffectedTargets = 5; ++count; break; @@ -4176,7 +4175,6 @@ void SpellMgr::LoadSpellCustomAttr() spellInfo->AreaGroupId = 0; // originally, these require area 4522, which is... outside of Icecrown Citadel ++count; break; - case 70588: // Suppression case 70602: // Corruption spellInfo->AttributesEx |= SPELL_ATTR1_STACK_FOR_DIFF_CASTERS; ++count; @@ -4227,9 +4225,6 @@ void SpellMgr::LoadSpellCustomAttr() // Starfall Target Selection if (spellInfo->SpellFamilyFlags[2] & 0x100) spellInfo->MaxAffectedTargets = 2; - // Starfall AOE Damage - else if (spellInfo->SpellFamilyFlags[2] & 0x800000) - mSpellCustomAttr[i] |= SPELL_ATTR0_CU_EXCLUDE_SELF; // Roar else if (spellInfo->SpellFamilyFlags[0] & 0x8) mSpellCustomAttr[i] |= SPELL_ATTR0_CU_AURA_CC; diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp index 71063c9a80b..39aefd45287 100644 --- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp @@ -75,11 +75,6 @@ enum Yells SAY_PREFIGHT_3 = -1601019 }; -enum Misc -{ - ACHIEV_WATH_HIM_DIE = 1296 -}; - const Position SpawnPoint[] = { { 566.164f, 682.087f, 769.079f, 2.21657f }, @@ -186,24 +181,8 @@ public: { DoScriptText(SAY_DEATH, me); - if (!pInstance) - return; - - pInstance->SetData(DATA_KRIKTHIR_THE_GATEWATCHER_EVENT, DONE); - //Achievement: Watch him die - Creature *pAdd = Unit::GetCreature(*me, pInstance->GetData64(DATA_WATCHER_GASHRA)); - if (!pAdd || !pAdd->isAlive()) - return; - - pAdd = Unit::GetCreature(*me, pInstance->GetData64(DATA_WATCHER_SILTHIK)); - if (!pAdd || !pAdd->isAlive()) - return; - - pAdd = Unit::GetCreature(*me, pInstance->GetData64(DATA_WATCHER_NARJIL)); - if (!pAdd || !pAdd->isAlive()) - return; - - pInstance->DoCompleteAchievement(ACHIEV_WATH_HIM_DIE); + if (pInstance) + pInstance->SetData(DATA_KRIKTHIR_THE_GATEWATCHER_EVENT, DONE); } void KilledUnit(Unit* victim) @@ -551,14 +530,43 @@ public: } }; +class achievement_watch_him_die : public AchievementCriteriaScript +{ + public: + achievement_watch_him_die() : AchievementCriteriaScript("achievement_watch_him_die") + { + } + + bool OnCheck(Player* /*player*/, Unit* target) + { + if (!target) + return false; + + InstanceScript* instance = target->GetInstanceScript(); + Creature* Watcher[3]; + if (!instance) + return false; + + for (uint8 n = 0; n < 3; ++n) + { + Watcher[n] = ObjectAccessor::GetCreature(*target, instance->GetData64(DATA_WATCHER_GASHRA + n)); + if (Watcher[n] && !Watcher[n]->isAlive()) + return false; + } + + return true; + } +}; + void AddSC_boss_krik_thir() { - new boss_krik_thir; - new npc_skittering_infector; - new npc_anub_ar_skirmisher; - new npc_anub_ar_shadowcaster; - new npc_watcher_gashra; - new npc_anub_ar_warrior; - new npc_watcher_silthik; - new npc_watcher_narjil; + new boss_krik_thir(); + new npc_skittering_infector(); + new npc_anub_ar_skirmisher(); + new npc_anub_ar_shadowcaster(); + new npc_watcher_gashra(); + new npc_anub_ar_warrior(); + new npc_watcher_silthik(); + new npc_watcher_narjil(); + new achievement_watch_him_die(); } diff --git a/src/server/scripts/Northrend/AzjolNerub/ahnkahet/ahnkahet.h b/src/server/scripts/Northrend/AzjolNerub/ahnkahet/ahnkahet.h index a25093579bb..e19054d2f46 100644 --- a/src/server/scripts/Northrend/AzjolNerub/ahnkahet/ahnkahet.h +++ b/src/server/scripts/Northrend/AzjolNerub/ahnkahet/ahnkahet.h @@ -44,7 +44,6 @@ enum Data DATA_SPHERE2_EVENT, DATA_JEDOGA_TRIGGER_SWITCH, DATA_JEDOGA_RESET_INITIANDS, - DATA_INITIAND_KILLED, DATA_ALL_INITIAND_DEAD }; diff --git a/src/server/scripts/Northrend/AzjolNerub/ahnkahet/boss_elder_nadox.cpp b/src/server/scripts/Northrend/AzjolNerub/ahnkahet/boss_elder_nadox.cpp index 25164e08f65..1513bebead7 100644 --- a/src/server/scripts/Northrend/AzjolNerub/ahnkahet/boss_elder_nadox.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/ahnkahet/boss_elder_nadox.cpp @@ -127,12 +127,6 @@ class boss_elder_nadox : public CreatureScript return 0; } - void SetData(uint32 id, uint32 data) - { - if (id == DATA_RESPECT_YOUR_ELDERS) - respectYourElders = data ? true : false; - } - void UpdateAI(uint32 const diff) { if (!UpdateVictim()) @@ -311,6 +305,9 @@ class achievement_respect_your_elders : public AchievementCriteriaScript bool OnCheck(Player* /*player*/, Unit* target) { + if (!target) + return false; + if (Creature* Nadox = target->ToCreature()) if (Nadox->AI()->GetData(DATA_RESPECT_YOUR_ELDERS)) return true; diff --git a/src/server/scripts/Northrend/AzjolNerub/ahnkahet/boss_jedoga_shadowseeker.cpp b/src/server/scripts/Northrend/AzjolNerub/ahnkahet/boss_jedoga_shadowseeker.cpp index 68d1272750c..a3fd20c830e 100644 --- a/src/server/scripts/Northrend/AzjolNerub/ahnkahet/boss_jedoga_shadowseeker.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/ahnkahet/boss_jedoga_shadowseeker.cpp @@ -63,6 +63,9 @@ const Position JedogaPosition[2] = {372.330994f, -705.278015f, -16.179716f, 5.427970f} }; +#define ACTION_INITIAND_KILLED 1 +#define DATA_VOLUNTEER_WORK 2 + class boss_jedoga_shadowseeker : public CreatureScript { public: @@ -89,7 +92,7 @@ public: bool bOnGround; bool bOpFerokFail; bool bCanDown; - + bool volunteerWork; bool bFirstTime; void Reset() @@ -104,6 +107,7 @@ public: bOpFerokFail = false; bOnGround = false; bCanDown = false; + volunteerWork = true; if (pInstance) { @@ -152,6 +156,20 @@ public: pInstance->SetData(DATA_JEDOGA_SHADOWSEEKER_EVENT, DONE); } + void DoAction(int32 const action) + { + if (action == ACTION_INITIAND_KILLED) + volunteerWork = false; + } + + uint32 GetData(uint32 type) + { + if (type == DATA_VOLUNTEER_WORK) + return volunteerWork ? 1 : 0; + + return 0; + } + void MoveInLineOfSight(Unit* who) { if (!pInstance || !who || (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_JEDOGA_CONTROLLER)) @@ -374,43 +392,53 @@ public: void JustDied(Unit* Killer) { - if (!Killer || !pInstance) return; + if (!Killer || !pInstance) + return; if (bWalking) { - Creature* boss = me->GetMap()->GetCreature(pInstance->GetData64(DATA_JEDOGA_SHADOWSEEKER)); - if (boss && !CAST_AI(boss_jedoga_shadowseeker::boss_jedoga_shadowseekerAI, boss->AI())->bOpFerok) CAST_AI(boss_jedoga_shadowseeker::boss_jedoga_shadowseekerAI, boss->AI())->bOpFerokFail = true; + if (Creature* boss = ObjectAccessor::GetCreature(*me, pInstance->GetData64(DATA_JEDOGA_SHADOWSEEKER))) + { + if (!CAST_AI(boss_jedoga_shadowseeker::boss_jedoga_shadowseekerAI, boss->AI())->bOpFerok) + CAST_AI(boss_jedoga_shadowseeker::boss_jedoga_shadowseekerAI, boss->AI())->bOpFerokFail = true; + + boss->AI()->DoAction(ACTION_INITIAND_KILLED); + } - if (Killer->GetTypeId() == TYPEID_PLAYER) pInstance->SetData(DATA_INITIAND_KILLED, 1); pInstance->SetData64(DATA_ADD_JEDOGA_OPFER, 0); bWalking = false; } - if (Killer->GetTypeId() == TYPEID_PLAYER) pInstance->SetData64(DATA_PL_JEDOGA_TARGET, Killer->GetGUID()); + if (Killer->GetTypeId() == TYPEID_PLAYER) + pInstance->SetData64(DATA_PL_JEDOGA_TARGET, Killer->GetGUID()); } void EnterCombat(Unit* who) { - if ((pInstance && pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) == IN_PROGRESS) || !who) return; + if ((pInstance && pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) == IN_PROGRESS) || !who) + return; } void AttackStart(Unit* victim) { - if ((pInstance && pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) == IN_PROGRESS) || !victim) return; + if ((pInstance && pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) == IN_PROGRESS) || !victim) + return; ScriptedAI::AttackStart(victim); } void MoveInLineOfSight(Unit* who) { - if ((pInstance && pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) == IN_PROGRESS) || !who) return; + if ((pInstance && pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) == IN_PROGRESS) || !who) + return; ScriptedAI::MoveInLineOfSight(who); } void MovementInform(uint32 uiType, uint32 uiPointId) { - if (uiType != POINT_MOTION_TYPE || !pInstance) return; + if (uiType != POINT_MOTION_TYPE || !pInstance) + return; switch(uiPointId) { @@ -569,9 +597,30 @@ public: } }; +class achievement_volunteer_work : public AchievementCriteriaScript +{ + public: + achievement_volunteer_work() : AchievementCriteriaScript("achievement_volunteer_work") + { + } + + bool OnCheck(Player* /*player*/, Unit* target) + { + if (!target) + return false; + + if (Creature* Jedoga = target->ToCreature()) + if (Jedoga->AI()->GetData(DATA_VOLUNTEER_WORK)) + return true; + + return false; + } +}; + void AddSC_boss_jedoga_shadowseeker() { - new boss_jedoga_shadowseeker; - new mob_jedoga_initiand; - new npc_jedogas_aufseher_trigger; + new boss_jedoga_shadowseeker(); + new mob_jedoga_initiand(); + new npc_jedogas_aufseher_trigger(); + new achievement_volunteer_work(); } diff --git a/src/server/scripts/Northrend/AzjolNerub/ahnkahet/instance_ahnkahet.cpp b/src/server/scripts/Northrend/AzjolNerub/ahnkahet/instance_ahnkahet.cpp index 55346cd8197..b10a49b7116 100644 --- a/src/server/scripts/Northrend/AzjolNerub/ahnkahet/instance_ahnkahet.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/ahnkahet/instance_ahnkahet.cpp @@ -59,9 +59,8 @@ public: uint32 m_auiEncounter[MAX_ENCOUNTER]; uint32 spheres[2]; - uint8 InitiandCnt, - switchtrigger, - initiandkilled; + uint8 InitiandCnt; + uint8 switchtrigger; std::string str_data; @@ -81,7 +80,6 @@ public: InitiandCnt = 0; switchtrigger = 0; - initiandkilled = 0; JedogaSacrifices = 0; JedogaTarget = 0; } @@ -200,8 +198,6 @@ public: cr->RemoveCorpse(); } } - if (!initiandkilled && instance->IsHeroic()) - DoCompleteAchievement(ACHIEV_VOLUNTEER_WORK); } break; case DATA_HERALD_VOLAZJ_EVENT: m_auiEncounter[3] = data; break; @@ -209,7 +205,6 @@ public: case DATA_SPHERE1_EVENT: spheres[0] = data; break; case DATA_SPHERE2_EVENT: spheres[1] = data; break; case DATA_JEDOGA_TRIGGER_SWITCH: switchtrigger = data; break; - case DATA_INITIAND_KILLED: initiandkilled = data; break; case DATA_JEDOGA_RESET_INITIANDS: for (std::set<uint64>::const_iterator itr = InitiandGUIDs.begin(); itr != InitiandGUIDs.end(); ++itr) { @@ -245,7 +240,6 @@ public: } return 1; case DATA_JEDOGA_TRIGGER_SWITCH: return switchtrigger; - case DATA_INITIAND_KILLED: return initiandkilled; } return 0; } diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp index bc844698fdb..847b5ddb9cc 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp @@ -122,14 +122,6 @@ enum eEnums //using these custom points for dragons start and end POINT_ID_INIT = 100, POINT_ID_LAND = 200, - - //Achievements - ACHIEV_TWILIGHT_ASSIST = 2049, - H_ACHIEV_TWILIGHT_ASSIST = 2052, - ACHIEV_TWILIGHT_DUO = 2050, - H_ACHIEV_TWILIGHT_DUO = 2053, - ACHIEV_TWILIGHT_ZONE = 2051, - H_ACHIEV_TWILIGHT_ZONE = 2054 }; #define DATA_CAN_LOOT 0 @@ -213,6 +205,8 @@ Locations TwilightEggsSarth[] = {3257.54f, 502.285f , 58.2077f} }; +#define TWILIGHT_ACHIEVEMENTS 1 + /*###### ## Boss Sartharion ######*/ @@ -256,7 +250,7 @@ public: bool m_bHasCalledShadron; bool m_bHasCalledVesperon; - uint32 achievProgress; + uint8 drakeCount; void Reset() { @@ -285,7 +279,7 @@ public: me->SetHomePosition(3246.57f, 551.263f, 58.6164f, 4.66003f); - achievProgress = 0; + drakeCount = 0; // Drakes respawning system if (pInstance) @@ -384,20 +378,6 @@ public: if (pVesperon && pVesperon->isAlive()) pVesperon->DisappearAndDie(); - if (achievProgress == 1) - pInstance->DoCompleteAchievement(RAID_MODE(ACHIEV_TWILIGHT_ASSIST, H_ACHIEV_TWILIGHT_ASSIST)); - else if (achievProgress == 2) - { - pInstance->DoCompleteAchievement(RAID_MODE(ACHIEV_TWILIGHT_ASSIST, H_ACHIEV_TWILIGHT_ASSIST)); - pInstance->DoCompleteAchievement(RAID_MODE(ACHIEV_TWILIGHT_DUO, H_ACHIEV_TWILIGHT_DUO)); - } - else if (achievProgress == 3) - { - pInstance->DoCompleteAchievement(RAID_MODE(ACHIEV_TWILIGHT_ASSIST, H_ACHIEV_TWILIGHT_ASSIST)); - pInstance->DoCompleteAchievement(RAID_MODE(ACHIEV_TWILIGHT_DUO, H_ACHIEV_TWILIGHT_DUO)); - pInstance->DoCompleteAchievement(RAID_MODE(ACHIEV_TWILIGHT_ZONE, H_ACHIEV_TWILIGHT_ZONE)); - } - pInstance->SetData(TYPE_SARTHARION_EVENT, DONE); } } @@ -419,13 +399,21 @@ public: me->AddLootMode(LOOT_MODE_HARD_MODE_1); // Add 1st Drake loot mode } + uint32 GetData(uint32 type) + { + if (type == TWILIGHT_ACHIEVEMENTS) + return drakeCount; + + return 0; + } + void FetchDragons() { - if(!pInstance) + if (!pInstance) return; me->ResetLootMode(); - achievProgress = 0; + drakeCount = 0; Creature* pFetchTene = Unit::GetCreature(*me, pInstance->GetData64(DATA_TENEBRON)); Creature* pFetchShad = Unit::GetCreature(*me, pInstance->GetData64(DATA_SHADRON)); @@ -437,10 +425,10 @@ public: if (pFetchTene && pFetchTene->isAlive() && !pFetchTene->getVictim()) { bCanUseWill = true; - if(!pFetchTene->isInCombat()) + if (!pFetchTene->isInCombat()) { AddDrakeLootMode(); - achievProgress++; + ++drakeCount; } pFetchTene->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aTene[0].m_fX, m_aTene[0].m_fY, m_aTene[0].m_fZ); @@ -451,10 +439,10 @@ public: if (pFetchShad && pFetchShad->isAlive() && !pFetchShad->getVictim()) { bCanUseWill = true; - if(!pFetchShad->isInCombat()) + if (!pFetchShad->isInCombat()) { AddDrakeLootMode(); - achievProgress++; + ++drakeCount; } pFetchShad->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aShad[0].m_fX, m_aShad[0].m_fY, m_aShad[0].m_fZ); @@ -465,10 +453,10 @@ public: if (pFetchVesp && pFetchVesp->isAlive() && !pFetchVesp->getVictim()) { bCanUseWill = true; - if(!pFetchVesp->isInCombat()) + if (!pFetchVesp->isInCombat()) { AddDrakeLootMode(); - achievProgress++; + ++drakeCount; } pFetchVesp->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aVesp[0].m_fX, m_aVesp[0].m_fY, m_aVesp[0].m_fZ); @@ -1710,6 +1698,66 @@ public: }; +class achievement_twilight_assist : public AchievementCriteriaScript +{ + public: + achievement_twilight_assist() : AchievementCriteriaScript("achievement_twilight_assist") + { + } + + bool OnCheck(Player* player, Unit* target) + { + if (!target) + return false; + + if (Creature* Sartharion = target->ToCreature()) + if (Sartharion->AI()->GetData(TWILIGHT_ACHIEVEMENTS) >= 1) + return true; + + return false; + } +}; + +class achievement_twilight_duo : public AchievementCriteriaScript +{ + public: + achievement_twilight_duo() : AchievementCriteriaScript("achievement_twilight_duo") + { + } + + bool OnCheck(Player* player, Unit* target) + { + if (!target) + return false; + + if (Creature* Sartharion = target->ToCreature()) + if (Sartharion->AI()->GetData(TWILIGHT_ACHIEVEMENTS) >= 2) + return true; + + return false; + } +}; + +class achievement_twilight_zone : public AchievementCriteriaScript +{ + public: + achievement_twilight_zone() : AchievementCriteriaScript("achievement_twilight_zone") + { + } + + bool OnCheck(Player* player, Unit* target) + { + if (!target) + return false; + + if (Creature* Sartharion = target->ToCreature()) + if (Sartharion->AI()->GetData(TWILIGHT_ACHIEVEMENTS) == 3) + return true; + + return false; + } +}; + void AddSC_boss_sartharion() { new boss_sartharion(); @@ -1722,4 +1770,7 @@ void AddSC_boss_sartharion() new npc_flame_tsunami(); new npc_twilight_fissure(); new mob_twilight_whelp(); + new achievement_twilight_assist(); + new achievement_twilight_duo(); + new achievement_twilight_zone(); } diff --git a/src/server/scripts/Northrend/DraktharonKeep/boss_dred.cpp b/src/server/scripts/Northrend/DraktharonKeep/boss_dred.cpp index 2274b30b29a..3dcc620c87a 100644 --- a/src/server/scripts/Northrend/DraktharonKeep/boss_dred.cpp +++ b/src/server/scripts/Northrend/DraktharonKeep/boss_dred.cpp @@ -283,6 +283,9 @@ class achievement_king_dred : public AchievementCriteriaScript bool OnCheck(Player* /*player*/, Unit* target) { + if (!target) + return false; + if (Creature* Dred = target->ToCreature()) if (Dred->AI()->GetData(DATA_KING_DRED) >= 6) return true; diff --git a/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp b/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp index 2672a22d26c..a92ed4abdb1 100644 --- a/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp +++ b/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp @@ -31,6 +31,7 @@ enum Spells H_SPELL_WRATH_OF_MISERY = 59856, SPELL_SUMMON_MINIONS = 59910 //Summons an army of Fetid Troll Corpses to assist the caster. }; + //not in db enum Yells { @@ -41,6 +42,7 @@ enum Yells SAY_REUBBLE_1 = -1600004, SAY_REUBBLE_2 = -1600005 }; + enum Creatures { CREATURE_RISEN_SHADOWCASTER = 27600, @@ -48,16 +50,16 @@ enum Creatures CREATURE_HULKING_CORPSE = 27597, CREATURE_CRYSTAL_HANDLER = 26627 }; + enum CombatPhase { IDLE, PHASE_1, PHASE_2 }; -enum Achievements -{ - ACHIEV_OH_NOVOS = 2057 -}; + +#define ACTION_MINION_REACHED 1 +#define DATA_OH_NOVOS 2 static Position AddSpawnPoint = { -379.20f, -816.76f, 59.70f, 0.0f }; static Position CrystalHandlerSpawnPoint = { -326.626343f, -709.956604f, 27.813314f, 0.0f }; @@ -79,7 +81,7 @@ public: uint32 uiCrystalHandlerTimer; uint8 crystalHandlerAmount; - bool bAchiev; + bool ohNovos; SummonList lSummons; @@ -93,7 +95,7 @@ public: { Phase = IDLE; luiCrystals.clear(); - bAchiev = true; + ohNovos = true; me->CastStop(); lSummons.DespawnAll(); crystalHandlerAmount = 0; @@ -108,10 +110,8 @@ public: if (pInstance) { pInstance->SetData(DATA_NOVOS_EVENT, NOT_STARTED); - luiCrystals.push_back(pInstance->GetData64(DATA_NOVOS_CRYSTAL_1)); - luiCrystals.push_back(pInstance->GetData64(DATA_NOVOS_CRYSTAL_2)); - luiCrystals.push_back(pInstance->GetData64(DATA_NOVOS_CRYSTAL_3)); - luiCrystals.push_back(pInstance->GetData64(DATA_NOVOS_CRYSTAL_4)); + for (uint8 n = 0; n < 4; ++n) + luiCrystals.push_back(pInstance->GetData64(DATA_NOVOS_CRYSTAL_1 + n)); for (std::list<uint64>::const_iterator itr = luiCrystals.begin(); itr != luiCrystals.end(); ++itr) { if (GameObject* pTemp = pInstance->instance->GetGameObject(*itr)) @@ -182,12 +182,7 @@ public: { DoScriptText(SAY_DEATH, me); if (pInstance) - { pInstance->SetData(DATA_NOVOS_EVENT, DONE); - - if (IsHeroic() && bAchiev) - pInstance->DoCompleteAchievement(ACHIEV_OH_NOVOS); - } lSummons.DespawnAll(); } @@ -206,6 +201,20 @@ public: lSummons.Summon(summon); } + void DoAction(int32 const action) + { + if (action == ACTION_MINION_REACHED) + ohNovos = false; + } + + uint32 GetData(uint32 type) + { + if (type == DATA_OH_NOVOS) + return ohNovos ? 1 : 0; + + return 0; + } + void RemoveCrystal() { if (!luiCrystals.empty()) @@ -319,10 +328,10 @@ public: { if (type != POINT_MOTION_TYPE || id !=0) return; - if (Creature* pNovos = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_NOVOS) : 0)) + if (Creature* Novos = ObjectAccessor::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_NOVOS) : 0)) { - CAST_AI(boss_novos::boss_novosAI, pNovos->AI())->bAchiev = false; - if (Unit *pTarget = CAST_AI(boss_novos::boss_novosAI, pNovos->AI())->GetRandomTarget()) + Novos->AI()->DoAction(ACTION_MINION_REACHED); + if (Unit *pTarget = CAST_AI(boss_novos::boss_novosAI, Novos->AI())->GetRandomTarget()) AttackStart(pTarget); } } @@ -334,9 +343,30 @@ public: } }; +class achievement_oh_novos : public AchievementCriteriaScript +{ + public: + achievement_oh_novos() : AchievementCriteriaScript("achievement_oh_novos") + { + } + + bool OnCheck(Player* /*player*/, Unit* target) + { + if (!target) + return false; + + if (Creature* Novos = target->ToCreature()) + if (Novos->AI()->GetData(DATA_OH_NOVOS)) + return true; + + return false; + } +}; + void AddSC_boss_novos() { - new boss_novos; - new mob_crystal_handler; - new mob_novos_minion; + new boss_novos(); + new mob_crystal_handler(); + new mob_novos_minion(); + new achievement_oh_novos(); } diff --git a/src/server/scripts/Northrend/DraktharonKeep/boss_trollgore.cpp b/src/server/scripts/Northrend/DraktharonKeep/boss_trollgore.cpp index db285306071..745c092b673 100644 --- a/src/server/scripts/Northrend/DraktharonKeep/boss_trollgore.cpp +++ b/src/server/scripts/Northrend/DraktharonKeep/boss_trollgore.cpp @@ -34,6 +34,7 @@ enum Spells H_SPELL_CONSUME = 59803, H_SPELL_CONSUME_AURA = 59805, }; + enum Yells { SAY_AGGRO = -1600006, @@ -42,16 +43,15 @@ enum Yells SAY_EXPLODE = -1600009, SAY_DEATH = -1600010 }; -enum Achievements -{ - ACHIEV_CONSUMPTION_JUNCTION = 2151 -}; + enum Creatures { NPC_DRAKKARI_INVADER_1 = 27753, NPC_DRAKKARI_INVADER_2 = 27709 }; +#define DATA_CONSUMPTION_JUNCTION 1 + Position AddSpawnPoint = { -260.493011f, -622.968018f, 26.605301f, 3.036870f }; class boss_trollgore : public CreatureScript @@ -73,7 +73,7 @@ public: uint32 uiExplodeCorpseTimer; uint32 uiSpawnTimer; - bool bAchiev; + bool consumptionJunction; SummonList lSummons; @@ -88,7 +88,7 @@ public: uiExplodeCorpseTimer = 3*IN_MILLISECONDS; uiSpawnTimer = urand(30*IN_MILLISECONDS, 40*IN_MILLISECONDS); - bAchiev = IsHeroic(); + consumptionJunction = true; lSummons.DespawnAll(); @@ -127,11 +127,11 @@ public: uiConsumeTimer = 15*IN_MILLISECONDS; } else uiConsumeTimer -= diff; - if (bAchiev) + if (consumptionJunction) { - Aura *pConsumeAura = me->GetAura(DUNGEON_MODE(SPELL_CONSUME_AURA, H_SPELL_CONSUME_AURA)); - if (pConsumeAura && pConsumeAura->GetStackAmount() > 9) - bAchiev = false; + Aura* ConsumeAura = me->GetAura(DUNGEON_MODE(SPELL_CONSUME_AURA, H_SPELL_CONSUME_AURA)); + if (ConsumeAura && ConsumeAura->GetStackAmount() > 9) + consumptionJunction = false; } if (uiCrushTimer <= diff) @@ -163,11 +163,15 @@ public: lSummons.DespawnAll(); if (pInstance) - { - if (bAchiev) - pInstance->DoCompleteAchievement(ACHIEV_CONSUMPTION_JUNCTION); pInstance->SetData(DATA_TROLLGORE_EVENT, DONE); - } + } + + uint32 GetData(uint32 type) + { + if (type == DATA_CONSUMPTION_JUNCTION) + return consumptionJunction ? 1 : 0; + + return 0; } void KilledUnit(Unit* victim) @@ -191,7 +195,28 @@ public: } }; +class achievement_consumption_junction : public AchievementCriteriaScript +{ + public: + achievement_consumption_junction() : AchievementCriteriaScript("achievement_consumption_junction") + { + } + + bool OnCheck(Player* /*player*/, Unit* target) + { + if (!target) + return false; + + if (Creature* Trollgore = target->ToCreature()) + if (Trollgore->AI()->GetData(DATA_CONSUMPTION_JUNCTION)) + return true; + + return false; + } +}; + void AddSC_boss_trollgore() { - new boss_trollgore; + new boss_trollgore(); + new achievement_consumption_junction(); } diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp index 38af9ad3a47..c7f54e27191 100644 --- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp @@ -77,7 +77,6 @@ enum Events enum eEnum { - ACHIEV_THREE_FACED = 4523, DISPLAY_ANGER = 30148, DISPLAY_SORROW = 30149, DISPLAY_DESIRE = 30150, @@ -115,6 +114,8 @@ struct outroPosition { { 0, 0 }, { 0.0f, 0.0f, 0.0f, 0.0f } } }; +#define DATA_THREE_FACED 1 + class boss_devourer_of_souls : public CreatureScript { public: @@ -143,7 +144,7 @@ class boss_devourer_of_souls : public CreatureScript events.Reset(); summons.DespawnAll(); - threeFaceAchievement = true; + threeFaced = true; mirroredSoulTarget = 0; instance->SetData(DATA_DEVOURER_EVENT, NOT_STARTED); @@ -214,9 +215,6 @@ class boss_devourer_of_souls : public CreatureScript instance->SetData(DATA_DEVOURER_EVENT, DONE); - if (threeFaceAchievement && IsHeroic()) - instance->DoCompleteAchievement(ACHIEV_THREE_FACED); - int32 entryIndex; if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) entryIndex = 0; @@ -239,7 +237,15 @@ class boss_devourer_of_souls : public CreatureScript void SpellHitTarget(Unit* /*target*/, const SpellEntry *spell) { if (spell->Id == H_SPELL_PHANTOM_BLAST) - threeFaceAchievement = false; + threeFaced = false; + } + + uint32 GetData(uint32 type) + { + if (type == DATA_THREE_FACED) + return threeFaced; + + return 0; } void UpdateAI(const uint32 diff) @@ -344,7 +350,7 @@ class boss_devourer_of_souls : public CreatureScript } private: - bool threeFaceAchievement; + bool threeFaced; // wailing soul event float beamAngle; @@ -360,7 +366,28 @@ class boss_devourer_of_souls : public CreatureScript } }; +class achievement_three_faced : public AchievementCriteriaScript +{ + public: + achievement_three_faced() : AchievementCriteriaScript("achievement_three_faced") + { + } + + bool OnCheck(Player* /*player*/, Unit* target) + { + if (!target) + return false; + + if (Creature* Devourer = target->ToCreature()) + if (Devourer->AI()->GetData(DATA_THREE_FACED)) + return true; + + return false; + } +}; + void AddSC_boss_devourer_of_souls() { new boss_devourer_of_souls(); + new achievement_three_faced(); } diff --git a/src/server/scripts/Northrend/Gundrak/boss_gal_darah.cpp b/src/server/scripts/Northrend/Gundrak/boss_gal_darah.cpp index 93acb74cee6..96f7fb200a5 100644 --- a/src/server/scripts/Northrend/Gundrak/boss_gal_darah.cpp +++ b/src/server/scripts/Northrend/Gundrak/boss_gal_darah.cpp @@ -32,7 +32,6 @@ enum Spells SPELL_STAMPEDE = 55218, SPELL_WHIRLING_SLASH = 55250, H_SPELL_WHIRLING_SLASH = 59824, - SPELL_ECK_RESIDUE = 55817 }; //Yells @@ -50,11 +49,6 @@ enum Yells SAY_TRANSFORM_2 = -1604009 }; -enum Achievements -{ - ACHIEV_WHAT_THE_ECK = 1864, -}; - enum Displays { DISPLAY_RHINO = 26265, @@ -276,21 +270,7 @@ public: DoScriptText(SAY_DEATH, me); if (pInstance) - { - if (IsHeroic()) - { - AchievementEntry const *achievWhatTheEck = GetAchievementStore()->LookupEntry(ACHIEV_WHAT_THE_ECK); - if (achievWhatTheEck) - { - Map::PlayerList const &players = pInstance->instance->GetPlayers(); - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - if (itr->getSource()->HasAura(SPELL_ECK_RESIDUE)) - itr->getSource()->CompletedAchievement(achievWhatTheEck); - } - } - pInstance->SetData(DATA_GAL_DARAH_EVENT, DONE); - } } void KilledUnit(Unit* victim) @@ -313,6 +293,9 @@ class achievement_share_the_love : public AchievementCriteriaScript bool OnCheck(Player* /*player*/, Unit* target) { + if (!target) + return false; + if (Creature* GalDarah = target->ToCreature()) if (GalDarah->AI()->GetData(DATA_SHARE_THE_LOVE) >= 5) return true; diff --git a/src/server/scripts/Northrend/Gundrak/boss_moorabi.cpp b/src/server/scripts/Northrend/Gundrak/boss_moorabi.cpp index d02a906b79b..660cf571c68 100644 --- a/src/server/scripts/Northrend/Gundrak/boss_moorabi.cpp +++ b/src/server/scripts/Northrend/Gundrak/boss_moorabi.cpp @@ -31,11 +31,6 @@ enum eSpells SPELL_TRANSFORMATION = 55098, //Periodic, The caster transforms into a powerful mammoth, increasing Physical damage done by 25% and granting immunity to Stun effects. }; -enum eArchivements -{ - ACHIEV_LESS_RABI = 2040 -}; - enum eSays { SAY_AGGRO = -1604010, @@ -48,6 +43,8 @@ enum eSays EMOTE_TRANSFORM = -1604017 }; +#define DATA_LESS_RABI 1 + class boss_moorabi : public CreatureScript { public: @@ -146,17 +143,20 @@ public: DoMeleeAttackIfReady(); } + uint32 GetData(uint32 type) + { + if (type == DATA_LESS_RABI) + return bPhase ? 0 : 1; + + return 0; + } + void JustDied(Unit* /*pKiller*/) { DoScriptText(SAY_DEATH, me); if (pInstance) - { pInstance->SetData(DATA_MOORABI_EVENT, DONE); - - if (IsHeroic() && !bPhase) - pInstance->DoCompleteAchievement(ACHIEV_LESS_RABI); - } } void KilledUnit(Unit* pVictim) @@ -170,7 +170,28 @@ public: }; +class achievement_less_rabi : public AchievementCriteriaScript +{ + public: + achievement_less_rabi() : AchievementCriteriaScript("achievement_less_rabi") + { + } + + bool OnCheck(Player* /*player*/, Unit* target) + { + if (!target) + return false; + + if (Creature* Moorabi = target->ToCreature()) + if (Moorabi->AI()->GetData(DATA_LESS_RABI)) + return true; + + return false; + } +}; + void AddSC_boss_moorabi() { new boss_moorabi(); + new achievement_less_rabi(); } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp b/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp index b11e5eb82f3..2fc5a8499c1 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp @@ -216,6 +216,9 @@ class achievement_safety_dance : public AchievementCriteriaScript bool OnCheck(Player* /*player*/, Unit* target) { + if (!target) + return false; + if (Creature* Heigan = target->ToCreature()) if (Heigan->AI()->GetData(DATA_SAFETY_DANCE)) return true; diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_anomalus.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_anomalus.cpp index eece702f984..98f821eb153 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/boss_anomalus.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_anomalus.cpp @@ -263,6 +263,9 @@ class achievement_chaos_theory : public AchievementCriteriaScript bool OnCheck(Player* /*player*/, Unit* target) { + if (!target) + return false; + if (Creature* Anomalus = target->ToCreature()) if (Anomalus->AI()->GetData(DATA_CHAOS_THEORY)) return true; diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp index 7a5261a0548..c0949cb03fe 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp @@ -32,6 +32,7 @@ enum Spells SPELL_INTENSE_COLD = 48094, SPELL_INTENSE_COLD_TRIGGERED = 48095 }; + enum Yells { //Yell @@ -41,13 +42,11 @@ enum Yells SAY_DEATH = -1576043, SAY_CRYSTAL_NOVA = -1576044 }; -enum Achievements -{ - ACHIEV_INTENSE_COLD = 2036 -}; + enum Misc { - DATA_CONTAINMENT_SPHERES = 3 + DATA_INTENSE_COLD = 1, + DATA_CONTAINMENT_SPHERES = 3, }; class boss_keristrasza : public CreatureScript @@ -69,16 +68,14 @@ public: InstanceScript* pInstance; + std::list<uint64> intenseColdList; + uint64 auiContainmentSphereGUIDs[DATA_CONTAINMENT_SPHERES]; uint32 uiCrystalfireBreathTimer; uint32 uiCrystalChainsCrystalizeTimer; uint32 uiTailSweepTimer; + bool intenseCold; bool bEnrage; - uint64 auiContainmentSphereGUIDs[DATA_CONTAINMENT_SPHERES]; - - uint32 uiCheckIntenseColdTimer; - bool bMoreThanTwoIntenseCold; // needed for achievement: Intense Cold(2036) - void Reset() { uiCrystalfireBreathTimer = 14*IN_MILLISECONDS; @@ -86,8 +83,8 @@ public: uiTailSweepTimer = 5*IN_MILLISECONDS; bEnrage = false; - uiCheckIntenseColdTimer = 2*IN_MILLISECONDS; - bMoreThanTwoIntenseCold = false; + intenseCold = true; + intenseColdList.clear(); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); @@ -111,11 +108,7 @@ public: DoScriptText(SAY_DEATH, me); if (pInstance) - { - if (IsHeroic() && !bMoreThanTwoIntenseCold) - pInstance->DoCompleteAchievement(ACHIEV_INTENSE_COLD); pInstance->SetData(DATA_KERISTRASZA_EVENT, DONE); - } } void KilledUnit(Unit* /*victim*/) @@ -164,30 +157,17 @@ public: } } + void SetGUID(uint64 const& guid, int32 id/* = 0 */) + { + if (id == DATA_INTENSE_COLD) + intenseColdList.push_back(guid); + } + void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; - if (uiCheckIntenseColdTimer < diff && !bMoreThanTwoIntenseCold) - { - std::list<HostileReference*> ThreatList = me->getThreatManager().getThreatList(); - for (std::list<HostileReference*>::const_iterator itr = ThreatList.begin(); itr != ThreatList.end(); ++itr) - { - Unit *pTarget = Unit::GetUnit(*me, (*itr)->getUnitGuid()); - if (!pTarget || pTarget->GetTypeId() != TYPEID_PLAYER) - continue; - - Aura *AuraIntenseCold = pTarget->GetAura(SPELL_INTENSE_COLD_TRIGGERED); - if (AuraIntenseCold && AuraIntenseCold->GetStackAmount() > 2) - { - bMoreThanTwoIntenseCold = true; - break; - } - } - uiCheckIntenseColdTimer = 2*IN_MILLISECONDS; - } else uiCheckIntenseColdTimer -= diff; - if (!bEnrage && HealthBelowPct(25)) { DoScriptText(SAY_ENRAGE, me); @@ -246,8 +226,63 @@ public: }; +class spell_intense_cold : public SpellScriptLoader +{ + public: + spell_intense_cold() : SpellScriptLoader("spell_intense_cold") { } + + class spell_intense_cold_AuraScript : public AuraScript + { + PrepareAuraScript(spell_intense_cold_AuraScript); + + void HandlePeriodicTick(AuraEffect const* aurEff) + { + Unit* caster = GetCaster(); + if (!caster) + return; + + if (aurEff->GetBase()->GetStackAmount() >= 2) + caster->GetAI()->SetGUID(GetTarget()->GetGUID(), DATA_INTENSE_COLD); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_intense_cold_AuraScript::HandlePeriodicTick, EFFECT_1, SPELL_AURA_PERIODIC_DAMAGE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_intense_cold_AuraScript(); + } +}; + +class achievement_intense_cold : public AchievementCriteriaScript +{ + public: + achievement_intense_cold() : AchievementCriteriaScript("achievement_intense_cold") + { + } + + bool OnCheck(Player* player, Unit* target) + { + if (!target) + return false; + + std::list<uint64> intenseColdList = CAST_AI(boss_keristrasza::boss_keristraszaAI, target->ToCreature()->AI())->intenseColdList; + if (!intenseColdList.empty()) + for (std::list<uint64>::iterator itr = intenseColdList.begin(); itr != intenseColdList.end(); ++itr) + if (player->GetGUID() == *itr) + return false; + + return true; + } +}; + void AddSC_boss_keristrasza() { new boss_keristrasza(); new containment_sphere(); + new achievement_intense_cold(); + new spell_intense_cold(); } diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp index 66d98186975..3440ba0a028 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp @@ -32,12 +32,14 @@ enum Spells SPELL_FROST_MAGUS_VISUAL = 47706, SPELL_ARCANE_MAGUS_VISUAL = 47704 }; + enum Creatures { MOB_FIRE_MAGUS = 26928, MOB_FROST_MAGUS = 26930, MOB_ARCANE_MAGUS = 26929 }; + enum Yells { SAY_AGGRO = -1576000, @@ -47,11 +49,9 @@ enum Yells SAY_SPLIT_1 = -1576004, SAY_SPLIT_2 = -1576005, }; -enum Achievements -{ - ACHIEV_SPLIT_PERSONALITY = 2150, - ACHIEV_TIMER = 5*IN_MILLISECONDS -}; + +#define ACTION_MAGUS_DEAD 1 +#define DATA_SPLIT_PERSONALITY 2 const Position CenterOfRoom = {504.80f, 89.07f, -16.12f, 6.27f}; @@ -82,17 +82,16 @@ public: bool bFrostMagusDead; bool bArcaneMagusDead; bool bIsWaitingToAppear; - bool bIsAchievementTimerRunning; uint32 uiIsWaitingToAppearTimer; uint32 uiIceNovaTimer; uint32 uiFireBombTimer; uint32 uiGravityWellTimer; uint32 uiCooldown; - uint32 uiAchievementTimer; uint8 Phase; - uint8 uiAchievementProgress; + uint8 splitPersonality; + time_t time[3]; void Reset() { @@ -107,10 +106,10 @@ public: uiFrostMagusGUID = 0; uiArcaneMagusGUID = 0; - uiAchievementProgress = 0; - uiAchievementTimer = 0; + for (uint8 n = 0; n < 3; ++n) + time[n] = 0; - bIsAchievementTimerRunning = false; + splitPersonality = 0; bIsWaitingToAppear = false; me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); @@ -133,11 +132,7 @@ public: DoScriptText(SAY_DEATH, me); if (pInstance) - { - if (IsHeroic() && uiAchievementProgress == 2) - pInstance->DoCompleteAchievement(ACHIEV_SPLIT_PERSONALITY); pInstance->SetData(DATA_MAGUS_TELESTRA_EVENT, DONE); - } } void KilledUnit(Unit* /*victim*/) @@ -145,6 +140,28 @@ public: DoScriptText(SAY_KILL, me); } + void DoAction(int32 const action) + { + if (action == ACTION_MAGUS_DEAD) + { + uint8 i = 0; + while (time[i] != 0) + ++i; + + time[i] = sWorld->GetGameTime(); + if (i == 2 && (time[2] - time[1] < 5) && (time[1] - time[0] < 5)) + ++splitPersonality; + } + } + + uint32 GetData(uint32 type) + { + if (type == DATA_SPLIT_PERSONALITY) + return splitPersonality; + + return 0; + } + uint64 SplitPersonality(uint32 entry) { if (Creature* Summoned = me->SummonCreature(entry, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1*IN_MILLISECONDS)) @@ -181,18 +198,18 @@ public: if (summon->GetGUID() == uiFireMagusGUID) { + me->AI()->DoAction(ACTION_MAGUS_DEAD); bFireMagusDead = true; - bIsAchievementTimerRunning = true; } else if (summon->GetGUID() == uiFrostMagusGUID) { + me->AI()->DoAction(ACTION_MAGUS_DEAD); bFrostMagusDead = true; - bIsAchievementTimerRunning = true; } else if (summon->GetGUID() == uiArcaneMagusGUID) { + me->AI()->DoAction(ACTION_MAGUS_DEAD); bArcaneMagusDead = true; - bIsAchievementTimerRunning = true; } } @@ -216,12 +233,10 @@ public: if ((Phase == 1) ||(Phase == 3)) { - if (bIsAchievementTimerRunning) - uiAchievementTimer += diff; if (bFireMagusDead && bFrostMagusDead && bArcaneMagusDead) { - if (uiAchievementTimer <= ACHIEV_TIMER) - uiAchievementProgress +=1; + for (uint8 n = 0; n < 3; ++n) + time[n] = 0; me->GetMotionMaster()->Clear(); me->GetMap()->CreatureRelocation(me, CenterOfRoom.GetPositionX(), CenterOfRoom.GetPositionY(), CenterOfRoom.GetPositionZ(), CenterOfRoom.GetOrientation()); DoCast(me, SPELL_TELESTRA_BACK); @@ -236,8 +251,6 @@ public: bIsWaitingToAppear = true; uiIsWaitingToAppearTimer = 4*IN_MILLISECONDS; DoScriptText(SAY_MERGE, me); - bIsAchievementTimerRunning = false; - uiAchievementTimer = 0; } else return; @@ -324,7 +337,28 @@ public: }; +class achievement_split_personality : public AchievementCriteriaScript +{ + public: + achievement_split_personality() : AchievementCriteriaScript("achievement_split_personality") + { + } + + bool OnCheck(Player* /*player*/, Unit* target) + { + if (!target) + return false; + + if (Creature* Telestra = target->ToCreature()) + if (Telestra->AI()->GetData(DATA_SPLIT_PERSONALITY) == 2) + return true; + + return false; + } +}; + void AddSC_boss_magus_telestra() { new boss_magus_telestra(); + new achievement_split_personality(); } diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_sjonnir.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_sjonnir.cpp index 2377c5e908a..808f0d6a8e0 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_sjonnir.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_sjonnir.cpp @@ -60,11 +60,7 @@ enum SjonnirCreatures CREATURE_IRON_SLUDGE = 28165 }; -enum Misc -{ - DATA_TIME_BEFORE_OOZE = 150000, //2min 30 secs - ACHIEV_ABUSE_THE_OOZE = 2155 -}; +#define DATA_TIME_BEFORE_OOZE 150000 //2min 30 secs struct Locations { @@ -73,10 +69,13 @@ struct Locations static Locations PipeLocations[] = { - {1295.44f, 734.07f, 200.3f}, //left - {1297.7f, 595.6f, 199.9f} //right + {1295.44f, 734.07f, 200.3f}, //left + {1297.7f, 595.6f, 199.9f} //right }; +#define ACTION_OOZE_DEAD 1 +#define DATA_ABUSE_THE_OOZE 2 + static Locations CenterPoint = {1295.21f, 667.157f, 189.691f}; class boss_sjonnir : public CreatureScript @@ -105,7 +104,7 @@ public: uint32 uiSummonTimer; uint32 uiFrenzyTimer; uint32 uiEncounterTimer; - uint32 uiKilledIronSludges; + uint8 abuseTheOoze; SummonList lSummons; @@ -122,7 +121,7 @@ public: uiLightningRingTimer = 30000 + rand()%5000; uiSummonTimer = 5000; uiFrenzyTimer = 300000; //5 minutes - uiKilledIronSludges = 0; + abuseTheOoze = 0; lSummons.DespawnAll(); @@ -221,11 +220,7 @@ public: lSummons.DespawnAll(); if (pInstance) - { pInstance->SetData(DATA_SJONNIR_EVENT, DONE); - if (IsHeroic() && uiKilledIronSludges > 4) - pInstance->DoCompleteAchievement(ACHIEV_ABUSE_THE_OOZE); - } } void KilledUnit(Unit* victim) { @@ -234,9 +229,18 @@ public: DoScriptText(RAND(SAY_SLAY_1, SAY_SLAY_2, SAY_SLAY_3), me); } - void KilledIronSludge() + void DoAction(int32 const action) { - ++uiKilledIronSludges; + if (action == ACTION_OOZE_DEAD) + ++abuseTheOoze; + } + + uint32 GetData(uint32 type) + { + if (type == DATA_ABUSE_THE_OOZE) + return abuseTheOoze; + + return 0; } }; @@ -307,16 +311,37 @@ public: void JustDied(Unit* /*pKiller*/) { if (pInstance) - if (Creature* pSjonnir = Unit::GetCreature(*me, pInstance->GetData64(DATA_SJONNIR))) - CAST_AI(boss_sjonnir::boss_sjonnirAI, pSjonnir->AI())->KilledIronSludge(); + if (Creature* Sjonnir = ObjectAccessor::GetCreature(*me, pInstance->GetData64(DATA_SJONNIR))) + Sjonnir->AI()->DoAction(ACTION_OOZE_DEAD); } }; }; +class achievement_abuse_the_ooze : public AchievementCriteriaScript +{ + public: + achievement_abuse_the_ooze() : AchievementCriteriaScript("achievement_abuse_the_ooze") + { + } + + bool OnCheck(Player* /*player*/, Unit* target) + { + if (!target) + return false; + + if (Creature* Sjonnir = target->ToCreature()) + if (Sjonnir->AI()->GetData(DATA_ABUSE_THE_OOZE) >= 5) + return true; + + return false; + } +}; + void AddSC_boss_sjonnir() { new boss_sjonnir(); new mob_malformed_ooze(); new mob_iron_sludge(); + new achievement_abuse_the_ooze(); } diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp index f237871ef90..2af26df3829 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp @@ -110,7 +110,9 @@ enum Spells H_SPELL_DARK_MATTER = 59868, //Abedneum SPELL_SEARING_GAZE = 51136, - H_SPELL_SEARING_GAZE = 59867 + H_SPELL_SEARING_GAZE = 59867, + + SPELL_REWARD_ACHIEVEMENT = 59046, }; enum Quests @@ -118,13 +120,9 @@ enum Quests QUEST_HALLS_OF_STONE = 13207 }; -enum Achievements -{ - ACHIEV_BRANN_SPANKIN_NEW = 2154 -}; - #define GOSSIP_ITEM_START "Brann, it would be our honor!" #define GOSSIP_ITEM_PROGRESS "Let's move Brann, enough of the history lessons!" +#define DATA_BRANN_SPARKLIN_NEWS 1 static Position SpawnLocations[]= { @@ -184,7 +182,7 @@ public: } void UpdateFacesList() - { + { /*GetCreatureListWithEntryInGrid(lKaddrakGUIDList, me, CREATURE_KADDRAK, 50.0f); if (!lKaddrakGUIDList.empty()) { @@ -315,7 +313,7 @@ public: bool bIsBattle; bool bIsLowHP; - bool bHasBeenDamaged; + bool brannSparklinNews; void Reset() { @@ -323,10 +321,10 @@ public: { bIsLowHP = false; bIsBattle = false; - bHasBeenDamaged = false; uiStep = 0; uiPhaseTimer = 0; uiControllerGUID = 0; + brannSparklinNews = true; DespawnDwarf(); @@ -425,8 +423,16 @@ public: void DamageTaken(Unit* /*done_by*/, uint32 & /*damage*/) { - if (!bHasBeenDamaged) - bHasBeenDamaged = true; + if (brannSparklinNews) + brannSparklinNews = false; + } + + uint32 GetData(uint32 type) + { + if (type == DATA_BRANN_SPARKLIN_NEWS) + return brannSparklinNews ? 1 : 0; + + return 0; } void UpdateEscortAI(const uint32 uiDiff) @@ -590,17 +596,8 @@ public: case 29: DoScriptText(SAY_EVENT_END_02, me); if (pInstance) - { pInstance->SetData(DATA_BRANN_EVENT, DONE); - - // Achievement criteria is with spell 59046 which does not exist. - // There is thus no way it can be given by casting the spell on the players. - pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 59046); - - if (!bHasBeenDamaged) - pInstance->DoCompleteAchievement(ACHIEV_BRANN_SPANKIN_NEW); - } - + me->CastSpell(me, SPELL_REWARD_ACHIEVEMENT, true); JumpToNextStep(5500); break; case 30: @@ -738,8 +735,29 @@ public: }; +class achievement_brann_spankin_new : public AchievementCriteriaScript +{ + public: + achievement_brann_spankin_new() : AchievementCriteriaScript("achievement_brann_spankin_new") + { + } + + bool OnCheck(Player* /*player*/, Unit* target) + { + if (!target) + return false; + + if (Creature* Brann = target->ToCreature()) + if (Brann->AI()->GetData(DATA_BRANN_SPARKLIN_NEWS)) + return true; + + return false; + } +}; + void AddSC_halls_of_stone() { new npc_brann_hos(); new mob_tribuna_controller(); + new achievement_brann_spankin_new(); } diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_auriaya.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_auriaya.cpp index ee0dd85519c..0684e8a4fac 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_auriaya.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_auriaya.cpp @@ -113,7 +113,7 @@ class boss_auriaya : public CreatureScript { _Reset(); DefenderGUID = 0; - defenderLifes = 8; + defenderLives = 8; crazyCatLady = true; nineLives = false; } @@ -165,8 +165,8 @@ class boss_auriaya : public CreatureScript SetData(DATA_CRAZY_CAT_LADY, 0); break; case ACTION_RESPAWN_DEFENDER: - --defenderLifes; - if (!defenderLifes) + --defenderLives; + if (!defenderLives) { SetData(DATA_NINE_LIVES, 1); break; @@ -247,8 +247,8 @@ class boss_auriaya : public CreatureScript if (Creature* Defender = ObjectAccessor::GetCreature(*me, DefenderGUID)) { Defender->Respawn(); - if (defenderLifes) - Defender->SetAuraStack(SPELL_FERAL_ESSENCE, Defender, defenderLifes); + if (defenderLives) + Defender->SetAuraStack(SPELL_FERAL_ESSENCE, Defender, defenderLives); Defender->SetInCombatWithZone(); if (!Defender->isInCombat()) Defender->AI()->AttackStart(me->getVictim()); @@ -273,7 +273,7 @@ class boss_auriaya : public CreatureScript private: uint64 DefenderGUID; - uint8 defenderLifes; + uint8 defenderLives; bool crazyCatLady; bool nineLives; }; @@ -507,6 +507,34 @@ class spell_auriaya_strenght_of_the_pack : public SpellScriptLoader } }; +class spell_auriaya_sentinel_blast : public SpellScriptLoader +{ + public: + spell_auriaya_sentinel_blast() : SpellScriptLoader("spell_auriaya_sentinel_blast") { } + + class spell_auriaya_sentinel_blast_SpellScript : public SpellScript + { + PrepareSpellScript(spell_auriaya_sentinel_blast_SpellScript); + + void FilterTargets(std::list<Unit*>& unitList) + { + unitList.remove_if(PlayerOrPetCheck()); + } + + void Register() + { + OnUnitTargetSelect += SpellUnitTargetFn(spell_auriaya_sentinel_blast_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_AREA_ENEMY_SRC); + OnUnitTargetSelect += SpellUnitTargetFn(spell_auriaya_sentinel_blast_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_AREA_ENEMY_SRC); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_auriaya_sentinel_blast_SpellScript(); + } +}; + + class achievement_nine_lives : public AchievementCriteriaScript { public: @@ -516,6 +544,9 @@ class achievement_nine_lives : public AchievementCriteriaScript bool OnCheck(Player* /*player*/, Unit* target) { + if (!target) + return false; + if (Creature* Auriaya = target->ToCreature()) if (Auriaya->AI()->GetData(DATA_NINE_LIVES)) return true; @@ -533,6 +564,9 @@ class achievement_crazy_cat_lady : public AchievementCriteriaScript bool OnCheck(Player* /*player*/, Unit* target) { + if (!target) + return false; + if (Creature* Auriaya = target->ToCreature()) if (Auriaya->AI()->GetData(DATA_CRAZY_CAT_LADY)) return true; @@ -548,6 +582,7 @@ void AddSC_boss_auriaya() new npc_feral_defender(); new npc_sanctum_sentry(); new spell_auriaya_strenght_of_the_pack(); + new spell_auriaya_sentinel_blast(); new achievement_nine_lives(); new achievement_crazy_cat_lady(); } diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp index 007ad1fb25b..209e3ce2ece 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp @@ -158,20 +158,6 @@ enum Yells SAY_OVERLOAD_3 = -1603075, }; -enum AchievementData -{ - ACHIEV_10_NUKED_FROM_ORBIT = 2915, - ACHIEV_25_NUKED_FROM_ORBIT = 2917, - ACHIEV_10_ORBITAL_BOMBARDMENT = 2913, - ACHIEV_25_ORBITAL_BOMBARDMENT = 2918, - ACHIEV_10_ORBITAL_DEVASTATION = 2914, - ACHIEV_25_ORBITAL_DEVASTATION = 2916, - ACHIEV_10_ORBIT_UARY = 3056, - ACHIEV_25_ORBIT_UARY = 3057, - ACHIEV_10_SIEGE_OF_ULDUAR = 2886, - ACHIEV_25_SIEGE_OF_ULDUAR = 2887, -}; - enum actions { ACTION_TOWER_OF_STORM_DESTROYED = 1, @@ -212,6 +198,8 @@ Position const PosDemolisher[5] = {-798.01f, -227.24f, 429.84f, 1.446f}, }; +#define DATA_ORBIT_ACHIEVEMENTS 1 + class boss_flame_leviathan : public CreatureScript { public: @@ -321,21 +309,6 @@ class boss_flame_leviathan : public CreatureScript { _JustDied(); DoScriptText(SAY_DEATH, me); - - if (ActiveTowers) - { - switch (ActiveTowersCount) - { - case 4: - instance->DoCompleteAchievement(RAID_MODE(ACHIEV_10_ORBIT_UARY, ACHIEV_25_ORBIT_UARY)); - case 3: - instance->DoCompleteAchievement(RAID_MODE(ACHIEV_10_NUKED_FROM_ORBIT, ACHIEV_25_NUKED_FROM_ORBIT)); - case 2: - instance->DoCompleteAchievement(RAID_MODE(ACHIEV_10_ORBITAL_DEVASTATION, ACHIEV_25_ORBITAL_DEVASTATION)); - case 1: - instance->DoCompleteAchievement(RAID_MODE(ACHIEV_10_ORBITAL_BOMBARDMENT, ACHIEV_25_ORBITAL_BOMBARDMENT)); - } - } } void SpellHit(Unit* /*caster*/, SpellEntry const* spell) @@ -358,6 +331,8 @@ class boss_flame_leviathan : public CreatureScript return Shutout ? 1 : 0; case DATA_UNBROKEN: return Unbroken ? 1 : 0; + case DATA_ORBIT_ACHIEVEMENTS: + return ActiveTowersCount; default: break; } @@ -846,15 +821,14 @@ class npc_mechanolift : public CreatureScript } }; -// WHY IS THIS CALLED spell_??? -class spell_pool_of_tar : public CreatureScript +class npc_pool_of_tar : public CreatureScript { public: - spell_pool_of_tar() : CreatureScript("spell_pool_of_tar") { } + npc_pool_of_tar() : CreatureScript("npc_pool_of_tar") { } - struct spell_pool_of_tarAI : public ScriptedAI + struct npc_pool_of_tarAI : public ScriptedAI { - spell_pool_of_tarAI(Creature* creature) : ScriptedAI(creature) + npc_pool_of_tarAI(Creature* creature) : ScriptedAI(creature) { me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetReactState(REACT_PASSIVE); @@ -877,7 +851,7 @@ class spell_pool_of_tar : public CreatureScript CreatureAI* GetAI(Creature* creature) const { - return new spell_pool_of_tarAI(creature); + return new npc_pool_of_tarAI(creature); } }; @@ -1412,6 +1386,78 @@ class achievement_unbroken : public AchievementCriteriaScript } }; +class achievement_orbital_bombardment : public AchievementCriteriaScript +{ + public: + achievement_orbital_bombardment() : AchievementCriteriaScript("achievement_orbital_bombardment") { } + + bool OnCheck(Player* /*source*/, Unit* target) + { + if (!target) + return false; + + if (Creature* Leviathan = target->ToCreature()) + if (Leviathan->AI()->GetData(DATA_ORBIT_ACHIEVEMENTS) >= 1) + return true; + + return false; + } +}; + +class achievement_orbital_devastation : public AchievementCriteriaScript +{ + public: + achievement_orbital_devastation() : AchievementCriteriaScript("achievement_orbital_devastation") { } + + bool OnCheck(Player* /*source*/, Unit* target) + { + if (!target) + return false; + + if (Creature* Leviathan = target->ToCreature()) + if (Leviathan->AI()->GetData(DATA_ORBIT_ACHIEVEMENTS) >= 2) + return true; + + return false; + } +}; + +class achievement_nuked_from_orbit : public AchievementCriteriaScript +{ + public: + achievement_nuked_from_orbit() : AchievementCriteriaScript("achievement_nuked_from_orbit") { } + + bool OnCheck(Player* /*source*/, Unit* target) + { + if (!target) + return false; + + if (Creature* Leviathan = target->ToCreature()) + if (Leviathan->AI()->GetData(DATA_ORBIT_ACHIEVEMENTS) >= 3) + return true; + + return false; + } +}; + +class achievement_orbit_uary : public AchievementCriteriaScript +{ + public: + achievement_orbit_uary() : AchievementCriteriaScript("achievement_orbit_uary") { } + + bool OnCheck(Player* /*source*/, Unit* target) + { + if (!target) + return false; + + if (Creature* Leviathan = target->ToCreature()) + if (Leviathan->AI()->GetData(DATA_ORBIT_ACHIEVEMENTS) == 4) + return true; + + return false; + } +}; + void AddSC_boss_flame_leviathan() { new boss_flame_leviathan(); @@ -1421,7 +1467,7 @@ void AddSC_boss_flame_leviathan() new boss_flame_leviathan_overload_device(); new boss_flame_leviathan_safety_container(); new npc_mechanolift(); - new spell_pool_of_tar(); + new npc_pool_of_tar(); new npc_colossus(); new npc_thorims_hammer(); new npc_mimirons_inferno(); @@ -1437,4 +1483,8 @@ void AddSC_boss_flame_leviathan() new achievement_three_car_garage_siege(); new achievement_shutout(); new achievement_unbroken(); + new achievement_orbital_bombardment(); + new achievement_orbital_devastation(); + new achievement_nuked_from_orbit(); + new achievement_orbit_uary(); } diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_freya.cpp index bcd22a5c248..b3dea49203b 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_freya.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_freya.cpp @@ -1620,6 +1620,9 @@ class achievement_knock_on_wood : public AchievementCriteriaScript bool OnCheck(Player* /*player*/, Unit* target) { + if (!target) + return false; + if (Creature* Freya = target->ToCreature()) if (Freya->AI()->GetData(DATA_KNOCK_ON_WOOD) >= 1) return true; @@ -1637,6 +1640,9 @@ class achievement_knock_knock_on_wood : public AchievementCriteriaScript bool OnCheck(Player* /*player*/, Unit* target) { + if (!target) + return false; + if (Creature* Freya = target->ToCreature()) if (Freya->AI()->GetData(DATA_KNOCK_ON_WOOD) >= 2) return true; @@ -1654,6 +1660,9 @@ class achievement_knock_knock_knock_on_wood : public AchievementCriteriaScript bool OnCheck(Player* /*player*/, Unit* target) { + if (!target) + return false; + if (Creature* Freya = target->ToCreature()) if (Freya->AI()->GetData(DATA_KNOCK_ON_WOOD) == 3) return true; @@ -1671,6 +1680,9 @@ class achievement_getting_back_to_nature : public AchievementCriteriaScript bool OnCheck(Player* /*player*/, Unit* target) { + if (!target) + return false; + if (Creature* Freya = target->ToCreature()) if (Freya->AI()->GetData(DATA_GETTING_BACK_TO_NATURE) >= 25) return true; diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_general_vezax.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_general_vezax.cpp index cbb4550a3e2..f45b0815abe 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_general_vezax.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_general_vezax.cpp @@ -203,7 +203,7 @@ class boss_general_vezax : public CreatureScript void SpellHitTarget(Unit* who, SpellEntry const* spell) { if (who && who->GetTypeId() == TYPEID_PLAYER && spell->Id == SPELL_SHADOW_CRASH_HIT) - SetData(DATA_SHADOWDODGER, 0); + shadowDodger = false; } void KilledUnit(Unit* /*who*/) @@ -245,25 +245,12 @@ class boss_general_vezax : public CreatureScript return 0; } - void SetData(uint32 id, uint32 data) - { - switch (id) - { - case DATA_SHADOWDODGER: - shadowDodger = data ? true : false; - break; - case DATA_SMELL_SARONITE: - smellSaronite = data ? true : false; - break; - } - } - void DoAction(int32 const action) { switch (action) { case ACTION_VAPORS_DIE: - SetData(DATA_SMELL_SARONITE, 0); + smellSaronite = false; break; case ACTION_ANIMUS_DIE: me->RemoveAurasDueToSpell(SPELL_SARONITE_BARRIER); @@ -487,6 +474,9 @@ class achievement_shadowdodger : public AchievementCriteriaScript bool OnCheck(Player* /*player*/, Unit* target) { + if (!target) + return false; + if (Creature* Vezax = target->ToCreature()) if (Vezax->AI()->GetData(DATA_SHADOWDODGER)) return true; @@ -504,6 +494,9 @@ class achievement_smell_saronite : public AchievementCriteriaScript bool OnCheck(Player* /*player*/, Unit* target) { + if (!target) + return false; + if (Creature* Vezax = target->ToCreature()) if (Vezax->AI()->GetData(DATA_SMELL_SARONITE)) return true; diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp index 1fb24699b60..7bd659400b7 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp @@ -194,13 +194,7 @@ public: void SpellHitTarget(Unit* who, SpellEntry const* spell) { if (who && who->GetTypeId() == TYPEID_PLAYER && spell->Id == 59302) - SetData(DATA_KINGS_BANE, 0); - } - - void SetData(uint32 id, uint32 data) - { - if (id == DATA_KINGS_BANE) - kingsBane = data ? true : false; + kingsBane = false; } uint32 GetData(uint32 type) @@ -406,6 +400,9 @@ class achievement_kings_bane : public AchievementCriteriaScript bool OnCheck(Player* /*player*/, Unit* target) { + if (!target) + return false; + if (Creature* Ymiron = target->ToCreature()) if (Ymiron->AI()->GetData(DATA_KINGS_BANE)) return true; diff --git a/src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp b/src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp index 017da20a176..804d602a06f 100644 --- a/src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp +++ b/src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp @@ -159,7 +159,28 @@ public: }; +class achievement_defenseless : public AchievementCriteriaScript +{ + public: + achievement_defenseless() : AchievementCriteriaScript("achievement_defenseless") + { + } + + bool OnCheck(Player* /*player*/, Unit* target) + { + InstanceScript* instance = target->GetInstanceScript(); + if (!instance) + return false; + + if (!instance->GetData(DATA_DEFENSELESS)) + return false; + + return true; + } +}; + void AddSC_boss_cyanigosa() { new boss_cyanigosa(); + new achievement_defenseless(); } diff --git a/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp b/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp index 3f2ea65958d..1e3914ab40b 100644 --- a/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp +++ b/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp @@ -50,11 +50,6 @@ enum Yells SAY_BUBBLE = -1608026 }; -enum Achievements -{ - ACHIEVEMENT_DEHYDRATION = 2041, -}; - enum Actions { ACTION_WATER_ELEMENT_HIT = 1, @@ -72,6 +67,8 @@ static Position SpawnLoc[MAX_SPAWN_LOC]= {1935.50f, 796.224f, 52.492f, 4.224f}, }; +#define DATA_DEHYDRATION 1 + class boss_ichoron : public CreatureScript { public: @@ -91,7 +88,7 @@ public: bool bIsExploded; bool bIsFrenzy; - bool bAchievement; + bool dehydration; uint32 uiBubbleCheckerTimer; uint32 uiWaterBoltVolleyTimer; @@ -104,7 +101,7 @@ public: { bIsExploded = false; bIsFrenzy = false; - bAchievement = true; + dehydration = true; uiBubbleCheckerTimer = 1000; uiWaterBoltVolleyTimer = urand(10000, 15000); @@ -168,7 +165,7 @@ public: if (bIsExploded) DoExplodeCompleted(); - bAchievement = false; + dehydration = false; break; case ACTION_WATER_ELEMENT_KILLED: uint32 damage = me->CountPctFromMaxHealth(3); @@ -199,11 +196,18 @@ public: me->GetMotionMaster()->MoveChase(me->getVictim()); } + uint32 GetData(uint32 type) + { + if (type == DATA_DEHYDRATION) + return dehydration ? 1 : 0; + + return 0; + } + void MoveInLineOfSight(Unit* /*pWho*/) {} void UpdateAI(const uint32 uiDiff) { - //Return since we have no target if (!UpdateVictim()) return; @@ -284,9 +288,6 @@ public: if (pInstance) { - if (IsHeroic() && bAchievement) - pInstance->DoCompleteAchievement(ACHIEVEMENT_DEHYDRATION); - if (pInstance->GetData(DATA_WAVE_COUNT) == 6) { pInstance->SetData(DATA_1ST_BOSS_EVENT, DONE); @@ -394,8 +395,29 @@ public: }; +class achievement_dehydration : public AchievementCriteriaScript +{ + public: + achievement_dehydration() : AchievementCriteriaScript("achievement_dehydration") + { + } + + bool OnCheck(Player* /*player*/, Unit* target) + { + if (!target) + return false; + + if (Creature* Ichoron = target->ToCreature()) + if (Ichoron->AI()->GetData(DATA_DEHYDRATION)) + return true; + + return false; + } +}; + void AddSC_boss_ichoron() { new boss_ichoron(); new mob_ichor_globule(); + new achievement_dehydration(); } diff --git a/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp b/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp index af7321b4dd1..16f49316782 100644 --- a/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp +++ b/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp @@ -154,13 +154,7 @@ public: void SummonedCreatureDies(Creature* summoned, Unit* /*who*/) { if (summoned->GetEntry() == CREATURE_VOID_SENTRY) - SetData(DATA_VOID_DANCE, 0); - } - - void SetData(uint32 id, uint32 data) - { - if (id == DATA_VOID_DANCE) - voidDance = data ? true : false; + voidDance = false; } uint32 GetData(uint32 type) @@ -217,6 +211,9 @@ class achievement_void_dance : public AchievementCriteriaScript bool OnCheck(Player* /*player*/, Unit* target) { + if (!target) + return false; + if (Creature* Zuramat = target->ToCreature()) if (Zuramat->AI()->GetData(DATA_VOID_DANCE)) return true; diff --git a/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp b/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp index 93ef8256fef..98731f4aa7b 100644 --- a/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp +++ b/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp @@ -93,15 +93,12 @@ enum Yells { CYANIGOSA_SAY_SPAWN = -1608005 }; + enum Spells { CYANIGOSA_SPELL_TRANSFORM = 58668, CYANIGOSA_BLUE_AURA = 47759, }; -enum Achievements -{ - ACHIEV_DEFENSELESS = 1816 -}; class instance_violet_hold : public InstanceMapScript { @@ -165,6 +162,7 @@ public: bool bWiped; bool bIsDoorSpellCasted; bool bCrystalActivated; + bool defenseless; std::list<uint8> NpcAtDoorCastingList; @@ -214,6 +212,7 @@ public: bActive = false; bIsDoorSpellCasted = false; bCrystalActivated = false; + defenseless = true; uiMainEventPhase = NOT_STARTED; memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); @@ -334,8 +333,6 @@ public: uiMainEventPhase = DONE; if (GameObject* pMainDoor = instance->GetGameObject(uiMainDoor)) pMainDoor->SetGoState(GO_STATE_ACTIVE); - if (!bCrystalActivated && uiDoorIntegrity == 100) - DoCompleteAchievement(ACHIEV_DEFENSELESS); } break; case DATA_WAVE_COUNT: @@ -350,6 +347,7 @@ public: break; case DATA_DOOR_INTEGRITY: uiDoorIntegrity = data; + defenseless = false; DoUpdateWorldState(WORLD_STATE_VH_PRISON_STATE, uiDoorIntegrity); break; case DATA_NPC_PRESENCE_AT_DOOR_ADD: @@ -432,6 +430,7 @@ public: case DATA_FIRST_BOSS: return uiFirstBoss; case DATA_SECOND_BOSS: return uiSecondBoss; case DATA_MAIN_EVENT_PHASE: return uiMainEventPhase; + case DATA_DEFENSELESS: return defenseless ? 1 : 0; } return 0; diff --git a/src/server/scripts/Northrend/VioletHold/violet_hold.h b/src/server/scripts/Northrend/VioletHold/violet_hold.h index 5fe8b75e97f..ff663efe275 100644 --- a/src/server/scripts/Northrend/VioletHold/violet_hold.h +++ b/src/server/scripts/Northrend/VioletHold/violet_hold.h @@ -52,7 +52,8 @@ enum Data DATA_FIRST_BOSS, DATA_SECOND_BOSS, DATA_ACTIVATE_CRYSTAL, - DATA_MAIN_EVENT_PHASE + DATA_MAIN_EVENT_PHASE, + DATA_DEFENSELESS, }; enum Data64 diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index f693c1b249e..67939a61f23 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -623,42 +623,6 @@ class spell_gen_animal_blood : public SpellScriptLoader } }; -class spell_gen_shroud_of_death : public SpellScriptLoader -{ - public: - spell_gen_shroud_of_death() : SpellScriptLoader("spell_gen_shroud_of_death") { } - - class spell_gen_shroud_of_death_AuraScript : public AuraScript - { - PrepareAuraScript(spell_gen_shroud_of_death_AuraScript); - - void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - target->m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_GHOST); - target->m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_GHOST); - } - - void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - target->m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE); - target->m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE); - } - - void Register() - { - OnEffectApply += AuraEffectApplyFn(spell_gen_shroud_of_death_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - OnEffectRemove += AuraEffectRemoveFn(spell_gen_shroud_of_death_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - }; - - AuraScript* GetAuraScript() const - { - return new spell_gen_shroud_of_death_AuraScript(); - } -}; - enum DivineStormSpell { SPELL_DIVINE_STORM = 53385, @@ -1161,6 +1125,35 @@ class spell_gen_magic_rooster : public SpellScriptLoader } }; +class spell_gen_allow_cast_from_item_only : public SpellScriptLoader +{ +public: + spell_gen_allow_cast_from_item_only() : SpellScriptLoader("spell_gen_allow_cast_from_item_only") { } + + class spell_gen_allow_cast_from_item_only_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_allow_cast_from_item_only_SpellScript); + + SpellCastResult CheckRequirement() + { + if (!GetCastItem()) + return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; + + return SPELL_CAST_OK; + } + + void Register() + { + OnCheckCast += SpellCheckCastFn(spell_gen_allow_cast_from_item_only_SpellScript::CheckRequirement); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_allow_cast_from_item_only_SpellScript(); + } +}; + void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); @@ -1176,7 +1169,6 @@ void AddSC_generic_spell_scripts() new spell_creature_permanent_feign_death(); new spell_pvp_trinket_wotf_shared_cd(); new spell_gen_animal_blood(); - new spell_gen_shroud_of_death(); new spell_gen_divine_storm_cd_reset(); new spell_gen_parachute_ic(); new spell_gen_gunship_portal(); @@ -1188,4 +1180,5 @@ void AddSC_generic_spell_scripts() new spell_gen_turkey_marker(); new spell_gen_lifeblood(); new spell_gen_magic_rooster(); + new spell_gen_allow_cast_from_item_only(); } diff --git a/src/server/scripts/World/boss_emerald_dragons.cpp b/src/server/scripts/World/boss_emerald_dragons.cpp index 223dbb43f11..ac101d239b5 100644 --- a/src/server/scripts/World/boss_emerald_dragons.cpp +++ b/src/server/scripts/World/boss_emerald_dragons.cpp @@ -85,9 +85,6 @@ enum Events * --- * --- Emerald Dragons : Base AI-structure used for all the Emerald dragons * --- - * - * TODO - * - Fix player teleportation when running off too far from the dragon (emerald_dragonAI) */ struct emerald_dragonAI : public WorldBossAI @@ -153,10 +150,8 @@ struct emerald_dragonAI : public WorldBossAI while (uint32 eventId = events.ExecuteEvent()) ExecuteEvent(eventId); - std::list<HostileReference*> threats = me->getThreatManager().getThreatList(); - if (Unit* target = threats.front()->getTarget()) - if ((target->GetTypeId() == TYPEID_PLAYER) && (me->GetDistance(target) > 20.0f)) - DoCast(target, SPELL_SUMMON_PLAYER); + if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 0, -50.0f, true)) + DoCast(target, SPELL_SUMMON_PLAYER); DoMeleeAttackIfReady(); } @@ -190,8 +185,7 @@ class npc_dream_fog : public CreatureScript if (!_roamTimer) { // Chase target, but don't attack - otherwise just roam around - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true); - if (target) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) { _roamTimer = urand(15000, 30000); me->GetMotionMaster()->Clear(false); @@ -397,22 +391,6 @@ class boss_ysondre : public CreatureScript } } - void UpdateAI(uint32 const diff) - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STAT_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - ExecuteEvent(eventId); - - DoMeleeAttackIfReady(); - } - private: uint8 _stage; }; @@ -496,22 +474,6 @@ class boss_lethon : public CreatureScript } } - void UpdateAI(uint32 const diff) - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STAT_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - ExecuteEvent(eventId); - - DoMeleeAttackIfReady(); - } - private: uint8 _stage; }; @@ -597,22 +559,6 @@ class boss_emeriss : public CreatureScript } } - void UpdateAI(uint32 const diff) - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STAT_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - ExecuteEvent(eventId); - - DoMeleeAttackIfReady(); - } - private: uint8 _stage; }; @@ -738,12 +684,7 @@ class boss_taerar : public CreatureScript void UpdateAI(uint32 const diff) { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STAT_CASTING)) + if (!me->isInCombat()) return; if (_banished) @@ -760,13 +701,14 @@ class boss_taerar : public CreatureScript // _banishtimer has not expired, and we still have active shades: else _banishedTimer -= diff; + + // Update the events before we return (handled under emerald_dragonAI::UpdateAI(diff); if we're not inside this check) + events.Update(diff); + return; } - while (uint32 eventId = events.ExecuteEvent()) - ExecuteEvent(eventId); - - DoMeleeAttackIfReady(); + emerald_dragonAI::UpdateAI(diff); } private: diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 66ca7645e49..eb1e33626c6 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -1895,11 +1895,12 @@ GM.LowerSecurity = 0 # # GM.AllowAchievementGain.Level -# Description: Max GM level that can obtain achievements. -# Default: 3 - (Anyone) -# 0 - (Only players) -# 1 - (Only moderators) -# 2 - (Only gamemasters) +# Description: Max GM level allowed to obtain achievements. +# Default: 3 - (Players, Moderators, GameMasters, Admins) +# 0 - (Players) +# 1 - (Players, Moderators) +# 2 - (Players, Moderators, GameMasters) +# 3 - (Players, Moderators, GameMasters, Admins) GM.AllowAchievementGain.Level = 3 |