SmarAI/Lookups

* unify lookups in functional groups
 * move code to class SmartAI
This commit is contained in:
Sarjuuk
2021-02-21 00:29:54 +01:00
parent c456ade870
commit aa82655845
4 changed files with 351 additions and 126 deletions

View File

@@ -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'));

View File

@@ -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

View File

@@ -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;
}
}