diff --git a/includes/loot.class.php b/includes/loot.class.php index 5e95d0bf..c9cdfe26 100644 --- a/includes/loot.class.php +++ b/includes/loot.class.php @@ -45,7 +45,7 @@ class Loot reset($this->results); while (list($k, $__) = each($this->results)) - yield $this->results[$k]; + yield $k => $this->results[$k]; } public function getResult() @@ -321,7 +321,7 @@ class Loot return true; } - public function getByItem($entry, $maxResults = CFG_SQL_LIMIT_DEFAULT) + public function getByItem($entry, $maxResults = CFG_SQL_LIMIT_DEFAULT, $lootTableList = []) { $this->entry = intVal($entry); @@ -450,6 +450,9 @@ class Loot */ for ($i = 1; $i < count($this->lootTemplates); $i++) { + if ($lootTableList && !in_array($this->lootTemplates[$i], $lootTableList)) + continue; + $result = $calcChance(DB::World()->select( sprintf($query, '{lt1.reference IN (?a) OR }(lt1.reference = 0 AND lt1.item = ?d)'), $this->lootTemplates[$i], $this->lootTemplates[$i], @@ -544,7 +547,12 @@ class Loot } continue 2; case LOOT_SPELL: - $conditions = ['OR', ['effect1CreateItemId', $this->entry], ['effect2CreateItemId', $this->entry], ['effect3CreateItemId', $this->entry]]; + $conditions = array( + 'OR', + ['AND', ['effect1CreateItemId', $this->entry], ['OR', ['effect1Id', SpellList::$effects['itemCreate']], ['effect1AuraId', SpellList::$auras['itemCreate']]]], + ['AND', ['effect2CreateItemId', $this->entry], ['OR', ['effect2Id', SpellList::$effects['itemCreate']], ['effect2AuraId', SpellList::$auras['itemCreate']]]], + ['AND', ['effect3CreateItemId', $this->entry], ['OR', ['effect3Id', SpellList::$effects['itemCreate']], ['effect3AuraId', SpellList::$auras['itemCreate']]]], + ); if ($ids) $conditions[] = ['id', $ids]; diff --git a/includes/types/creature.class.php b/includes/types/creature.class.php index eff8c617..0356fb6d 100644 --- a/includes/types/creature.class.php +++ b/includes/types/creature.class.php @@ -13,7 +13,10 @@ class CreatureList extends BaseType protected $queryBase = 'SELECT ct.*, ct.id AS ARRAY_KEY FROM ?_creature ct'; public $queryOpts = array( - 'ct' => [['ft', 'qse']], + 'ct' => [['ft', 'qse', 'dct1', 'dct2', 'dct3'], 's' => ', IFNULL(dct1.id, IFNULL(dct2.id, IFNULL(dct3.id, 0))) AS parentId, IFNULL(dct1.name_loc0, IFNULL(dct2.name_loc0, IFNULL(dct3.name_loc0, ""))) AS parent_loc0, IFNULL(dct1.name_loc2, IFNULL(dct2.name_loc2, IFNULL(dct3.name_loc2, ""))) AS parent_loc2, IFNULL(dct1.name_loc3, IFNULL(dct2.name_loc3, IFNULL(dct3.name_loc3, ""))) AS parent_loc3, IFNULL(dct1.name_loc6, IFNULL(dct2.name_loc6, IFNULL(dct3.name_loc6, ""))) AS parent_loc6, IFNULL(dct1.name_loc8, IFNULL(dct2.name_loc8, IFNULL(dct3.name_loc8, ""))) AS parent_loc8, IF(dct1.difficultyEntry1 = ct.id, 1, IF(dct2.difficultyEntry2 = ct.id, 2, IF(dct3.difficultyEntry3 = ct.id, 3, 0))) AS difficultyMode'], + 'dct1' => ['j' => ['?_creature dct1 ON ct.cuFlags & 0x02 AND dct1.difficultyEntry1 = ct.id', true]], + 'dct2' => ['j' => ['?_creature dct2 ON ct.cuFlags & 0x02 AND dct2.difficultyEntry2 = ct.id', true]], + 'dct3' => ['j' => ['?_creature dct3 ON ct.cuFlags & 0x02 AND dct3.difficultyEntry3 = ct.id', true]], 'ft' => ['j' => '?_factiontemplate ft ON ft.id = ct.faction', 's' => ', ft.A, ft.H, ft.factionId'], 'qse' => ['j' => ['?_quests_startend qse ON qse.type = 1 AND qse.typeId = ct.id', true], 's' => ', IF(min(qse.method) = 1 OR max(qse.method) = 3, 1, 0) AS startsQuests, IF(min(qse.method) = 2 OR max(qse.method) = 3, 1, 0) AS endsQuests', 'g' => 'ct.id'], 'qt' => ['j' => '?_quests qt ON qse.questId = qt.id'], @@ -236,9 +239,9 @@ class CreatureList extends BaseType foreach ($this->iterate() as $__) { $data[$this->id] = array( - 'n' => $this->getField('name', true), + 'n' => $this->getField('parentId') ? $this->getField('parent', true) : $this->getField('name', true), 't' => TYPE_NPC, - 'ti' => $this->id, + 'ti' => $this->getField('parentId') ?: $this->id, // 'bd' => (int)($this->curTpl['cuFlags'] & NPC_CU_INSTANCE_BOSS || ($this->curTpl['typeFlags'] & 0x4 && $this->curTpl['rank'])) // 'z' where am i spawned // 'dd' DungeonDifficulty requires 'z' diff --git a/includes/types/item.class.php b/includes/types/item.class.php index 5a89add7..1c6d3c22 100644 --- a/includes/types/item.class.php +++ b/includes/types/item.class.php @@ -389,6 +389,9 @@ class ItemList extends BaseType else if (!empty($this->sources[$this->id][3])) $data[$this->id]['sourcemore'] = [['p' => $this->sources[$this->id][3][0]]]; } + + if (!empty($this->curTpl['cooldown'])) + $data[$this->id]['cooldown'] = $this->curTpl['cooldown'] / 1000; } /* even more complicated crap @@ -1620,6 +1623,10 @@ class ItemListFilter extends Filter 17, 2366, 3840, 3713, 3847, 3775, 4100, 1581, 3557, 3845, 4500, 4809, 47, 3849, 4265, 4493, 4228, 3698, 4406, 3714, 3717, 3715, 717, 67, 3716, 457, 4415, 400, 1638, 1216, 85, 4723, 4722, 1337, 4273, 490, 1497, 206, 1196, 4603, 718, 3277, 28, 40, 11, 4197, 618, 3521, 3805, 66, 1176, 1977 + ), + 163 => array( // enchantment mats + 34057, 22445, 11176, 34052, 11082, 34055, 16203, 10939, 11135, 11175, 22446, 16204, 34054, 14344, 11084, 11139, 22449, 11178, + 10998, 34056, 16202, 10938, 11134, 11174, 22447, 20725, 14343, 34053, 10978, 11138, 22448, 11177, 11083, 10940, 11137, 22450 ) ); @@ -2064,15 +2071,68 @@ class ItemListFilter extends Filter if (!$this->isSaneNumeric($cr[2]) || !$this->int2Op($cr[1])) break; + $cr[2] *= 1000; // field supplied in milliseconds + $this->formData['extraCols'][] = $cr[0]; -/* todo */ return [1]; + $this->extraOpts['is']['s'][] = ', IF(spellCooldown1 > 1, spellCooldown1, IF(spellCooldown2 > 1, spellCooldown2, IF(spellCooldown3 > 1, spellCooldown3, IF(spellCooldown4 > 1, spellCooldown4, IF(spellCooldown5 > 1, spellCooldown5,))))) AS cooldown'; + + return [ + 'OR', + ['AND', ['spellTrigger1', 0], ['spellId1', 0, '!'], ['spellCooldown1', 0, '>'], ['spellCooldown1', $cr[2], $cr[1]]], + ['AND', ['spellTrigger2', 0], ['spellId2', 0, '!'], ['spellCooldown2', 0, '>'], ['spellCooldown2', $cr[2], $cr[1]]], + ['AND', ['spellTrigger3', 0], ['spellId3', 0, '!'], ['spellCooldown3', 0, '>'], ['spellCooldown3', $cr[2], $cr[1]]], + ['AND', ['spellTrigger4', 0], ['spellId4', 0, '!'], ['spellCooldown4', 0, '>'], ['spellCooldown4', $cr[2], $cr[1]]], + ['AND', ['spellTrigger5', 0], ['spellId5', 0, '!'], ['spellCooldown5', 0, '>'], ['spellCooldown5', $cr[2], $cr[1]]], + ]; case 163: // disenchantsinto [disenchanting] if (!$this->isSaneNumeric($cr[1])) break; -/* todo */ return [1]; + if (!in_array($cr[1], $this->enums[$cr[0]])) + break; + + $refResults = []; + $newRefs = DB::World()->selectCol('SELECT entry FROM ?# WHERE item = ?d AND reference = 0', LOOT_REFERENCE, $cr[1]); + while ($newRefs) + { + $refResults += $newRefs; + $newRefs = DB::World()->selectCol('SELECT entry FROM ?# WHERE reference IN (?a)', LOOT_REFERENCE, $newRefs); + } + + $lootIds = DB::World()->selectCol('SELECT entry FROM ?# WHERE {reference IN (?a) OR }(reference = 0 AND item = ?d)', LOOT_DISENCHANT, $refResults ?: DBSIMPLE_SKIP, $cr[1]); + + return $lootIds ? ['disenchantId', $lootIds] : [0]; case 85: // objectivequest [side] -/* todo */ return [1]; + $w = ''; + switch ($cr[1]) + { + case 1: // Yes + case 5: // No + $w = 1; + break; + case 2: // Alliance + $w = 'reqRaceMask & '.RACE_MASK_ALLIANCE.' AND (reqRaceMask & '.RACE_MASK_HORDE.') = 0'; + break; + case 3: // Horde + $w = 'reqRaceMask & '.RACE_MASK_HORDE.' AND (reqRaceMask & '.RACE_MASK_ALLIANCE.') = 0'; + break; + case 4: // Both + $w = '(reqRaceMask & '.RACE_MASK_ALLIANCE.' AND reqRaceMask & '.RACE_MASK_HORDE.') OR reqRaceMask = 0'; + break; + default: + break 2; + } + + $itemIds = DB::Aowow()->selectCol(sprintf(' + SELECT reqItemId1 FROM ?_quests WHERE %1$s UNION SELECT reqItemId2 FROM ?_quests WHERE %1$s UNION + SELECT reqItemId3 FROM ?_quests WHERE %1$s UNION SELECT reqItemId4 FROM ?_quests WHERE %1$s UNION + SELECT reqItemId5 FROM ?_quests WHERE %1$s UNION SELECT reqItemId6 FROM ?_quests WHERE %1$s', $w) + ); + + if ($itemIds) + return ['id', $itemIds, $cr[1] == 5 ? '!' : null]; + + return [0]; case 87: // reagentforability [enum] $_ = isset($this->enums[99][$cr[1]]) ? $this->enums[99][$cr[1]] : null; if ($_ !== null) diff --git a/localization/locale_dede.php b/localization/locale_dede.php index 2490e92e..dca6f5fe 100644 --- a/localization/locale_dede.php +++ b/localization/locale_dede.php @@ -723,7 +723,7 @@ $lang = array( 'unlimRange' => "Unbegrenzte Reichweite", 'reagents' => "Reagenzien", 'tools' => "Extras", - 'home' => "%lt;Gasthaus>", + 'home' => "<Gasthaus>", 'pctCostOf' => "vom Grund%s", 'costPerSec' => ", plus %s pro Sekunde", 'costPerLevel' => ", plus %s pro Stufe", diff --git a/pages/item.php b/pages/item.php index 65e431ee..e63ecbea 100644 --- a/pages/item.php +++ b/pages/item.php @@ -405,13 +405,20 @@ class ItemPage extends genericPage /**************/ // tabs: this item is contained in.. - $lootTabs = new Loot(); + $lootTabs = new Loot(); + $createdBy = []; if ($lootTabs->getByItem($this->typeId)) { $this->extendGlobalData($lootTabs->jsGlobals); - foreach ($lootTabs->iterate() as $tab) + foreach ($lootTabs->iterate() as $idx => $tab) { + if (!$tab[1]) + continue; + + if ($idx == 16) + $createdBy = array_column($tab[1], 'id'); + $this->lvTabs[] = array( 'file' => $tab[0], 'data' => $tab[1], @@ -910,9 +917,42 @@ class ItemPage extends genericPage } } - // todo: taught by (req. workaround over the spell taught) + // tab: Shared cooldown + $cdCats = []; + for ($i = 1; $i < 6; $i++) + if ($this->subject->getField('spellId'.$i) > 0 && $this->subject->getField('spellCategory'.$i) > 0) + $cdCats[] = $this->subject->getField('spellCategory'.$i); - // todo: Shared cooldown + if ($cdCats) + { + $conditions = array( + 'OR', + ['spellCategory1', $cdCats], + ['spellCategory2', $cdCats], + ['spellCategory3', $cdCats], + ['spellCategory4', $cdCats], + ['spellCategory5', $cdCats] + ); + $cdItems = new ItemList($conditions); + if (!$cdItems->error) + { + $this->lvTabs[] = array( + 'file' => 'item', + 'data' => $cdItems->getListviewData(), + 'params' => [ + 'name' => '$LANG.tab_sharedcooldown', + 'id' => 'shared-cooldown' + ] + ); + + $this->extendGlobalData($cdItems->getJSGlobals(GLOBALINFO_SELF)); + } + } + + // // todo - tab: taught by + // use var $createdBy to find source of this spell + // id: 'taught-by-X', + // name: LANG.tab_taughtby } protected function generateTooltip($asError = false) diff --git a/pages/items.php b/pages/items.php index 37d68e36..0d8c95d4 100644 --- a/pages/items.php +++ b/pages/items.php @@ -65,11 +65,11 @@ class ItemsPage extends GenericPage 7 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], 6 => [2, 3], 11 => [2, 3], - 9 => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], // some of the books to propper professions + 9 => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], 3 => [0, 1, 2, 3, 4, 5, 6, 7, 8], - 15 => [-2, -7, 0, 1, 2, 3, 4, 5], // -2: armor tokes, -7: flying mounts fuck it .. need major overhaul + 15 => [-2, -7, 0, 1, 2, 3, 4, 5], // -2: armor tokes, -7: flying mounts 10 => true, - 12 => true, // todo: contains enchantments + 12 => true, 13 => true ); diff --git a/pages/npc.php b/pages/npc.php index 998b4b5e..9caad420 100644 --- a/pages/npc.php +++ b/pages/npc.php @@ -61,11 +61,7 @@ class NpcPage extends GenericPage // difficulty entries of self if ($this->subject->getField('cuFlags') & NPC_CU_DIFFICULTY_DUMMY) - { - // find and create link to regular creature - $regNPC = new CreatureList(array(['OR', ['difficultyEntry1', $this->typeId], ['difficultyEntry2', $this->typeId], ['difficultyEntry3', $this->typeId]])); - $position = [$regNPC->id, $regNPC->getField('name', true)]; - } + $position = [$this->subject->getField('parentId'), $this->subject->getField('parent', true)]; else { for ($i = 1; $i < 4; $i++) diff --git a/setup/tools/sqlgen/items.func.php b/setup/tools/sqlgen/items.func.php index c4fc34f5..9e150614 100644 --- a/setup/tools/sqlgen/items.func.php +++ b/setup/tools/sqlgen/items.func.php @@ -181,6 +181,27 @@ function items(array $ids = []) // move armor tokens to own category DB::Aowow()->query('UPDATE ?_items SET subClass = -2 WHERE quality = 4 AND class = 15 AND subClassBak = 0 AND requiredClass AND (requiredClass & 0x5FF) <> 0x5FF'); + // move some junk to holiday if it requires one + DB::Aowow()->query('UPDATE ?_items SET subClass = 3 WHERE classBak = 15 AND subClassBak = 0 AND holidayId <> 0'); + + // move misc items that start quests to class: quest (except Sayges scrolls for consistency) + DB::Aowow()->query('UPDATE ?_items SET class = 12 WHERE classBak = 15 AND startQuest <> 0 AND name_loc0 NOT LIKE "sayge\'s fortune%"'); + + // move perm. enchantments into appropriate cat/subcat + DB::Aowow()->query('UPDATE ?_items i, dbc_spell s SET i.class = 0, i.subClass = 6 WHERE s.Id = i.spellId1 AND s.effect1Id = 53 AND i.classBak = 12'); + + // move some generic recipes into appropriate sub-categories + $skillz = array( + 773 => 11, // inscription + 356 => 9, // fishing + 186 => 12, // mining + 185 => 5, // cooking + 171 => 6 // alchemy + + ); + foreach ($skillz as $skill => $cat) + DB::Aowow()->query('UPDATE ?_items SET subClass = ?d WHERE classBak = 9 AND subClassBak = 0 AND requiredSkill = ?d', $cat, $skill); + // calculate durabilityCosts DB::Aowow()->query(' UPDATE diff --git a/setup/updates/1433023200_01.sql b/setup/updates/1433023200_01.sql new file mode 100644 index 00000000..661f1804 --- /dev/null +++ b/setup/updates/1433023200_01.sql @@ -0,0 +1,13 @@ +ALTER TABLE `aowow_creature` + ADD INDEX `difficultyEntry1` (`difficultyEntry1`), + ADD INDEX `difficultyEntry2` (`difficultyEntry2`), + ADD INDEX `difficultyEntry3` (`difficultyEntry3`); + +UPDATE aowow_items i, aowow_spell s SET i.class = 0, i.subClass = 6 WHERE s.Id = i.spellId1 AND s.effect1Id = 53 AND i.classBak = 12; +UPDATE aowow_items SET class = 12 WHERE classBak = 15 AND startQuest <> 0 AND name_loc0 NOT LIKE "sayge\'s fortune%"; +UPDATE aowow_items SET subClass = 3 WHERE classBak = 15 AND subClassBak = 0 AND holidayId <> 0; +UPDATE aowow_items SET subClass = 11 WHERE classBak = 9 AND subClassBak = 0 AND requiredSkill = 773; +UPDATE aowow_items SET subClass = 9 WHERE classBak = 9 AND subClassBak = 0 AND requiredSkill = 356; +UPDATE aowow_items SET subClass = 12 WHERE classBak = 9 AND subClassBak = 0 AND requiredSkill = 186; +UPDATE aowow_items SET subClass = 5 WHERE classBak = 9 AND subClassBak = 0 AND requiredSkill = 185; +UPDATE aowow_items SET subClass = 6 WHERE classBak = 9 AND subClassBak = 0 AND requiredSkill = 171;