mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-19 17:05:44 +01:00
Core/SAI: changed multiple validation checks
This commit is contained in:
@@ -83,13 +83,13 @@ void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint3
|
||||
{
|
||||
for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i)
|
||||
{
|
||||
SMART_EVENT eventType = SMART_EVENT((*i).GetEventType());
|
||||
SMART_EVENT eventType = SMART_EVENT(i->GetEventType());
|
||||
if (eventType == SMART_EVENT_LINK)//special handling
|
||||
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 /*&& (!i->event.event_phase_mask || IsInPhase(i->event.event_phase_mask)) && !(i->event.event_flags & SMART_EVENT_FLAG_NOT_REPEATABLE && i->runOnce)*/)
|
||||
{
|
||||
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());
|
||||
|
||||
if (sConditionMgr->IsObjectMeetToConditions(info, conds))
|
||||
@@ -167,7 +167,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
|
||||
{
|
||||
if (IsCreature(*itr))
|
||||
sCreatureTextMgr->SendChat((*itr)->ToCreature(), uint8(e.action.talk.textGroupID), IsPlayer(GetLastInvoker())? GetLastInvoker() : 0);
|
||||
sCreatureTextMgr->SendChat((*itr)->ToCreature(), uint8(e.action.talk.textGroupID), IsPlayer(GetLastInvoker()) ? GetLastInvoker() : 0);
|
||||
else if (IsPlayer(*itr) && me)
|
||||
{
|
||||
Unit* templastInvoker = GetLastInvoker();
|
||||
@@ -2252,8 +2252,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
|
||||
if (e.link && e.link != e.event_id)
|
||||
{
|
||||
SmartScriptHolder linked = FindLinkedEvent(e.link);
|
||||
if (linked.GetActionType() && linked.GetEventType() == SMART_EVENT_LINK)
|
||||
SmartScriptHolder& linked = SmartAIMgr::FindLinkedEvent(mEvents, e.link);
|
||||
if (linked)
|
||||
ProcessEvent(linked, unit, var0, var1, bvar, spell, gob);
|
||||
else
|
||||
TC_LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.link);
|
||||
@@ -2461,7 +2461,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
|
||||
if (me && me->GetGUID() == (*itr)->GetGUID())
|
||||
continue;
|
||||
|
||||
if (((e.target.unitRange.creature && (*itr)->ToCreature()->GetEntry() == e.target.unitRange.creature) || !e.target.unitRange.creature) && baseObject->IsInRange(*itr, (float)e.target.unitRange.minDist, (float)e.target.unitRange.maxDist))
|
||||
if ((!e.target.unitRange.creature || (*itr)->ToCreature()->GetEntry() == e.target.unitRange.creature) && baseObject->IsInRange(*itr, float(e.target.unitRange.minDist), float(e.target.unitRange.maxDist)))
|
||||
l->push_back(*itr);
|
||||
}
|
||||
|
||||
@@ -2480,7 +2480,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
|
||||
if (me && me->GetGUID() == (*itr)->GetGUID())
|
||||
continue;
|
||||
|
||||
if ((e.target.unitDistance.creature && (*itr)->ToCreature()->GetEntry() == e.target.unitDistance.creature) || !e.target.unitDistance.creature)
|
||||
if (!e.target.unitDistance.creature || (*itr)->ToCreature()->GetEntry() == e.target.unitDistance.creature)
|
||||
l->push_back(*itr);
|
||||
}
|
||||
|
||||
@@ -2499,7 +2499,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
|
||||
if (go && go->GetGUID() == (*itr)->GetGUID())
|
||||
continue;
|
||||
|
||||
if ((e.target.goDistance.entry && (*itr)->ToGameObject()->GetEntry() == e.target.goDistance.entry) || !e.target.goDistance.entry)
|
||||
if (!e.target.goDistance.entry || (*itr)->ToGameObject()->GetEntry() == e.target.goDistance.entry)
|
||||
l->push_back(*itr);
|
||||
}
|
||||
|
||||
@@ -2518,7 +2518,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
|
||||
if (go && go->GetGUID() == (*itr)->GetGUID())
|
||||
continue;
|
||||
|
||||
if (((e.target.goRange.entry && IsGameObject(*itr) && (*itr)->ToGameObject()->GetEntry() == e.target.goRange.entry) || !e.target.goRange.entry) && baseObject->IsInRange((*itr), (float)e.target.goRange.minDist, (float)e.target.goRange.maxDist))
|
||||
if ((!e.target.goRange.entry && (*itr)->ToGameObject()->GetEntry() == e.target.goRange.entry) && baseObject->IsInRange(*itr, float(e.target.goRange.minDist), float(e.target.goRange.maxDist)))
|
||||
l->push_back(*itr);
|
||||
}
|
||||
|
||||
@@ -2527,32 +2527,28 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
|
||||
}
|
||||
case SMART_TARGET_CREATURE_GUID:
|
||||
{
|
||||
Creature* target = NULL;
|
||||
if (!scriptTrigger && !baseObject)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SMART_TARGET_CREATURE_GUID can not be used without invoker");
|
||||
break;
|
||||
}
|
||||
|
||||
target = FindCreatureNear(scriptTrigger ? scriptTrigger : baseObject, e.target.unitGUID.dbGuid);
|
||||
|
||||
if (target && (!e.target.unitGUID.entry || target->GetEntry() == e.target.unitGUID.entry))
|
||||
l->push_back(target);
|
||||
if (Creature* target = FindCreatureNear(scriptTrigger ? scriptTrigger : baseObject, e.target.unitGUID.dbGuid))
|
||||
if (!e.target.unitGUID.entry || target->GetEntry() == e.target.unitGUID.entry)
|
||||
l->push_back(target);
|
||||
break;
|
||||
}
|
||||
case SMART_TARGET_GAMEOBJECT_GUID:
|
||||
{
|
||||
GameObject* target = NULL;
|
||||
if (!scriptTrigger && !baseObject)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SMART_TARGET_GAMEOBJECT_GUID can not be used without invoker");
|
||||
break;
|
||||
}
|
||||
|
||||
target = FindGameObjectNear(scriptTrigger ? scriptTrigger : baseObject, e.target.goGUID.dbGuid);
|
||||
|
||||
if (target && (!e.target.goGUID.entry || target->GetEntry() == e.target.goGUID.entry))
|
||||
l->push_back(target);
|
||||
if (GameObject* target = FindGameObjectNear(scriptTrigger ? scriptTrigger : baseObject, e.target.goGUID.dbGuid))
|
||||
if (!e.target.goGUID.entry || target->GetEntry() == e.target.goGUID.entry)
|
||||
l->push_back(target);
|
||||
break;
|
||||
}
|
||||
case SMART_TARGET_PLAYER_RANGE:
|
||||
@@ -2591,26 +2587,21 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
|
||||
}
|
||||
case SMART_TARGET_CLOSEST_CREATURE:
|
||||
{
|
||||
Creature* target = GetClosestCreatureWithEntry(baseObject, e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100), !e.target.closest.dead);
|
||||
if (target)
|
||||
if (Creature* target = GetClosestCreatureWithEntry(baseObject, e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100), !e.target.closest.dead))
|
||||
l->push_back(target);
|
||||
break;
|
||||
}
|
||||
case SMART_TARGET_CLOSEST_GAMEOBJECT:
|
||||
{
|
||||
GameObject* target = GetClosestGameObjectWithEntry(baseObject, e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100));
|
||||
if (target)
|
||||
if (GameObject* target = GetClosestGameObjectWithEntry(baseObject, e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100)))
|
||||
l->push_back(target);
|
||||
break;
|
||||
}
|
||||
case SMART_TARGET_CLOSEST_PLAYER:
|
||||
{
|
||||
if (me)
|
||||
{
|
||||
Player* target = me->SelectNearestPlayer((float)e.target.playerDistance.dist);
|
||||
if (target)
|
||||
if (Player* target = me->SelectNearestPlayer(float(e.target.playerDistance.dist)))
|
||||
l->push_back(target);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SMART_TARGET_OWNER_OR_SUMMONER:
|
||||
@@ -2643,7 +2634,6 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
|
||||
if (me)
|
||||
if (Unit* target = me->SelectNearestTarget(e.target.closestAttackable.maxDist, e.target.closestAttackable.playerOnly != 0))
|
||||
l->push_back(target);
|
||||
|
||||
break;
|
||||
}
|
||||
case SMART_TARGET_CLOSEST_FRIENDLY:
|
||||
@@ -2651,7 +2641,6 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
|
||||
if (me)
|
||||
if (Unit* target = DoFindClosestFriendlyInRange(e.target.closestFriendly.maxDist, e.target.closestFriendly.playerOnly != 0))
|
||||
l->push_back(target);
|
||||
|
||||
break;
|
||||
}
|
||||
case SMART_TARGET_POSITION:
|
||||
|
||||
@@ -257,21 +257,6 @@ class SmartScript
|
||||
}
|
||||
}
|
||||
}
|
||||
SmartScriptHolder FindLinkedEvent(uint32 link)
|
||||
{
|
||||
if (!mEvents.empty())
|
||||
{
|
||||
for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i)
|
||||
{
|
||||
if (i->event_id == link)
|
||||
{
|
||||
return (*i);
|
||||
}
|
||||
}
|
||||
}
|
||||
SmartScriptHolder s;
|
||||
return s;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -91,7 +91,6 @@ void SmartWaypointMgr::LoadFromDB()
|
||||
while (result->NextRow());
|
||||
|
||||
TC_LOG_INFO("server.loading", ">> Loaded %u SmartAI waypoint paths (total %u waypoints) in %u ms", count, total, GetMSTimeDiffToNow(oldMSTime));
|
||||
|
||||
}
|
||||
|
||||
SmartWaypointMgr::~SmartWaypointMgr()
|
||||
@@ -192,23 +191,23 @@ void SmartAIMgr::LoadSmartAIFromDB()
|
||||
}
|
||||
else
|
||||
{
|
||||
CreatureData const* creature = sObjectMgr->GetCreatureData(uint32(abs(temp.entryOrGuid)));
|
||||
CreatureData const* creature = sObjectMgr->GetCreatureData(uint32(std::abs(temp.entryOrGuid)));
|
||||
if (!creature)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid (%u) does not exist, skipped loading.", uint32(abs(temp.entryOrGuid)));
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid (%u) does not exist, skipped loading.", uint32(std::abs(temp.entryOrGuid)));
|
||||
continue;
|
||||
}
|
||||
|
||||
CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creature->id);
|
||||
if (!creatureInfo)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) does not exist, skipped loading.", creature->id, uint32(abs(temp.entryOrGuid)));
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) does not exist, skipped loading.", creature->id, uint32(std::abs(temp.entryOrGuid)));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (creatureInfo->AIName != "SmartAI")
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) is not using SmartAI, skipped loading.", creature->id, uint32(abs(temp.entryOrGuid)));
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) is not using SmartAI, skipped loading.", creature->id, uint32(std::abs(temp.entryOrGuid)));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -263,26 +262,29 @@ void SmartAIMgr::LoadSmartAIFromDB()
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
// TO-DO: Find better way
|
||||
for (uint8 i = 0; i < SMART_SCRIPT_TYPE_MAX; i++)
|
||||
// Post Loading Validation
|
||||
for (uint8 i = 0; i < SMART_SCRIPT_TYPE_MAX; ++i)
|
||||
{
|
||||
for (auto itr = mEventMap[i].begin(); itr != mEventMap[i].end(); ++itr)
|
||||
for (SmartAIEventMap::iterator itr = mEventMap[i].begin(); itr != mEventMap[i].end(); ++itr)
|
||||
{
|
||||
for (auto e : mEventMap[i][itr->first])
|
||||
for (SmartScriptHolder const& e : itr->second)
|
||||
{
|
||||
bool found = false;
|
||||
if (e.link && e.link != e.event_id)
|
||||
if (e.link)
|
||||
{
|
||||
for (auto linked : mEventMap[i][itr->first])
|
||||
if (!FindLinkedEvent(itr->second, e.link))
|
||||
{
|
||||
if (linked.event_id == e.link)
|
||||
if (linked.GetActionType() && linked.GetEventType() == SMART_EVENT_LINK)
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid",
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid.",
|
||||
e.entryOrGuid, e.GetScriptType(), e.event_id, e.link);
|
||||
}
|
||||
}
|
||||
|
||||
if (e.GetEventType() == SMART_EVENT_LINK)
|
||||
{
|
||||
if (!FindLinkedSourceEvent(itr->second, e.event_id))
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Entry %d SourceType %u, Event %u, Link Source Event not found or invalid. Event will never trigger.",
|
||||
e.entryOrGuid, e.GetScriptType(), e.event_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -301,6 +303,7 @@ bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e)
|
||||
|
||||
if (e.GetActionType() == SMART_ACTION_INSTALL_AI_TEMPLATE)
|
||||
return true; // AI template has special handling
|
||||
|
||||
switch (e.GetTargetType())
|
||||
{
|
||||
case SMART_TARGET_CREATURE_DISTANCE:
|
||||
@@ -379,27 +382,38 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid event type (%u), skipped.", e.entryOrGuid, e.event_id, e.GetEventType());
|
||||
return false;
|
||||
}
|
||||
|
||||
// in SMART_SCRIPT_TYPE_TIMED_ACTIONLIST all event types are overriden by core
|
||||
if (e.GetScriptType() != SMART_SCRIPT_TYPE_TIMED_ACTIONLIST && !(SmartAIEventMask[e.event.type][1] & SmartAITypeMask[e.GetScriptType()][1]))
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d, event type %u can not be used for Script type %u", e.entryOrGuid, e.GetEventType(), e.GetScriptType());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (e.action.type <= 0 || e.action.type >= SMART_ACTION_END)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid action type (%u), skipped.", e.entryOrGuid, e.event_id, e.GetActionType());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (e.event.event_phase_mask > SMART_EVENT_PHASE_ALL)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid phase mask (%u), skipped.", e.entryOrGuid, e.event_id, e.event.event_phase_mask);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (e.event.event_flags > SMART_EVENT_FLAGS_ALL)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid event flags (%u), skipped.", e.entryOrGuid, e.event_id, e.event.event_flags);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (e.link && e.link == e.event_id)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d SourceType %u, Event %u, Event is linking self (infinite loop), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (e.GetScriptType() == SMART_SCRIPT_TYPE_TIMED_ACTIONLIST)
|
||||
{
|
||||
e.event.type = SMART_EVENT_UPDATE_OOC;//force default OOC, can change when calling the script!
|
||||
@@ -411,8 +425,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 type = e.event.type;
|
||||
switch (type)
|
||||
switch (e.GetEventType())
|
||||
{
|
||||
case SMART_EVENT_UPDATE:
|
||||
case SMART_EVENT_UPDATE_IC:
|
||||
@@ -572,17 +585,9 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
break;
|
||||
}
|
||||
case SMART_EVENT_TEXT_OVER:
|
||||
//if (e.event.textOver.textGroupID && !IsTextValid(e, e.event.textOver.textGroupID)) return false;// 0 is a valid text group!
|
||||
break;
|
||||
case SMART_EVENT_LINK:
|
||||
{
|
||||
if (e.link && e.link == e.event_id)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u, Event %u, Link Event is linking self (infinite loop), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id);
|
||||
if (!IsTextValid(e, e.event.textOver.textGroupID))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SMART_EVENT_DUMMY_EFFECT:
|
||||
{
|
||||
if (!IsSpellValid(e, e.event.dummy.spell))
|
||||
@@ -690,6 +695,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case SMART_EVENT_LINK:
|
||||
case SMART_EVENT_GO_STATE_CHANGED:
|
||||
case SMART_EVENT_GO_EVENT_INFORM:
|
||||
case SMART_EVENT_TIMED_EVENT_TRIGGERED:
|
||||
@@ -733,14 +739,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
switch (e.GetActionType())
|
||||
{
|
||||
case SMART_ACTION_TALK:
|
||||
{
|
||||
if (e.GetScriptType() == SMART_SCRIPT_TYPE_CREATURE)
|
||||
{
|
||||
if (!IsTextValid(e, e.action.talk.textGroupID))
|
||||
return false;
|
||||
}
|
||||
case SMART_ACTION_SIMPLE_TALK:
|
||||
if (!IsTextValid(e, e.action.talk.textGroupID))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case SMART_ACTION_SET_FACTION:
|
||||
if (e.action.faction.factionID && !sFactionTemplateStore.LookupEntry(e.action.faction.factionID))
|
||||
{
|
||||
@@ -820,7 +822,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
if (!IsSpellValid(e, e.action.cast.spell))
|
||||
return false;
|
||||
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(e.action.cast.spell);
|
||||
SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(e.action.cast.spell);
|
||||
for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
|
||||
{
|
||||
if (spellInfo->Effects[j].IsEffect(SPELL_EFFECT_KILL_CREDIT) || spellInfo->Effects[j].IsEffect(SPELL_EFFECT_KILL_CREDIT2))
|
||||
@@ -983,10 +985,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
if (!NotNULL(e, e.action.item.count))
|
||||
return false;
|
||||
|
||||
CacheSpellContainerBounds sBounds = GetCreditItemSpellContainerBounds(e.action.item.entry);
|
||||
CacheSpellContainerBounds sBounds = GetCreateItemSpellContainerBounds(e.action.item.entry);
|
||||
for (CacheSpellContainer::const_iterator itr = sBounds.first; itr != sBounds.second; ++itr)
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u Create Item: There is a create item spell for item %u (SpellId: %u effect: %u)",
|
||||
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.item.entry, itr->second.first, itr->second.second);
|
||||
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.item.entry, itr->second.first, itr->second.second);
|
||||
break;
|
||||
}
|
||||
case SMART_ACTION_TELEPORT:
|
||||
@@ -1150,7 +1152,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
case SMART_ACTION_SET_NPC_FLAG:
|
||||
case SMART_ACTION_ADD_NPC_FLAG:
|
||||
case SMART_ACTION_REMOVE_NPC_FLAG:
|
||||
case SMART_ACTION_SIMPLE_TALK:
|
||||
case SMART_ACTION_CROSS_CAST:
|
||||
case SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST:
|
||||
case SMART_ACTION_RANDOM_MOVE:
|
||||
@@ -1181,49 +1182,45 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id) // unused
|
||||
bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id)
|
||||
{
|
||||
bool error = false;
|
||||
if (e.GetScriptType() != SMART_SCRIPT_TYPE_CREATURE)
|
||||
return true;
|
||||
|
||||
uint32 entry = 0;
|
||||
|
||||
if (e.entryOrGuid >= 0)
|
||||
if (e.GetEventType() == SMART_EVENT_TEXT_OVER)
|
||||
{
|
||||
if (e.GetEventType() == SMART_EVENT_TEXT_OVER)
|
||||
{
|
||||
entry = e.event.textOver.creatureEntry;
|
||||
id = e.event.textOver.textGroupID;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (e.GetTargetType())
|
||||
{
|
||||
case SMART_TARGET_CREATURE_DISTANCE:
|
||||
case SMART_TARGET_CREATURE_RANGE:
|
||||
case SMART_TARGET_CLOSEST_CREATURE:
|
||||
return true; // ignore
|
||||
default:
|
||||
entry = uint32(e.entryOrGuid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
entry = e.event.textOver.creatureEntry;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry = uint32(abs(e.entryOrGuid));
|
||||
CreatureData const* data = sObjectMgr->GetCreatureData(entry);
|
||||
if (!data)
|
||||
switch (e.GetTargetType())
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Creature guid %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry);
|
||||
return false;
|
||||
case SMART_TARGET_CREATURE_DISTANCE:
|
||||
case SMART_TARGET_CREATURE_RANGE:
|
||||
case SMART_TARGET_CLOSEST_CREATURE:
|
||||
return true; // ignore
|
||||
default:
|
||||
if (e.entryOrGuid < 0)
|
||||
{
|
||||
entry = uint32(std::abs(e.entryOrGuid));
|
||||
CreatureData const* data = sObjectMgr->GetCreatureData(entry);
|
||||
if (!data)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Creature guid %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
entry = data->id;
|
||||
}
|
||||
else
|
||||
entry = uint32(e.entryOrGuid);
|
||||
break;
|
||||
}
|
||||
else
|
||||
entry = data->id;
|
||||
}
|
||||
|
||||
if (!entry || !sCreatureTextMgr->TextExist(entry, uint8(id)))
|
||||
error = true;
|
||||
|
||||
if (error)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Text id %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), id);
|
||||
return false;
|
||||
@@ -1285,7 +1282,7 @@ CacheSpellContainerBounds SmartAIMgr::GetKillCreditSpellContainerBounds(uint32 k
|
||||
return KillCreditSpellStore.equal_range(killCredit);
|
||||
}
|
||||
|
||||
CacheSpellContainerBounds SmartAIMgr::GetCreditItemSpellContainerBounds(uint32 itemId) const
|
||||
CacheSpellContainerBounds SmartAIMgr::GetCreateItemSpellContainerBounds(uint32 itemId) const
|
||||
{
|
||||
return CreateItemSpellStore.equal_range(itemId);
|
||||
}
|
||||
|
||||
@@ -1347,6 +1347,8 @@ struct SmartScriptHolder
|
||||
bool active;
|
||||
bool runOnce;
|
||||
bool enableTimed;
|
||||
|
||||
operator bool() const { return entryOrGuid != 0; }
|
||||
};
|
||||
|
||||
typedef std::unordered_map<uint32, WayPoint*> WPPath;
|
||||
@@ -1469,6 +1471,30 @@ class SmartAIMgr
|
||||
}
|
||||
}
|
||||
|
||||
static SmartScriptHolder& FindLinkedSourceEvent(SmartAIEventList& list, uint32 eventId)
|
||||
{
|
||||
SmartAIEventList::iterator itr = std::find_if(list.begin(), list.end(),
|
||||
[eventId](SmartScriptHolder& source) { return source.link == eventId; });
|
||||
|
||||
if (itr != list.end())
|
||||
return *itr;
|
||||
|
||||
static SmartScriptHolder SmartScriptHolderDummy;
|
||||
return SmartScriptHolderDummy;
|
||||
}
|
||||
|
||||
static SmartScriptHolder& FindLinkedEvent(SmartAIEventList& list, uint32 link)
|
||||
{
|
||||
SmartAIEventList::iterator itr = std::find_if(list.begin(), list.end(),
|
||||
[link](SmartScriptHolder& linked) { return linked.event_id == link && linked.GetEventType() == SMART_EVENT_LINK; });
|
||||
|
||||
if (itr != list.end())
|
||||
return *itr;
|
||||
|
||||
static SmartScriptHolder SmartScriptHolderDummy;
|
||||
return SmartScriptHolderDummy;
|
||||
}
|
||||
|
||||
private:
|
||||
//event stores
|
||||
SmartAIEventMap mEventMap[SMART_SCRIPT_TYPE_MAX];
|
||||
@@ -1476,16 +1502,6 @@ class SmartAIMgr
|
||||
bool IsEventValid(SmartScriptHolder& e);
|
||||
bool IsTargetValid(SmartScriptHolder const& e);
|
||||
|
||||
/*inline bool IsTargetValid(SmartScriptHolder e, int32 target)
|
||||
{
|
||||
if (target < SMART_TARGET_NONE || target >= SMART_TARGET_END)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid Target type %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), target);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}*/
|
||||
|
||||
bool IsMinMaxValid(SmartScriptHolder const& e, uint32 min, uint32 max)
|
||||
{
|
||||
if (max < min)
|
||||
@@ -1615,7 +1631,7 @@ class SmartAIMgr
|
||||
CacheSpellContainerBounds GetSummonCreatureSpellContainerBounds(uint32 creatureEntry) const;
|
||||
CacheSpellContainerBounds GetSummonGameObjectSpellContainerBounds(uint32 gameObjectEntry) const;
|
||||
CacheSpellContainerBounds GetKillCreditSpellContainerBounds(uint32 killCredit) const;
|
||||
CacheSpellContainerBounds GetCreditItemSpellContainerBounds(uint32 itemId) const;
|
||||
CacheSpellContainerBounds GetCreateItemSpellContainerBounds(uint32 itemId) const;
|
||||
|
||||
CacheSpellContainer SummonCreatureSpellStore;
|
||||
CacheSpellContainer SummonGameObjectSpellStore;
|
||||
|
||||
Reference in New Issue
Block a user