Core/SmartAI: some error checks for actionlists, and enabled lists for GOs

--HG--
branch : trunk
This commit is contained in:
Rat
2010-12-07 20:25:45 +01:00
parent bb09a4a50f
commit cebf8590e3
4 changed files with 53 additions and 7 deletions

View File

@@ -790,8 +790,10 @@ void SmartAI::SetFollow(Unit* target, float dist, float angle, uint32 credit, ui
mFollowCreditType = creditType;
}
void SmartAI::SetScript9(SmartScriptHolder &e, uint32 entry)
void SmartAI::SetScript9(SmartScriptHolder &e, uint32 entry, Unit* invoker)
{
if (invoker)
GetScript()->mLastInvoker = invoker;
GetScript()->SetScript9(e, entry);
}
/*
@@ -889,6 +891,13 @@ void SmartGameObjectAI::SetData(uint32 id, uint32 value)
GetScript()->ProcessEventsFor(SMART_EVENT_DATA_SET, NULL, id, value);
}
void SmartGameObjectAI::SetScript9(SmartScriptHolder &e, uint32 entry, Unit* invoker)
{
if (invoker)
GetScript()->mLastInvoker = invoker;
GetScript()->SetScript9(e, entry);
}
class SmartTrigger : public AreaTriggerScript
{
public:

View File

@@ -65,7 +65,7 @@ class SmartAI : public CreatureAI
void SetCombatMove(bool on);
void SetFollow(Unit* target, float dist = 0.0f, float angle = 0.0f, uint32 credit = 0, uint32 end = 0, uint32 creditType = 0);
void SetScript9(SmartScriptHolder &e, uint32 entry);
void SetScript9(SmartScriptHolder &e, uint32 entry, Unit* invoker);
SmartScript* GetScript() { return &mScript; }
bool IsEscortInvokerInRange();
@@ -248,6 +248,7 @@ public:
uint32 GetDialogStatus(Player* /*player*/);
void Destroyed(Player* player, uint32 eventId);
void SetData(uint32 id, uint32 value);
void SetScript9(SmartScriptHolder &e, uint32 entry, Unit* invoker);
protected:
GameObject * const go;

View File

@@ -1063,6 +1063,11 @@ void SmartScript::ProcessAction(SmartScriptHolder &e, Unit* unit, uint32 var0, u
}
case SMART_ACTION_CALL_TIMED_ACTIONLIST:
{
if (e.GetTargetType() == SMART_TARGET_NONE)
{
sLog.outErrorDb("SmartScript: Entry %d SourceType %u Event %u Action %u is using TARGET_NONE(0) for Script9 target. Please correct target_type in database.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType());
return;
}
ObjectList* targets = GetTargets(e, unit);
if (targets)
{
@@ -1071,7 +1076,11 @@ void SmartScript::ProcessAction(SmartScriptHolder &e, Unit* unit, uint32 var0, u
if (Creature* target = (*itr)->ToCreature())
{
if (IsSmart(target))
CAST_AI(SmartAI, target->AI())->SetScript9(e, e.action.timedActionList.id);
CAST_AI(SmartAI, target->AI())->SetScript9(e, e.action.timedActionList.id, mLastInvoker);
} else if (GameObject* target = (*itr)->ToGameObject())
{
if (IsSmartGO(target))
CAST_AI(SmartGameObjectAI, target->AI())->SetScript9(e, e.action.timedActionList.id, mLastInvoker);
}
}
}
@@ -1147,6 +1156,11 @@ void SmartScript::ProcessAction(SmartScriptHolder &e, Unit* unit, uint32 var0, u
}
}
uint32 id = temp[urand(0, count)];
if (e.GetTargetType() == SMART_TARGET_NONE)
{
sLog.outErrorDb("SmartScript: Entry %d SourceType %u Event %u Action %u is using TARGET_NONE(0) for Script9 target. Please correct target_type in database.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType());
return;
}
ObjectList* targets = GetTargets(e, unit);
if (targets)
{
@@ -1155,7 +1169,11 @@ void SmartScript::ProcessAction(SmartScriptHolder &e, Unit* unit, uint32 var0, u
if (Creature* target = (*itr)->ToCreature())
{
if (IsSmart(target))
CAST_AI(SmartAI, target->AI())->SetScript9(e, id);
CAST_AI(SmartAI, target->AI())->SetScript9(e, id, mLastInvoker);
} else if (GameObject* target = (*itr)->ToGameObject())
{
if (IsSmartGO(target))
CAST_AI(SmartGameObjectAI, target->AI())->SetScript9(e, id, mLastInvoker);
}
}
}
@@ -1164,6 +1182,11 @@ void SmartScript::ProcessAction(SmartScriptHolder &e, Unit* unit, uint32 var0, u
case SMART_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST:
{
uint32 id = urand(e.action.randTimedActionList.entry1, e.action.randTimedActionList.entry2);
if (e.GetTargetType() == SMART_TARGET_NONE)
{
sLog.outErrorDb("SmartScript: Entry %d SourceType %u Event %u Action %u is using TARGET_NONE(0) for Script9 target. Please correct target_type in database.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType());
return;
}
ObjectList* targets = GetTargets(e, unit);
if (targets)
{
@@ -1172,7 +1195,11 @@ void SmartScript::ProcessAction(SmartScriptHolder &e, Unit* unit, uint32 var0, u
if (Creature* target = (*itr)->ToCreature())
{
if (IsSmart(target))
CAST_AI(SmartAI, target->AI())->SetScript9(e, id);
CAST_AI(SmartAI, target->AI())->SetScript9(e, id, mLastInvoker);
} else if (GameObject* target = (*itr)->ToGameObject())
{
if (IsSmartGO(target))
CAST_AI(SmartGameObjectAI, target->AI())->SetScript9(e, id, mLastInvoker);
}
}
}

View File

@@ -111,7 +111,16 @@ class SmartScript
if (c && c->GetAIName() != "SmartAI") smart = false;
if (!me || me->GetAIName() != "SmartAI") smart = false;
if (!smart)
sLog.outErrorDb("SmartScript: Action target creature(entry: %u) is not using SmartAI, action skipped to prevent crash.", c?c->GetEntry():(me?me->GetEntry():0));
sLog.outErrorDb("SmartScript: Action target Creature(entry: %u) is not using SmartAI, action skipped to prevent crash.", c?c->GetEntry():(me?me->GetEntry():0));
return smart;
}
bool IsSmartGO(GameObject* g = NULL)
{
bool smart = true;
if (g && g->GetAIName() != "SmartGameObjectAI") smart = false;
if (!go || go->GetAIName() != "SmartGameObjectAI") smart = false;
if (!smart)
sLog.outErrorDb("SmartScript: Action target GameObject(entry: %u) is not using SmartGameObjectAI, action skipped to prevent crash.", g?g->GetEntry():(go?go->GetEntry():0));
return smart;
}
ObjectList* GetTargetList(uint32 id)
@@ -182,6 +191,7 @@ class SmartScript
//TIMED_ACTIONLIST (script type 9 aka script9)
void SetScript9(SmartScriptHolder &e, uint32 entry);
Unit* mLastInvoker;
private:
void IncPhase(int32 p = 1) {
@@ -217,7 +227,6 @@ class SmartScript
uint64 mTextGUID;
Creature* talker;
bool mUseTextTimer;
Unit* mLastInvoker;
SMARTAI_TEMPLATE mTemplate;
void InstallEvents();