Merge branch 'master' of git://github.com/TrinityCore/TrinityCore

This commit is contained in:
Frca
2012-04-22 19:19:32 +02:00
49 changed files with 2978 additions and 757 deletions
@@ -1107,7 +1107,7 @@ void CreatureEventAI::UpdateAI(const uint32 diff)
break;
case EVENT_T_RANGE:
if (me->getVictim())
if (me->IsInMap(me->getVictim()))
if (me->IsInMap(me->getVictim()) && me->InSamePhase(me->getVictim()))
if (me->IsInRange(me->getVictim(), (float)(*i).Event.range.minDist, (float)(*i).Event.range.maxDist))
ProcessEvent(*i);
break;
@@ -1119,12 +1119,13 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
if (!IsUnit(*itr))
continue;
(*itr)->GetPosition(x, y, z, o);
x += e.target.x;
y += e.target.y;
z += e.target.z;
o += e.target.o;
if (Creature* summon = GetBaseObject()->SummonCreature(e.action.summonCreature.creature, x, y, z, o, (TempSummonType)e.action.summonCreature.type, e.action.summonCreature.duration))
if (unit && e.action.summonCreature.attackInvoker)
if (e.action.summonCreature.attackInvoker)
summon->AI()->AttackStart((*itr)->ToUnit());
}
@@ -1154,6 +1155,10 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
continue;
(*itr)->GetPosition(x, y, z, o);
x += e.target.x;
y += e.target.y;
z += e.target.z;
o += e.target.o;
GetBaseObject()->SummonGameObject(e.action.summonGO.entry, x, y, z, o, 0, 0, 0, 0, e.action.summonGO.despawnTime);
}
+2 -1
View File
@@ -75,7 +75,7 @@ bool ThreatCalcHelper::isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellIn
return false;
// not in same map or phase
if (!hatedUnit->IsInMap(hatingUnit))
if (!hatedUnit->IsInMap(hatingUnit) || !hatedUnit->InSamePhase(hatingUnit))
return false;
// spell not causing threat
@@ -182,6 +182,7 @@ void HostileReference::updateOnlineStatus()
&& (getTarget()->GetTypeId() != TYPEID_PLAYER || !getTarget()->ToPlayer()->isGameMaster())
&& !getTarget()->HasUnitState(UNIT_STATE_IN_FLIGHT)
&& getTarget()->IsInMap(getSourceUnit())
&& getTarget()->InSamePhase(getSourceUnit())
)
{
Creature* creature = getSourceUnit()->ToCreature();
@@ -796,10 +796,12 @@ bool Creature::Create(uint32 guidlow, Map* map, uint32 phaseMask, uint32 Entry,
//! Need to be called after LoadCreaturesAddon - MOVEMENTFLAG_HOVER is set there
if (HasUnitMovementFlag(MOVEMENTFLAG_HOVER))
{
z += GetFloatValue(UNIT_FIELD_HOVERHEIGHT);
//! Relocate again with updated Z coord
Relocate(x, y, z, ang);
//! Relocate again with updated Z coord
Relocate(x, y, z, ang);
}
uint32 displayID = GetNativeDisplayId();
CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelRandomGender(&displayID);
+1 -1
View File
@@ -507,7 +507,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
if (isPet())
return false;
return GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS;
return GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_BOSS;
}
bool IsDungeonBoss() const;
@@ -1825,6 +1825,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
m_goValue->Building.Health = m_goValue->Building.MaxHealth;
SetGoAnimProgress(255);
}
EnableCollision(true);
break;
case GO_DESTRUCTIBLE_DAMAGED:
{
@@ -1881,6 +1882,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
m_goValue->Building.Health = 0;
SetGoAnimProgress(0);
}
EnableCollision(false);
break;
}
case GO_DESTRUCTIBLE_REBUILDING:
@@ -1900,6 +1902,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
m_goValue->Building.Health = m_goValue->Building.MaxHealth;
SetGoAnimProgress(255);
}
EnableCollision(true);
break;
}
}
+2 -2
View File
@@ -685,7 +685,7 @@ class WorldObject : public Object, public WorldLocation
bool IsInMap(const WorldObject* obj) const
{
if (obj)
return IsInWorld() && obj->IsInWorld() && (GetMap() == obj->GetMap()) && InSamePhase(obj);
return IsInWorld() && obj->IsInWorld() && (GetMap() == obj->GetMap());
return false;
}
bool IsWithinDist3d(float x, float y, float z, float dist) const
@@ -703,7 +703,7 @@ class WorldObject : public Object, public WorldLocation
}
bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true) const
{
return obj && IsInMap(obj) && _IsWithinDist(obj, dist2compare, is3D);
return obj && IsInMap(obj) && InSamePhase(obj) && _IsWithinDist(obj, dist2compare, is3D);
}
bool IsWithinLOS(float x, float y, float z) const;
bool IsWithinLOSInMap(const WorldObject* obj) const;
@@ -9217,6 +9217,9 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
case 4100: // The Culling of Stratholme
NumberOfFields = 13;
break;
case 4273: // Ulduar
NumberOfFields = 10;
break;
default:
NumberOfFields = 12;
break;
@@ -9761,6 +9764,16 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
data << uint32(3932) << uint32(0); // 13 WORLDSTATE_TIME_GUARDIAN_SHOW
}
break;
// Ulduar
case 4273:
if (instance && mapid == 603)
instance->FillInitialWorldStates(data);
else
{
data << uint32(4132) << uint32(0); // 9 WORLDSTATE_SHOW_CRATES
data << uint32(4131) << uint32(0); // 10 WORLDSTATE_CRATES_REVEALED
}
break;
default:
data << uint32(0x914) << uint32(0x0); // 7
data << uint32(0x913) << uint32(0x0); // 8
+2 -2
View File
@@ -460,7 +460,7 @@ void Unit::resetAttackTimer(WeaponAttackType type)
bool Unit::IsWithinCombatRange(const Unit* obj, float dist2compare) const
{
if (!obj || !IsInMap(obj))
if (!obj || !IsInMap(obj) || !InSamePhase(obj))
return false;
float dx = GetPositionX() - obj->GetPositionX();
@@ -476,7 +476,7 @@ bool Unit::IsWithinCombatRange(const Unit* obj, float dist2compare) const
bool Unit::IsWithinMeleeRange(const Unit* obj, float dist) const
{
if (!obj || !IsInMap(obj))
if (!obj || !IsInMap(obj) || !InSamePhase(obj))
return false;
float dx = GetPositionX() - obj->GetPositionX();
@@ -1287,7 +1287,7 @@ namespace Trinity
AllWorldObjectsInRange(const WorldObject* object, float maxRange) : m_pObject(object), m_fRange(maxRange) {}
bool operator() (WorldObject* go)
{
return m_pObject->IsWithinDist(go, m_fRange, false);
return m_pObject->IsWithinDist(go, m_fRange, false) && m_pObject->InSamePhase(go);
}
private:
const WorldObject* m_pObject;
@@ -251,9 +251,8 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(PlayerMapType &m)
return;
for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
if (itr->getSource()->InSamePhase(i_phaseMask))
if (i_check(itr->getSource()))
i_objects.push_back(itr->getSource());
if (i_check(itr->getSource()))
i_objects.push_back(itr->getSource());
}
template<class Check>
@@ -263,9 +262,8 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(CreatureMapType &m)
return;
for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
if (itr->getSource()->InSamePhase(i_phaseMask))
if (i_check(itr->getSource()))
i_objects.push_back(itr->getSource());
if (i_check(itr->getSource()))
i_objects.push_back(itr->getSource());
}
template<class Check>
@@ -275,9 +273,8 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(CorpseMapType &m)
return;
for (CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
if (itr->getSource()->InSamePhase(i_phaseMask))
if (i_check(itr->getSource()))
i_objects.push_back(itr->getSource());
if (i_check(itr->getSource()))
i_objects.push_back(itr->getSource());
}
template<class Check>
@@ -287,9 +284,8 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(GameObjectMapType &m)
return;
for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
if (itr->getSource()->InSamePhase(i_phaseMask))
if (i_check(itr->getSource()))
i_objects.push_back(itr->getSource());
if (i_check(itr->getSource()))
i_objects.push_back(itr->getSource());
}
template<class Check>
@@ -299,9 +295,8 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(DynamicObjectMapType &m)
return;
for (DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
if (itr->getSource()->InSamePhase(i_phaseMask))
if (i_check(itr->getSource()))
i_objects.push_back(itr->getSource());
if (i_check(itr->getSource()))
i_objects.push_back(itr->getSource());
}
// Gameobject searchers
+1 -1
View File
@@ -228,7 +228,7 @@ enum LevelRequirementVsMode
#define MAX_HEIGHT 100000.0f // can be use for find ground height at surface
#define INVALID_HEIGHT -100000.0f // for check, must be equal to VMAP_INVALID_HEIGHT, real value for unknown height is VMAP_INVALID_HEIGHT_VALUE
#define MAX_FALL_DISTANCE 250000.0f // "unlimited fall" to find VMap ground if it is available, just larger than MAX_HEIGHT - INVALID_HEIGHT
#define DEFAULT_HEIGHT_SEARCH 10.0f // default search distance to find height at nearby locations
#define DEFAULT_HEIGHT_SEARCH 50.0f // default search distance to find height at nearby locations
#define MIN_UNLOAD_DELAY 1 // immediate unload
typedef std::map<uint32/*leaderDBGUID*/, CreatureGroup*> CreatureGroupHolderType;
@@ -2566,7 +2566,7 @@ enum CreatureTypeFlags
{
CREATURE_TYPEFLAGS_TAMEABLE = 0x00000001, // Tameable by any hunter
CREATURE_TYPEFLAGS_GHOST = 0x00000002, // Creature are also visible for not alive player. Allow gossip interaction if npcflag allow?
CREATURE_TYPEFLAGS_UNK2 = 0x00000004,
CREATURE_TYPEFLAGS_BOSS = 0x00000004,
CREATURE_TYPEFLAGS_UNK3 = 0x00000008,
CREATURE_TYPEFLAGS_UNK4 = 0x00000010,
CREATURE_TYPEFLAGS_UNK5 = 0x00000020,
@@ -425,6 +425,7 @@ void AddSC_ulduar_teleporter();
void AddSC_boss_mimiron();
void AddSC_boss_hodir();
void AddSC_boss_freya();
void AddSC_boss_algalon_the_observer();
void AddSC_instance_ulduar();
void AddSC_boss_keleseth(); //Utgarde Keep
void AddSC_boss_skarvald_dalronn();
@@ -1129,6 +1130,7 @@ void AddNorthrendScripts()
AddSC_boss_mimiron();
AddSC_boss_hodir();
AddSC_boss_freya();
AddSC_boss_algalon_the_observer();
AddSC_instance_ulduar();
AddSC_boss_keleseth(); //Utgarde Keep
AddSC_boss_skarvald_dalronn();
+7 -7
View File
@@ -3107,13 +3107,13 @@ void Spell::cast(bool skipCheck)
// should be done before the spell is actually executed
sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
// Let any pets know we've attacked something. As of 3.0.2 pets begin
// attacking their owner's target immediately
if (Pet* playerPet = playerCaster->GetPet())
{
if (playerPet->isAlive() && playerPet->isControlled() && (m_targets.GetTargetMask() & TARGET_FLAG_UNIT))
playerPet->AI()->OwnerAttacked(m_targets.GetObjectTarget()->ToUnit());
}
// As of 3.0.2 pets begin attacking their owner's target immediately
// Let any pets know we've attacked something. Check DmgClass for harmful spells only
// This prevents spells such as Hunter's Mark from triggering pet attack
if (this->GetSpellInfo()->DmgClass != SPELL_DAMAGE_CLASS_NONE)
if (Pet* playerPet = playerCaster->GetPet())
if (playerPet->isAlive() && playerPet->isControlled() && (m_targets.GetTargetMask() & TARGET_FLAG_UNIT))
playerPet->AI()->OwnerAttacked(m_targets.GetObjectTarget()->ToUnit());
}
SetExecutedCurrently(true);
+6 -23
View File
@@ -390,23 +390,6 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
if (!unitTarget->HasAura(27825))
return;
break;
// Cataclysmic Bolt
case 38441:
{
damage = unitTarget->CountPctFromMaxHealth(50);
break;
}
case 20625: // Ritual of Doom Sacrifice
case 29142: // Eyesore Blaster
case 35139: // Throw Boom's Doom
case 42393: // Brewfest - Attack Keg
case 55269: // Deathly Stare
case 56578: // Rapid-Fire Harpoon
case 62775: // Tympanic Tantrum
{
damage = unitTarget->CountPctFromMaxHealth(damage);
break;
}
// Gargoyle Strike
case 51963:
{
@@ -666,19 +649,19 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
if (found)
damage += m_spellInfo->Effects[EFFECT_1].CalcValue();
if (m_caster->GetTypeId() == TYPEID_PLAYER)
if (Player* caster = m_caster->ToPlayer())
{
// Add Ammo and Weapon damage plus RAP * 0.1
Item* item = m_caster->ToPlayer()->GetWeaponForAttack(RANGED_ATTACK);
if (item)
if (Item* item = caster->GetWeaponForAttack(RANGED_ATTACK))
{
float dmg_min = item->GetTemplate()->Damage->DamageMin;
float dmg_max = item->GetTemplate()->Damage->DamageMax;
ItemTemplate const* weaponTemplate = item->GetTemplate();
float dmg_min = weaponTemplate->Damage[0].DamageMin;
float dmg_max = weaponTemplate->Damage[0].DamageMax;
if (dmg_max == 0.0f && dmg_min > dmg_max)
damage += int32(dmg_min);
else
damage += irand(int32(dmg_min), int32(dmg_max));
damage += int32(m_caster->ToPlayer()->GetAmmoDPS()*item->GetTemplate()->Delay*0.001f);
damage += int32(caster->GetAmmoDPS() * weaponTemplate->Delay * 0.001f);
}
}
}
+13
View File
@@ -3298,6 +3298,19 @@ void SpellMgr::LoadDbcDataCorrections()
spellInfo->EffectImplicitTargetB[1] = TARGET_UNIT_NEARBY_ENTRY;
spellInfo->EffectImplicitTargetB[2] = TARGET_UNIT_NEARBY_ENTRY;
break;
case 62301: // Cosmic Smash (Algalon the Observer)
spellInfo->MaxAffectedTargets = 1;
break;
case 64598: // Cosmic Smash (Algalon the Observer)
spellInfo->MaxAffectedTargets = 3;
break;
case 62293: // Cosmic Smash (Algalon the Observer)
spellInfo->EffectImplicitTargetB[0] = TARGET_DEST_CASTER;
break;
case 62311: // Cosmic Smash (Algalon the Observer)
case 64596: // Cosmic Smash (Algalon the Observer)
spellInfo->rangeIndex = 6; // 100yd
break;
// ENDOF ULDUAR SPELLS
//
// TRIAL OF THE CRUSADER SPELLS
+1 -1
View File
@@ -403,7 +403,7 @@ GameObject* SpellScript::GetHitGObj()
return m_spell->gameObjTarget;
}
WorldLocation const* SpellScript::GetHitDest()
WorldLocation* SpellScript::GetHitDest()
{
if (!IsInEffectHook())
{
+1 -1
View File
@@ -325,7 +325,7 @@ class SpellScript : public _SpellScript
// returns: target of current effect if it was GameObject otherwise NULL
GameObject* GetHitGObj();
// returns: destination of current effect
WorldLocation const* GetHitDest();
WorldLocation* GetHitDest();
// setter/getter for for damage done by spell to target of spell hit
// returns damage calculated before hit, and real dmg done after hit
int32 GetHitDamage();
+1
View File
@@ -119,6 +119,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/game/Maps
${CMAKE_SOURCE_DIR}/src/server/game/Movement
${CMAKE_SOURCE_DIR}/src/server/game/Movement/MovementGenerators
${CMAKE_SOURCE_DIR}/src/server/game/Movement/Spline
${CMAKE_SOURCE_DIR}/src/server/game/Movement/Waypoints
${CMAKE_SOURCE_DIR}/src/server/game/Opcodes
${CMAKE_SOURCE_DIR}/src/server/game/OutdoorPvP
+1 -1
View File
@@ -22,7 +22,7 @@ set(scripts_STAT_SRCS
Northrend/Ulduar/Ulduar/ulduar_teleporter.cpp
Northrend/Ulduar/Ulduar/boss_thorim.cpp
Northrend/Ulduar/Ulduar/boss_ignis.cpp
Northrend/Ulduar/Ulduar/boss_algalon.cpp
Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
Northrend/Ulduar/Ulduar/instance_ulduar.cpp
Northrend/Ulduar/Ulduar/boss_auriaya.cpp
Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp
@@ -515,36 +515,6 @@ public:
};
class spell_spinning_pain_spike : public SpellScriptLoader
{
public:
spell_spinning_pain_spike() : SpellScriptLoader("spell_spinning_pain_spike") {}
class spell_spinning_pain_spike_SpellScript : public SpellScript
{
PrepareSpellScript(spell_spinning_pain_spike_SpellScript);
void HandleScript(SpellEffIndex /*eff*/)
{
Unit* target = GetHitUnit();
if (!target)
return;
if (target->isAlive())
SetHitDamage(target->CountPctFromMaxHealth(50));
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_spinning_pain_spike_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
}
};
SpellScript* GetSpellScript() const
{
return new spell_spinning_pain_spike_SpellScript();
}
};
void AddSC_boss_jaraxxus()
{
new boss_jaraxxus();
@@ -553,5 +523,4 @@ void AddSC_boss_jaraxxus()
new mob_fel_infernal();
new mob_nether_portal();
new mob_mistress_of_pain();
new spell_spinning_pain_spike();
}
@@ -1,376 +0,0 @@
/*
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ulduar.h"
#define GAMEOBJECT_GIVE_OF_THE_OBSERVER 194821
enum Spells
{
SPELL_ASCEND = 64487,
SPELL_BERSERK = 47008,
SPELL_BIG_BANG = 64443,
H_SPELL_BIG_BANG = 64584,
SPELL_COSMIC_SMASH = 62301,
H_SPELL_COSMIC_SMASH = 64598,
SPELL_PHASE_PUNCH = 64412,
SPELL_QUANTUM_STRIKE = 64395,
H_SPELL_QUANTUM_STRIKE = 64592,
SPELL_BLACK_HOLE_EXPLOSION = 64122,
SPELL_ARCANE_BARAGE = 64599,
H_SPELL_ARCANE_BARAGE = 64607
};
enum Creatures
{
CREATURE_COLLAPSING_STAR = 32955,
CREATURE_BLACK_HOLE = 32953,
CREATURE_LIVING_CONSTELLATION = 33052,
CREATURE_DARK_MATTER = 33089
};
enum Yells
{
SAY_AGGRO = -1603000,
SAY_SLAY_1 = -1603001,
SAY_SLAY_2 = -1603002,
SAY_ENGADED_FOR_FIRTS_TIME = -1603003,
SAY_PHASE_2 = -1603004,
SAY_SUMMON_COLLAPSING_STAR = -1603005,
SAY_DEATH_1 = -1603006,
SAY_DEATH_2 = -1603007,
SAY_DEATH_3 = -1603008,
SAY_DEATH_4 = -1603009,
SAY_DEATH_5 = -1603010,
SAY_BERSERK = -1603011,
SAY_BIG_BANG_1 = -1603012,
SAY_BIG_BANG_2 = -1603013,
SAY_TIMER_1 = -1603014,
SAY_TIMER_2 = -1603015,
SAY_TIMER_3 = -1603016,
SAY_SUMMON_1 = -1603017,
SAY_SUMMON_2 = -1603018,
SAY_SUMMON_3 = -1603019,
};
class boss_algalon : public CreatureScript
{
public:
boss_algalon() : CreatureScript("boss_algalon") { }
CreatureAI* GetAI(Creature* creature) const
{
return GetUlduarAI<boss_algalonAI>(creature);
}
struct boss_algalonAI : public ScriptedAI
{
boss_algalonAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
Summon = false; // not in reset. intro speech done only once.
}
InstanceScript* instance;
std::list<uint64> m_lCollapsingStarGUIDList;
uint32 Phase;
uint32 Ascend_Timer;
uint32 Berserk_Timer;
uint32 BigBang_Timer;
uint32 CosmicSmash_Timer;
uint32 PhasePunch_Timer;
uint32 QuantumStrike_Timer;
uint32 CollapsingStar_Timer;
uint32 uiPhase_timer;
uint32 uiStep;
uint64 BlackHoleGUID;
bool Enrage;
bool Summon;
void EnterCombat(Unit* who)
{
if (Summon)
{
DoScriptText(SAY_AGGRO, me);
me->InterruptSpell(CURRENT_CHANNELED_SPELL);
DoZoneInCombat(who->ToCreature());
}
else
{
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->SetReactState(REACT_PASSIVE);
uiStep = 1;
}
if (instance)
instance->SetData(BOSS_ALGALON, IN_PROGRESS);
}
void KilledUnit(Unit* /*victim*/)
{
DoScriptText(RAND(SAY_SLAY_1, SAY_SLAY_2), me);
}
void Reset()
{
Phase = 1;
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
if (instance)
instance->SetData(BOSS_ALGALON, NOT_STARTED);
BlackHoleGUID = 0;
uiPhase_timer = 0;
Ascend_Timer = 480000; //8 minutes
QuantumStrike_Timer = urand(4000, 14000);
Berserk_Timer = 360000; //6 minutes
CollapsingStar_Timer = urand(15000, 20000); //Spawns between 15 to 20 seconds
BigBang_Timer = 90000;
PhasePunch_Timer = 8000;
CosmicSmash_Timer = urand(30000, 60000);
Enrage = false;
}
void JumpToNextStep(uint32 uiTimer)
{
uiPhase_timer = uiTimer;
++uiStep;
}
void DespawnCollapsingStar()
{
if (m_lCollapsingStarGUIDList.empty())
return;
for (std::list<uint64>::const_iterator itr = m_lCollapsingStarGUIDList.begin(); itr != m_lCollapsingStarGUIDList.end(); ++itr)
{
if (Creature* temp = Unit::GetCreature(*me, *itr))
{
if (temp->isAlive())
temp->DespawnOrUnsummon();
}
}
m_lCollapsingStarGUIDList.clear();
}
void JustSummoned(Creature* summoned)
{
if (summoned->GetEntry() == CREATURE_COLLAPSING_STAR)
{
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0);
if (me->getVictim())
summoned->AI()->AttackStart(target ? target : me->getVictim());
m_lCollapsingStarGUIDList.push_back(summoned->GetGUID());
}
}
void SummonCollapsingStar(Unit* target)
{
DoScriptText(SAY_SUMMON_COLLAPSING_STAR, me);
me->SummonCreature(CREATURE_COLLAPSING_STAR, target->GetPositionX()+15.0f, target->GetPositionY()+15.0f, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 100000);
me->SummonCreature(CREATURE_BLACK_HOLE, target->GetPositionX()+15.0f, target->GetPositionY()+15.0f, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 27000);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (Phase == 1 && HealthBelowPct(20))
{
Phase = 2;
DoScriptText(SAY_PHASE_2, me);
}
if (HealthBelowPct(2))
{
me->SummonGameObject(GAMEOBJECT_GIVE_OF_THE_OBSERVER, 1634.258667f, -295.101166f, 417.321381f, 0, 0, 0, 0, 0, 0);
// All of them. or random?
DoScriptText(SAY_DEATH_1, me);
DoScriptText(SAY_DEATH_2, me);
DoScriptText(SAY_DEATH_3, me);
DoScriptText(SAY_DEATH_4, me);
DoScriptText(SAY_DEATH_5, me);
me->DisappearAndDie();
if (instance)
instance->SetData(BOSS_ALGALON, DONE);
return;
}
if (Phase == 1)
{
if (!Summon)
{
if (uiPhase_timer <= diff)
{
switch (uiStep)
{
case 1:
DoScriptText(SAY_SUMMON_1, me);
JumpToNextStep(3000);
break;
case 2:
DoScriptText(SAY_SUMMON_2, me);
JumpToNextStep(3000);
break;
case 3:
DoScriptText(SAY_SUMMON_3, me);
JumpToNextStep(3000);
break;
case 4:
DoScriptText(SAY_ENGADED_FOR_FIRTS_TIME, me);
JumpToNextStep(3000);
break;
case 5:
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->SetReactState(REACT_AGGRESSIVE);
Summon = true;
break;
}
} else uiPhase_timer -= diff;
return;
}
if (QuantumStrike_Timer <= diff)
{
DoCast(me->getVictim(), RAID_MODE(SPELL_QUANTUM_STRIKE, H_SPELL_QUANTUM_STRIKE), true);
QuantumStrike_Timer = urand(4000, 14000);
} else QuantumStrike_Timer -= diff;
if (BigBang_Timer <= diff)
{
DoScriptText(RAND(SAY_BIG_BANG_1, SAY_BIG_BANG_2), me);
DoCast(me->getVictim(), RAID_MODE(SPELL_BIG_BANG, H_SPELL_BIG_BANG), true);
BigBang_Timer = 90000;
} else BigBang_Timer -= diff;
if (Ascend_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_ASCEND, true);
Ascend_Timer = 480000;
} else Ascend_Timer -= diff;
if (PhasePunch_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_PHASE_PUNCH, true);
PhasePunch_Timer = 8000;
} else PhasePunch_Timer -= diff;
if (CosmicSmash_Timer <= diff)
{
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), RAID_MODE(SPELL_COSMIC_SMASH, H_SPELL_COSMIC_SMASH), true);
CosmicSmash_Timer = urand(30000, 60000);
} else CosmicSmash_Timer -= diff;
if (Berserk_Timer <= diff)
{
DoScriptText(SAY_BERSERK, me);
DoCast(me->getVictim(), SPELL_BERSERK, true);
Berserk_Timer = 360000;
} else Berserk_Timer -= diff;
DoMeleeAttackIfReady();
EnterEvadeIfOutOfCombatArea(diff);
}
if (Phase == 2)
{
if (Enrage)
{
if (Ascend_Timer <= diff)
{
DoCast(me, SPELL_ASCEND);
DoScriptText(SAY_BERSERK, me);
Ascend_Timer = urand(360000, 365000);
Enrage = false;
} else Ascend_Timer -= diff;
}
}
DoMeleeAttackIfReady();
}
};
};
//Collapsing Star
class mob_collapsing_star : public CreatureScript
{
public:
mob_collapsing_star() : CreatureScript("mob_collapsing_star") { }
CreatureAI* GetAI(Creature* creature) const
{
return new mob_collapsing_starAI(creature);
}
struct mob_collapsing_starAI : public ScriptedAI
{
mob_collapsing_starAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
}
InstanceScript* instance;
uint32 BlackHoleExplosion_Timer;
void Reset()
{
BlackHoleExplosion_Timer = 0;
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (BlackHoleExplosion_Timer <= diff)
{
me->CastSpell(me, SPELL_BLACK_HOLE_EXPLOSION, false);
BlackHoleExplosion_Timer = 0;
} else BlackHoleExplosion_Timer -= diff;
}
};
};
void AddSC_boss_Algalon()
{
new boss_algalon();
new mob_collapsing_star();
}
File diff suppressed because it is too large Load Diff
@@ -947,13 +947,19 @@ class spell_xt002_tympanic_tantrum : public SpellScriptLoader
void FilterTargets(std::list<Unit*>& unitList)
{
unitList.remove_if (PlayerOrPetCheck());
unitList.remove_if(PlayerOrPetCheck());
}
void RecalculateDamage()
{
SetHitDamage(GetHitUnit()->CountPctFromMaxHealth(GetHitDamage()));
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_xt002_tympanic_tantrum_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_xt002_tympanic_tantrum_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnHit += SpellHitFn(spell_xt002_tympanic_tantrum_SpellScript::RecalculateDamage);
}
};
@@ -22,9 +22,14 @@
static DoorData const doorData[] =
{
{ GO_LEVIATHAN_DOOR, BOSS_LEVIATHAN, DOOR_TYPE_ROOM, BOUNDARY_S },
{ GO_XT_002_DOOR, BOSS_XT002, DOOR_TYPE_ROOM, BOUNDARY_S },
{ 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE },
{GO_LEVIATHAN_DOOR, BOSS_LEVIATHAN, DOOR_TYPE_ROOM, BOUNDARY_S },
{GO_XT_002_DOOR, BOSS_XT002, DOOR_TYPE_ROOM, BOUNDARY_S },
{GO_DOODAD_UL_SIGILDOOR_03, BOSS_ALGALON, DOOR_TYPE_ROOM, BOUNDARY_W },
{GO_DOODAD_UL_UNIVERSEFLOOR_01, BOSS_ALGALON, DOOR_TYPE_ROOM, BOUNDARY_NONE },
{GO_DOODAD_UL_UNIVERSEFLOOR_02, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_NONE },
{GO_DOODAD_UL_UNIVERSEGLOBE01, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_NONE },
{GO_DOODAD_UL_ULDUAR_TRAPDOOR_03, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_NONE },
{0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE },
};
class instance_ulduar : public InstanceMapScript
@@ -36,7 +41,6 @@ class instance_ulduar : public InstanceMapScript
{
instance_ulduar_InstanceMapScript(InstanceMap* map) : InstanceScript(map) { }
uint32 Encounter[MAX_ENCOUNTER];
std::string m_strInstData;
// Creatures
@@ -72,6 +76,12 @@ class instance_ulduar : public InstanceMapScript
uint64 HodirDoorGUID;
uint64 HodirIceDoorGUID;
uint64 ArchivumDoorGUID;
uint64 AlgalonSigilDoorGUID[3];
uint64 AlgalonFloorGUID[2];
uint64 AlgalonUniverseGUID;
uint64 AlgalonTrapdoorGUID;
uint64 BrannBronzebeardAlgGUID;
uint64 GiftOfTheObserverGUID;
// Miscellaneous
uint32 TeamInInstance;
@@ -111,35 +121,49 @@ class instance_ulduar : public InstanceMapScript
HodirDoorGUID = 0;
HodirIceDoorGUID = 0;
ArchivumDoorGUID = 0;
AlgalonUniverseGUID = 0;
AlgalonTrapdoorGUID = 0;
BrannBronzebeardAlgGUID = 0;
GiftOfTheObserverGUID = 0;
_algalonTimer = 61;
_maxArmorItemLevel = 0;
_maxWeaponItemLevel = 0;
TeamInInstance = 0;
HodirRareCacheData = 0;
ColossusData = 0;
elderCount = 0;
conSpeedAtory = false;
Unbroken = true;
_summonAlgalon = false;
memset(Encounter, 0, sizeof(Encounter));
memset(AlgalonSigilDoorGUID, 0, sizeof(AlgalonSigilDoorGUID));
memset(AlgalonFloorGUID, 0, sizeof(AlgalonFloorGUID));
memset(XTToyPileGUIDs, 0, sizeof(XTToyPileGUIDs));
memset(AssemblyGUIDs, 0, sizeof(AssemblyGUIDs));
memset(RazorHarpoonGUIDs, 0, sizeof(RazorHarpoonGUIDs));
memset(KeeperGUIDs, 0, sizeof(KeeperGUIDs));
}
bool IsEncounterInProgress() const
void FillInitialWorldStates(WorldPacket& packet)
{
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
{
if (Encounter[i] == IN_PROGRESS)
return true;
}
return false;
packet << uint32(WORLD_STATE_ALGALON_TIMER_ENABLED) << uint32(_algalonTimer && _algalonTimer <= 60);
packet << uint32(WORLD_STATE_ALGALON_DESPAWN_TIMER) << uint32(std::min<uint32>(_algalonTimer, 60));
}
void OnPlayerEnter(Player* player)
{
if (!TeamInInstance)
TeamInInstance = player->GetTeam();
if (_summonAlgalon)
{
_summonAlgalon = false;
TempSummon* algalon = instance->SummonCreature(NPC_ALGALON, AlgalonLandPos);
if (_algalonTimer && _algalonTimer <= 60)
algalon->AI()->DoAction(ACTION_INIT_ALGALON);
else
algalon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
}
}
void OnCreatureCreate(Creature* creature)
@@ -267,9 +291,32 @@ class instance_ulduar : public InstanceMapScript
if (TeamInInstance == HORDE)
creature->UpdateEntry(NPC_BATTLE_PRIEST_GINA, HORDE);
break;
case NPC_BRANN_BRONZBEARD_ALG:
BrannBronzebeardAlgGUID = creature->GetGUID();
break;
//! These creatures are summoned by something else than Algalon
//! but need to be controlled/despawned by him - so they need to be
//! registered in his summon list
case NPC_ALGALON_VOID_ZONE_VISUAL_STALKER:
case NPC_ALGALON_STALKER_ASTEROID_TARGET_01:
case NPC_ALGALON_STALKER_ASTEROID_TARGET_02:
case NPC_UNLEASHED_DARK_MATTER:
if (Creature* algalon = instance->GetCreature(AlgalonGUID))
algalon->AI()->JustSummoned(creature);
break;
}
}
}
void OnCreatureRemove(Creature* creature)
{
switch (creature->GetEntry())
{
case NPC_BRANN_BRONZBEARD_ALG:
if (BrannBronzebeardAlgGUID == creature->GetGUID())
BrannBronzebeardAlgGUID = 0;
break;
}
}
void OnGameObjectCreate(GameObject* gameObject)
{
@@ -340,6 +387,45 @@ class instance_ulduar : public InstanceMapScript
if (GetBossState(BOSS_ASSEMBLY_OF_IRON) != DONE)
HandleGameObject(ArchivumDoorGUID, false);
break;
case GO_CELESTIAL_PLANETARIUM_ACCESS_10:
case GO_CELESTIAL_PLANETARIUM_ACCESS_25:
if (_algalonSummoned)
gameObject->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE);
break;
case GO_DOODAD_UL_SIGILDOOR_01:
AlgalonSigilDoorGUID[0] = gameObject->GetGUID();
if (_algalonSummoned)
gameObject->SetGoState(GO_STATE_ACTIVE);
break;
case GO_DOODAD_UL_SIGILDOOR_02:
AlgalonSigilDoorGUID[1] = gameObject->GetGUID();
if (_algalonSummoned)
gameObject->SetGoState(GO_STATE_ACTIVE);
break;
case GO_DOODAD_UL_SIGILDOOR_03:
AlgalonSigilDoorGUID[2] = gameObject->GetGUID();
AddDoor(gameObject, true);
break;
case GO_DOODAD_UL_UNIVERSEFLOOR_01:
AlgalonFloorGUID[0] = gameObject->GetGUID();
AddDoor(gameObject, true);
break;
case GO_DOODAD_UL_UNIVERSEFLOOR_02:
AlgalonFloorGUID[1] = gameObject->GetGUID();
AddDoor(gameObject, true);
break;
case GO_DOODAD_UL_UNIVERSEGLOBE01:
AlgalonUniverseGUID = gameObject->GetGUID();
AddDoor(gameObject, true);
break;
case GO_DOODAD_UL_ULDUAR_TRAPDOOR_03:
AlgalonTrapdoorGUID = gameObject->GetGUID();
AddDoor(gameObject, true);
break;
case GO_GIFT_OF_THE_OBSERVER_10:
case GO_GIFT_OF_THE_OBSERVER_25:
GiftOfTheObserverGUID = gameObject->GetGUID();
break;
}
}
@@ -348,10 +434,14 @@ class instance_ulduar : public InstanceMapScript
switch (gameObject->GetEntry())
{
case GO_LEVIATHAN_DOOR:
case GO_XT_002_DOOR:
case GO_DOODAD_UL_SIGILDOOR_03:
case GO_DOODAD_UL_UNIVERSEFLOOR_01:
case GO_DOODAD_UL_UNIVERSEFLOOR_02:
case GO_DOODAD_UL_UNIVERSEGLOBE01:
case GO_DOODAD_UL_ULDUAR_TRAPDOOR_03:
AddDoor(gameObject, false);
break;
case GO_XT_002_DOOR:
AddDoor(gameObject, false);
default:
break;
}
@@ -389,6 +479,7 @@ class instance_ulduar : public InstanceMapScript
// Flame Leviathan's Tower Event triggers
Creature* FlameLeviathan = instance->GetCreature(LeviathanGUID);
if (FlameLeviathan && FlameLeviathan->isAlive()) // No leviathan, no event triggering ;)
{
switch (eventId)
{
case EVENT_TOWER_OF_STORM_DESTROYED:
@@ -404,6 +495,7 @@ class instance_ulduar : public InstanceMapScript
FlameLeviathan->AI()->DoAction(ACTION_TOWER_OF_LIFE_DESTROYED);
break;
}
}
}
@@ -464,6 +556,52 @@ class instance_ulduar : public InstanceMapScript
if (GameObject* gameObject = instance->GetGameObject(ThorimChestGUID))
gameObject->SetRespawnTime(gameObject->GetRespawnDelay());
break;
case BOSS_ALGALON:
if (state == DONE)
{
_events.CancelEvent(EVENT_UPDATE_ALGALON_TIMER);
_events.CancelEvent(EVENT_DESPAWN_ALGALON);
DoUpdateWorldState(WORLD_STATE_ALGALON_TIMER_ENABLED, 0);
_algalonTimer = 61;
if (GameObject* gameObject = instance->GetGameObject(GiftOfTheObserverGUID))
gameObject->SetRespawnTime(gameObject->GetRespawnDelay());
// get item level (recheck weapons)
Map::PlayerList const& players = instance->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
if (Player* player = itr->getSource())
for (uint8 slot = EQUIPMENT_SLOT_MAINHAND; slot <= EQUIPMENT_SLOT_RANGED; ++slot)
if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
if (item->GetTemplate()->ItemLevel > _maxWeaponItemLevel)
_maxWeaponItemLevel = item->GetTemplate()->ItemLevel;
}
else if (state == IN_PROGRESS)
{
// get item level (armor cannot be swapped in combat)
Map::PlayerList const& players = instance->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
{
if (Player* player = itr->getSource())
{
for (uint8 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; ++slot)
{
if (slot == EQUIPMENT_SLOT_TABARD || slot == EQUIPMENT_SLOT_BODY)
continue;
if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
{
if (slot >= EQUIPMENT_SLOT_MAINHAND && slot <= EQUIPMENT_SLOT_RANGED)
{
if (item->GetTemplate()->ItemLevel > _maxWeaponItemLevel)
_maxWeaponItemLevel = item->GetTemplate()->ItemLevel;
}
else if (item->GetTemplate()->ItemLevel > _maxArmorItemLevel)
_maxArmorItemLevel = item->GetTemplate()->ItemLevel;
}
}
}
}
}
break;
}
return true;
@@ -496,6 +634,16 @@ class instance_ulduar : public InstanceMapScript
case DATA_UNBROKEN:
Unbroken = bool(data);
break;
case EVENT_DESPAWN_ALGALON:
DoUpdateWorldState(WORLD_STATE_ALGALON_TIMER_ENABLED, 1);
DoUpdateWorldState(WORLD_STATE_ALGALON_DESPAWN_TIMER, 60);
_algalonTimer = 60;
_events.ScheduleEvent(EVENT_DESPAWN_ALGALON, 3600000);
_events.ScheduleEvent(EVENT_UPDATE_ALGALON_TIMER, 60000);
break;
case DATA_ALGALON_SUMMON_STATE:
_algalonSummoned = true;
break;
default:
break;
}
@@ -570,6 +718,22 @@ class instance_ulduar : public InstanceMapScript
return KeeperGUIDs[1];
case BOSS_STONEBARK:
return KeeperGUIDs[2];
case DATA_SIGILDOOR_01:
return AlgalonSigilDoorGUID[0];
case DATA_SIGILDOOR_02:
return AlgalonSigilDoorGUID[1];
case DATA_SIGILDOOR_03:
return AlgalonSigilDoorGUID[2];
case DATA_UNIVERSE_FLOOR_01:
return AlgalonFloorGUID[0];
case DATA_UNIVERSE_FLOOR_02:
return AlgalonFloorGUID[1];
case DATA_UNIVERSE_GLOBE:
return AlgalonUniverseGUID;
case DATA_ALGALON_TRAPDOOR:
return AlgalonTrapdoorGUID;
case DATA_BRANN_BRONZEBEARD_ALG:
return BrannBronzebeardAlgGUID;
}
return 0;
@@ -592,12 +756,23 @@ class instance_ulduar : public InstanceMapScript
return 0;
}
bool CheckAchievementCriteriaMeet(uint32 criteriaId, Player const* , Unit const* /* = NULL */, uint32 /* = 0 */)
{
switch (criteriaId)
{
case CRITERIA_HERALD_OF_TITANS:
return _maxArmorItemLevel <= MAX_HERALD_ARMOR_ITEMLEVEL && _maxWeaponItemLevel <= MAX_HERALD_WEAPON_ITEMLEVEL;
}
return false;
}
std::string GetSaveData()
{
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
saveStream << "U U " << GetBossSaveData() << GetData(DATA_COLOSSUS);
saveStream << "U U " << GetBossSaveData() << GetData(DATA_COLOSSUS) << ' ' << _algalonTimer << ' ' << (_algalonSummoned ? 1 : 0);
OUT_SAVE_INST_DATA_COMPLETE;
return saveStream.str();
@@ -627,15 +802,68 @@ class instance_ulduar : public InstanceMapScript
if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
tmpState = NOT_STARTED;
if (i == DATA_COLOSSUS)
SetData(i, tmpState);
else
SetBossState(i, EncounterState(tmpState));
SetBossState(i, EncounterState(tmpState));
}
uint32 tempState;
loadStream >> tempState;
if (tempState == IN_PROGRESS || tempState > SPECIAL)
tempState = NOT_STARTED;
SetData(DATA_COLOSSUS, tempState);
loadStream >> _algalonTimer;
loadStream >> tempState;
_algalonSummoned = tempState != 0;
if (_algalonSummoned && GetBossState(BOSS_ALGALON) != DONE)
{
_summonAlgalon = true;
if (_algalonTimer && _algalonTimer <= 60)
{
_events.ScheduleEvent(EVENT_UPDATE_ALGALON_TIMER, 60000);
DoUpdateWorldState(WORLD_STATE_ALGALON_TIMER_ENABLED, 1);
DoUpdateWorldState(WORLD_STATE_ALGALON_DESPAWN_TIMER, _algalonTimer);
}
}
}
OUT_LOAD_INST_DATA_COMPLETE;
}
void Update(uint32 diff)
{
if (_events.Empty())
return;
_events.Update(diff);
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_UPDATE_ALGALON_TIMER:
SaveToDB();
DoUpdateWorldState(WORLD_STATE_ALGALON_DESPAWN_TIMER, --_algalonTimer);
if (_algalonTimer)
_events.ScheduleEvent(EVENT_UPDATE_ALGALON_TIMER, 60000);
else
{
DoUpdateWorldState(WORLD_STATE_ALGALON_TIMER_ENABLED, 0);
_events.CancelEvent(EVENT_UPDATE_ALGALON_TIMER);
if (Creature* algalon = instance->GetCreature(AlgalonGUID))
algalon->AI()->DoAction(EVENT_DESPAWN_ALGALON);
}
break;
}
}
}
private:
EventMap _events;
uint32 _algalonTimer;
bool _summonAlgalon;
bool _algalonSummoned;
uint32 _maxArmorItemLevel;
uint32 _maxWeaponItemLevel;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const
@@ -21,6 +21,8 @@
#include "ObjectMgr.h"
#define UlduarScriptName "instance_ulduar"
extern Position const AlgalonLandPos;
enum UlduarBosses
{
MAX_ENCOUNTER = 20,
@@ -50,98 +52,124 @@ enum UlduarBosses
enum UlduarNPCs
{
// General
NPC_LEVIATHAN = 33113,
NPC_SALVAGED_DEMOLISHER = 33109,
NPC_SALVAGED_SIEGE_ENGINE = 33060,
NPC_IGNIS = 33118,
NPC_RAZORSCALE = 33186,
NPC_RAZORSCALE_CONTROLLER = 33233,
NPC_STEELFORGED_DEFFENDER = 33236,
NPC_EXPEDITION_COMMANDER = 33210,
NPC_XT002 = 33293,
NPC_XT_TOY_PILE = 33337,
NPC_STEELBREAKER = 32867,
NPC_MOLGEIM = 32927,
NPC_BRUNDIR = 32857,
NPC_KOLOGARN = 32930,
NPC_FOCUSED_EYEBEAM = 33632,
NPC_FOCUSED_EYEBEAM_RIGHT = 33802,
NPC_LEFT_ARM = 32933,
NPC_RIGHT_ARM = 32934,
NPC_RUBBLE = 33768,
NPC_AURIAYA = 33515,
NPC_MIMIRON = 33350,
NPC_HODIR = 32845,
NPC_THORIM = 32865,
NPC_FREYA = 32906,
NPC_VEZAX = 33271,
NPC_YOGGSARON = 33288,
NPC_ALGALON = 32871,
NPC_LEVIATHAN = 33113,
NPC_SALVAGED_DEMOLISHER = 33109,
NPC_SALVAGED_SIEGE_ENGINE = 33060,
NPC_IGNIS = 33118,
NPC_RAZORSCALE = 33186,
NPC_RAZORSCALE_CONTROLLER = 33233,
NPC_STEELFORGED_DEFFENDER = 33236,
NPC_EXPEDITION_COMMANDER = 33210,
NPC_XT002 = 33293,
NPC_XT_TOY_PILE = 33337,
NPC_STEELBREAKER = 32867,
NPC_MOLGEIM = 32927,
NPC_BRUNDIR = 32857,
NPC_KOLOGARN = 32930,
NPC_FOCUSED_EYEBEAM = 33632,
NPC_FOCUSED_EYEBEAM_RIGHT = 33802,
NPC_LEFT_ARM = 32933,
NPC_RIGHT_ARM = 32934,
NPC_RUBBLE = 33768,
NPC_AURIAYA = 33515,
NPC_MIMIRON = 33350,
NPC_HODIR = 32845,
NPC_THORIM = 32865,
NPC_FREYA = 32906,
NPC_VEZAX = 33271,
NPC_YOGGSARON = 33288,
NPC_ALGALON = 32871,
// Mimiron
NPC_LEVIATHAN_MKII = 33432,
NPC_VX_001 = 33651,
NPC_AERIAL_COMMAND_UNIT = 33670,
NPC_LEVIATHAN_MKII = 33432,
NPC_VX_001 = 33651,
NPC_AERIAL_COMMAND_UNIT = 33670,
// Freya's Keepers
NPC_IRONBRANCH = 32913,
NPC_BRIGHTLEAF = 32915,
NPC_STONEBARK = 32914,
NPC_IRONBRANCH = 32913,
NPC_BRIGHTLEAF = 32915,
NPC_STONEBARK = 32914,
// Hodir's Helper NPCs
NPC_TOR_GREYCLOUD = 32941,
NPC_KAR_GREYCLOUD = 33333,
NPC_EIVI_NIGHTFEATHER = 33325,
NPC_ELLIE_NIGHTFEATHER = 32901,
NPC_SPIRITWALKER_TARA = 33332,
NPC_SPIRITWALKER_YONA = 32950,
NPC_ELEMENTALIST_MAHFUUN = 33328,
NPC_ELEMENTALIST_AVUUN = 32900,
NPC_AMIRA_BLAZEWEAVER = 33331,
NPC_VEESHA_BLAZEWEAVER = 32946,
NPC_MISSY_FLAMECUFFS = 32893,
NPC_SISSY_FLAMECUFFS = 33327,
NPC_BATTLE_PRIEST_ELIZA = 32948,
NPC_BATTLE_PRIEST_GINA = 33330,
NPC_FIELD_MEDIC_PENNY = 32897,
NPC_FIELD_MEDIC_JESSI = 33326,
NPC_TOR_GREYCLOUD = 32941,
NPC_KAR_GREYCLOUD = 33333,
NPC_EIVI_NIGHTFEATHER = 33325,
NPC_ELLIE_NIGHTFEATHER = 32901,
NPC_SPIRITWALKER_TARA = 33332,
NPC_SPIRITWALKER_YONA = 32950,
NPC_ELEMENTALIST_MAHFUUN = 33328,
NPC_ELEMENTALIST_AVUUN = 32900,
NPC_AMIRA_BLAZEWEAVER = 33331,
NPC_VEESHA_BLAZEWEAVER = 32946,
NPC_MISSY_FLAMECUFFS = 32893,
NPC_SISSY_FLAMECUFFS = 33327,
NPC_BATTLE_PRIEST_ELIZA = 32948,
NPC_BATTLE_PRIEST_GINA = 33330,
NPC_FIELD_MEDIC_PENNY = 32897,
NPC_FIELD_MEDIC_JESSI = 33326,
// Freya's trash NPCs
NPC_CORRUPTED_SERVITOR = 33354,
NPC_MISGUIDED_NYMPH = 33355,
NPC_GUARDIAN_LASHER = 33430,
NPC_FOREST_SWARMER = 33431,
NPC_MANGROVE_ENT = 33525,
NPC_IRONROOT_LASHER = 33526,
NPC_NATURES_BLADE = 33527,
NPC_GUARDIAN_OF_LIFE = 33528,
NPC_CORRUPTED_SERVITOR = 33354,
NPC_MISGUIDED_NYMPH = 33355,
NPC_GUARDIAN_LASHER = 33430,
NPC_FOREST_SWARMER = 33431,
NPC_MANGROVE_ENT = 33525,
NPC_IRONROOT_LASHER = 33526,
NPC_NATURES_BLADE = 33527,
NPC_GUARDIAN_OF_LIFE = 33528,
// Algalon the Observer
NPC_BRANN_BRONZBEARD_ALG = 34064,
NPC_AZEROTH = 34246,
NPC_LIVING_CONSTELLATION = 33052,
NPC_ALGALON_STALKER = 33086,
NPC_COLLAPSING_STAR = 32955,
NPC_BLACK_HOLE = 32953,
NPC_WORM_HOLE = 34099,
NPC_ALGALON_VOID_ZONE_VISUAL_STALKER = 34100,
NPC_ALGALON_STALKER_ASTEROID_TARGET_01 = 33104,
NPC_ALGALON_STALKER_ASTEROID_TARGET_02 = 33105,
NPC_UNLEASHED_DARK_MATTER = 34097,
};
enum UlduarGameObjects
{
GO_KOLOGARN_CHEST_HERO = 195047,
GO_KOLOGARN_CHEST = 195046,
GO_KOLOGARN_BRIDGE = 194232,
GO_KOLOGARN_DOOR = 194553,
GO_THORIM_CHEST_HERO = 194315,
GO_THORIM_CHEST = 194314,
GO_HODIR_RARE_CACHE_OF_WINTER = 194200,
GO_HODIR_RARE_CACHE_OF_WINTER_HERO = 194201,
GO_HODIR_CHEST_HERO = 194308,
GO_HODIR_CHEST = 194307,
GO_LEVIATHAN_DOOR = 194905,
GO_LEVIATHAN_GATE = 194630,
GO_XT_002_DOOR = 194631,
GO_VEZAX_DOOR = 194750,
GO_MOLE_MACHINE = 194316,
GO_RAZOR_HARPOON_1 = 194542,
GO_RAZOR_HARPOON_2 = 194541,
GO_RAZOR_HARPOON_3 = 194543,
GO_RAZOR_HARPOON_4 = 194519,
GO_RAZOR_BROKEN_HARPOON = 194565,
GO_HODIR_DOOR = 194634,
GO_HODIR_ICE_DOOR = 194441,
GO_ARCHIVUM_DOOR = 194556,
GO_KOLOGARN_CHEST_HERO = 195047,
GO_KOLOGARN_CHEST = 195046,
GO_KOLOGARN_BRIDGE = 194232,
GO_KOLOGARN_DOOR = 194553,
GO_THORIM_CHEST_HERO = 194315,
GO_THORIM_CHEST = 194314,
GO_HODIR_RARE_CACHE_OF_WINTER = 194200,
GO_HODIR_RARE_CACHE_OF_WINTER_HERO = 194201,
GO_HODIR_CHEST_HERO = 194308,
GO_HODIR_CHEST = 194307,
GO_LEVIATHAN_DOOR = 194905,
GO_LEVIATHAN_GATE = 194630,
GO_XT_002_DOOR = 194631,
GO_VEZAX_DOOR = 194750,
GO_MOLE_MACHINE = 194316,
GO_RAZOR_HARPOON_1 = 194542,
GO_RAZOR_HARPOON_2 = 194541,
GO_RAZOR_HARPOON_3 = 194543,
GO_RAZOR_HARPOON_4 = 194519,
GO_RAZOR_BROKEN_HARPOON = 194565,
GO_HODIR_DOOR = 194634,
GO_HODIR_ICE_DOOR = 194441,
GO_ARCHIVUM_DOOR = 194556,
// Algalon the Observer
GO_CELESTIAL_PLANETARIUM_ACCESS_10 = 194628,
GO_CELESTIAL_PLANETARIUM_ACCESS_25 = 194752,
GO_DOODAD_UL_SIGILDOOR_01 = 194767,
GO_DOODAD_UL_SIGILDOOR_02 = 194911,
GO_DOODAD_UL_SIGILDOOR_03 = 194910,
GO_DOODAD_UL_UNIVERSEFLOOR_01 = 194715,
GO_DOODAD_UL_UNIVERSEFLOOR_02 = 194716,
GO_DOODAD_UL_UNIVERSEGLOBE01 = 194148,
GO_DOODAD_UL_ULDUAR_TRAPDOOR_03 = 194253,
GO_GIFT_OF_THE_OBSERVER_10 = 194821,
GO_GIFT_OF_THE_OBSERVER_25 = 194822,
};
enum LeviathanData
@@ -161,6 +189,7 @@ enum UlduarAchievementCriteriaIds
{
CRITERIA_CON_SPEED_ATORY = 21597,
CRITERIA_DISARMED = 21687,
CRITERIA_HERALD_OF_TITANS = 10678,
};
enum UlduarData
@@ -180,12 +209,38 @@ enum UlduarData
// Hodir
DATA_HODIR_RARE_CACHE,
// Algalon the Observer
DATA_ALGALON_SUMMON_STATE,
DATA_SIGILDOOR_01,
DATA_SIGILDOOR_02,
DATA_SIGILDOOR_03,
DATA_UNIVERSE_FLOOR_01,
DATA_UNIVERSE_FLOOR_02,
DATA_UNIVERSE_GLOBE,
DATA_ALGALON_TRAPDOOR,
DATA_BRANN_BRONZEBEARD_ALG,
};
enum UlduarWorldStates
{
WORLD_STATE_ALGALON_DESPAWN_TIMER = 4131,
WORLD_STATE_ALGALON_TIMER_ENABLED = 4132,
};
enum UlduarAchievementData
{
// FL Achievement boolean
DATA_UNBROKEN = 29052906, // 2905, 2906 are achievement IDs,
MAX_HERALD_ARMOR_ITEMLEVEL = 226,
MAX_HERALD_WEAPON_ITEMLEVEL = 232,
};
enum UlduarEvents
{
EVENT_DESPAWN_ALGALON = 1,
EVENT_UPDATE_ALGALON_TIMER = 2,
ACTION_INIT_ALGALON = 6,
};
template<class AI>
@@ -199,6 +254,17 @@ CreatureAI* GetUlduarAI(Creature* creature)
return NULL;
}
template<class AI>
GameObjectAI* GetUlduarAI(GameObject* go)
{
if (InstanceMap* instance = go->GetMap()->ToInstanceMap())
if (instance->GetInstanceScript())
if (instance->GetScriptId() == sObjectMgr->GetScriptId(UlduarScriptName))
return new AI(go);
return NULL;
}
class PlayerOrPetCheck
{
public:
@@ -31,15 +31,15 @@ enum Texts
enum Spells
{
SPELL_SHADOWVOLLEY = 32963,
SPELL_SHADOW_VOLLEY = 32963,
SPELL_CLEAVE = 31779,
SPELL_THUNDERCLAP = 36706,
SPELL_VOIDBOLT = 39329,
SPELL_MARKOFKAZZAK = 32960,
SPELL_MARKOFKAZZAK_DAMAGE = 32961,
SPELL_VOID_BOLT = 39329,
SPELL_MARK_OF_KAZZAK = 32960,
SPELL_ENRAGE = 32964,
SPELL_CAPTURESOUL = 32966,
SPELL_TWISTEDREFLECTION = 21063
SPELL_CAPTURE_SOUL = 32966,
SPELL_TWISTED_REFLECTION = 21063,
SPELL_BERSERK = 32965,
};
enum Events
@@ -47,10 +47,11 @@ enum Events
EVENT_SHADOW_VOLLEY = 1,
EVENT_CLEAVE = 2,
EVENT_THUNDERCLAP = 3,
EVENT_VOIDBOLT = 4,
EVENT_VOID_BOLT = 4,
EVENT_MARK_OF_KAZZAK = 5,
EVENT_ENRAGE = 6,
EVENT_TWISTED_REFLECTION = 7
EVENT_TWISTED_REFLECTION = 7,
EVENT_BERSERK = 8
};
class boss_doomlord_kazzak : public CreatureScript
@@ -70,10 +71,11 @@ class boss_doomlord_kazzak : public CreatureScript
_events.ScheduleEvent(EVENT_SHADOW_VOLLEY, urand(6000, 10000));
_events.ScheduleEvent(EVENT_CLEAVE, 7000);
_events.ScheduleEvent(EVENT_THUNDERCLAP, urand(14000, 18000));
_events.ScheduleEvent(EVENT_VOIDBOLT, 30000);
_events.ScheduleEvent(EVENT_VOID_BOLT, 30000);
_events.ScheduleEvent(EVENT_MARK_OF_KAZZAK, 25000);
_events.ScheduleEvent(EVENT_ENRAGE, 60000);
_events.ScheduleEvent(EVENT_TWISTED_REFLECTION, 33000);
_events.ScheduleEvent(EVENT_BERSERK, 180000);
}
void JustRespawned()
@@ -92,7 +94,7 @@ class boss_doomlord_kazzak : public CreatureScript
if (victim->GetTypeId() != TYPEID_PLAYER)
return;
DoCast(me, SPELL_CAPTURESOUL);
DoCast(me, SPELL_CAPTURE_SOUL);
Talk(SAY_KILL);
}
@@ -118,7 +120,7 @@ class boss_doomlord_kazzak : public CreatureScript
switch (eventId)
{
case EVENT_SHADOW_VOLLEY:
DoCastVictim(SPELL_SHADOWVOLLEY);
DoCastVictim(SPELL_SHADOW_VOLLEY);
_events.ScheduleEvent(EVENT_SHADOW_VOLLEY, urand(4000, 6000));
break;
case EVENT_CLEAVE:
@@ -129,13 +131,13 @@ class boss_doomlord_kazzak : public CreatureScript
DoCastVictim(SPELL_THUNDERCLAP);
_events.ScheduleEvent(EVENT_THUNDERCLAP, urand(10000, 14000));
break;
case EVENT_VOIDBOLT:
DoCastVictim(SPELL_VOIDBOLT);
_events.ScheduleEvent(EVENT_VOIDBOLT, urand(15000, 18000));
case EVENT_VOID_BOLT:
DoCastVictim(SPELL_VOID_BOLT);
_events.ScheduleEvent(EVENT_VOID_BOLT, urand(15000, 18000));
break;
case EVENT_MARK_OF_KAZZAK:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
DoCast(target, SPELL_MARKOFKAZZAK);
DoCast(target, SPELL_MARK_OF_KAZZAK);
_events.ScheduleEvent(EVENT_MARK_OF_KAZZAK, 20000);
break;
case EVENT_ENRAGE:
@@ -145,9 +147,12 @@ class boss_doomlord_kazzak : public CreatureScript
break;
case EVENT_TWISTED_REFLECTION:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
DoCast(target, SPELL_TWISTEDREFLECTION);
DoCast(target, SPELL_TWISTED_REFLECTION);
_events.ScheduleEvent(EVENT_TWISTED_REFLECTION, 15000);
break;
case EVENT_BERSERK:
DoCast(me, SPELL_BERSERK);
break;
default:
break;
}
@@ -2618,6 +2618,44 @@ class spell_gen_wg_water : public SpellScriptLoader
}
};
class spell_gen_count_pct_from_max_hp : public SpellScriptLoader
{
public:
spell_gen_count_pct_from_max_hp(char const* name, int32 damagePct = 0) : SpellScriptLoader(name), _damagePct(damagePct) { }
class spell_gen_count_pct_from_max_hp_SpellScript : public SpellScript
{
PrepareSpellScript(spell_gen_count_pct_from_max_hp_SpellScript)
public:
spell_gen_count_pct_from_max_hp_SpellScript(int32 damagePct) : SpellScript(), _damagePct(damagePct) { }
void RecalculateDamage()
{
if (!_damagePct)
_damagePct = GetHitDamage();
SetHitDamage(GetHitUnit()->CountPctFromMaxHealth(_damagePct));
}
void Register()
{
OnHit += SpellHitFn(spell_gen_count_pct_from_max_hp_SpellScript::RecalculateDamage);
}
private:
int32 _damagePct;
};
SpellScript* GetSpellScript() const
{
return new spell_gen_count_pct_from_max_hp_SpellScript(_damagePct);
}
private:
int32 _damagePct;
};
void AddSC_generic_spell_scripts()
{
new spell_gen_absorb0_hitlimit1();
@@ -2669,4 +2707,6 @@ void AddSC_generic_spell_scripts()
new spell_gen_chaos_blast();
new spell_gen_ds_flush_knockback();
new spell_gen_wg_water();
new spell_gen_count_pct_from_max_hp("spell_gen_default_count_pct_from_max_hp");
new spell_gen_count_pct_from_max_hp("spell_gen_50pct_count_pct_from_max_hp", 50);
}
-167
View File
@@ -2529,172 +2529,6 @@ public:
}
};
/*######
## npc_tabard_vendor
######*/
enum
{
QUEST_TRUE_MASTERS_OF_LIGHT = 9737,
QUEST_THE_UNWRITTEN_PROPHECY = 9762,
QUEST_INTO_THE_BREACH = 10259,
QUEST_BATTLE_OF_THE_CRIMSON_WATCH = 10781,
QUEST_SHARDS_OF_AHUNE = 11972,
ACHIEVEMENT_EXPLORE_NORTHREND = 45,
ACHIEVEMENT_TWENTYFIVE_TABARDS = 1021,
ACHIEVEMENT_THE_LOREMASTER_A = 1681,
ACHIEVEMENT_THE_LOREMASTER_H = 1682,
ITEM_TABARD_OF_THE_HAND = 24344,
ITEM_TABARD_OF_THE_BLOOD_KNIGHT = 25549,
ITEM_TABARD_OF_THE_PROTECTOR = 28788,
ITEM_OFFERING_OF_THE_SHATAR = 31408,
ITEM_GREEN_TROPHY_TABARD_OF_THE_ILLIDARI = 31404,
ITEM_PURPLE_TROPHY_TABARD_OF_THE_ILLIDARI = 31405,
ITEM_TABARD_OF_THE_SUMMER_SKIES = 35279,
ITEM_TABARD_OF_THE_SUMMER_FLAMES = 35280,
ITEM_TABARD_OF_THE_ACHIEVER = 40643,
ITEM_LOREMASTERS_COLORS = 43300,
ITEM_TABARD_OF_THE_EXPLORER = 43348,
SPELL_TABARD_OF_THE_BLOOD_KNIGHT = 54974,
SPELL_TABARD_OF_THE_HAND = 54976,
SPELL_GREEN_TROPHY_TABARD_OF_THE_ILLIDARI = 54977,
SPELL_PURPLE_TROPHY_TABARD_OF_THE_ILLIDARI = 54982,
SPELL_TABARD_OF_THE_ACHIEVER = 55006,
SPELL_TABARD_OF_THE_PROTECTOR = 55008,
SPELL_LOREMASTERS_COLORS = 58194,
SPELL_TABARD_OF_THE_EXPLORER = 58224,
SPELL_TABARD_OF_SUMMER_SKIES = 62768,
SPELL_TABARD_OF_SUMMER_FLAMES = 62769
};
#define GOSSIP_LOST_TABARD_OF_BLOOD_KNIGHT "I've lost my Tabard of Blood Knight."
#define GOSSIP_LOST_TABARD_OF_THE_HAND "I've lost my Tabard of the Hand."
#define GOSSIP_LOST_TABARD_OF_THE_PROTECTOR "I've lost my Tabard of the Protector."
#define GOSSIP_LOST_GREEN_TROPHY_TABARD_OF_THE_ILLIDARI "I've lost my Green Trophy Tabard of the Illidari."
#define GOSSIP_LOST_PURPLE_TROPHY_TABARD_OF_THE_ILLIDARI "I've lost my Purple Trophy Tabard of the Illidari."
#define GOSSIP_LOST_TABARD_OF_SUMMER_SKIES "I've lost my Tabard of Summer Skies."
#define GOSSIP_LOST_TABARD_OF_SUMMER_FLAMES "I've lost my Tabard of Summer Flames."
#define GOSSIP_LOST_LOREMASTERS_COLORS "I've lost my Loremaster's Colors."
#define GOSSIP_LOST_TABARD_OF_THE_EXPLORER "I've lost my Tabard of the Explorer."
#define GOSSIP_LOST_TABARD_OF_THE_ACHIEVER "I've lost my Tabard of the Achiever."
class npc_tabard_vendor : public CreatureScript
{
public:
npc_tabard_vendor() : CreatureScript("npc_tabard_vendor") { }
bool OnGossipHello(Player* player, Creature* creature)
{
bool lostBloodKnight = false;
bool lostHand = false;
bool lostProtector = false;
bool lostIllidari = false;
bool lostSummer = false;
//Tabard of the Blood Knight
if (player->GetQuestRewardStatus(QUEST_TRUE_MASTERS_OF_LIGHT) && !player->HasItemCount(ITEM_TABARD_OF_THE_BLOOD_KNIGHT, 1, true))
lostBloodKnight = true;
//Tabard of the Hand
if (player->GetQuestRewardStatus(QUEST_THE_UNWRITTEN_PROPHECY) && !player->HasItemCount(ITEM_TABARD_OF_THE_HAND, 1, true))
lostHand = true;
//Tabard of the Protector
if (player->GetQuestRewardStatus(QUEST_INTO_THE_BREACH) && !player->HasItemCount(ITEM_TABARD_OF_THE_PROTECTOR, 1, true))
lostProtector = true;
//Green Trophy Tabard of the Illidari
//Purple Trophy Tabard of the Illidari
if (player->GetQuestRewardStatus(QUEST_BATTLE_OF_THE_CRIMSON_WATCH) &&
(!player->HasItemCount(ITEM_GREEN_TROPHY_TABARD_OF_THE_ILLIDARI, 1, true) &&
!player->HasItemCount(ITEM_PURPLE_TROPHY_TABARD_OF_THE_ILLIDARI, 1, true) &&
!player->HasItemCount(ITEM_OFFERING_OF_THE_SHATAR, 1, true)))
lostIllidari = true;
//Tabard of Summer Skies
//Tabard of Summer Flames
if (player->GetQuestRewardStatus(QUEST_SHARDS_OF_AHUNE) &&
!player->HasItemCount(ITEM_TABARD_OF_THE_SUMMER_SKIES, 1, true) &&
!player->HasItemCount(ITEM_TABARD_OF_THE_SUMMER_FLAMES, 1, true))
lostSummer = true;
if (lostBloodKnight || lostHand || lostProtector || lostIllidari || lostSummer)
{
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
if (lostBloodKnight)
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_TABARD_OF_BLOOD_KNIGHT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
if (lostHand)
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_TABARD_OF_THE_HAND, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
if (lostProtector)
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_TABARD_OF_THE_PROTECTOR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
if (lostIllidari)
{
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_GREEN_TROPHY_TABARD_OF_THE_ILLIDARI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_PURPLE_TROPHY_TABARD_OF_THE_ILLIDARI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
}
if (lostSummer)
{
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_TABARD_OF_SUMMER_SKIES, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6);
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_TABARD_OF_SUMMER_FLAMES, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7);
}
player->SEND_GOSSIP_MENU(13583, creature->GetGUID());
}
else
player->GetSession()->SendListInventory(creature->GetGUID());
return true;
}
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
{
player->PlayerTalkClass->ClearMenus();
switch (action)
{
case GOSSIP_ACTION_TRADE:
player->GetSession()->SendListInventory(creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF + 1:
player->CLOSE_GOSSIP_MENU();
player->CastSpell(player, SPELL_TABARD_OF_THE_BLOOD_KNIGHT, false);
break;
case GOSSIP_ACTION_INFO_DEF + 2:
player->CLOSE_GOSSIP_MENU();
player->CastSpell(player, SPELL_TABARD_OF_THE_HAND, false);
break;
case GOSSIP_ACTION_INFO_DEF + 3:
player->CLOSE_GOSSIP_MENU();
player->CastSpell(player, SPELL_TABARD_OF_THE_PROTECTOR, false);
break;
case GOSSIP_ACTION_INFO_DEF + 4:
player->CLOSE_GOSSIP_MENU();
player->CastSpell(player, SPELL_GREEN_TROPHY_TABARD_OF_THE_ILLIDARI, false);
break;
case GOSSIP_ACTION_INFO_DEF + 5:
player->CLOSE_GOSSIP_MENU();
player->CastSpell(player, SPELL_PURPLE_TROPHY_TABARD_OF_THE_ILLIDARI, false);
break;
case GOSSIP_ACTION_INFO_DEF + 6:
player->CLOSE_GOSSIP_MENU();
player->CastSpell(player, SPELL_TABARD_OF_SUMMER_SKIES, false);
break;
case GOSSIP_ACTION_INFO_DEF + 7:
player->CLOSE_GOSSIP_MENU();
player->CastSpell(player, SPELL_TABARD_OF_SUMMER_FLAMES, false);
break;
}
return true;
}
};
/*######
## npc_experience
######*/
@@ -3158,7 +2992,6 @@ void AddSC_npcs_special()
new npc_wormhole();
new npc_pet_trainer();
new npc_locksmith();
new npc_tabard_vendor();
new npc_experience();
new npc_fire_elemental();
new npc_earth_elemental();
@@ -195,7 +195,23 @@ BOOL WheatyExceptionReport::_GetWindowsVersion(TCHAR* szVersion, DWORD cntMax)
case VER_PLATFORM_WIN32_NT:
// Test for the specific product family.
if (osvi.dwMajorVersion == 6)
_tcsncat(szVersion, _T("Windows Vista or Windows Server 2008 "), cntMax);
{
#if WINVER < 0x0500
if (osvi.wReserved[1] == VER_NT_WORKSTATION)
#else
if (osvi.wProductType == VER_NT_WORKSTATION)
#endif // WINVER < 0x0500
{
if (osvi.dwMinorVersion == 1)
_tcsncat(szVersion, _T("Windows 7 "), cntMax);
else
_tcsncat(szVersion, _T("Windows Vista "), cntMax);
}
else if (osvi.dwMinorVersion == 1)
_tcsncat(szVersion, _T("Windows Server 2008 R2 "), cntMax);
else
_tcsncat(szVersion, _T("Windows Server 2008 "), cntMax);
}
if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
_tcsncat(szVersion, _T("Microsoft Windows Server 2003 "), cntMax);
if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)