feat(Core/SmartScripts): SMART_EVENT_EVENT_PHASE_CHANGE (#10054)

* cherry-pick commit (https://github.com/TrinityCore/TrinityCore/commit/619a5534c5f6ce5e736b22e645f7bac72eba9b16)
This commit is contained in:
IntelligentQuantum
2022-04-17 04:25:52 +04:30
committed by GitHub
parent 02ba514f0a
commit e38a17d2da
4 changed files with 92 additions and 24 deletions
@@ -105,7 +105,7 @@ void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint3
if (eventType == SMART_EVENT_LINK)//special handling if (eventType == SMART_EVENT_LINK)//special handling
continue; continue;
if (eventType == e/* && (!(*i).event.event_phase_mask || IsInPhase((*i).event.event_phase_mask)) && !((*i).event.event_flags & SMART_EVENT_FLAG_NOT_REPEATABLE && (*i).runOnce)*/) if (eventType == e)
{ {
ConditionList conds = sConditionMgr->GetConditionsForSmartEvent((*i).entryOrGuid, (*i).event_id, (*i).source_type); ConditionList conds = sConditionMgr->GetConditionsForSmartEvent((*i).entryOrGuid, (*i).event_id, (*i).source_type);
ConditionSourceInfo info = ConditionSourceInfo(unit, GetBaseObject(), me ? me->GetVictim() : nullptr); ConditionSourceInfo info = ConditionSourceInfo(unit, GetBaseObject(), me ? me->GetVictim() : nullptr);
@@ -1496,6 +1496,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
unitTarget->AttackStop(); unitTarget->AttackStop();
} }
} }
delete targets;
break; break;
} }
case SMART_ACTION_SUMMON_CREATURE: case SMART_ACTION_SUMMON_CREATURE:
@@ -4456,6 +4458,16 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
ProcessAction(e, unit, var0, var1); ProcessAction(e, unit, var0, var1);
break; break;
} }
case SMART_EVENT_EVENT_PHASE_CHANGE:
{
if (!IsInPhase(e.event.eventPhaseChange.phasemask))
{
return;
}
ProcessAction(e, GetLastInvoker());
break;
}
case SMART_EVENT_GAME_EVENT_START: case SMART_EVENT_GAME_EVENT_START:
case SMART_EVENT_GAME_EVENT_END: case SMART_EVENT_GAME_EVENT_END:
{ {
@@ -5092,3 +5104,43 @@ Unit* SmartScript::GetLastInvoker(Unit* invoker)
return ObjectAccessor::GetUnit(*invoker, mLastInvoker); return ObjectAccessor::GetUnit(*invoker, mLastInvoker);
return nullptr; return nullptr;
} }
void SmartScript::IncPhase(uint32 p)
{
// protect phase from overflowing
SetPhase(std::min<uint32>(SMART_EVENT_PHASE_12, mEventPhase + p));
}
void SmartScript::DecPhase(uint32 p)
{
if (p >= mEventPhase)
{
SetPhase(0);
}
else
{
SetPhase(mEventPhase - p);
}
}
void SmartScript::SetPhase(uint32 p)
{
uint32 oldPhase = mEventPhase;
mEventPhase = p;
if (oldPhase != mEventPhase)
{
ProcessEventsFor(SMART_EVENT_EVENT_PHASE_CHANGE);
}
}
bool SmartScript::IsInPhase(uint32 p) const
{
if (mEventPhase == 0)
{
return false;
}
return ((1 << (mEventPhase - 1)) & p) != 0;
}
+4 -20
View File
@@ -258,26 +258,10 @@ public:
void SetPhaseReset(bool allow) { _allowPhaseReset = allow; } void SetPhaseReset(bool allow) { _allowPhaseReset = allow; }
private: private:
void IncPhase(uint32 p) void IncPhase(uint32 p);
{ void DecPhase(uint32 p);
// Xinef: protect phase from overflowing void SetPhase(uint32 p);
mEventPhase = std::min<uint32>(SMART_EVENT_PHASE_12, mEventPhase + p); bool IsInPhase(uint32 p) const;
}
void DecPhase(uint32 p)
{
if (p >= mEventPhase)
mEventPhase = 0;
else
mEventPhase -= p;
}
bool IsInPhase(uint32 p) const
{
if (mEventPhase == 0)
return false;
return (1 << (mEventPhase - 1)) & p;
}
void SetPhase(uint32 p = 0) { mEventPhase = p; }
SmartAIEventList mEvents; SmartAIEventList mEvents;
SmartAIEventList mInstallEvents; SmartAIEventList mInstallEvents;
@@ -528,7 +528,7 @@ bool SmartAIMgr::CheckUnusedEventParams(SmartScriptHolder const& e)
case SMART_EVENT_JUST_CREATED: return NO_PARAMS; case SMART_EVENT_JUST_CREATED: return NO_PARAMS;
case SMART_EVENT_GOSSIP_HELLO: return sizeof(SmartEvent::gossipHello); case SMART_EVENT_GOSSIP_HELLO: return sizeof(SmartEvent::gossipHello);
case SMART_EVENT_FOLLOW_COMPLETED: return NO_PARAMS; case SMART_EVENT_FOLLOW_COMPLETED: return NO_PARAMS;
// case SMART_EVENT_EVENT_PHASE_CHANGE: return sizeof(SmartEvent::eventPhaseChange); case SMART_EVENT_EVENT_PHASE_CHANGE: return sizeof(SmartEvent::eventPhaseChange);
case SMART_EVENT_IS_BEHIND_TARGET: return sizeof(SmartEvent::behindTarget); case SMART_EVENT_IS_BEHIND_TARGET: return sizeof(SmartEvent::behindTarget);
case SMART_EVENT_GAME_EVENT_START: return sizeof(SmartEvent::gameEvent); case SMART_EVENT_GAME_EVENT_START: return sizeof(SmartEvent::gameEvent);
case SMART_EVENT_GAME_EVENT_END: return sizeof(SmartEvent::gameEvent); case SMART_EVENT_GAME_EVENT_END: return sizeof(SmartEvent::gameEvent);
@@ -1076,6 +1076,27 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
} }
break; break;
} }
case SMART_EVENT_EVENT_PHASE_CHANGE:
{
if (!e.event.eventPhaseChange.phasemask)
{
LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} has no param set, event won't be executed!.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
return false;
}
if (e.event.eventPhaseChange.phasemask > SMART_EVENT_PHASE_ALL)
{
LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} uses invalid phasemask {}, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.eventPhaseChange.phasemask);
return false;
}
if (e.event.event_phase_mask && !(e.event.event_phase_mask & e.event.eventPhaseChange.phasemask))
{
LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} uses event phasemask {} and incompatible event_param1 {}, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.event_phase_mask, e.event.eventPhaseChange.phasemask);
return false;
}
break;
}
case SMART_EVENT_IS_BEHIND_TARGET: case SMART_EVENT_IS_BEHIND_TARGET:
if (!IsMinMaxValid(e, e.event.behindTarget.cooldownMin, e.event.behindTarget.cooldownMax)) if (!IsMinMaxValid(e, e.event.behindTarget.cooldownMin, e.event.behindTarget.cooldownMax))
return false; return false;
@@ -170,7 +170,7 @@ enum SMART_EVENT
SMART_EVENT_JUST_CREATED = 63, // none SMART_EVENT_JUST_CREATED = 63, // none
SMART_EVENT_GOSSIP_HELLO = 64, // event_para_1 (only) 0 = no filter set, always execute action, 1 = GossipHello only filter set, skip action if reportUse, 2 = reportUse only filter set, skip action if GossipHello SMART_EVENT_GOSSIP_HELLO = 64, // event_para_1 (only) 0 = no filter set, always execute action, 1 = GossipHello only filter set, skip action if reportUse, 2 = reportUse only filter set, skip action if GossipHello
SMART_EVENT_FOLLOW_COMPLETED = 65, // none SMART_EVENT_FOLLOW_COMPLETED = 65, // none
SMART_EVENT_UNUSED_66 = 66, // UNUSED SMART_EVENT_EVENT_PHASE_CHANGE = 66, // event phase mask (<= SMART_EVENT_PHASE_ALL)
SMART_EVENT_IS_BEHIND_TARGET = 67, // cooldownMin, CooldownMax SMART_EVENT_IS_BEHIND_TARGET = 67, // cooldownMin, CooldownMax
SMART_EVENT_GAME_EVENT_START = 68, // game_event.Entry SMART_EVENT_GAME_EVENT_START = 68, // game_event.Entry
SMART_EVENT_GAME_EVENT_END = 69, // game_event.Entry SMART_EVENT_GAME_EVENT_END = 69, // game_event.Entry
@@ -376,6 +376,17 @@ struct SmartEvent
uint32 action; uint32 action;
} gossip; } gossip;
struct
{
uint32 spell;
uint32 effIndex;
} dummy;
struct
{
uint32 phasemask;
} eventPhaseChange;
struct struct
{ {
uint32 cooldownMin; uint32 cooldownMin;
@@ -1677,7 +1688,7 @@ const uint32 SmartAIEventMask[SMART_EVENT_AC_END][2] =
{SMART_EVENT_JUST_CREATED, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, {SMART_EVENT_JUST_CREATED, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },
{SMART_EVENT_GOSSIP_HELLO, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, {SMART_EVENT_GOSSIP_HELLO, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },
{SMART_EVENT_FOLLOW_COMPLETED, SMART_SCRIPT_TYPE_MASK_CREATURE }, {SMART_EVENT_FOLLOW_COMPLETED, SMART_SCRIPT_TYPE_MASK_CREATURE },
{SMART_EVENT_UNUSED_66, 0}, {SMART_EVENT_EVENT_PHASE_CHANGE, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },
{SMART_EVENT_IS_BEHIND_TARGET, SMART_SCRIPT_TYPE_MASK_CREATURE }, {SMART_EVENT_IS_BEHIND_TARGET, SMART_SCRIPT_TYPE_MASK_CREATURE },
{SMART_EVENT_GAME_EVENT_START, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, {SMART_EVENT_GAME_EVENT_START, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },
{SMART_EVENT_GAME_EVENT_END, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, {SMART_EVENT_GAME_EVENT_END, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },