aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVincent_Michael <Vincent_Michael@gmx.de>2014-01-23 19:23:17 +0100
committerVincent_Michael <Vincent_Michael@gmx.de>2014-01-23 19:23:17 +0100
commitb61bf8f01f6ec9298df6b94eb31cadbde72c4b57 (patch)
treebff89cba8127f8a353b9bed8b700acaf4c1f064f /src
parentf1e1a5cad0fb32fea2aebdc864eb72005594c60c (diff)
parentf731116766268a38a58572e57cc8abbac400c5ca (diff)
Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.3.4
Conflicts: src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Spells/Spell.cpp220
-rw-r--r--src/server/game/Spells/Spell.h8
-rw-r--r--src/server/game/Spells/SpellScript.cpp26
-rw-r--r--src/server/game/Spells/SpellScript.h27
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h8
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp389
-rw-r--r--src/server/shared/Cryptography/OpenSSLCrypto.cpp5
7 files changed, 422 insertions, 261 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 0d5ba60df65..a526be904a3 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -87,9 +87,26 @@ SpellDestination::SpellDestination(WorldObject const& wObj)
_transportGUID = wObj.GetTransGUID();
_transportOffset.Relocate(wObj.GetTransOffsetX(), wObj.GetTransOffsetY(), wObj.GetTransOffsetZ(), wObj.GetTransOffsetO());
_position.Relocate(wObj);
- _position.SetOrientation(wObj.GetOrientation());
}
+void SpellDestination::Relocate(Position const& pos)
+{
+ if (_transportGUID)
+ {
+ Position offset;
+ _position.GetPositionOffsetTo(pos, offset);
+ _transportOffset.RelocateOffset(offset);
+ }
+ _position.Relocate(pos);
+}
+
+void SpellDestination::RelocateOffset(Position const& offset)
+{
+ if (_transportGUID)
+ _transportOffset.RelocateOffset(offset);
+
+ _position.RelocateOffset(offset);
+}
SpellCastTargets::SpellCastTargets() : m_elevation(0), m_speed(0), m_strTarget()
{
@@ -352,14 +369,7 @@ void SpellCastTargets::SetSrc(WorldObject const& wObj)
void SpellCastTargets::ModSrc(Position const& pos)
{
ASSERT(m_targetMask & TARGET_FLAG_SOURCE_LOCATION);
-
- if (m_src._transportGUID)
- {
- Position offset;
- m_src._position.GetPositionOffsetTo(pos, offset);
- m_src._transportOffset.RelocateOffset(offset);
- }
- m_src._position.Relocate(pos);
+ m_src.Relocate(pos);
}
void SpellCastTargets::RemoveSrc()
@@ -395,6 +405,12 @@ void SpellCastTargets::SetDst(WorldObject const& wObj)
m_targetMask |= TARGET_FLAG_DEST_LOCATION;
}
+void SpellCastTargets::SetDst(SpellDestination const& spellDest)
+{
+ m_dst = spellDest;
+ m_targetMask |= TARGET_FLAG_DEST_LOCATION;
+}
+
void SpellCastTargets::SetDst(SpellCastTargets const& spellTargets)
{
m_dst = spellTargets.m_dst;
@@ -404,14 +420,13 @@ void SpellCastTargets::SetDst(SpellCastTargets const& spellTargets)
void SpellCastTargets::ModDst(Position const& pos)
{
ASSERT(m_targetMask & TARGET_FLAG_DEST_LOCATION);
+ m_dst.Relocate(pos);
+}
- if (m_dst._transportGUID)
- {
- Position offset;
- m_dst._position.GetPositionOffsetTo(pos, offset);
- m_dst._transportOffset.RelocateOffset(offset);
- }
- m_dst._position.Relocate(pos);
+void SpellCastTargets::ModDst(SpellDestination const& spellDest)
+{
+ ASSERT(m_targetMask & TARGET_FLAG_DEST_LOCATION);
+ m_dst = spellDest;
}
void SpellCastTargets::RemoveDst()
@@ -1088,24 +1103,13 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge
if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
Trinity::Containers::RandomResizeList(targets, maxTargets);
- // for compability with older code - add only unit and go targets
- /// @todo remove this
- std::list<Unit*> unitTargets;
- std::list<GameObject*> gObjTargets;
-
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
{
if (Unit* unitTarget = (*itr)->ToUnit())
- unitTargets.push_back(unitTarget);
+ AddUnitTarget(unitTarget, effMask, false);
else if (GameObject* gObjTarget = (*itr)->ToGameObject())
- gObjTargets.push_back(gObjTarget);
+ AddGOTarget(gObjTarget, effMask);
}
-
- for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr)
- AddUnitTarget(*itr, effMask, false);
-
- for (std::list<GameObject*>::iterator itr = gObjTargets.begin(); itr != gObjTargets.end(); ++itr)
- AddGOTarget(*itr, effMask);
}
}
}
@@ -1379,31 +1383,32 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
{
+ SpellDestination dest(*m_caster);
+
switch (targetType.GetTarget())
{
case TARGET_DEST_CASTER:
- m_targets.SetDst(*m_caster);
- return;
+ break;
case TARGET_DEST_HOME:
if (Player* playerCaster = m_caster->ToPlayer())
- m_targets.SetDst(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
- return;
+ dest = SpellDestination(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
+ break;
case TARGET_DEST_DB:
if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex))
{
/// @todo fix this check
if (m_spellInfo->HasEffect(SPELL_EFFECT_TELEPORT_UNITS) || m_spellInfo->HasEffect(SPELL_EFFECT_BIND))
- m_targets.SetDst(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
+ dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
else if (st->target_mapId == m_caster->GetMapId())
- m_targets.SetDst(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
+ dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
}
else
{
TC_LOG_DEBUG("spells", "SPELL: unknown target coordinates for spell ID %u", m_spellInfo->Id);
- WorldObject* target = m_targets.GetObjectTarget();
- m_targets.SetDst(target ? *target : *m_caster);
+ if (WorldObject* target = m_targets.GetObjectTarget())
+ dest = SpellDestination(*target);
}
- return;
+ break;
case TARGET_DEST_CASTER_FISHING:
{
float min_dis = m_spellInfo->GetMinRange(true);
@@ -1431,60 +1436,70 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici
return;
}
- m_targets.SetDst(x, y, liquidLevel, m_caster->GetOrientation());
- return;
+ dest = SpellDestination(x, y, liquidLevel, m_caster->GetOrientation());
+ break;
}
default:
- break;
- }
+ {
+ float dist;
+ float angle = targetType.CalcDirectionAngle();
+ float objSize = m_caster->GetObjectSize();
+ if (targetType.GetTarget() == TARGET_DEST_CASTER_SUMMON)
+ dist = PET_FOLLOW_DIST;
+ else
+ dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
- float dist;
- float angle = targetType.CalcDirectionAngle();
- float objSize = m_caster->GetObjectSize();
- if (targetType.GetTarget() == TARGET_DEST_CASTER_SUMMON)
- dist = PET_FOLLOW_DIST;
- else
- dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
+ if (dist < objSize)
+ dist = objSize;
+ else if (targetType.GetTarget() == TARGET_DEST_CASTER_RANDOM)
+ dist = objSize + (dist - objSize) * float(rand_norm());
- if (dist < objSize)
- dist = objSize;
- else if (targetType.GetTarget() == TARGET_DEST_CASTER_RANDOM)
- dist = objSize + (dist - objSize) * (float)rand_norm();
+ Position pos = dest._position;
+ if (targetType.GetTarget() == TARGET_DEST_CASTER_FRONT_LEAP)
+ m_caster->MovePositionToFirstCollision(pos, dist, angle);
+ else
+ m_caster->MovePosition(pos, dist, angle);
- Position pos;
- if (targetType.GetTarget() == TARGET_DEST_CASTER_FRONT_LEAP)
- m_caster->GetFirstCollisionPosition(pos, dist, angle);
- else
- m_caster->GetNearPosition(pos, dist, angle);
- m_targets.SetDst(*m_caster);
- m_targets.ModDst(pos);
+ dest.Relocate(pos);
+ break;
+ }
+ }
+
+ CallScriptDestinationTargetSelectHandlers(dest, effIndex);
+ m_targets.SetDst(dest);
}
void Spell::SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
{
WorldObject* target = m_targets.GetObjectTarget();
+
+ SpellDestination dest(*target);
+
switch (targetType.GetTarget())
{
case TARGET_DEST_TARGET_ENEMY:
case TARGET_DEST_TARGET_ANY:
- m_targets.SetDst(*target);
- return;
+ break;
default:
+ {
+ float angle = targetType.CalcDirectionAngle();
+ float objSize = target->GetObjectSize();
+ float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
+ if (dist < objSize)
+ dist = objSize;
+ else if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
+ dist = objSize + (dist - objSize) * float(rand_norm());
+
+ Position pos = dest._position;
+ target->MovePosition(pos, dist, angle);
+
+ dest.Relocate(pos);
break;
+ }
}
- float angle = targetType.CalcDirectionAngle();
- float objSize = target->GetObjectSize();
- float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
- if (dist < objSize)
- dist = objSize;
- else if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
- dist = objSize + (dist - objSize) * (float)rand_norm();
-
- Position pos;
- target->GetNearPosition(pos, dist, angle);
- m_targets.SetDst(*target);
- m_targets.ModDst(pos);
+ CallScriptDestinationTargetSelectHandlers(dest, effIndex);
+ m_targets.SetDst(dest);
}
void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
@@ -1493,8 +1508,9 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT
// can only happen if previous destination target could not be set for some reason
// (not found nearby target, or channel target for example
// maybe we should abort the spell in such case?
- if (!m_targets.HasDst())
- m_targets.SetDst(*m_caster);
+ CheckDst();
+
+ SpellDestination dest(*m_targets.GetDst());
switch (targetType.GetTarget())
{
@@ -1504,20 +1520,25 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT
case TARGET_DEST_DEST:
return;
case TARGET_DEST_TRAJ:
- SelectImplicitTrajTargets();
+ SelectImplicitTrajTargets(effIndex);
return;
default:
+ {
+ float angle = targetType.CalcDirectionAngle();
+ float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
+ if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
+ dist *= float(rand_norm());
+
+ Position pos = dest._position;
+ m_caster->MovePosition(pos, dist, angle);
+
+ dest.Relocate(pos);
break;
+ }
}
- float angle = targetType.CalcDirectionAngle();
- float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
- if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
- dist *= (float)rand_norm();
-
- Position pos = *m_targets.GetDstPos();
- m_caster->MovePosition(pos, dist, angle);
- m_targets.ModDst(pos);
+ CallScriptDestinationTargetSelectHandlers(dest, effIndex);
+ m_targets.ModDst(dest);
}
void Spell::SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
@@ -1608,14 +1629,9 @@ void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTarg
// Chain primary target is added earlier
CallScriptObjectAreaTargetSelectHandlers(targets, effIndex);
- // for backward compability
- std::list<Unit*> unitTargets;
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
if (Unit* unitTarget = (*itr)->ToUnit())
- unitTargets.push_back(unitTarget);
-
- for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr)
- AddUnitTarget(*itr, effMask, false);
+ AddUnitTarget(unitTarget, effMask, false);
}
}
@@ -1633,7 +1649,7 @@ float tangent(float x)
#define DEBUG_TRAJ(a) //a
-void Spell::SelectImplicitTrajTargets()
+void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex)
{
if (!m_targets.HasTraj())
return;
@@ -1762,7 +1778,11 @@ void Spell::SelectImplicitTrajTargets()
Position trajDst;
trajDst.Relocate(x, y, z, m_caster->GetOrientation());
- m_targets.ModDst(trajDst);
+ SpellDestination dest(*m_targets.GetDst());
+ dest.Relocate(trajDst);
+
+ CallScriptDestinationTargetSelectHandlers(dest, effIndex);
+ m_targets.ModDst(dest);
}
if (Vehicle* veh = m_caster->GetVehicleKit())
@@ -7197,6 +7217,20 @@ void Spell::CallScriptObjectTargetSelectHandlers(WorldObject*& target, SpellEffI
}
}
+void Spell::CallScriptDestinationTargetSelectHandlers(SpellDestination& target, SpellEffIndex effIndex)
+{
+ for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
+ {
+ (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
+ std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
+ for (; hookItr != hookItrEnd; ++hookItr)
+ if (hookItr->IsEffectAffected(m_spellInfo, effIndex))
+ hookItr->Call(*scritr, target);
+
+ (*scritr)->_FinishScriptCall();
+ }
+}
+
bool Spell::CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
{
// Skip if there are not any script
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index e8bc084b835..1b415cd6cb8 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -87,6 +87,9 @@ struct SpellDestination
SpellDestination(Position const& pos);
SpellDestination(WorldObject const& wObj);
+ void Relocate(Position const& pos);
+ void RelocateOffset(Position const& offset);
+
WorldLocation _position;
uint64 _transportGUID;
Position _transportOffset;
@@ -141,8 +144,10 @@ class SpellCastTargets
void SetDst(float x, float y, float z, float orientation, uint32 mapId = MAPID_INVALID);
void SetDst(Position const& pos);
void SetDst(WorldObject const& wObj);
+ void SetDst(SpellDestination const& spellDest);
void SetDst(SpellCastTargets const& spellTargets);
void ModDst(Position const& pos);
+ void ModDst(SpellDestination const& spellDest);
void RemoveDst();
bool HasSrc() const { return GetTargetMask() & TARGET_FLAG_SOURCE_LOCATION; }
@@ -364,7 +369,7 @@ class Spell
void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask);
- void SelectImplicitTrajTargets();
+ void SelectImplicitTrajTargets(SpellEffIndex effIndex);
void SelectEffectTypeImplicitTargets(uint8 effIndex);
@@ -641,6 +646,7 @@ class Spell
void CallScriptAfterHitHandlers();
void CallScriptObjectAreaTargetSelectHandlers(std::list<WorldObject*>& targets, SpellEffIndex effIndex);
void CallScriptObjectTargetSelectHandlers(WorldObject*& target, SpellEffIndex effIndex);
+ void CallScriptDestinationTargetSelectHandlers(SpellDestination& target, SpellEffIndex effIndex);
bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck);
std::list<SpellScript*> m_loadedScripts;
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index 7301e693978..c7eebb495c0 100644
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -203,8 +203,8 @@ void SpellScript::HitHandler::Call(SpellScript* spellScript)
(spellScript->*pHitHandlerScript)();
}
-SpellScript::TargetHook::TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area)
- : _SpellScript::EffectHook(_effectIndex), targetType(_targetType), area(_area) { }
+SpellScript::TargetHook::TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area, bool _dest)
+ : _SpellScript::EffectHook(_effectIndex), targetType(_targetType), area(_area), dest(_dest) { }
std::string SpellScript::TargetHook::ToString()
{
@@ -236,8 +236,9 @@ bool SpellScript::TargetHook::CheckEffect(SpellInfo const* spellEntry, uint8 eff
switch (targetInfo.GetObjectType())
{
case TARGET_OBJECT_TYPE_SRC: // EMPTY
- case TARGET_OBJECT_TYPE_DEST: // EMPTY
return false;
+ case TARGET_OBJECT_TYPE_DEST: // DEST
+ return dest;
default:
switch (targetInfo.GetReferenceType())
{
@@ -259,7 +260,7 @@ bool SpellScript::TargetHook::CheckEffect(SpellInfo const* spellEntry, uint8 eff
}
SpellScript::ObjectAreaTargetSelectHandler::ObjectAreaTargetSelectHandler(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType)
- : TargetHook(_effIndex, _targetType, true)
+ : TargetHook(_effIndex, _targetType, true, false)
{
pObjectAreaTargetSelectHandlerScript = _pObjectAreaTargetSelectHandlerScript;
}
@@ -270,7 +271,7 @@ void SpellScript::ObjectAreaTargetSelectHandler::Call(SpellScript* spellScript,
}
SpellScript::ObjectTargetSelectHandler::ObjectTargetSelectHandler(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType)
- : TargetHook(_effIndex, _targetType, false)
+ : TargetHook(_effIndex, _targetType, false, false)
{
pObjectTargetSelectHandlerScript = _pObjectTargetSelectHandlerScript;
}
@@ -280,6 +281,17 @@ void SpellScript::ObjectTargetSelectHandler::Call(SpellScript* spellScript, Worl
(spellScript->*pObjectTargetSelectHandlerScript)(target);
}
+SpellScript::DestinationTargetSelectHandler::DestinationTargetSelectHandler(SpellDestinationTargetSelectFnType _DestinationTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType)
+ : TargetHook(_effIndex, _targetType, false, true)
+{
+ DestinationTargetSelectHandlerScript = _DestinationTargetSelectHandlerScript;
+}
+
+void SpellScript::DestinationTargetSelectHandler::Call(SpellScript* spellScript, SpellDestination& target)
+{
+ (spellScript->*DestinationTargetSelectHandlerScript)(target);
+}
+
bool SpellScript::_Validate(SpellInfo const* entry)
{
for (std::list<EffectHandler>::iterator itr = OnEffectLaunch.begin(); itr != OnEffectLaunch.end(); ++itr)
@@ -306,6 +318,10 @@ bool SpellScript::_Validate(SpellInfo const* entry)
if (!(*itr).GetAffectedEffectsMask(entry))
TC_LOG_ERROR("scripts", "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnObjectTargetSelect` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
+ for (std::list<DestinationTargetSelectHandler>::iterator itr = OnDestinationTargetSelect.begin(); itr != OnDestinationTargetSelect.end(); ++itr)
+ if (!(*itr).GetAffectedEffectsMask(entry))
+ TC_LOG_ERROR("scripts", "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnDestinationTargetSelect` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
+
return _SpellScript::_Validate(entry);
}
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index 75cf63b495b..dfa494e38e6 100644
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -135,6 +135,7 @@ enum SpellScriptHookType
SPELL_SCRIPT_HOOK_AFTER_HIT,
SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT,
SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT,
+ SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT,
SPELL_SCRIPT_HOOK_CHECK_CAST,
SPELL_SCRIPT_HOOK_BEFORE_CAST,
SPELL_SCRIPT_HOOK_ON_CAST,
@@ -158,7 +159,8 @@ class SpellScript : public _SpellScript
typedef void(CLASSNAME::*SpellHitFnType)(); \
typedef void(CLASSNAME::*SpellCastFnType)(); \
typedef void(CLASSNAME::*SpellObjectAreaTargetSelectFnType)(std::list<WorldObject*>&); \
- typedef void(CLASSNAME::*SpellObjectTargetSelectFnType)(WorldObject*&);
+ typedef void(CLASSNAME::*SpellObjectTargetSelectFnType)(WorldObject*&); \
+ typedef void(CLASSNAME::*SpellDestinationTargetSelectFnType)(SpellDestination&);
SPELLSCRIPT_FUNCTION_TYPE_DEFINES(SpellScript)
@@ -203,12 +205,13 @@ class SpellScript : public _SpellScript
class TargetHook : public _SpellScript::EffectHook
{
public:
- TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area);
+ TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area, bool _dest);
bool CheckEffect(SpellInfo const* spellInfo, uint8 effIndex);
std::string ToString();
protected:
uint16 targetType;
bool area;
+ bool dest;
};
class ObjectAreaTargetSelectHandler : public TargetHook
@@ -224,18 +227,28 @@ class SpellScript : public _SpellScript
{
public:
ObjectTargetSelectHandler(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType);
- void Call(SpellScript* spellScript, WorldObject*& targets);
+ void Call(SpellScript* spellScript, WorldObject*& target);
private:
SpellObjectTargetSelectFnType pObjectTargetSelectHandlerScript;
};
+ class DestinationTargetSelectHandler : public TargetHook
+ {
+ public:
+ DestinationTargetSelectHandler(SpellDestinationTargetSelectFnType _DestinationTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType);
+ void Call(SpellScript* spellScript, SpellDestination& target);
+ private:
+ SpellDestinationTargetSelectFnType DestinationTargetSelectHandlerScript;
+ };
+
#define SPELLSCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) \
class CastHandlerFunction : public SpellScript::CastHandler { public: CastHandlerFunction(SpellCastFnType _pCastHandlerScript) : SpellScript::CastHandler((SpellScript::SpellCastFnType)_pCastHandlerScript) { } }; \
class CheckCastHandlerFunction : public SpellScript::CheckCastHandler { public: CheckCastHandlerFunction(SpellCheckCastFnType _checkCastHandlerScript) : SpellScript::CheckCastHandler((SpellScript::SpellCheckCastFnType)_checkCastHandlerScript) { } }; \
class EffectHandlerFunction : public SpellScript::EffectHandler { public: EffectHandlerFunction(SpellEffectFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName) : SpellScript::EffectHandler((SpellScript::SpellEffectFnType)_pEffectHandlerScript, _effIndex, _effName) { } }; \
class HitHandlerFunction : public SpellScript::HitHandler { public: HitHandlerFunction(SpellHitFnType _pHitHandlerScript) : SpellScript::HitHandler((SpellScript::SpellHitFnType)_pHitHandlerScript) { } }; \
class ObjectAreaTargetSelectHandlerFunction : public SpellScript::ObjectAreaTargetSelectHandler { public: ObjectAreaTargetSelectHandlerFunction(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::ObjectAreaTargetSelectHandler((SpellScript::SpellObjectAreaTargetSelectFnType)_pObjectAreaTargetSelectHandlerScript, _effIndex, _targetType) { } }; \
- class ObjectTargetSelectHandlerFunction : public SpellScript::ObjectTargetSelectHandler { public: ObjectTargetSelectHandlerFunction(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::ObjectTargetSelectHandler((SpellScript::SpellObjectTargetSelectFnType)_pObjectTargetSelectHandlerScript, _effIndex, _targetType) { } };
+ class ObjectTargetSelectHandlerFunction : public SpellScript::ObjectTargetSelectHandler { public: ObjectTargetSelectHandlerFunction(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::ObjectTargetSelectHandler((SpellScript::SpellObjectTargetSelectFnType)_pObjectTargetSelectHandlerScript, _effIndex, _targetType) { } }; \
+ class DestinationTargetSelectHandlerFunction : public SpellScript::DestinationTargetSelectHandler { public: DestinationTargetSelectHandlerFunction(SpellDestinationTargetSelectFnType _DestinationTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::DestinationTargetSelectHandler((SpellScript::SpellDestinationTargetSelectFnType)_DestinationTargetSelectHandlerScript, _effIndex, _targetType) { } };
#define PrepareSpellScript(CLASSNAME) SPELLSCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) SPELLSCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME)
public:
@@ -299,11 +312,17 @@ class SpellScript : public _SpellScript
HookList<ObjectTargetSelectHandler> OnObjectTargetSelect;
#define SpellObjectTargetSelectFn(F, I, N) ObjectTargetSelectHandlerFunction(&F, I, N)
+ // example: OnDestinationTargetSelect += SpellDestinationTargetSelectFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier);
+ // where function is void function(SpellDestination& target)
+ HookList<DestinationTargetSelectHandler> OnDestinationTargetSelect;
+ #define SpellDestinationTargetSelectFn(F, I, N) DestinationTargetSelectHandlerFunction(&F, I, N)
+
// hooks are executed in following order, at specified event of spell:
// 1. BeforeCast - executed when spell preparation is finished (when cast bar becomes full) before cast is handled
// 2. OnCheckCast - allows to override result of CheckCast function
// 3a. OnObjectAreaTargetSelect - executed just before adding selected targets to final target list (for area targets)
// 3b. OnObjectTargetSelect - executed just before adding selected target to final target list (for single unit targets)
+ // 3c. OnDestinationTargetSelect - executed just before adding selected target to final target list (for destination targets)
// 4. OnCast - executed just before spell is launched (creates missile) or executed
// 5. AfterCast - executed after spell missile is launched and immediate spell actions are done
// 6. OnEffectLaunch - executed just before specified effect handler call - when spell missile is launched
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h
index 7543a1bb597..5fbd18b7590 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h
@@ -88,13 +88,9 @@ enum GameObjectIds
};
template<class AI>
-CreatureAI* GetZulGurubAI(Creature* creature)
+AI* GetZulGurubAI(Creature* creature)
{
- if (InstanceMap* instance = creature->GetMap()->ToInstanceMap())
- if (instance->GetInstanceScript())
- if (instance->GetScriptId() == sObjectMgr->GetScriptId(ZGScriptName))
- return new AI(creature);
- return NULL;
+ return GetInstanceAI<AI>(creature, ZGScriptName);
}
#endif
diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp
index 77d3ce21d0c..efe439de440 100644
--- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp
+++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp
@@ -17,76 +17,75 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
+#include "SpellScript.h"
#include "Player.h"
#include "ahnkahet.h"
enum Spells
{
- SPELL_BLOODTHIRST = 55968, // Trigger Spell + add aura
- SPELL_CONJURE_FLAME_SPHERE = 55931,
- SPELL_FLAME_SPHERE_SUMMON_1 = 55895, // 1x 30106
- H_SPELL_FLAME_SPHERE_SUMMON_1 = 59511, // 1x 31686
- H_SPELL_FLAME_SPHERE_SUMMON_2 = 59512, // 1x 31687
- SPELL_FLAME_SPHERE_SPAWN_EFFECT = 55891,
- SPELL_FLAME_SPHERE_VISUAL = 55928,
- SPELL_FLAME_SPHERE_PERIODIC = 55926,
- SPELL_FLAME_SPHERE_DEATH_EFFECT = 55947,
- SPELL_BEAM_VISUAL = 60342,
- SPELL_EMBRACE_OF_THE_VAMPYR = 55959,
- SPELL_VANISH = 55964,
- CREATURE_FLAME_SPHERE = 30106,
- H_CREATURE_FLAME_SPHERE_1 = 31686,
- H_CREATURE_FLAME_SPHERE_2 = 31687,
- SPELL_HOVER_FALL = 60425
+ SPELL_BLOODTHIRST = 55968, // Trigger Spell + add aura
+ SPELL_CONJURE_FLAME_SPHERE = 55931,
+ SPELL_FLAME_SPHERE_SUMMON_1 = 55895, // 1x 30106
+ SPELL_FLAME_SPHERE_SUMMON_2 = 59511, // 1x 31686
+ SPELL_FLAME_SPHERE_SUMMON_3 = 59512, // 1x 31687
+ SPELL_FLAME_SPHERE_SPAWN_EFFECT = 55891,
+ SPELL_FLAME_SPHERE_VISUAL = 55928,
+ SPELL_FLAME_SPHERE_PERIODIC = 55926,
+ SPELL_FLAME_SPHERE_DEATH_EFFECT = 55947,
+ SPELL_EMBRACE_OF_THE_VAMPYR = 55959,
+ SPELL_VANISH = 55964,
+
+ NPC_FLAME_SPHERE_1 = 30106,
+ NPC_FLAME_SPHERE_2 = 31686,
+ NPC_FLAME_SPHERE_3 = 31687,
+
+ SPELL_BEAM_VISUAL = 60342,
+ SPELL_HOVER_FALL = 60425
};
enum Misc
{
- DATA_EMBRACE_DMG = 20000,
- H_DATA_EMBRACE_DMG = 40000,
- DATA_SPHERE_DISTANCE = 15
+ DATA_EMBRACE_DMG = 20000,
+ H_DATA_EMBRACE_DMG = 40000
};
-#define DATA_SPHERE_ANGLE_OFFSET 0.7f
-#define DATA_GROUND_POSITION_Z 11.30809f
+#define DATA_SPHERE_DISTANCE 25.0f
+#define DATA_SPHERE_ANGLE_OFFSET M_PI / 2
+#define DATA_GROUND_POSITION_Z 11.30809f
enum Yells
{
- SAY_1 = 0,
- SAY_WARNING = 1,
- SAY_AGGRO = 2,
- SAY_SLAY = 3,
- SAY_DEATH = 4,
- SAY_FEED = 5,
- SAY_VANISH = 6
+ SAY_1 = 0,
+ SAY_WARNING = 1,
+ SAY_AGGRO = 2,
+ SAY_SLAY = 3,
+ SAY_DEATH = 4,
+ SAY_FEED = 5,
+ SAY_VANISH = 6
};
enum Events
{
- EVENT_CASTING_FLAME_SPHERES = 1,
+ EVENT_CONJURE_FLAME_SPHERES = 1,
+ EVENT_BLOODTHIRST,
+ EVENT_VANISH,
EVENT_JUST_VANISHED,
EVENT_VANISHED,
EVENT_FEEDING,
- EVENT_BLOODTHIRST,
- EVENT_FLAME_SPHERE,
- EVENT_VANISH
-};
-
-enum Phase
-{
- PHASE_NORMAL = 1,
- PHASE_SPECIAL = 2
+ // Flame Sphere
+ EVENT_START_MOVE,
+ EVENT_DESPAWN
};
-class boss_taldaram : public CreatureScript
+class boss_prince_taldaram : public CreatureScript
{
public:
- boss_taldaram() : CreatureScript("boss_taldaram") { }
+ boss_prince_taldaram() : CreatureScript("boss_prince_taldaram") { }
- struct boss_taldaramAI : public BossAI
+ struct boss_prince_taldaramAI : public BossAI
{
- boss_taldaramAI(Creature* creature) : BossAI(creature, DATA_PRINCE_TALDARAM)
+ boss_prince_taldaramAI(Creature* creature) : BossAI(creature, DATA_PRINCE_TALDARAM)
{
me->SetDisableGravity(true);
}
@@ -94,6 +93,7 @@ class boss_taldaram : public CreatureScript
void Reset() OVERRIDE
{
_Reset();
+ _flameSphereTargetGUID = 0;
_embraceTargetGUID = 0;
_embraceTakenDamage = 0;
}
@@ -102,10 +102,24 @@ class boss_taldaram : public CreatureScript
{
_EnterCombat();
Talk(SAY_AGGRO);
- events.SetPhase(PHASE_NORMAL);
events.ScheduleEvent(EVENT_BLOODTHIRST, 10000);
events.ScheduleEvent(EVENT_VANISH, urand(25000, 35000));
- events.ScheduleEvent(EVENT_FLAME_SPHERE, 5000);
+ events.ScheduleEvent(EVENT_CONJURE_FLAME_SPHERES, 5000);
+ }
+
+ void JustSummoned(Creature* summon)
+ {
+ BossAI::JustSummoned(summon);
+
+ switch (summon->GetEntry())
+ {
+ case NPC_FLAME_SPHERE_1:
+ case NPC_FLAME_SPHERE_2:
+ case NPC_FLAME_SPHERE_3:
+ summon->AI()->SetGUID(_flameSphereTargetGUID);
+ default:
+ return;
+ }
}
void UpdateAI(uint32 diff) OVERRIDE
@@ -122,80 +136,40 @@ class boss_taldaram : public CreatureScript
{
switch (eventId)
{
- if (events.IsInPhase(PHASE_NORMAL))
- {
- case EVENT_BLOODTHIRST:
- DoCast(me, SPELL_BLOODTHIRST);
- events.ScheduleEvent(EVENT_BLOODTHIRST, 10000);
- break;
- case EVENT_FLAME_SPHERE:
- DoCastVictim(SPELL_CONJURE_FLAME_SPHERE);
- events.SetPhase(PHASE_SPECIAL);
- events.ScheduleEvent(EVENT_CASTING_FLAME_SPHERES, 3000);
- events.ScheduleEvent(EVENT_FLAME_SPHERE, 15000);
- break;
- case EVENT_VANISH:
+ case EVENT_BLOODTHIRST:
+ DoCast(me, SPELL_BLOODTHIRST);
+ events.ScheduleEvent(EVENT_BLOODTHIRST, 10000);
+ break;
+ case EVENT_CONJURE_FLAME_SPHERES:
+ // random target?
+ if (Unit* victim = me->GetVictim())
{
- Map::PlayerList const& players = me->GetMap()->GetPlayers();
- uint32 targets = 0;
- for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
- {
- Player* player = i->GetSource();
- if (player && player->IsAlive())
- ++targets;
- }
-
- if (targets > 2)
- {
- Talk(SAY_VANISH);
- DoCast(me, SPELL_VANISH);
- events.SetPhase(PHASE_SPECIAL);
- events.ScheduleEvent(EVENT_JUST_VANISHED, 500);
- if (Unit* embraceTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- _embraceTargetGUID = embraceTarget->GetGUID();
- }
- events.ScheduleEvent(EVENT_VANISH, urand(25000, 35000));
- break;
+ _flameSphereTargetGUID = victim->GetGUID();
+ DoCast(victim, SPELL_CONJURE_FLAME_SPHERE);
}
- }
- case EVENT_CASTING_FLAME_SPHERES:
+ events.ScheduleEvent(EVENT_CONJURE_FLAME_SPHERES, 15000);
+ break;
+ case EVENT_VANISH:
{
- events.SetPhase(PHASE_NORMAL);
- Unit* sphereTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
- if (!sphereTarget)
- break;
-
- float angle, x, y;
-
- //DoCast(me, SPELL_FLAME_SPHERE_SUMMON_1);
- if (Creature* sphere = DoSpawnCreature(CREATURE_FLAME_SPHERE, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10 * IN_MILLISECONDS))
+ Map::PlayerList const& players = me->GetMap()->GetPlayers();
+ uint32 targets = 0;
+ for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
{
- angle = sphere->GetAngle(sphereTarget);
- x = sphere->GetPositionX() + DATA_SPHERE_DISTANCE * std::cos(angle);
- y = sphere->GetPositionY() + DATA_SPHERE_DISTANCE * std::sin(angle);
- sphere->GetMotionMaster()->MovePoint(0, x, y, sphere->GetPositionZ());
+ Player* player = i->GetSource();
+ if (player && player->IsAlive())
+ ++targets;
}
- if (IsHeroic())
+ if (targets > 2)
{
- //DoCast(me, H_SPELL_FLAME_SPHERE_SUMMON_1);
- if (Creature* sphere = DoSpawnCreature(H_CREATURE_FLAME_SPHERE_1, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10 * IN_MILLISECONDS))
- {
- angle = sphere->GetAngle(sphereTarget) + DATA_SPHERE_ANGLE_OFFSET;
- x = sphere->GetPositionX() + DATA_SPHERE_DISTANCE/2 * std::cos(angle);
- y = sphere->GetPositionY() + DATA_SPHERE_DISTANCE/2 * std::sin(angle);
- sphere->GetMotionMaster()->MovePoint(0, x, y, sphere->GetPositionZ());
- }
-
- //DoCast(me, H_SPELL_FLAME_SPHERE_SUMMON_2);
- if (Creature* sphere = DoSpawnCreature(H_CREATURE_FLAME_SPHERE_2, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10 * IN_MILLISECONDS))
- {
- angle = sphere->GetAngle(sphereTarget) - DATA_SPHERE_ANGLE_OFFSET;
- x = sphere->GetPositionX() + DATA_SPHERE_DISTANCE/2 * std::cos(angle);
- y = sphere->GetPositionY() + DATA_SPHERE_DISTANCE/2 * std::sin(angle);
- sphere->GetMotionMaster()->MovePoint(0, x, y, sphere->GetPositionZ());
- }
+ Talk(SAY_VANISH);
+ DoCast(me, SPELL_VANISH);
+ events.DelayEvents(500);
+ events.ScheduleEvent(EVENT_JUST_VANISHED, 500);
+ if (Unit* embraceTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ _embraceTargetGUID = embraceTarget->GetGUID();
}
+ events.ScheduleEvent(EVENT_VANISH, urand(25000, 35000));
break;
}
case EVENT_JUST_VANISHED:
@@ -218,7 +192,6 @@ class boss_taldaram : public CreatureScript
break;
case EVENT_FEEDING:
_embraceTargetGUID = 0;
- events.SetPhase(PHASE_NORMAL);
break;
default:
break;
@@ -232,13 +205,12 @@ class boss_taldaram : public CreatureScript
{
Unit* embraceTarget = GetEmbraceTarget();
- if (events.IsInPhase(PHASE_SPECIAL) && embraceTarget && embraceTarget->IsAlive())
+ if (embraceTarget && embraceTarget->IsAlive())
{
_embraceTakenDamage += damage;
if (_embraceTakenDamage > DUNGEON_MODE<uint32>(DATA_EMBRACE_DMG, H_DATA_EMBRACE_DMG))
{
_embraceTargetGUID = 0;
- events.SetPhase(PHASE_NORMAL);
me->CastStop();
}
}
@@ -255,12 +227,9 @@ class boss_taldaram : public CreatureScript
if (victim->GetTypeId() != TYPEID_PLAYER)
return;
- Unit* embraceTarget = GetEmbraceTarget();
- if (events.IsInPhase(PHASE_SPECIAL) && embraceTarget && victim == embraceTarget)
- {
+ if (victim->GetGUID() == _embraceTargetGUID)
_embraceTargetGUID = 0;
- events.SetPhase(PHASE_NORMAL);
- }
+
Talk(SAY_SLAY);
}
@@ -289,76 +258,120 @@ class boss_taldaram : public CreatureScript
me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), DATA_GROUND_POSITION_Z, me->GetOrientation());
DoCast(SPELL_HOVER_FALL);
me->SetDisableGravity(false);
- me->GetMotionMaster()->MovePoint(0, me->GetHomePosition());
+ me->GetMotionMaster()->MoveLand(0, me->GetHomePosition());
Talk(SAY_WARNING);
instance->HandleGameObject(instance->GetData64(DATA_PRINCE_TALDARAM_PLATFORM), true);
}
private:
+ uint64 _flameSphereTargetGUID;
uint64 _embraceTargetGUID;
uint32 _embraceTakenDamage;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- return GetAhnKahetAI<boss_taldaramAI>(creature);
+ return GetAhnKahetAI<boss_prince_taldaramAI>(creature);
}
};
-class npc_taldaram_flamesphere : public CreatureScript
+// 30106, 31686, 31687 - Flame Sphere
+class npc_prince_taldaram_flame_sphere : public CreatureScript
{
public:
- npc_taldaram_flamesphere() : CreatureScript("npc_taldaram_flamesphere") { }
+ npc_prince_taldaram_flame_sphere() : CreatureScript("npc_prince_taldaram_flame_sphere") { }
- struct npc_taldaram_flamesphereAI : public ScriptedAI
+ struct npc_prince_taldaram_flame_sphereAI : public ScriptedAI
{
- npc_taldaram_flamesphereAI(Creature* creature) : ScriptedAI(creature)
+ npc_prince_taldaram_flame_sphereAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void Reset() OVERRIDE
{
+ DoCast(me, SPELL_FLAME_SPHERE_SPAWN_EFFECT, true);
+ DoCast(me, SPELL_FLAME_SPHERE_VISUAL, true);
+
+ _flameSphereTargetGUID = 0;
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_START_MOVE, 3 * IN_MILLISECONDS);
+ _events.ScheduleEvent(EVENT_DESPAWN, 13 * IN_MILLISECONDS);
}
- void Reset() OVERRIDE
+ void SetGUID(uint64 guid, int32 /*id = 0*/) OVERRIDE
{
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- //! HACK: Creature's can't have MOVEMENTFLAG_FLYING
- me->AddUnitMovementFlag(MOVEMENTFLAG_FLYING);
- me->setFaction(16);
- me->SetObjectScale(1.0f);
- DoCast(me, SPELL_FLAME_SPHERE_VISUAL);
- DoCast(me, SPELL_FLAME_SPHERE_SPAWN_EFFECT);
- DoCast(me, SPELL_FLAME_SPHERE_PERIODIC);
- _despawnTimer = 10 * IN_MILLISECONDS;
+ _flameSphereTargetGUID = guid;
}
void EnterCombat(Unit* /*who*/) OVERRIDE { }
void MoveInLineOfSight(Unit* /*who*/) OVERRIDE { }
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- DoCast(me, SPELL_FLAME_SPHERE_DEATH_EFFECT);
- }
-
void UpdateAI(uint32 diff) OVERRIDE
{
- if (_despawnTimer <= diff)
- me->DisappearAndDie();
- else
- _despawnTimer -= diff;
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_START_MOVE:
+ {
+ DoCast(me, SPELL_FLAME_SPHERE_PERIODIC, true);
+
+ /// @todo: find correct values
+ float angleOffset = 0.0f;
+ float distOffset = DATA_SPHERE_DISTANCE;
+
+ switch (me->GetEntry())
+ {
+ case NPC_FLAME_SPHERE_1:
+ break;
+ case NPC_FLAME_SPHERE_2:
+ angleOffset = DATA_SPHERE_ANGLE_OFFSET;
+ break;
+ case NPC_FLAME_SPHERE_3:
+ angleOffset = -DATA_SPHERE_ANGLE_OFFSET;
+ break;
+ default:
+ return;
+ }
+
+ Unit* sphereTarget = ObjectAccessor::GetUnit(*me, _flameSphereTargetGUID);
+ if (!sphereTarget)
+ return;
+
+ float angle = me->GetAngle(sphereTarget) + angleOffset;
+ float x = me->GetPositionX() + distOffset * std::cos(angle);
+ float y = me->GetPositionY() + distOffset * std::sin(angle);
+
+ /// @todo: correct speed
+ me->GetMotionMaster()->MovePoint(0, x, y, me->GetPositionZ());
+ break;
+ }
+ case EVENT_DESPAWN:
+ DoCast(me, SPELL_FLAME_SPHERE_DEATH_EFFECT, true);
+ me->DespawnOrUnsummon(1000);
+ break;
+ default:
+ break;
+ }
+ }
}
private:
- uint32 _despawnTimer;
+ EventMap _events;
+ uint64 _flameSphereTargetGUID;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- return new npc_taldaram_flamesphereAI(creature);
+ return new npc_prince_taldaram_flame_sphereAI(creature);
}
};
-class prince_taldaram_sphere : public GameObjectScript
+// 193093, 193094 - Ancient Nerubian Device
+class go_prince_taldaram_sphere : public GameObjectScript
{
public:
- prince_taldaram_sphere() : GameObjectScript("prince_taldaram_sphere") { }
+ go_prince_taldaram_sphere() : GameObjectScript("go_prince_taldaram_sphere") { }
bool OnGossipHello(Player* /*player*/, GameObject* go) OVERRIDE
{
@@ -369,7 +382,6 @@ class prince_taldaram_sphere : public GameObjectScript
Creature* PrinceTaldaram = ObjectAccessor::GetCreature(*go, instance->GetData64(DATA_PRINCE_TALDARAM));
if (PrinceTaldaram && PrinceTaldaram->IsAlive())
{
- // maybe these are hacks :(
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
go->SetGoState(GO_STATE_ACTIVE);
@@ -385,15 +397,88 @@ class prince_taldaram_sphere : public GameObjectScript
break;
}
- CAST_AI(boss_taldaram::boss_taldaramAI, PrinceTaldaram->AI())->CheckSpheres();
+ CAST_AI(boss_prince_taldaram::boss_prince_taldaramAI, PrinceTaldaram->AI())->CheckSpheres();
}
return true;
}
};
+// 55931 - Conjure Flame Sphere
+class spell_prince_taldaram_conjure_flame_sphere : public SpellScriptLoader
+{
+ public:
+ spell_prince_taldaram_conjure_flame_sphere() : SpellScriptLoader("spell_prince_taldaram_conjure_flame_sphere") { }
+
+ class spell_prince_taldaram_conjure_flame_sphere_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_prince_taldaram_conjure_flame_sphere_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_FLAME_SPHERE_SUMMON_1)
+ || !sSpellMgr->GetSpellInfo(SPELL_FLAME_SPHERE_SUMMON_2)
+ || !sSpellMgr->GetSpellInfo(SPELL_FLAME_SPHERE_SUMMON_3))
+ return false;
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+ caster->CastSpell(caster, SPELL_FLAME_SPHERE_SUMMON_1, true);
+
+ if (caster->GetMap()->IsHeroic())
+ {
+ caster->CastSpell(caster, SPELL_FLAME_SPHERE_SUMMON_2, true);
+ caster->CastSpell(caster, SPELL_FLAME_SPHERE_SUMMON_3, true);
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_prince_taldaram_conjure_flame_sphere_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_prince_taldaram_conjure_flame_sphere_SpellScript();
+ }
+};
+
+// 55895, 59511, 59512 - Flame Sphere Summon
+class spell_prince_taldaram_flame_sphere_summon : public SpellScriptLoader
+{
+ public:
+ spell_prince_taldaram_flame_sphere_summon() : SpellScriptLoader("spell_prince_taldaram_flame_sphere_summon") { }
+
+ class spell_prince_taldaram_flame_sphere_summon_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_prince_taldaram_flame_sphere_summon_SpellScript);
+
+ void SetDest(SpellDestination& dest)
+ {
+ Position offset = { 0.0f, 0.0f, 5.5f, 0.0f };
+ dest.RelocateOffset(offset);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_prince_taldaram_flame_sphere_summon_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_prince_taldaram_flame_sphere_summon_SpellScript();
+ }
+};
+
void AddSC_boss_taldaram()
{
- new boss_taldaram();
- new npc_taldaram_flamesphere();
- new prince_taldaram_sphere();
+ new boss_prince_taldaram();
+ new npc_prince_taldaram_flame_sphere();
+ new go_prince_taldaram_sphere();
+ new spell_prince_taldaram_conjure_flame_sphere();
+ new spell_prince_taldaram_flame_sphere_summon();
}
diff --git a/src/server/shared/Cryptography/OpenSSLCrypto.cpp b/src/server/shared/Cryptography/OpenSSLCrypto.cpp
index 10ea595640a..bd72459e9df 100644
--- a/src/server/shared/Cryptography/OpenSSLCrypto.cpp
+++ b/src/server/shared/Cryptography/OpenSSLCrypto.cpp
@@ -33,7 +33,12 @@ static void lockingCallback(int mode, int type, const char* /*file*/, int /*line
static void threadIdCallback(CRYPTO_THREADID * id)
{
+/// ACE_thread_t turns out to be a struct under Mac OS.
+#ifndef __APPLE__
CRYPTO_THREADID_set_numeric(id, ACE_Thread::self());
+#else
+ CRYPTO_THREADID_set_pointer(id, ACE_Thread::self());
+#endif
}
void OpenSSLCrypto::threadsSetup()