Setup/Source

* respect disabled Quests and Spells when flagging Items as unavailable
 * reuse data from loot_link to set difficuly bits and zoneId
   for loot container GOs
This commit is contained in:
Sarjuuk
2025-10-11 03:30:13 +02:00
parent 65d490a8ae
commit 04f3aa7a82
2 changed files with 104 additions and 44 deletions

View File

@@ -0,0 +1 @@
UPDATE `aowow_dbversion` SET `sql` = CONCAT(IFNULL(`sql`, ''), ' source');

View File

@@ -19,12 +19,14 @@ CLISetup::registerSetup("sql", new class extends SetupScript
protected $worldDependency = ['playercreateinfo_skills', 'playercreateinfo_item', 'skill_discovery_template', 'achievement_reward', 'skill_perfect_item_template', 'item_template', 'gameobject_template', 'quest_template', 'quest_template_addon', 'creature_template', 'creature', 'creature_default_trainer', 'trainer_spell', 'npc_vendor', 'game_event_npc_vendor', 'reference_loot_template', 'item_loot_template', 'creature_loot_template', 'gameobject_loot_template', 'mail_loot_template', 'disenchant_loot_template', 'fishing_loot_template', 'skinning_loot_template', 'milling_loot_template', 'prospecting_loot_template', 'pickpocketing_loot_template'];
protected $setupAfter = [['spell', 'achievement', 'items', 'itemset', 'spawns', 'creature', 'zones', 'titles'], []];
private $srcBuffer = [];
private $refLoot = [];
private $dummyNPCs = [];
private array $srcBuffer = [];
private array $refLoot = [];
private array $dummyNPCs = [];
private array $dummyGOs = [];
private array $disables = [];
private const PVP_MONEY = [26045, 24581, 24579, 43589, 37836]; // Nagrand, Hellfire Pen. H, Hellfire Pen. A, Wintergrasp, Grizzly Hills
private const COMMON_THRESHOLD = 100;
private const /* array */ PVP_MONEY = [26045, 24581, 24579, 43589, 37836]; // Nagrand, Hellfire Pen. H, Hellfire Pen. A, Wintergrasp, Grizzly Hills
private const /* int */ COMMON_THRESHOLD = 100;
public function generate(array $ids = []) : bool
{
@@ -33,17 +35,30 @@ CLISetup::registerSetup("sql", new class extends SetupScript
/*********************************/
$this->dummyNPCs = DB::Aowow()->select(
'SELECT difficultyEntry1 AS ARRAY_KEY, 2 AS "0", `id` AS "1" FROM ?_creature WHERE difficultyEntry1 > 0 UNION
SELECT difficultyEntry2 AS ARRAY_KEY, 4 AS "0", `id` AS "1" FROM ?_creature WHERE difficultyEntry2 > 0 UNION
SELECT difficultyEntry3 AS ARRAY_KEY, 8 AS "0", `id` AS "1" FROM ?_creature WHERE difficultyEntry3 > 0'
'SELECT `difficultyEntry1` AS ARRAY_KEY, 2 AS "0", `id` AS "1" FROM ?_creature WHERE `difficultyEntry1` > 0 UNION
SELECT `difficultyEntry2` AS ARRAY_KEY, 4 AS "0", `id` AS "1" FROM ?_creature WHERE `difficultyEntry2` > 0 UNION
SELECT `difficultyEntry3` AS ARRAY_KEY, 8 AS "0", `id` AS "1" FROM ?_creature WHERE `difficultyEntry3` > 0'
);
$this->dummyGOs = DB::Aowow()->select(
'SELECT l1.`objectId` AS ARRAY_KEY, BIT_OR(l1.`difficulty`) AS "0", IFNULL(l2.`npcId`, l1.`npcId`) AS "1"
FROM aowow_loot_link l1
LEFT JOIN aowow_loot_link l2 ON l1.`objectId` = l2.`objectId` AND l2.`priority` = 1
GROUP BY l1.`objectid`'
);
$this->disables = DB::World()->selectCol(
'SELECT IF(`sourceType`, ?d, ?d) AS ARRAY_KEY, `entry` AS ARRAY_KEY2, `entry`
FROM disables
WHERE (`sourceType` = 0 AND (`flags` & 0xF)) OR `sourceType` = 1',
Type::QUEST, Type::SPELL
);
// todo: do the same for GOs
CLI::write('[source] - resolving ref-loot tree', CLI::LOG_BLANK, true, true);
$this->refLoot = DB::World()->select(
'SELECT rlt.Entry AS ARRAY_KEY, IF(Reference, -Reference, Item) AS ARRAY_KEY2, it.entry, it.class, it.subclass, it.spellid_1, it.spelltrigger_1, it.spellid_2, it.spelltrigger_2
'SELECT rlt.`Entry` AS ARRAY_KEY, IF(`Reference`, -`Reference`, `Item`) AS ARRAY_KEY2, it.`entry`, it.`class`, it.`subclass`, it.`spellid_1`, it.`spelltrigger_1`, it.`spellid_2`, it.`spelltrigger_2`
FROM reference_loot_template rlt
LEFT JOIN item_template it ON rlt.Reference = 0 AND rlt.Item = it.entry
LEFT JOIN item_template it ON rlt.`Reference` = 0 AND rlt.`Item` = it.`entry`
GROUP BY ARRAY_KEY, ARRAY_KEY2'
);
@@ -155,9 +170,22 @@ CLISetup::registerSetup("sql", new class extends SetupScript
CLI::write('[source] - Inserting... (done)');
// generally treat all items generated by spell as being available. The spells may be triggered in convoluted ways but usually _are_ in use.
$itemSpellSource = DB::Aowow()->selectCol(
'SELECT x.`itemId` FROM (
SELECT `effect1CreateItemId` AS "itemId", s.`id` FROM dbc_spell s WHERE `effect1CreateItemId` > 0 AND (`effect1Id` IN (?a) OR `effect1AuraId` IN (?a)) UNION ALL
SELECT `effect2CreateItemId` AS "itemId", s.`id` FROM dbc_spell s WHERE `effect2CreateItemId` > 0 AND (`effect2Id` IN (?a) OR `effect2AuraId` IN (?a)) UNION ALL
SELECT `effect3CreateItemId` AS "itemId", s.`id` FROM dbc_spell s WHERE `effect3CreateItemId` > 0 AND (`effect3Id` IN (?a) OR `effect3AuraId` IN (?a)) ) AS x
{ WHERE x.`id` NOT IN (?a) }',
SpellList::EFFECTS_ITEM_CREATE, SpellList::AURAS_ITEM_CREATE,
SpellList::EFFECTS_ITEM_CREATE, SpellList::AURAS_ITEM_CREATE,
SpellList::EFFECTS_ITEM_CREATE, SpellList::AURAS_ITEM_CREATE,
!empty($this->disables[Type::SPELL]) ? array_values($this->disables[Type::SPELL]) : DBSIMPLE_SKIP
);
// flagging aowow_items for source (note: this is not exact! creatures dropping items may not be spawnd, quests granting items may be disabled)
DB::Aowow()->query('UPDATE ?_items SET `cuFlags` = `cuFlags` & ?d', ~CUSTOM_UNAVAILABLE);
DB::Aowow()->query('UPDATE ?_items i LEFT JOIN ?_source s ON s.`typeId` = i.`id` AND s.`type` = ?d SET i.`cuFlags` = i.`cuFlags` | ?d WHERE s.`typeId` IS NULL', Type::ITEM, CUSTOM_UNAVAILABLE);
DB::Aowow()->query('UPDATE ?_items i LEFT JOIN ?_source s ON s.`typeId` = i.`id` AND s.`type` = ?d SET i.`cuFlags` = i.`cuFlags` | ?d WHERE s.`typeId` IS NULL AND i.`id` NOT IN (?a)', Type::ITEM, CUSTOM_UNAVAILABLE, $itemSpellSource);
return true;
}
@@ -206,8 +234,6 @@ CLISetup::registerSetup("sql", new class extends SetupScript
private function taughtSpell(array $item) : int
{
# spelltrigger_X (0: onUse; 6: onLearnSpell)
// should not be able to teach spells (recipe || mount || vanityPet)
if ($item['class'] != ITEM_CLASS_RECIPE && ($item['class'] != ITEM_CLASS_MISC || ($item['subclass'] != 2 && $item['subclass'] != 5)))
return 0;
@@ -235,11 +261,14 @@ CLISetup::registerSetup("sql", new class extends SetupScript
GROUP BY ARRAY_KEY',
array_merge(SKILLS_TRADE_PRIMARY, [SKILL_FIRST_AID, SKILL_COOKING, SKILL_FISHING])
);
// assume unique craft spells per item
$perfectItems = DB::World()->selectCol('SELECT `perfectItemType` AS ARRAY_KEY, `spellId` AS "spell" FROM skill_perfect_item_template');
foreach ($perfectItems AS $item => $spell)
$itemSpells[$item] = $spell;
$itemSpells = array_filter($itemSpells, fn($x) => empty($this->disables[Type::SPELL][$x]));
$spellItems = DB::World()->select('SELECT `entry` AS ARRAY_KEY, `class`, `subclass`, `spellid_1`, `spelltrigger_1`, `spellid_2`, `spelltrigger_2` FROM item_template WHERE `entry` IN (?a)', array_keys($itemSpells));
foreach ($spellItems as $iId => $si)
{
@@ -266,7 +295,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript
GROUP BY `refOrItem`, ct.`entry`'
);
$spawns = DB::Aowow()->select('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT s.`areaId`) > 1, 0, s.`areaId`) AS "areaId", z.`type` FROM ?_spawns s JOIN ?_zones z ON z.`id` = s.`areaId` WHERE s.`type` = ?d AND `typeId`IN (?a) GROUP BY `typeId`', Type::NPC, array_filter(array_column($creatureLoot, 'entry')));
$npcSpawns = DB::Aowow()->select('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT s.`areaId`) > 1, 0, s.`areaId`) AS "areaId", z.`type` FROM ?_spawns s JOIN ?_zones z ON z.`id` = s.`areaId` WHERE s.`type` = ?d AND `typeId`IN (?a) GROUP BY `typeId`', Type::NPC, array_merge(array_column($this->dummyGOs, 1), array_filter(array_column($creatureLoot, 'entry'))));
$bosses = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, IF(`cuFlags` & ?d, 1, IF(`typeFlags` & 0x4 AND `rank` > 0, 1, 0)) FROM ?_creature WHERE `id` IN (?a)', NPC_CU_INSTANCE_BOSS, array_filter(array_column($creatureLoot, 'entry')));
foreach ($creatureLoot as $l)
@@ -282,9 +311,9 @@ CLISetup::registerSetup("sql", new class extends SetupScript
if (isset($bosses[$entry]) && $bosses[$entry]) // can be empty...?
$mMask |= SRC_FLAG_BOSSDROP;
if (isset($spawns[$entry]))
if (isset($npcSpawns[$entry]))
{
switch ($spawns[$entry]['type'])
switch ($npcSpawns[$entry]['type'])
{
case MAP_TYPE_DUNGEON_HC:
$mMask |= SRC_FLAG_DUNGEON_DROP; break;
@@ -293,7 +322,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript
$mMask |= SRC_FLAG_RAID_DROP; break;
}
$zoneId = $spawns[$entry]['areaId'];
$zoneId = $npcSpawns[$entry]['areaId'];
}
if ($roi < 0 && !empty($this->refLoot[-$roi]))
@@ -333,34 +362,58 @@ CLISetup::registerSetup("sql", new class extends SetupScript
DB::Aowow()->selectCol('SELECT `id` FROM dbc_lock WHERE `properties1` IN (?a)', [LOCK_PROPERTY_HERBALISM, LOCK_PROPERTY_MINING])
);
$spawns = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ?_spawns WHERE `type` = ?d AND `typeId`IN (?a) GROUP BY `typeId`', Type::OBJECT, array_column($objectLoot, 'entry'));
$goSpawns = DB::Aowow()->select('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT s.`areaId`) > 1, 0, s.`areaId`) AS "areaId", z.`type` FROM ?_spawns s JOIN ?_zones z ON z.`id` = s.`areaId` WHERE s.`type` = ?d AND `typeId`IN (?a) GROUP BY `typeId`', Type::OBJECT, array_filter(array_column($objectLoot, 'entry')));
// todo: difficulty entrys for boss chests
foreach ($objectLoot as $l)
{
$roi = $l['refOrItem'];
$zoneId = $spawns[$l['entry']] ?? 0;
$entry = $l['entry'];
$mode = 1 | ($this->dummyGOs[$entry][0] ?? 0);
$zoneId = 0;
$mMask = 0x0;
$spawn = [];
if (isset($this->dummyGOs[$entry])) // we know these are all boss drops
$mMask |= SRC_FLAG_BOSSDROP;
if (isset($goSpawns[$entry]))
$spawn = $goSpawns[$entry];
else if (isset($this->dummyGOs[$entry]) && isset($npcSpawns[$this->dummyGOs[$entry][1]]))
$spawn = $npcSpawns[$this->dummyGOs[$entry][1]];
if ($spawn)
{
switch ($spawn['type'])
{
case MAP_TYPE_DUNGEON_HC:
$mMask |= SRC_FLAG_DUNGEON_DROP; break;
case MAP_TYPE_MMODE_RAID:
case MAP_TYPE_MMODE_RAID_HC:
$mMask |= SRC_FLAG_RAID_DROP; break;
}
$zoneId = $spawn['areaId'];
}
if ($roi < 0 && !empty($this->refLoot[-$roi]))
{
foreach ($this->refLoot[-$roi] as $iId => $r)
{
if ($_ = $this->taughtSpell($r))
$this->pushBuffer(Type::SPELL, $_, SRC_DROP, 1, $l['qty'] > 1 ? 0 : Type::OBJECT, $l['entry'], $zoneId, $mMask, $l['qty']);
$this->pushBuffer(Type::SPELL, $_, SRC_DROP, $mode, $l['qty'] > 1 ? 0 : Type::OBJECT, $l['entry'], $zoneId, $mMask, $l['qty']);
$objectOT[] = $iId;
$this->pushBuffer(Type::ITEM, $iId, SRC_DROP, 1, $l['qty'] > 1 ? 0 : Type::OBJECT, $l['entry'], $zoneId, $mMask, $l['qty']);
$this->pushBuffer(Type::ITEM, $iId, SRC_DROP, $mode, $l['qty'] > 1 ? 0 : Type::OBJECT, $l['entry'], $zoneId, $mMask, $l['qty']);
}
continue;
}
if ($_ = $this->taughtSpell($l))
$this->pushBuffer(Type::SPELL, $_, SRC_DROP, 1, $l['qty'] > 1 ? 0 : Type::OBJECT, $l['entry'], $zoneId, $mMask, $l['qty']);
$this->pushBuffer(Type::SPELL, $_, SRC_DROP, $mode, $l['qty'] > 1 ? 0 : Type::OBJECT, $l['entry'], $zoneId, $mMask, $l['qty']);
$objectOT[] = $roi;
$this->pushBuffer(Type::ITEM, $roi, SRC_DROP, 1, $l['qty'] > 1 ? 0 : Type::OBJECT, $l['entry'], $zoneId, $mMask, $l['qty']);
$this->pushBuffer(Type::ITEM, $roi, SRC_DROP, $mode, $l['qty'] > 1 ? 0 : Type::OBJECT, $l['entry'], $zoneId, $mMask, $l['qty']);
}
CLI::write('[source] * #2 Drop [Item]', CLI::LOG_BLANK, true, true);
@@ -436,19 +489,20 @@ CLISetup::registerSetup("sql", new class extends SetupScript
CLI::write('[source] * #4 Quest', CLI::LOG_BLANK, true, true);
$quests = DB::World()->select(
'SELECT n.`item` AS ARRAY_KEY, n.`Id` AS "quest", SUM(n.`qty`) AS "qty", BIT_OR(n.`side`) AS "side", IF(COUNT(DISTINCT `zone`) > 1, 0, `zone`) AS "zone", it.`class`, it.`subclass`, it.`spellid_1`, it.`spelltrigger_1`, it.`spellid_2`, it.`spelltrigger_2`
FROM (SELECT `RewardChoiceItemID1` AS "item", `ID`, COUNT(1) AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", IF(COUNT(DISTINCT `QuestSortID`) > 1, 0, GREATEST(`QuestSortID`, 0)) AS "zone" FROM quest_template WHERE `RewardChoiceItemID1` > 0 GROUP BY `item` UNION
SELECT `RewardChoiceItemID2` AS "item", `ID`, COUNT(1) AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", IF(COUNT(DISTINCT `QuestSortID`) > 1, 0, GREATEST(`QuestSortID`, 0)) AS "zone" FROM quest_template WHERE `RewardChoiceItemID2` > 0 GROUP BY `item` UNION
SELECT `RewardChoiceItemID3` AS "item", `ID`, COUNT(1) AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", IF(COUNT(DISTINCT `QuestSortID`) > 1, 0, GREATEST(`QuestSortID`, 0)) AS "zone" FROM quest_template WHERE `RewardChoiceItemID3` > 0 GROUP BY `item` UNION
SELECT `RewardChoiceItemID4` AS "item", `ID`, COUNT(1) AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", IF(COUNT(DISTINCT `QuestSortID`) > 1, 0, GREATEST(`QuestSortID`, 0)) AS "zone" FROM quest_template WHERE `RewardChoiceItemID4` > 0 GROUP BY `item` UNION
SELECT `RewardChoiceItemID5` AS "item", `ID`, COUNT(1) AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", IF(COUNT(DISTINCT `QuestSortID`) > 1, 0, GREATEST(`QuestSortID`, 0)) AS "zone" FROM quest_template WHERE `RewardChoiceItemID5` > 0 GROUP BY `item` UNION
SELECT `RewardChoiceItemID6` AS "item", `ID`, COUNT(1) AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", IF(COUNT(DISTINCT `QuestSortID`) > 1, 0, GREATEST(`QuestSortID`, 0)) AS "zone" FROM quest_template WHERE `RewardChoiceItemID6` > 0 GROUP BY `item` UNION
SELECT `RewardItem1` AS "item", `ID`, COUNT(1) AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", IF(COUNT(DISTINCT `QuestSortID`) > 1, 0, GREATEST(`QuestSortID`, 0)) AS "zone" FROM quest_template WHERE `RewardItem1` > 0 GROUP BY `item` UNION
SELECT `RewardItem2` AS "item", `ID`, COUNT(1) AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", IF(COUNT(DISTINCT `QuestSortID`) > 1, 0, GREATEST(`QuestSortID`, 0)) AS "zone" FROM quest_template WHERE `RewardItem2` > 0 GROUP BY `item` UNION
SELECT `RewardItem3` AS "item", `ID`, COUNT(1) AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", IF(COUNT(DISTINCT `QuestSortID`) > 1, 0, GREATEST(`QuestSortID`, 0)) AS "zone" FROM quest_template WHERE `RewardItem3` > 0 GROUP BY `item` UNION
SELECT `RewardItem4` AS "item", `ID`, COUNT(1) AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", IF(COUNT(DISTINCT `QuestSortID`) > 1, 0, GREATEST(`QuestSortID`, 0)) AS "zone" FROM quest_template WHERE `RewardItem4` > 0 GROUP BY `item` UNION
SELECT `StartItem` AS "item", `ID`, COUNT(1) AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", IF(COUNT(DISTINCT `QuestSortID`) > 1, 0, GREATEST(`QuestSortID`, 0)) AS "zone" FROM quest_template WHERE `StartItem` > 0 GROUP BY `item`) n
'SELECT n.`item` AS ARRAY_KEY, n.`ID` AS "quest", SUM(n.`qty`) AS "qty", BIT_OR(n.`side`) AS "side", IF(COUNT(DISTINCT `zone`) > 1, 0, `zone`) AS "zone", it.`class`, it.`subclass`, it.`spellid_1`, it.`spelltrigger_1`, it.`spellid_2`, it.`spelltrigger_2`
FROM (SELECT `RewardChoiceItemID1` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardChoiceItemID1` > 0 UNION ALL
SELECT `RewardChoiceItemID2` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardChoiceItemID2` > 0 UNION ALL
SELECT `RewardChoiceItemID3` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardChoiceItemID3` > 0 UNION ALL
SELECT `RewardChoiceItemID4` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardChoiceItemID4` > 0 UNION ALL
SELECT `RewardChoiceItemID5` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardChoiceItemID5` > 0 UNION ALL
SELECT `RewardChoiceItemID6` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardChoiceItemID6` > 0 UNION ALL
SELECT `RewardItem1` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardItem1` > 0 UNION ALL
SELECT `RewardItem2` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardItem2` > 0 UNION ALL
SELECT `RewardItem3` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardItem3` > 0 UNION ALL
SELECT `RewardItem4` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardItem4` > 0 UNION ALL
SELECT `StartItem` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `StartItem` > 0) n
JOIN item_template it ON it.`entry` = n.`item`
{ WHERE n.`ID` NOT IN (?a) }
GROUP BY `item`',
ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
@@ -460,7 +514,8 @@ CLISetup::registerSetup("sql", new class extends SetupScript
ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH
ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
!empty($this->disables[Type::QUEST]) ? array_values($this->disables[Type::QUEST]) : DBSIMPLE_SKIP
);
$areaParent = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `parentArea` FROM ?_zones WHERE `id` IN (?a) AND `parentArea` > 0', array_filter(array_column($quests, 'zone')));
@@ -1012,12 +1067,14 @@ CLISetup::registerSetup("sql", new class extends SetupScript
CLI::write('[source] * #4 Quest', CLI::LOG_BLANK, true, true);
$quests = DB::World()->select(
'SELECT `spell` AS ARRAY_KEY, `id`, SUM(`qty`) AS "qty", BIT_OR(`side`) AS "side", IF(COUNT(DISTINCT `zone`) > 1, 0, `zone`) AS "zone"
FROM (SELECT IF(`RewardSpell` = 0, `RewardDisplaySpell`, `RewardSpell`) AS "spell", `Id`, COUNT(1) AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE IF(`RewardSpell` = 0, `RewardDisplaySpell`, `RewardSpell`) > 0 GROUP BY `spell` UNION
SELECT qta.`SourceSpellId` AS "spell", qt.`Id`, COUNT(1) AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template qt JOIN quest_template_addon qta ON qta.ID = qt.ID WHERE qta.`SourceSpellId` > 0 GROUP BY `spell`) t
'SELECT `spell` AS ARRAY_KEY, `ID` AS "id", SUM(`qty`) AS "qty", BIT_OR(`side`) AS "side", IF(COUNT(DISTINCT `zone`) > 1, 0, `zone`) AS "zone"
FROM (SELECT IF(`RewardSpell` = 0, `RewardDisplaySpell`, `RewardSpell`) AS "spell", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE IF(`RewardSpell` = 0, `RewardDisplaySpell`, `RewardSpell`) > 0 UNION ALL
SELECT qta.`SourceSpellId` AS "spell", qt.`ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template qt JOIN quest_template_addon qta ON qta.ID = qt.ID WHERE qta.`SourceSpellId` > 0 ) t
{ WHERE t.`ID` NOT IN (?a) }
GROUP BY `spell`',
ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH
ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
!empty($this->disables[Type::QUEST]) ? array_values($this->disables[Type::QUEST]) : DBSIMPLE_SKIP
);
if (!$quests)
@@ -1145,8 +1202,10 @@ CLISetup::registerSetup("sql", new class extends SetupScript
$quests = DB::World()->select(
'SELECT `RewardTitle` AS ARRAY_KEY, `ID` AS "id", SUM(`qty`) AS "qty", BIT_OR(`side`) AS "side", IF(COUNT(DISTINCT `zone`) > 1, 0, `zone`) AS "zone"
FROM (SELECT `RewardTitle`, `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardTitle` > 0) q
{ WHERE q.`Id` NOT IN (?a) }
GROUP BY `RewardTitle`',
ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH
ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
!empty($this->disables[Type::QUEST]) ? array_values($this->disables[Type::QUEST]) : DBSIMPLE_SKIP
);
if (!$quests)