mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 15:40:45 +01:00
AI/SmartScripts: Add param3 to SMART_ACTION_CAST and SMART_ACTION_INVOKER_CAST that allows specific triggered flags to be set (rather than all-or-nothing). Ignored if SMARTCAST_TRIGGERED is not set.
This commit is contained in:
2
sql/updates/world/3.3.5/2016_08_19_01_world.sql
Normal file
2
sql/updates/world/3.3.5/2016_08_19_01_world.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
-- remove old (never used) param values from _CAST and _INVOKER_CAST
|
||||
UPDATE `smart_scripts` SET `action_param3`=0,`action_param4`=0,`action_param5`=0,`action_param6`=0 WHERE `action_type` IN (11,85);
|
||||
@@ -476,14 +476,23 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
if (!IsUnit(*itr))
|
||||
continue;
|
||||
|
||||
if (!(e.action.cast.flags & SMARTCAST_AURA_NOT_PRESENT) || !(*itr)->ToUnit()->HasAura(e.action.cast.spell))
|
||||
if (!(e.action.cast.castFlags & SMARTCAST_AURA_NOT_PRESENT) || !(*itr)->ToUnit()->HasAura(e.action.cast.spell))
|
||||
{
|
||||
TriggerCastFlags triggerFlag = TRIGGERED_NONE;
|
||||
if (e.action.cast.castFlags & SMARTCAST_TRIGGERED)
|
||||
{
|
||||
if (e.action.cast.triggerFlags)
|
||||
triggerFlag = TriggerCastFlags(e.action.cast.triggerFlags);
|
||||
else
|
||||
triggerFlag = TRIGGERED_FULL_MASK;
|
||||
}
|
||||
|
||||
if (me)
|
||||
{
|
||||
if (e.action.cast.flags & SMARTCAST_INTERRUPT_PREVIOUS)
|
||||
if (e.action.cast.castFlags & SMARTCAST_INTERRUPT_PREVIOUS)
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
|
||||
if (e.action.cast.flags & SMARTCAST_COMBAT_MOVE)
|
||||
if (e.action.cast.castFlags & SMARTCAST_COMBAT_MOVE)
|
||||
{
|
||||
// If cast flag SMARTCAST_COMBAT_MOVE is set combat movement will not be allowed
|
||||
// unless target is outside spell range, out of mana, or LOS.
|
||||
@@ -501,13 +510,13 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
ENSURE_AI(SmartAI, me->AI())->SetCombatMove(_allowMove);
|
||||
}
|
||||
|
||||
me->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED) != 0);
|
||||
me->CastSpell((*itr)->ToUnit(), e.action.cast.spell, triggerFlag);
|
||||
}
|
||||
else if (go)
|
||||
go->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED) != 0);
|
||||
go->CastSpell((*itr)->ToUnit(), e.action.cast.spell, triggerFlag);
|
||||
|
||||
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_CAST:: %s: %u casts spell %u on target %u with castflags %u",
|
||||
(me ? me->GetGUID() : go->GetGUID()).GetTypeName(), me ? me->GetGUID().GetCounter() : go->GetGUID().GetCounter(), e.action.cast.spell, (*itr)->GetGUID().GetCounter(), e.action.cast.flags);
|
||||
(me ? me->GetGUID() : go->GetGUID()).GetTypeName(), me ? me->GetGUID().GetCounter() : go->GetGUID().GetCounter(), e.action.cast.spell, (*itr)->GetGUID().GetCounter(), e.action.cast.castFlags);
|
||||
}
|
||||
else
|
||||
TC_LOG_DEBUG("scripts.ai", "Spell %u not cast because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (%s) already has the aura", e.action.cast.spell, (*itr)->GetGUID().ToString().c_str());
|
||||
@@ -531,14 +540,23 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
if (!IsUnit(*itr))
|
||||
continue;
|
||||
|
||||
if (!(e.action.cast.flags & SMARTCAST_AURA_NOT_PRESENT) || !(*itr)->ToUnit()->HasAura(e.action.cast.spell))
|
||||
if (!(e.action.cast.castFlags & SMARTCAST_AURA_NOT_PRESENT) || !(*itr)->ToUnit()->HasAura(e.action.cast.spell))
|
||||
{
|
||||
if (e.action.cast.flags & SMARTCAST_INTERRUPT_PREVIOUS)
|
||||
if (e.action.cast.castFlags & SMARTCAST_INTERRUPT_PREVIOUS)
|
||||
tempLastInvoker->InterruptNonMeleeSpells(false);
|
||||
|
||||
tempLastInvoker->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED) != 0);
|
||||
TriggerCastFlags triggerFlag = TRIGGERED_NONE;
|
||||
if (e.action.cast.castFlags & SMARTCAST_TRIGGERED)
|
||||
{
|
||||
if (e.action.cast.triggerFlags)
|
||||
triggerFlag = TriggerCastFlags(e.action.cast.triggerFlags);
|
||||
else
|
||||
triggerFlag = TRIGGERED_FULL_MASK;
|
||||
}
|
||||
|
||||
tempLastInvoker->CastSpell((*itr)->ToUnit(), e.action.cast.spell, triggerFlag);
|
||||
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_INVOKER_CAST: Invoker %u casts spell %u on target %u with castflags %u",
|
||||
tempLastInvoker->GetGUID().GetCounter(), e.action.cast.spell, (*itr)->GetGUID().GetCounter(), e.action.cast.flags);
|
||||
tempLastInvoker->GetGUID().GetCounter(), e.action.cast.spell, (*itr)->GetGUID().GetCounter(), e.action.cast.castFlags);
|
||||
}
|
||||
else
|
||||
TC_LOG_DEBUG("scripts.ai", "Spell %u not cast because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (%s) already has the aura", e.action.cast.spell, (*itr)->GetGUID().ToString().c_str());
|
||||
@@ -1738,7 +1756,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
}
|
||||
case SMART_ACTION_CROSS_CAST:
|
||||
{
|
||||
ObjectList* casters = GetTargets(CreateEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, 0, 0, SMART_ACTION_NONE, 0, 0, 0, 0, 0, 0, (SMARTAI_TARGETS)e.action.cast.targetType, e.action.cast.targetParam1, e.action.cast.targetParam2, e.action.cast.targetParam3, 0), unit);
|
||||
ObjectList* casters = GetTargets(CreateEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, 0, 0, SMART_ACTION_NONE, 0, 0, 0, 0, 0, 0, (SMARTAI_TARGETS)e.action.crossCast.targetType, e.action.crossCast.targetParam1, e.action.crossCast.targetParam2, e.action.crossCast.targetParam3, 0), unit);
|
||||
if (!casters)
|
||||
break;
|
||||
|
||||
@@ -1763,18 +1781,18 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
if (!IsUnit(*it))
|
||||
continue;
|
||||
|
||||
if (!(e.action.cast.flags & SMARTCAST_AURA_NOT_PRESENT) || !(*it)->ToUnit()->HasAura(e.action.cast.spell))
|
||||
if (!(e.action.crossCast.castFlags & SMARTCAST_AURA_NOT_PRESENT) || !(*it)->ToUnit()->HasAura(e.action.crossCast.spell))
|
||||
{
|
||||
if (!interruptedSpell && e.action.cast.flags & SMARTCAST_INTERRUPT_PREVIOUS)
|
||||
if (!interruptedSpell && e.action.crossCast.castFlags & SMARTCAST_INTERRUPT_PREVIOUS)
|
||||
{
|
||||
targetUnit->InterruptNonMeleeSpells(false);
|
||||
interruptedSpell = true;
|
||||
}
|
||||
|
||||
targetUnit->CastSpell((*it)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED) != 0);
|
||||
targetUnit->CastSpell((*it)->ToUnit(), e.action.crossCast.spell, (e.action.crossCast.castFlags & SMARTCAST_TRIGGERED) != 0);
|
||||
}
|
||||
else
|
||||
TC_LOG_DEBUG("scripts.ai", "Spell %u not cast because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (%s) already has the aura", e.action.cast.spell, (*it)->GetGUID().ToString().c_str());
|
||||
TC_LOG_DEBUG("scripts.ai", "Spell %u not cast because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (%s) already has the aura", e.action.crossCast.spell, (*it)->GetGUID().ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3385,7 +3403,7 @@ void SmartScript::UpdateTimer(SmartScriptHolder& e, uint32 const diff)
|
||||
// delay spell cast event if another spell is being cast
|
||||
if (e.GetActionType() == SMART_ACTION_CAST)
|
||||
{
|
||||
if (!(e.action.cast.flags & SMARTCAST_INTERRUPT_PREVIOUS))
|
||||
if (!(e.action.cast.castFlags & SMARTCAST_INTERRUPT_PREVIOUS))
|
||||
{
|
||||
if (me && me->HasUnitState(UNIT_STATE_CASTING))
|
||||
{
|
||||
|
||||
@@ -446,7 +446,7 @@ enum SMART_ACTION
|
||||
SMART_ACTION_SET_REACT_STATE = 8, // state
|
||||
SMART_ACTION_ACTIVATE_GOBJECT = 9, //
|
||||
SMART_ACTION_RANDOM_EMOTE = 10, // EmoteId1, EmoteId2, EmoteId3...
|
||||
SMART_ACTION_CAST = 11, // SpellId, CastFlags
|
||||
SMART_ACTION_CAST = 11, // SpellId, CastFlags, TriggeredFlags
|
||||
SMART_ACTION_SUMMON_CREATURE = 12, // CreatureID, summonType, duration in ms, attackInvoker
|
||||
SMART_ACTION_THREAT_SINGLE_PCT = 13, // Threat%
|
||||
SMART_ACTION_THREAT_ALL_PCT = 14, // Threat%
|
||||
@@ -614,12 +614,19 @@ struct SmartAction
|
||||
struct
|
||||
{
|
||||
uint32 spell;
|
||||
uint32 flags;
|
||||
uint32 castFlags;
|
||||
uint32 triggerFlags;
|
||||
} cast;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32 spell;
|
||||
uint32 castFlags;
|
||||
uint32 targetType;
|
||||
uint32 targetParam1;
|
||||
uint32 targetParam2;
|
||||
uint32 targetParam3;
|
||||
} cast;
|
||||
} crossCast;
|
||||
|
||||
struct
|
||||
{
|
||||
|
||||
@@ -1780,7 +1780,12 @@ void GameObject::Use(Unit* user)
|
||||
CastSpell(user, spellId);
|
||||
}
|
||||
|
||||
void GameObject::CastSpell(Unit* target, uint32 spellId, bool triggered /*= true*/)
|
||||
void GameObject::CastSpell(Unit* target, uint32 spellId, bool triggered /* = true*/)
|
||||
{
|
||||
CastSpell(target, spellId, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE);
|
||||
}
|
||||
|
||||
void GameObject::CastSpell(Unit* target, uint32 spellId, TriggerCastFlags triggered)
|
||||
{
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
if (!spellInfo)
|
||||
|
||||
@@ -832,6 +832,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
|
||||
GameObject* LookupFishingHoleAround(float range);
|
||||
|
||||
void CastSpell(Unit* target, uint32 spell, bool triggered = true);
|
||||
void CastSpell(Unit* target, uint32 spell, TriggerCastFlags triggered);
|
||||
void SendCustomAnim(uint32 anim);
|
||||
bool IsInRange(float x, float y, float z, float radius) const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user