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:
treeston
2016-08-19 15:23:19 +02:00
parent 14b44af38d
commit 9072e0221b
5 changed files with 53 additions and 20 deletions

View 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);

View File

@@ -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))
{

View File

@@ -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
{

View File

@@ -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)

View File

@@ -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;