Merge branch 'master' into 4.3.4

Conflicts:
	src/server/game/Handlers/BattleGroundHandler.cpp
This commit is contained in:
Spp
2012-11-16 08:51:15 +01:00
30 changed files with 1056 additions and 330 deletions

View File

@@ -1027,109 +1027,72 @@ public:
return true;
}
static bool HandleLookupMapCommand(ChatHandler* /*handler*/, char const* args)
static bool HandleLookupMapCommand(ChatHandler* handler, char const* args)
{
if (!*args)
return false;
/*
std::string namePart = args;
std::wstring wNamePart;
// converting string that we try to find to lower case
if (!Utf8toWStr(namePart, wNamePart))
return false;
wstrToLower(wNamePart);
bool found = false;
uint32 counter = 0;
uint32 maxResults = sWorld->getIntConfig(CONFIG_MAX_RESULTS_LOOKUP_COMMANDS);
uint8 locale = handler->GetSession() ? handler->GetSession()->GetSessionDbcLocale() : sWorld->GetDefaultDbcLocale();
// search in Map.dbc
for (uint32 id = 0; id < sMapStore.GetNumRows(); id++)
{
MapEntry const* MapInfo = sMapStore.LookupEntry(id);
if (MapInfo)
if (MapEntry const* mapInfo = sMapStore.LookupEntry(id))
{
uint8 locale = handler->GetSession() ? handler->GetSession()->GetSessionDbcLocale() : sWorld->GetDefaultDbcLocale();
std::string name = MapInfo->name[locale];
std::string name = mapInfo->name[locale];
if (name.empty())
continue;
if (!Utf8FitTo(name, wNamePart))
if (Utf8FitTo(name, wNamePart) && locale < TOTAL_LOCALES)
{
locale = LOCALE_enUS;
for (; locale < TOTAL_LOCALES; locale++)
if (maxResults && counter == maxResults)
{
if (handler->GetSession() && locale == handler->GetSession()->GetSessionDbcLocale())
continue;
name = MapInfo->name[locale];
if (name.empty())
continue;
if (Utf8FitTo(name, wNamePart))
break;
handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
return true;
}
}
if (locale < TOTAL_LOCALES)
{
// send map in "id - [name][Continent][Instance/Battleground/Arena][Raid reset time:][Heroic reset time:][Mountable]" format
std::ostringstream ss;
ss << id << " - [" << name << ']';
if (handler->GetSession())
ss << id << " - |cffffffff|Hmap:" << id << "|h[" << name << ']';
else // console
ss << id << " - [" << name << ']';
if (MapInfo->IsContinent())
if (mapInfo->IsContinent())
ss << handler->GetTrinityString(LANG_CONTINENT);
switch (MapInfo->map_type)
switch (mapInfo->map_type)
{
case MAP_INSTANCE: ss << handler->GetTrinityString(LANG_INSTANCE); break;
case MAP_BATTLEGROUND: ss << handler->GetTrinityString(LANG_BATTLEGROUND); break;
case MAP_ARENA: ss << handler->GetTrinityString(LANG_ARENA); break;
case MAP_INSTANCE:
ss << handler->GetTrinityString(LANG_INSTANCE);
break;
case MAP_RAID:
ss << handler->GetTrinityString(LANG_RAID);
break;
case MAP_BATTLEGROUND:
ss << handler->GetTrinityString(LANG_BATTLEGROUND);
break;
case MAP_ARENA:
ss << handler->GetTrinityString(LANG_ARENA);
break;
}
if (MapInfo->IsRaid())
ss << handler->GetTrinityString(LANG_RAID);
handler->SendSysMessage(ss.str().c_str());
if (MapInfo->SupportsHeroicMode())
ss << handler->GetTrinityString(LANG_HEROIC);
uint32 ResetTimeRaid = MapInfo->resetTimeRaid;
std::string ResetTimeRaidStr;
if (ResetTimeRaid)
ResetTimeRaidStr = secsToTimeString(ResetTimeRaid, true, false);
uint32 ResetTimeHeroic = MapInfo->resetTimeHeroic;
std::string ResetTimeHeroicStr;
if (ResetTimeHeroic)
ResetTimeHeroicStr = secsToTimeString(ResetTimeHeroic, true, false);
if (MapInfo->IsMountAllowed())
ss << handler->GetTrinityString(LANG_MOUNTABLE);
if (ResetTimeRaid && !ResetTimeHeroic)
handler->PSendSysMessage(ss.str().c_str(), ResetTimeRaidStr.c_str());
else if (!ResetTimeRaid && ResetTimeHeroic)
handler->PSendSysMessage(ss.str().c_str(), ResetTimeHeroicStr.c_str());
else if (ResetTimeRaid && ResetTimeHeroic)
handler->PSendSysMessage(ss.str().c_str(), ResetTimeRaidStr.c_str(), ResetTimeHeroicStr.c_str());
else
handler->SendSysMessage(ss.str().c_str());
if (!found)
found = true;
++counter;
}
}
}
if (!found)
if (!counter)
handler->SendSysMessage(LANG_COMMAND_NOMAPFOUND);
*/
return true;
}

View File

@@ -22,6 +22,7 @@
#include "SpellScript.h"
#include "Spell.h"
#include "SpellAuraEffects.h"
#include "PassiveAI.h"
//
// Emerald Dragon NPCs and IDs (kept here for reference)
@@ -91,14 +92,12 @@ struct emerald_dragonAI : public WorldBossAI
{
emerald_dragonAI(Creature* creature) : WorldBossAI(creature)
{
// me->m_CombatDistance = 12.0f;
// me->m_SightDistance = 60.0f;
}
void Reset()
{
_Reset();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NON_ATTACKABLE);
WorldBossAI::Reset();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
me->SetReactState(REACT_AGGRESSIVE);
DoCast(me, SPELL_MARK_OF_NATURE_AURA, true);
events.ScheduleEvent(EVENT_TAIL_SWEEP, 4000);
@@ -109,7 +108,8 @@ struct emerald_dragonAI : public WorldBossAI
// Target killed during encounter, mark them as suspectible for Aura Of Nature
void KilledUnit(Unit* who)
{
who->CastSpell(who, SPELL_MARK_OF_NATURE, true);
if (who->GetTypeId() == TYPEID_PLAYER)
who->CastSpell(who, SPELL_MARK_OF_NATURE, true);
}
// Execute and reschedule base events shared between all Emerald Dragons
@@ -215,109 +215,6 @@ class npc_dream_fog : public CreatureScript
}
};
/*
* --- Spell: Dream Fog
*/
class DreamFogTargetSelector
{
public:
DreamFogTargetSelector() { }
bool operator()(WorldObject* object) const
{
return object->ToUnit() && object->ToUnit()->HasAura(SPELL_SLEEP);
}
};
class spell_dream_fog_sleep : public SpellScriptLoader
{
public:
spell_dream_fog_sleep() : SpellScriptLoader("spell_dream_fog_sleep") { }
class spell_dream_fog_sleep_SpellScript : public SpellScript
{
PrepareSpellScript(spell_dream_fog_sleep_SpellScript);
void FilterTargets(std::list<WorldObject*>& unitList)
{
unitList.remove_if(DreamFogTargetSelector());
}
void Register()
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dream_fog_sleep_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
SpellScript* GetSpellScript() const
{
return new spell_dream_fog_sleep_SpellScript();
}
};
/*
* --- Spell: Mark of Nature
*/
class MarkOfNatureTargetSelector
{
public:
MarkOfNatureTargetSelector() { }
bool operator()(WorldObject* object) const
{
if (Unit* unit = object->ToUnit())
// return anyone that isn't tagged or already under the influence of Aura of Nature
return !(unit->HasAura(SPELL_MARK_OF_NATURE) && !unit->HasAura(SPELL_AURA_OF_NATURE));
return true;
}
};
class spell_mark_of_nature : public SpellScriptLoader
{
public:
spell_mark_of_nature() : SpellScriptLoader("spell_mark_of_nature") { }
class spell_mark_of_nature_SpellScript : public SpellScript
{
PrepareSpellScript(spell_mark_of_nature_SpellScript);
bool Validate(SpellInfo const* /*spellInfo*/)
{
if (!sSpellMgr->GetSpellInfo(SPELL_MARK_OF_NATURE))
return false;
if (!sSpellMgr->GetSpellInfo(SPELL_AURA_OF_NATURE))
return false;
return true;
}
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove_if(MarkOfNatureTargetSelector());
}
void HandleEffect(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
if (GetHitUnit())
GetHitUnit()->CastSpell(GetHitUnit(), SPELL_AURA_OF_NATURE, true);
}
void Register()
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mark_of_nature_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_mark_of_nature_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
}
};
SpellScript* GetSpellScript() const
{
return new spell_mark_of_nature_SpellScript();
}
};
/*
* ---
* --- Dragonspecific scripts and handling: YSONDRE
@@ -355,7 +252,6 @@ class boss_ysondre : public CreatureScript
void Reset()
{
_stage = 1;
_Reset();
emerald_dragonAI::Reset();
events.ScheduleEvent(EVENT_LIGHTNING_WAVE, 12000);
}
@@ -394,7 +290,7 @@ class boss_ysondre : public CreatureScript
}
private:
uint8 _stage;
uint8 _stage;
};
CreatureAI* GetAI(Creature* creature) const
@@ -409,8 +305,6 @@ class boss_ysondre : public CreatureScript
* ---
*
* TODO:
* - NPC helper for spirit shades(?)
* - Spirit shade NPC moves towards Lethon and heals him if close enough (each shade heals for 15000 HP)
* - Spell: Shadow bolt whirl casts needs custom handling (spellscript)
*/
@@ -424,7 +318,12 @@ enum LethonSpells
{
SPELL_DRAW_SPIRIT = 24811,
SPELL_SHADOW_BOLT_WHIRL = 24834,
SPELL_SPIRIT_SHADE_VISUAL = 24908,
SPELL_DARK_OFFERING = 24804,
};
enum LethonCreatures
{
NPC_SPIRIT_SHADE = 15261,
};
class boss_lethon : public CreatureScript
@@ -441,7 +340,6 @@ class boss_lethon : public CreatureScript
void Reset()
{
_stage = 1;
_Reset();
emerald_dragonAI::Reset();
events.ScheduleEvent(EVENT_SHADOW_BOLT_WHIRL, 10000);
}
@@ -462,12 +360,22 @@ class boss_lethon : public CreatureScript
}
}
void SpellHitTarget(Unit* target, SpellInfo const* spell)
{
if (spell->Id == SPELL_DRAW_SPIRIT && target->GetTypeId() == TYPEID_PLAYER)
{
Position targetPos;
target->GetPosition(&targetPos);
me->GetMap()->SummonCreature(NPC_SPIRIT_SHADE, targetPos, NULL, 50000, (Unit*)this);
}
}
void ExecuteEvent(uint32 const eventId)
{
switch (eventId)
{
case EVENT_SHADOW_BOLT_WHIRL:
DoCast(me, SPELL_SHADOW_BOLT_WHIRL, true);
me->CastSpell((Unit*)NULL, SPELL_SHADOW_BOLT_WHIRL, false);
events.ScheduleEvent(EVENT_SHADOW_BOLT_WHIRL, urand(15000, 30000));
break;
default:
@@ -477,7 +385,7 @@ class boss_lethon : public CreatureScript
}
private:
uint8 _stage;
uint8 _stage;
};
CreatureAI* GetAI(Creature* creature) const
@@ -486,6 +394,42 @@ class boss_lethon : public CreatureScript
}
};
class npc_spirit_shade : public CreatureScript
{
public:
npc_spirit_shade() : CreatureScript("npc_spirit_shade") { }
struct npc_spirit_shadeAI : public PassiveAI
{
npc_spirit_shadeAI(Creature* creature) : PassiveAI(creature), _summonerGuid(0)
{
}
void IsSummonedBy(Unit* summoner)
{
_summonerGuid = summoner->GetGUID();
me->GetMotionMaster()->MoveFollow(summoner, 0.0f, 0.0f);
}
void MovementInform(uint32 moveType, uint32 data)
{
if (moveType == FOLLOW_MOTION_TYPE && data == _summonerGuid)
{
me->CastSpell((Unit*)NULL, SPELL_DARK_OFFERING, false);
me->DespawnOrUnsummon(1000);
}
}
private:
uint64 _summonerGuid;
};
CreatureAI* GetAI(Creature* creature) const
{
return new npc_spirit_shadeAI(creature);
}
};
/*
* ---
* --- Dragonspecific scripts and handling: EMERISS
@@ -519,7 +463,6 @@ class boss_emeriss : public CreatureScript
void Reset()
{
_stage = 1;
_Reset();
emerald_dragonAI::Reset();
events.ScheduleEvent(EVENT_VOLATILE_INFECTION, 12000);
}
@@ -562,7 +505,7 @@ class boss_emeriss : public CreatureScript
}
private:
uint8 _stage;
uint8 _stage;
};
CreatureAI* GetAI(Creature* creature) const
@@ -607,10 +550,6 @@ class boss_taerar : public CreatureScript
{
boss_taerarAI(Creature* creature) : emerald_dragonAI(creature)
{
_stage = 1;
_shades = 0;
_banished = false;
_banishedTimer = 0;
}
void Reset()
@@ -622,7 +561,6 @@ class boss_taerar : public CreatureScript
_banished = false;
_banishedTimer = 0;
_Reset();
emerald_dragonAI::Reset();
events.ScheduleEvent(EVENT_ARCANE_BLAST, 12000);
events.ScheduleEvent(EVENT_BELLOWING_ROAR, 30000);
@@ -655,11 +593,11 @@ class boss_taerar : public CreatureScript
uint32 count = sizeof(TaerarShadeSpells) / sizeof(uint32);
for (uint32 i = 0; i < count; ++i)
DoCastVictim(TaerarShadeSpells[i], true);
DoCast(me->getVictim(), TaerarShadeSpells[i], true);
_shades += count;
DoCast(SPELL_SHADE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NON_ATTACKABLE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
me->SetReactState(REACT_PASSIVE);
++_stage;
@@ -696,7 +634,7 @@ class boss_taerar : public CreatureScript
{
_banished = false;
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NON_ATTACKABLE);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
me->RemoveAurasDueToSpell(SPELL_SHADE);
me->SetReactState(REACT_AGGRESSIVE);
}
@@ -714,10 +652,10 @@ class boss_taerar : public CreatureScript
}
private:
bool _banished; // used for shades activation testing
uint32 _banishedTimer; // counter for banishment timeout
uint8 _shades; // keep track of how many shades are dead
uint8 _stage; // check which "shade phase" we're at (75-50-25 percentage counters)
bool _banished; // used for shades activation testing
uint32 _banishedTimer; // counter for banishment timeout
uint8 _shades; // keep track of how many shades are dead
uint8 _stage; // check which "shade phase" we're at (75-50-25 percentage counters)
};
CreatureAI* GetAI(Creature* creature) const
@@ -726,18 +664,122 @@ class boss_taerar : public CreatureScript
}
};
/*
* --- Spell: Dream Fog
*/
class DreamFogTargetSelector
{
public:
DreamFogTargetSelector() { }
bool operator()(WorldObject* object)
{
if (Unit* unit = object->ToUnit())
return unit->HasAura(SPELL_SLEEP);
return true;
}
};
class spell_dream_fog_sleep : public SpellScriptLoader
{
public:
spell_dream_fog_sleep() : SpellScriptLoader("spell_dream_fog_sleep") { }
class spell_dream_fog_sleep_SpellScript : public SpellScript
{
PrepareSpellScript(spell_dream_fog_sleep_SpellScript);
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove_if(DreamFogTargetSelector());
}
void Register()
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dream_fog_sleep_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
SpellScript* GetSpellScript() const
{
return new spell_dream_fog_sleep_SpellScript();
}
};
/*
* --- Spell: Mark of Nature
*/
class MarkOfNatureTargetSelector
{
public:
MarkOfNatureTargetSelector() { }
bool operator()(WorldObject* object)
{
// return those not tagged or already under the influence of Aura of Nature
if (Unit* unit = object->ToUnit())
return !(unit->HasAura(SPELL_MARK_OF_NATURE) && !unit->HasAura(SPELL_AURA_OF_NATURE));
return true;
}
};
class spell_mark_of_nature : public SpellScriptLoader
{
public:
spell_mark_of_nature() : SpellScriptLoader("spell_mark_of_nature") { }
class spell_mark_of_nature_SpellScript : public SpellScript
{
PrepareSpellScript(spell_mark_of_nature_SpellScript);
bool Validate(SpellInfo const* /*spellInfo*/)
{
if (!sSpellMgr->GetSpellInfo(SPELL_MARK_OF_NATURE))
return false;
if (!sSpellMgr->GetSpellInfo(SPELL_AURA_OF_NATURE))
return false;
return true;
}
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove_if(MarkOfNatureTargetSelector());
}
void HandleEffect(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
GetHitUnit()->CastSpell(GetHitUnit(), SPELL_AURA_OF_NATURE, true);
}
void Register()
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mark_of_nature_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_mark_of_nature_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
}
};
SpellScript* GetSpellScript() const
{
return new spell_mark_of_nature_SpellScript();
}
};
void AddSC_emerald_dragons()
{
// helper NPC scripts
new npc_dream_fog();
// dragon spellscripts
new spell_dream_fog_sleep();
new spell_mark_of_nature();
new npc_spirit_shade();
// dragons
new boss_ysondre();
new boss_taerar();
new boss_emeriss();
new boss_lethon();
// dragon spellscripts
new spell_dream_fog_sleep();
new spell_mark_of_nature();
};