diff --git a/includes/smartAI.class.php b/includes/smartAI.class.php index b4678ff1..31c4c975 100644 --- a/includes/smartAI.class.php +++ b/includes/smartAI.class.php @@ -19,6 +19,302 @@ class SmartAI private $quotes = []; private $summons = null; + /*********************/ + /* Lookups by action */ + /*********************/ + + public static function getOwnerOfNPCSummon(int $npcId, int $typeFilter = 0) : array + { + if ($npcId <= 0) + return []; + + $lookup = array( + SAI_ACTION_SUMMON_CREATURE => [1 => $npcId], + SAI_ACTION_MOUNT_TO_ENTRY_OR_MODEL => [1 => $npcId] + ); + + if ($npcGuids = DB::Aowow()->selectCol('SELECT guid FROM ?_spawns WHERE `type` = ?d AND `typeId` = ?d', TYPE_NPC, $npcId)) + if ($groups = DB::World()->selectCol('SELECT `groupId` FROM spawn_group WHERE `spawnType` = 0 AND `spawnId` IN (?a)', $npcGuids)) + foreach ($groups as $g) + $lookup[SAI_ACTION_SPAWN_SPAWNGROUP][1] = $g; + + $result = self::getActionOwner($lookup, $typeFilter); + + // can skip lookups for SAI_ACTION_SUMMON_CREATURE_GROUP as creature_summon_groups already contains summoner info + if ($sgs = DB::World()->select('SELECT `summonerType` AS "0", `summonerId` AS "1" FROM creature_summon_groups WHERE `entry` = ?d', $npcId)) + foreach ($sgs as [$type, $typeId]) + $result[$type][] = $typeId; + + return $result; + } + + public static function getOwnerOfObjectSummon(int $objectId, int $typeFilter = 0) : array + { + if ($objectId <= 0) + return []; + + $lookup = array( + SAI_ACTION_SUMMON_GO => [1 => $objectId] + ); + + if ($objGuids = DB::Aowow()->selectCol('SELECT guid FROM ?_spawns WHERE `type` = ?d AND `typeId` = ?d', TYPE_OBJECT, $objectId)) + if ($groups = DB::World()->selectCol('SELECT `groupId` FROM spawn_group WHERE `spawnType` = 1 AND `spawnId` IN (?a)', $objGuids)) + foreach ($groups as $g) + $lookup[SAI_ACTION_SPAWN_SPAWNGROUP][1] = $g; + + return self::getActionOwner($lookup, $typeFilter); + } + + public static function getOwnerOfSpellCast(int $spellId, int $typeFilter = 0) : array + { + if ($spellId <= 0) + return []; + + $lookup = array( + SAI_ACTION_CAST => [1 => $spellId], + SAI_ACTION_ADD_AURA => [1 => $spellId], + SAI_ACTION_SELF_CAST => [1 => $spellId], + SAI_ACTION_CROSS_CAST => [1 => $spellId], + SAI_ACTION_INVOKER_CAST => [1 => $spellId] + ); + + return self::getActionOwner($lookup, $typeFilter); + } + + public static function getOwnerOfSoundPlayed(int $soundId, int $typeFilter = 0) : array + { + if ($soundId <= 0) + return []; + + $lookup = array( + SAI_ACTION_SOUND => [1 => $soundId] + ); + + return self::getActionOwner($lookup, $typeFilter); + } + + private static function getActionOwner(array $lookup, int $typeFilter = 0) : array + { + $qParts = []; + $result = []; + $genLimit = $talLimit = []; + switch ($typeFilter) + { + case TYPE_NPC: + $genLimit = [SAI_SRC_TYPE_CREATURE, SAI_SRC_TYPE_ACTIONLIST]; + $talLimit = [SAI_SRC_TYPE_CREATURE]; + break; + case TYPE_OBJECT: + $genLimit = [SAI_SRC_TYPE_OBJECT, SAI_SRC_TYPE_ACTIONLIST]; + $talLimit = [SAI_SRC_TYPE_OBJECT]; + break; + case TYPE_AREATRIGGER: + $genLimit = [SAI_SRC_TYPE_AREATRIGGER, SAI_SRC_TYPE_ACTIONLIST]; + $talLimit = [SAI_SRC_TYPE_AREATRIGGER]; + break; + } + + foreach ($lookup as $action => $params) + { + $aq = '(`action_type` = '.(int)$action.' AND ('; + $pq = []; + foreach ($params as $idx => $p) + $pq[] = '`action_param'.(int)$idx.'` = '.(int)$p; + + if ($pq) + $qParts[] = $aq.implode(' OR ', $pq).'))'; + } + + $smartS = DB::World()->select(sprintf('SELECT `source_type` AS "0", `entryOrGUID` AS "1" FROM smart_scripts WHERE (%s){ AND `source_type` IN (?a)} GROUP BY "0", "1"', $qParts ? implode(' OR ', $qParts) : '0'), $genLimit ?: DBSIMPLE_SKIP); + + // filter for TAL shenanigans + if ($smartTAL = array_filter($smartS, function ($x) {return $x[0] == SAI_SRC_TYPE_ACTIONLIST;})) + { + $smartS = array_diff_key($smartS, $smartTAL); + + $q = []; + foreach ($smartTAL as [, $eog]) + { + // SAI_ACTION_CALL_TIMED_ACTIONLIST + $q[] = '`action_type` = '.SAI_ACTION_CALL_TIMED_ACTIONLIST.' AND `action_param1` = '.$eog; + + // SAI_ACTION_CALL_RANDOM_TIMED_ACTIONLIST + $q[] = '`action_type` = '.SAI_ACTION_CALL_RANDOM_TIMED_ACTIONLIST.' AND (`action_param1` = '.$eog.' OR `action_param2` = '.$eog.' OR `action_param3` = '.$eog.' OR `action_param4` = '.$eog.' OR `action_param5` = '.$eog.')'; + + // SAI_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST + $q[] = '`action_type` = '.SAI_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST.' AND `action_param1` <= '.$eog.' AND `action_param2` >= '.$eog; + } + + if ($_ = DB::World()->select(sprintf('SELECT `source_type` AS "0", `entryOrGUID` AS "1" FROM smart_scripts WHERE ((%s)){ AND `source_type` IN (?a)} GROUP BY "0", "1"', $q ? implode(') OR (', $q) : '0'), $talLimit ?: DBSIMPLE_SKIP)) + $smartS = array_merge($smartS, $_); + } + + // filter guids for entries + if ($smartG = array_filter($smartS, function ($x) {return $x[1] < 0;})) + { + $smartS = array_diff_key($smartS, $smartG); + + $q = []; + foreach ($smartG as [$st, $eog]) + { + if ($st == SAI_SRC_TYPE_CREATURE) + $q[] = '`type` = '.TYPE_NPC.' AND `guid` = '.-$eog; + else if ($st == SAI_SRC_TYPE_OBJECT) + $q[] = '`type` = '.TYPE_OBJECT.' AND `guid` = '.-$eog; + } + + if ($q) + $result = DB::Aowow()->selectCol(sprintf('SELECT `type` AS ARRAY_KEY, `typeId` FROM ?_spawns WHERE (%s)', implode(') OR (', $q))); + } + + foreach ($smartS as [$st, $eog]) + { + if ($st == SAI_SRC_TYPE_CREATURE) + $result[TYPE_NPC][] = $eog; + else if ($st == SAI_SRC_TYPE_OBJECT) + $result[TYPE_OBJECT][] = $eog; + else if ($st == SAI_SRC_TYPE_AREATRIGGER) + $result[TYPE_AREATRIGGER][] = $eog; + } + + return $result; + } + + + /********************/ + /* Lookups by owner */ + /********************/ + + public static function getNPCSummonsForOwner(int $entry, int $srcType = SAI_SRC_TYPE_CREATURE) : array + { + // action => paramIdx with npcIds/spawnGoupIds + $lookup = array( + SAI_ACTION_SUMMON_CREATURE => [1], + SAI_ACTION_MOUNT_TO_ENTRY_OR_MODEL => [1], + SAI_ACTION_SPAWN_SPAWNGROUP => [1] + ); + + $result = self::getOwnerAction($srcType, $entry, $lookup); + + // can skip lookups for SAI_ACTION_SUMMON_CREATURE_GROUP as creature_summon_groups already contains summoner info + if ($srcType == SAI_SRC_TYPE_CREATURE || $srcType == SAI_SRC_TYPE_OBJECT) + { + $st = $srcType == SAI_SRC_TYPE_CREATURE ? 0 : 1;// 0:SUMMONER_TYPE_CREATURE; 1:SUMMONER_TYPE_GAMEOBJECT + if ($csg = DB::World()->selectCol('SELECT `entry` FROM creature_summon_groups WHERE `summonerType` = ?d AND `summonerId` = ?d', $st, $entry)) + $result = array_merge($result, $csg); + } + + if (!empty($moreInfo[SAI_ACTION_SPAWN_SPAWNGROUP])) + { + $grp = $moreInfo[SAI_ACTION_SPAWN_SPAWNGROUP]; + if ($sgs = DB::World()->selectCol('SELECT `spawnId` FROM spawn_group WHERE `spawnType` = ?d AND `groupId` IN (?a)', 0 /*0:SUMMONER_TYPE_CREATURE*/, $grp)) + if ($ids = DB::Aowow()->selectCol('SELECT DISTINCT `typeId` FROM ?_spawns WHERE `type` = ?d AND `guid` IN (?a)', TYPE_NPC, $sgs)) + $result = array_merge($result, $ids); + } + + return $result; + } + + public static function getObjectSummonsForOwner(int $entry, int $srcType = SAI_SRC_TYPE_CREATURE) : array + { + // action => paramIdx with gobIds/spawnGoupIds + $lookup = array( + SAI_ACTION_SUMMON_GO => [1], + SAI_ACTION_SPAWN_SPAWNGROUP => [1] + ); + + $result = self::getOwnerAction($srcType, $entry, $lookup, $moreInfo); + + if (!empty($moreInfo[SAI_ACTION_SPAWN_SPAWNGROUP])) + { + $grp = $moreInfo[SAI_ACTION_SPAWN_SPAWNGROUP]; + if ($sgs = DB::World()->selectCol('SELECT `spawnId` FROM spawn_group WHERE `spawnType` = ?d AND `groupId` IN (?a)', 1 /*1:SUMMONER_TYPE_GAMEOBJECT*/, $grp)) + if ($ids = DB::Aowow()->selectCol('SELECT DISTINCT `typeId` FROM ?_spawns WHERE `type` = ?d AND `guid` IN (?a)', TYPE_OBJECT, $sgs)) + $result = array_merge($result, $ids); + } + + return $result; + } + + public static function getSpellCastsForOwner(int $entry, int $srcType = SAI_SRC_TYPE_CREATURE) : array + { + // action => paramIdx with spellIds + $lookup = array( + SAI_SRC_TYPE_CREATURE => [1], + SAI_ACTION_CAST => [1], + SAI_ACTION_ADD_AURA => [1], + SAI_ACTION_INVOKER_CAST => [1], + SAI_ACTION_CROSS_CAST => [1] + ); + + return self::getOwnerAction($srcType, $entry, $lookup); + } + + public static function getSoundsPlayedForOwner(int $entry, int $srcType = SAI_SRC_TYPE_CREATURE) : array + { + // action => paramIdx with soundIds + $lookup = [SAI_ACTION_SOUND => [1]]; + + return self::getOwnerAction($srcType, $entry, $lookup); + } + + private static function getOwnerAction(int $sourceType, int $entry, array $lookup, ?array $moreInfo = []) : array + { + if ($entry < 0) // please not individual entities :( + return []; + + $smartScripts = DB::World()->select('SELECT action_type, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6 FROM smart_scripts WHERE source_type = ?d AND action_type IN (?a) AND entryOrGUID = ?d', $sourceType, array_merge(array_keys($lookup), SAI_ACTION_ALL_TIMED_ACTION_LISTS), $entry); + $smartResults = []; + $smartTALs = []; + foreach ($smartScripts as $s) + { + if ($e['action_type'] == SAI_ACTION_SPAWN_SPAWNGROUP) + $moreInfo[SAI_ACTION_SPAWN_SPAWNGROUP][] = $e['action_param'.$i]; + else if (in_array($s['action_type'], array_keys($lookup))) + { + foreach ($lookup[$s['action_type']] as $p) + $smartResults[] = $s['action_param'.$p]; + } + else if ($s['action_type'] == SAI_ACTION_CALL_TIMED_ACTIONLIST) + $smartTALs[] = $s['action_param1']; + else if ($s['action_type'] == SAI_ACTION_CALL_RANDOM_TIMED_ACTIONLIST) + { + for ($i = 1; $i < 7; $i++) + if ($s['action_param'.$i]) + $smartTALs[] = $s['action_param'.$i]; + } + else if ($s['action_type'] == SAI_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST) + { + for ($i = $s['action_param1']; $i <= $s['action_param2']; $i++) + $smartTALs[] = $i; + } + } + + if ($smartTALs) + { + if ($TALActList = DB::World()->selectCol('SELECT action_type, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6 FROM smart_scripts WHERE source_type = ?d AND action_type IN (?a) AND entryOrGUID IN (?a)', SAI_SRC_TYPE_ACTIONLIST, $lookup, $smartTALs)) + { + foreach ($TALActList as $e) + { + foreach ($lookup[$e['action_type']] as $i) + { + if ($e['action_type'] == SAI_ACTION_SPAWN_SPAWNGROUP) + $moreInfo[SAI_ACTION_SPAWN_SPAWNGROUP][] = $e['action_param'.$i]; + else + $smartResults[] = $e['action_param'.$i]; + } + } + } + } + + return $smartResults; + } + + + /******************************/ + /* Structured Lisview Display */ + /******************************/ + public function __construct(int $srcType, int $entry, array $miscData = []) { $this->srcType = $srcType; @@ -167,11 +463,12 @@ class SmartAI return $this->jsGlobals; } - public function getTabs() : array + public function getTabs() : array { return $this->tabs; } + private function &iterate() : iterable { reset($this->rawData); diff --git a/pages/npc.php b/pages/npc.php index 34230d9b..0c4ab888 100644 --- a/pages/npc.php +++ b/pages/npc.php @@ -408,36 +408,8 @@ class NpcPage extends GenericPage /**************/ // tab: abilities / tab_controlledabilities (dep: VehicleId) - // SMART_SCRIPT_TYPE_CREATURE = 0; SMART_ACTION_CAST = 11; SMART_ACTION_ADD_AURA = 75; SMART_ACTION_INVOKER_CAST = 85; SMART_ACTION_CROSS_CAST = 86 - $smartScripts = DB::World()->select('SELECT action_type, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6 FROM smart_scripts WHERE source_type = ?d AND action_type IN (?a) AND entryOrGUID = ?d', SAI_SRC_TYPE_CREATURE, array_merge(SAI_ACTION_ALL_SPELLCASTS, SAI_ACTION_ALL_TIMED_ACTION_LISTS), $this->typeId); - $smartSpells = []; - $smartTALs = []; - foreach ($smartScripts as $s) - { - if (in_array($s['action_type'], SAI_ACTION_ALL_SPELLCASTS)) - $smartSpells[] = $s['action_param1']; - else if ($s['action_type'] == SAI_ACTION_CALL_TIMED_ACTIONLIST) - $smartTALs[] = $s['action_param1']; - else if ($s['action_type'] == SAI_ACTION_CALL_RANDOM_TIMED_ACTIONLIST) - { - for ($i = 1; $i < 7; $i++) - if ($s['action_param'.$i]) - $smartTALs[] = $s['action_param'.$i]; - } - else if ($s['action_type'] == SAI_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST) - { - for ($i = $s['action_param1']; $i <= $s['action_param2']; $i++) - $smartTALs[] = $i; - } - else - var_dump($s); - } - - if ($smartTALs) - if ($_ = DB::World()->selectCol('SELECT action_param1 FROM smart_scripts WHERE source_type = ?d AND action_type IN (?a) AND entryOrGUID IN (?a)', SAI_SRC_TYPE_ACTIONLIST, SAI_ACTION_ALL_SPELLCASTS, $smartTALs)) - $smartSpells = array_merge($smartSpells, $_); - $tplSpells = []; + $smartSpells = []; $conditions = ['OR']; for ($i = 1; $i < 9; $i++) @@ -447,7 +419,7 @@ class NpcPage extends GenericPage if ($tplSpells) $conditions[] = ['id', $tplSpells]; - if ($smartSpells) + if ($smartSpells = SmartAI::getSpellCastsForOwner($this->typeId, SAI_SRC_TYPE_CREATURE)) $conditions[] = ['id', $smartSpells]; // Pet-Abilities @@ -511,7 +483,7 @@ class NpcPage extends GenericPage } } - // tab: summoned by + // tab: summoned by [spell] $conditions = array( 'OR', ['AND', ['effect1Id', [28, 56, 112]], ['effect1MiscValue', $this->typeId]], @@ -519,18 +491,51 @@ class NpcPage extends GenericPage ['AND', ['effect3Id', [28, 56, 112]], ['effect3MiscValue', $this->typeId]] ); - $summoned = new SpellList($conditions); - if (!$summoned->error) + $sbSpell = new SpellList($conditions); + if (!$sbSpell->error) { - $this->extendGlobalData($summoned->getJSGlobals()); + $this->extendGlobalData($sbSpell->getJSGlobals()); $this->lvTabs[] = ['spell', array( - 'data' => array_values($summoned->getListviewData()), + 'data' => array_values($sbSpell->getListviewData()), 'name' => '$LANG.tab_summonedby', - 'id' => 'summoned-by' + 'id' => 'summoned-by-spell' )]; } + // tab: summoned by [NPC] + $sb = SmartAI::getOwnerOfNPCSummon($this->typeId); + if (!empty($sb[TYPE_NPC])) + { + $sbNPC = new CreatureList(array(['id', $sb[TYPE_NPC]])); + if (!$sbNPC->error) + { + $this->extendGlobalData($sbNPC->getJSGlobals()); + + $this->lvTabs[] = ['creature', array( + 'data' => array_values($sbNPC->getListviewData()), + 'name' => '$LANG.tab_summonedby', + 'id' => 'summoned-by-npc' + )]; + } + } + + // tab: summoned by [Object] + if (!empty($sb[TYPE_OBJECT])) + { + $sbGO = new GameObjectList(array(['id', $sb[TYPE_OBJECT]])); + if (!$sbGO->error) + { + $this->extendGlobalData($sbGO->getJSGlobals()); + + $this->lvTabs[] = ['object', array( + 'data' => array_values($sbGO->getListviewData()), + 'name' => '$LANG.tab_summonedby', + 'id' => 'summoned-by-object' + )]; + } + } + // tab: teaches if ($this->subject->getField('npcflag') & NPC_FLAG_TRAINER) { @@ -865,27 +870,7 @@ class NpcPage extends GenericPage * Dialogue VO => creature_text * onClick VO => CreatureDisplayInfo.dbc => NPCSounds.dbc */ - $ssActionLists = DB::World()->select('SELECT action_type, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6 FROM smart_scripts WHERE entryorguid = ?d AND source_type = 0 AND action_type IN (80, 87, 88)', $this->typeId); - $actionListIds = []; - foreach ($ssActionLists as $sal) - { - $iMax = 0; - switch ($sal['action_type']) - { - case 80: $iMax = 1; break; - case 87: $iMax = 6; break; - case 88: $iMax = 2; break; - default: continue; - } - - for ($i = 1; $i <= $iMax; $i++) - if ($sal['action_param'.$i]) - $actionListIds[] = $sal['action_param'.$i]; - } - - // not going for a per guid basis. The infos are nested enough as is. - $smartScripts = DB::World()->selectCol('SELECT action_param1 FROM smart_scripts WHERE action_type = 4 AND ((source_type = 0 AND entryorguid = ?d) { OR (source_type = 9 AND entryorguid IN (?a)) } )', $this->typeId, $actionListIds ?: DBSIMPLE_SKIP); - $this->soundIds = array_merge($this->soundIds, $smartScripts); + $this->soundIds = array_merge($this->soundIds, SmartAI::getSoundsPlayedForOwner($this->typeId, SAI_SRC_TYPE_CREATURE)); // up to 4 possible displayIds .. for the love of things betwixt, just use the first! $activitySounds = DB::Aowow()->selectRow('SELECT * FROM ?_creature_sounds WHERE id = ?d', $this->subject->getField('displayId1')); diff --git a/pages/sound.php b/pages/sound.php index f6102c11..7abd7f2f 100644 --- a/pages/sound.php +++ b/pages/sound.php @@ -269,39 +269,11 @@ class SoundPage extends GenericPage } } - $ssQuery = ' - SELECT - source_type AS ARRAY_KEY, - entryorguid AS ARRAY_KEY2, - 0 - FROM - smart_scripts - WHERE - (action_type = 4 AND action_param1 = ?d AND source_type <> 9) { - OR (action_type = 80 AND (action_param1 IN (?a))) - OR (action_type = 87 AND (action_param1 IN (?a) OR action_param2 IN (?a) OR action_param3 IN (?a) OR action_param4 IN (?a) OR action_param5 IN (?a) OR action_param6 IN (?a))) - OR (action_type = 88 AND (action_param1 IN (?a) OR action_param2 IN (?a))) - } - '; - - $ssActionLists = DB::World()->selectCol('SELECT entryorguid FROM smart_scripts WHERE action_type = 4 AND action_param1 = ?d AND source_type = 9', $this->typeId); - $smartScripts = DB::World()->selectCol($ssQuery, $this->typeId, $ssActionLists ?: DBSIMPLE_SKIP, $ssActionLists, $ssActionLists, $ssActionLists, $ssActionLists, $ssActionLists, $ssActionLists, $ssActionLists, $ssActionLists); - $creatureIds = DB::World()->selectCol('SELECT ct.CreatureID FROM creature_text ct LEFT JOIN broadcast_text bct ON bct.ID = ct.BroadCastTextId WHERE bct.SoundEntriesID = ?d OR ct.Sound = ?d', $this->typeId, $this->typeId); - foreach ($smartScripts as $source => $ids) - { - switch($source) - { - case 0: // npc - // filter for guids (id < 0) - $creatureIds = array_merge($creatureIds, array_keys(array_filter($ids, function($x) { return $x > 0; })) ); - break; - case 1: // gameobject - default: - break; - } - } + // can objects or areatrigger play sound...? + if ($goosp = SmartAI::getOwnerOfSoundPlayed($this->typeId, TYPE_NPC)) + $creatureIds = array_merge($creatureIds, $goosp[TYPE_NPC]); // tab: NPC (dialogues...?, generic creature sound) // skipping (always empty): transforms, footsteps diff --git a/pages/spell.php b/pages/spell.php index 93cfdc7e..d155ebe3 100644 --- a/pages/spell.php +++ b/pages/spell.php @@ -325,6 +325,8 @@ class SpellPage extends GenericPage $j = [null, 'A', 'B', 'C']; + $ubSAI = SmartAI::getOwnerOfSpellCast($this->typeId); + // tab: abilities [of shapeshift form] for ($i = 1; $i < 4; $i++) { @@ -610,8 +612,8 @@ class SpellPage extends GenericPage ['onUseSpell', $this->subject->id], ['onSuccessSpell', $this->subject->id], ['auraSpell', $this->subject->id], ['triggeredSpell', $this->subject->id] ); - if ($_ = $this->ubSmartScript(TYPE_OBJECT)) - $conditions[] = ['id', $_]; + if (!empty($ubSAI[TYPE_OBJECT])) + $conditions[] = ['id', $ubSAI[TYPE_OBJECT]]; $ubObjects = new GameObjectList($conditions); if (!$ubObjects->error) @@ -628,9 +630,9 @@ class SpellPage extends GenericPage // tab: used by - areatrigger if (User::isInGroup(U_GROUP_EMPLOYEE)) { - if ($_ = $this->ubSmartScript(TYPE_AREATRIGGER)) + if (!empty($ubSAI[TYPE_AREATRIGGER])) { - $ubTriggers = new AreaTriggerList(array(['id', $_])); + $ubTriggers = new AreaTriggerList(array(['id', $ubSAI[TYPE_AREATRIGGER]])); if (!$ubTriggers->error) { $this->lvTabs[] = ['areatrigger', array( @@ -845,8 +847,8 @@ class SpellPage extends GenericPage ['spell1', $this->typeId], ['spell2', $this->typeId], ['spell3', $this->typeId], ['spell4', $this->typeId], ['spell5', $this->typeId], ['spell6', $this->typeId], ['spell7', $this->typeId], ['spell8', $this->typeId] ); - if ($_ = $this->ubSmartScript(TYPE_NPC)) - $conditions[] = ['id', $_]; + if (!empty($ubSAI[TYPE_NPC])) + $conditions[] = ['id', $ubSAI[TYPE_NPC]]; $ubCreature = new CreatureList($conditions); if (!$ubCreature->error) @@ -2231,37 +2233,6 @@ class SpellPage extends GenericPage return $list; } - - private function ubSmartScript(int $type) : array - { - $src = -1; - if ($type == TYPE_OBJECT) - $src = SAI_SRC_TYPE_OBJECT; - else if ($type == TYPE_NPC) - $src = SAI_SRC_TYPE_CREATURE; - else if ($type == TYPE_AREATRIGGER) - $src = SAI_SRC_TYPE_AREATRIGGER; - else - return []; - - $ids = []; - if ($smartS = DB::World()->select('SELECT entryOrGUID, source_type FROM smart_scripts WHERE entryOrGUID > 0 AND source_type IN (?a) AND action_type IN (?a) AND action_param1 = ?d', [$src, SAI_SRC_TYPE_ACTIONLIST], SAI_ACTION_ALL_SPELLCASTS, $this->typeId)) - { - // filter for timed action list - if ($tal = array_filter($smartS, function($x) {return $x['source_type'] == SAI_SRC_TYPE_ACTIONLIST;})) - { - $talIds = array_column($tal, 'entryOrGUID'); - if ($_ = DB::World()->selectCol('SELECT entryOrGUID FROM smart_scripts WHERE entryOrGUID > 0 AND source_type = ?d AND action_type IN (?a) AND (action_param1 IN (?a) OR action_param2 IN (?a) OR action_param3 IN (?a) OR action_param4 IN (?a) OR action_param5 IN (?a) OR action_param6 IN (?a))', $src, SAI_ACTION_ALL_TIMED_ACTION_LISTS, $talIds, $talIds, $talIds, $talIds, $talIds, $talIds)) - $ids = $_; - - $smartS = array_diff_key($smartS, $tal); - } - if ($smartS); - $ids = array_merge($ids, array_column($smartS, 'entryOrGUID')); - } - - return $ids; - } }