Scripts/SmartAI: SMART_TARGET_INVOKER cleanup step 1. The core will now log errors on start-up if SMART_TARGET_INVOKER abuse is found, but will continue to load the scripts as deprecated for now.

Note that a lot of these scripts may either not currently work, not work reliably, or may be prone to breaking unexpectedly when core internals change. SMART_TARGET_INVOKER is undefined behavior on any event that doesn't directly specify its invoker.

(We are considering options for allowing INVOKER to make sense in timed action lists in a reliable fashion, so they are exempted at this time.)

(cherry picked from commit 482328bddf)
This commit is contained in:
Treeston
2018-02-13 16:38:28 +01:00
committed by Shauren
parent 6c5e170d9f
commit 06b5b8d8b7
5 changed files with 76 additions and 7 deletions

View File

@@ -452,6 +452,63 @@ SmartScriptHolder& SmartAIMgr::FindLinkedEvent(SmartAIEventList& list, uint32 li
return SmartScriptHolderDummy;
}
/*static*/ bool SmartAIMgr::EventHasInvoker(SMART_EVENT event)
{
switch (event)
{ // white list of events that actually have an invoker passed to them
case SMART_EVENT_AGGRO:
case SMART_EVENT_DEATH:
case SMART_EVENT_KILL:
case SMART_EVENT_SUMMONED_UNIT:
case SMART_EVENT_SPELLHIT:
case SMART_EVENT_SPELLHIT_TARGET:
case SMART_EVENT_DAMAGED:
case SMART_EVENT_RECEIVE_HEAL:
case SMART_EVENT_RECEIVE_EMOTE:
case SMART_EVENT_JUST_SUMMONED:
case SMART_EVENT_DAMAGED_TARGET:
case SMART_EVENT_SUMMON_DESPAWNED:
case SMART_EVENT_PASSENGER_BOARDED:
case SMART_EVENT_PASSENGER_REMOVED:
case SMART_EVENT_GOSSIP_HELLO:
case SMART_EVENT_GOSSIP_SELECT:
case SMART_EVENT_ACCEPTED_QUEST:
case SMART_EVENT_REWARD_QUEST:
case SMART_EVENT_FOLLOW_COMPLETED:
case SMART_EVENT_ON_SPELLCLICK:
case SMART_EVENT_GO_LOOT_STATE_CHANGED:
case SMART_EVENT_AREATRIGGER_ONTRIGGER:
case SMART_EVENT_IC_LOS:
case SMART_EVENT_OOC_LOS:
case SMART_EVENT_DISTANCE_CREATURE:
case SMART_EVENT_FRIENDLY_HEALTH:
case SMART_EVENT_FRIENDLY_HEALTH_PCT:
case SMART_EVENT_FRIENDLY_IS_CC:
case SMART_EVENT_FRIENDLY_MISSING_BUFF:
case SMART_EVENT_ACTION_DONE:
case SMART_EVENT_TARGET_HEALTH_PCT:
case SMART_EVENT_TARGET_MANA_PCT:
case SMART_EVENT_RANGE:
case SMART_EVENT_VICTIM_CASTING:
case SMART_EVENT_TARGET_BUFFED:
case SMART_EVENT_IS_BEHIND_TARGET:
case SMART_EVENT_INSTANCE_PLAYER_ENTER:
case SMART_EVENT_TRANSPORT_ADDCREATURE:
case SMART_EVENT_QUEST_ACCEPTED:
case SMART_EVENT_QUEST_OBJ_COPLETETION:
case SMART_EVENT_QUEST_COMPLETION:
case SMART_EVENT_QUEST_FAIL:
case SMART_EVENT_QUEST_REWARDED:
case SMART_EVENT_SCENE_START:
case SMART_EVENT_SCENE_TRIGGER:
case SMART_EVENT_SCENE_CANCEL:
case SMART_EVENT_SCENE_COMPLETE:
return true;
default:
return false;
}
}
bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e)
{
if (std::abs(e.target.o) > 2 * float(M_PI))
@@ -505,6 +562,16 @@ bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e)
}
break;
}
case SMART_TARGET_ACTION_INVOKER:
case SMART_TARGET_ACTION_INVOKER_VEHICLE:
case SMART_TARGET_INVOKER_PARTY:
if (e.GetScriptType() != SMART_SCRIPT_TYPE_TIMED_ACTIONLIST && e.GetEventType() != SMART_EVENT_LINK && !EventHasInvoker(e.event.type))
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u has invoker target, but action does not provide any invoker!", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType());
// allow this to load for now
// return false;
}
break;
case SMART_TARGET_PLAYER_RANGE:
case SMART_TARGET_SELF:
case SMART_TARGET_VICTIM:
@@ -512,11 +579,8 @@ bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e)
case SMART_TARGET_HOSTILE_LAST_AGGRO:
case SMART_TARGET_HOSTILE_RANDOM:
case SMART_TARGET_HOSTILE_RANDOM_NOT_TOP:
case SMART_TARGET_ACTION_INVOKER:
case SMART_TARGET_INVOKER_PARTY:
case SMART_TARGET_POSITION:
case SMART_TARGET_NONE:
case SMART_TARGET_ACTION_INVOKER_VEHICLE:
case SMART_TARGET_OWNER_OR_SUMMONER:
case SMART_TARGET_THREAT_LIST:
case SMART_TARGET_CLOSEST_GAMEOBJECT: