public static function getName($id) { if ($id > 0) { $row = DB::Aowow()->SelectRow('SELECT * FROM ?_holidays WHERE Id = ?d', intVal($id)); } else { $row = DB::Aowow()->SelectRow('SELECT description as name FROM ?_events WHERE Id = ?d', intVal(-$id)); } return Util::localizedString($row, 'name'); }
function gems() { // sketchy, but should work // Id < 36'000 || ilevel < 70 ? BC : WOTLK $gems = DB::Aowow()->Select('SELECT i.id AS itemId, i.name_loc0, i.name_loc2, i.name_loc3, i.name_loc4, i.name_loc6, i.name_loc8, IF (i.id < 36000 OR i.itemLevel < 70, 1 , 2) AS expansion, i.quality, ic.iconString AS icon, i.gemEnchantmentId AS enchId, i.gemColorMask AS colors FROM ?_items i JOIN ?_icons ic ON ic.id = -i.displayId WHERE i.gemEnchantmentId <> 0 ORDER BY i.id DESC'); $success = true; // check directory-structure foreach (Util::$localeStrings as $dir) { if (!CLISetup::writeDir('datasets/' . $dir)) { $success = false; } } $enchIds = []; foreach ($gems as $pop) { $enchIds[] = $pop['enchId']; } $enchantments = new EnchantmentList(array(['id', $enchIds], CFG_SQL_LIMIT_NONE)); if ($enchantments->error) { CLISetup::log('Required table ?_itemenchantment seems to be empty! Leaving gems()...', CLISetup::LOG_ERROR); CLISetup::log(); return false; } foreach (CLISetup::$localeIds as $lId) { set_time_limit(5); User::useLocale($lId); Lang::load(Util::$localeStrings[$lId]); $gemsOut = []; foreach ($gems as $pop) { if (!$enchantments->getEntry($pop['enchId'])) { CLISetup::log(' * could not find enchantment #' . $pop['enchId'] . ' referenced by item #' . $gem['itemId'], CLISetup::LOG_WARN); continue; } $gemsOut[$pop['itemId']] = array('name' => Util::localizedString($pop, 'name'), 'quality' => $pop['quality'], 'icon' => strToLower($pop['icon']), 'enchantment' => $enchantments->getField('name', true), 'jsonequip' => $enchantments->getStatGain(), 'colors' => $pop['colors'], 'expansion' => $pop['expansion']); } $toFile = "var g_gems = " . Util::toJSON($gemsOut) . ";"; $file = 'datasets/' . User::$localeString . '/gems'; if (!CLISetup::writeFile($file, $toFile)) { $success = false; } } return $success; }
function glyphs() { $success = true; $glyphList = DB::Aowow()->Select('SELECT i.id AS itemId, i.*, IF (g.typeFlags & 0x1, 2, 1) AS type, i.subclass AS classs, i.requiredLevel AS level, s1.Id AS glyphSpell, ic.iconString AS icon, s1.skillLine1 AS skillId, s2.Id AS glyphEffect, s2.Id AS ARRAY_KEY FROM ?_items i JOIN ?_spell s1 ON s1.Id = i.spellid1 JOIN ?_glyphproperties g ON g.Id = s1.effect1MiscValue JOIN ?_spell s2 ON s2.Id = g.spellId JOIN ?_icons ic ON ic.Id = s1.iconIdAlt WHERE i.classBak = 16'); // check directory-structure foreach (Util::$localeStrings as $dir) { if (!CLISetup::writeDir('datasets/' . $dir)) { $success = false; } } $glyphSpells = new SpellList(array(['s.id', array_keys($glyphList)], CFG_SQL_LIMIT_NONE)); foreach (CLISetup::$localeIds as $lId) { set_time_limit(30); User::useLocale($lId); Lang::load(Util::$localeStrings[$lId]); $glyphsOut = []; foreach ($glyphSpells->iterate() as $__) { $pop = $glyphList[$glyphSpells->id]; if (!$pop['glyphEffect']) { continue; } if ($glyphSpells->getField('effect1Id') != 6 && $glyphSpells->getField('effect2Id') != 6 && $glyphSpells->getField('effect3Id') != 6) { continue; } $glyphsOut[$pop['itemId']] = array('name' => Util::localizedString($pop, 'name'), 'description' => $glyphSpells->parseText()[0], 'icon' => $pop['icon'], 'type' => $pop['type'], 'classs' => $pop['classs'], 'skill' => $pop['skillId'], 'level' => $pop['level']); } $toFile = "var g_glyphs = " . Util::toJSON($glyphsOut) . ";"; $file = 'datasets/' . User::$localeString . '/glyphs'; if (!CLISetup::writeFile($file, $toFile)) { $success = false; } } return $success; }
function pets() { $success = true; $locations = []; $petList = DB::Aowow()->Select('SELECT cr. id, cr.name_loc0, cr.name_loc2, cr.name_loc3, cr.name_loc6, cr.name_loc8, cr.minLevel, cr.maxLevel, ft.A, ft.H, cr.rank AS classification, cr.family, cr.displayId1 AS displayId, cr.textureString AS skin, LOWER(SUBSTRING_INDEX(cf.iconString, "\\\\", -1)) AS icon, cf.petTalentType AS type FROM ?_creature cr JOIN ?_factiontemplate ft ON ft.Id = cr.faction JOIN dbc_creaturefamily cf ON cf.id = cr.family WHERE cr.typeFlags & 0x1 AND (cr.cuFlags & 0x2) = 0 ORDER BY cr.id ASC'); // check directory-structure foreach (Util::$localeStrings as $dir) { if (!CLISetup::writeDir('datasets/' . $dir)) { $success = false; } } foreach (CLISetup::$localeIds as $lId) { User::useLocale($lId); Lang::load(Util::$localeStrings[$lId]); $petsOut = []; foreach ($petList as $pet) { // get locations // again: caching will save you time and nerves if (!isset($locations[$pet['id']])) { $locations[$pet['id']] = DB::Aowow()->SelectCol('SELECT DISTINCT areaId FROM ?_spawns WHERE type = ?d AND typeId = ?d', TYPE_NPC, $pet['id']); } $petsOut[$pet['id']] = array('id' => $pet['id'], 'name' => Util::localizedString($pet, 'name'), 'minlevel' => $pet['minLevel'], 'maxlevel' => $pet['maxLevel'], 'location' => $locations[$pet['id']], 'react' => [$pet['A'], $pet['H']], 'classification' => $pet['classification'], 'family' => $pet['family'], 'displayId' => $pet['displayId'], 'skin' => $pet['skin'], 'icon' => $pet['icon'], 'type' => $pet['type']); } $toFile = "var g_pets = " . Util::toJSON($petsOut) . ";"; $file = 'datasets/' . User::$localeString . '/pets'; if (!CLISetup::writeFile($file, $toFile)) { $success = false; } } return $success; }
public static function getName($id) { $row = DB::Aowow()->SelectRow(' SELECT IFNULL(h.name_loc0, e.description) AS name_loc0, h.name_loc2, h.name_loc3, h.name_loc6, h.name_loc8 FROM ?_events e LEFT JOIN ?_holidays h ON e.holidayId = h.id WHERE e.id = ?d', $id); return Util::localizedString($row, 'name'); }
function gems() { // sketchy, but should work // Id < 36'000 || ilevel < 70 ? BC : WOTLK $gems = DB::Aowow()->Select('SELECT i.id AS itemId, i.name_loc0, i.name_loc2, i.name_loc3, i.name_loc6, i.name_loc8, IF (i.id < 36000 OR i.itemLevel < 70, 1 , 2) AS expansion, i.quality, ic.iconString AS icon, i.gemEnchantmentId AS enchId, i.gemColorMask AS colors FROM ?_items i JOIN ?_icons ic ON ic.id = -i.displayId WHERE i.gemEnchantmentId <> 0 ORDER BY i.id DESC'); $success = true; // check directory-structure foreach (Util::$localeStrings as $dir) { if (!CLISetup::writeDir('datasets/' . $dir)) { $success = false; } } $enchIds = []; foreach ($gems as $pop) { $enchIds[] = $pop['enchId']; } $enchMisc = []; $enchJSON = Util::parseItemEnchantment($enchIds, false, $enchMisc); foreach (CLISetup::$localeIds as $lId) { set_time_limit(5); User::useLocale($lId); Lang::load(Util::$localeStrings[$lId]); $gemsOut = []; foreach ($gems as $pop) { $gemsOut[$pop['itemId']] = array('name' => Util::localizedString($pop, 'name'), 'quality' => $pop['quality'], 'icon' => strToLower($pop['icon']), 'enchantment' => Util::localizedString(@$enchMisc[$pop['enchId']]['text'] ?: [], 'text'), 'jsonequip' => @$enchJSON[$pop['enchId']] ?: [], 'colors' => $pop['colors'], 'expansion' => $pop['expansion']); } $toFile = "var g_gems = " . Util::toJSON($gemsOut) . ";"; $file = 'datasets/' . User::$localeString . '/gems'; if (!CLISetup::writeFile($file, $toFile)) { $success = false; } } return $success; }
protected function generateContent() { $this->addCSS(['string' => '.announcement { margin: auto; max-width: 1200px; padding: 0px 15px 15px 15px }']); // load news $this->news = DB::Aowow()->selectRow('SELECT id as ARRAY_KEY, n.* FROM ?_news n WHERE active = 1 ORDER BY id DESC LIMIT 1'); if (!$this->news) { return; } $this->news['text'] = Util::localizedString($this->news, 'text', true); if ($_ = (new Markup($this->news['text']))->parseGlobalsFromText()) { $this->extendGlobalData($_); } if (empty($this->news['bgImgUrl'])) { $this->news['bgImgUrl'] = STATIC_URL . '/images/' . User::$localeString . '/mainpage-bg-news.jpg'; } else { $this->news['bgImgUrl'] = strtr($this->news['bgImgUrl'], ['HOST_URL' => HOST_URL, 'STATIC_URL' => STATIC_URL]); } // load overlay links $this->news['overlays'] = DB::Aowow()->select('SELECT * FROM ?_news_overlay WHERE newsId = ?d', $this->news['id']); foreach ($this->news['overlays'] as &$o) { $o['title'] = Util::localizedString($o, 'title', true); $o['title'] = strtr($o['title'], ['HOST_URL' => HOST_URL, 'STATIC_URL' => STATIC_URL]); } }
private function createEffects(&$infobox, &$redButtons) { // proc data .. maybe use more information..? $procData = DB::World()->selectRow('SELECT IF(ppmRate > 0, -ppmRate, customChance) AS chance, cooldown FROM spell_proc_event WHERE entry = ?d', $this->typeId); if (!isset($procData['cooldown'])) { $procData['cooldown'] = 0; } $effects = []; $spellIdx = array_unique(array_merge($this->subject->canTriggerSpell(), $this->subject->canTeachSpell())); $itemIdx = $this->subject->canCreateItem(); // Iterate through all effects: for ($i = 1; $i < 4; $i++) { if ($this->subject->getField('effect' . $i . 'Id') <= 0) { continue; } $effId = (int) $this->subject->getField('effect' . $i . 'Id'); $effMV = (int) $this->subject->getField('effect' . $i . 'MiscValue'); $effBP = (int) $this->subject->getField('effect' . $i . 'BasePoints'); $effDS = (int) $this->subject->getField('effect' . $i . 'DieSides'); $effRPPL = $this->subject->getField('effect' . $i . 'RealPointsPerLevel'); $effAura = (int) $this->subject->getField('effect' . $i . 'AuraId'); $foo =& $effects[]; // Icons: // .. from item if (in_array($i, $itemIdx)) { $_ = $this->subject->getField('effect' . $i . 'CreateItemId'); foreach ($this->subject->relItems->iterate() as $itemId => $__) { if ($itemId != $_) { continue; } $foo['icon'] = array('id' => $this->subject->relItems->id, 'name' => $this->subject->relItems->getField('name', true), 'quality' => $this->subject->relItems->getField('quality'), 'count' => $effDS + $effBP, 'icon' => $this->subject->relItems->getField('iconString')); break; } if ($effDS > 1) { $foo['icon']['count'] = "'" . ($effBP + 1) . '-' . $foo['icon']['count'] . "'"; } } else { if (in_array($i, $spellIdx) || $effId == 133) { $_ = $this->subject->getField('effect' . $i . 'TriggerSpell'); if (!$_) { $_ = $this->subject->getField('effect' . $i . 'MiscValue'); } $trig = new SpellList(array(['s.id', (int) $_])); $foo['icon'] = array('id' => $_, 'name' => $trig->error ? Util::ucFirst(Lang::game('spell')) . ' #' . $_ : $trig->getField('name', true), 'count' => 0); $this->extendGlobalData($trig->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); } } // Effect Name $foo['name'] = (User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'EffectId: ' . $effId, Util::$spellEffectStrings[$effId]) : Util::$spellEffectStrings[$effId]) . Lang::main('colon'); if ($this->subject->getField('effect' . $i . 'RadiusMax') > 0) { $foo['radius'] = $this->subject->getField('effect' . $i . 'RadiusMax'); } if (!in_array($i, $itemIdx) && !in_array($i, $spellIdx) && !in_array($effAura, [225, 227])) { $foo['value'] = ($effDS && $effDS != 1 ? $effBP + 1 . Lang::game('valueDelim') : null) . ($effBP + $effDS); } if ($effRPPL != 0) { $foo['value'] = (isset($foo['value']) ? $foo['value'] : '0') . sprintf(Lang::spell('costPerLevel'), $effRPPL); } if ($this->subject->getField('effect' . $i . 'Periode') > 0) { $foo['interval'] = Util::formatTime($this->subject->getField('effect' . $i . 'Periode')); } if ($_ = $this->subject->getField('effect' . $i . 'Mechanic')) { $foo['mechanic'] = Lang::game('me', $_); } if (!empty($procData['chance'])) { $foo['procData'] = array($procData['chance'], $procData['cooldown'] ? Util::formatTime($procData['cooldown'] * 1000, true) : null); } else { if (in_array($i, $this->subject->canTriggerSpell()) && $this->subject->getField('procChance')) { $foo['procData'] = array($this->subject->getField('procChance'), $procData['cooldown'] ? Util::formatTime($procData['cooldown'] * 1000, true) : null); } } // parse masks and indizes switch ($effId) { case 8: // Power Drain // Power Drain case 30: // Energize // Energize case 137: // Energize Pct $_ = Lang::spell('powerTypes', $effMV); if ($_ && User::isInGroup(U_GROUP_EMPLOYEE)) { $_ = sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_); } else { if (!$_) { $_ = $effMV; } } if ($effMV == POWER_RAGE || $effMV == POWER_RUNIC_POWER) { $foo['value'] = ($effDS && $effDS != 1 ? ($effBP + 1) / 10 . Lang::game('valueDelim') : null) . ($effBP + $effDS) / 10; } $foo['name'] .= ' (' . $_ . ')'; break; case 16: // QuestComplete if ($_ = QuestList::getName($effMV)) { $foo['name'] .= '(<a href="?quest=' . $effMV . '">' . $_ . '</a>)'; } else { $foo['name'] .= Util::ucFirst(Lang::game('quest')) . ' #' . $effMV; } break; case 28: // Summon // Summon case 90: // Kill Credit // Kill Credit case 134: // Kill Credit2 $_ = Lang::game('npc') . ' #' . $effMV; if ($summon = $this->subject->getModelInfo($this->typeId, $i)) { $_ = $summon['typeId'] ? ' (<a href="?npc=' . $summon['typeId'] . '">' . $summon['displayName'] . '</a>)' : ' (#0)'; $redButtons[BUTTON_VIEW3D] = ['type' => TYPE_NPC, 'displayId' => $summon['displayId']]; } $foo['name'] .= $_; break; case 33: // Open Lock $_ = $effMV ? Lang::spell('lockType', $effMV) : $effMV; if ($_ && User::isInGroup(U_GROUP_EMPLOYEE)) { $_ = sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_); } else { if (!$_) { $_ = $effMV; } } $foo['name'] .= ' (' . $_ . ')'; break; case 53: // Enchant Item Perm // Enchant Item Perm case 54: // Enchant Item Temp // Enchant Item Temp case 92: // Enchant Held Item // Enchant Held Item case 156: // Enchant Item Prismatic if ($_ = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantment WHERE id = ?d', $effMV)) { $foo['name'] .= ' (<a href="?enchantment=' . $effMV . '" class="q2">' . Util::localizedString($_, 'name') . '</a>)'; } else { $foo['name'] .= ' #' . $effMV; } break; case 38: // Dispel [miscValue => Types] // Dispel [miscValue => Types] case 126: // Steal Aura $_ = Lang::game('dt', $effMV); if ($_ && User::isInGroup(U_GROUP_EMPLOYEE)) { $_ = sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_); } else { if (!$_) { $_ = $effMV; } } $foo['name'] .= ' (' . $_ . ')'; break; case 39: // Learn Language $_ = Lang::game('languages', $effMV); if ($_ && User::isInGroup(U_GROUP_EMPLOYEE)) { $_ = sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_); } else { if (!$_) { $_ = $effMV; } } $foo['name'] .= ' (' . $_ . ')'; break; case 50: // Trans Door // Trans Door case 76: // Summon Object (Wild) // case 86: // Activate Object // Summon Object (Wild) // case 86: // Activate Object case 104: // Summon Object (slot 1) // Summon Object (slot 1) case 105: // Summon Object (slot 2) // Summon Object (slot 2) case 106: // Summon Object (slot 3) // Summon Object (slot 3) case 107: // Summon Object (slot 4) $_ = Util::ucFirst(Lang::game('object')) . ' #' . $effMV; if ($summon = $this->subject->getModelInfo($this->typeId, $i)) { $_ = $summon['typeId'] ? ' (<a href="?object=' . $summon['typeId'] . '">' . $summon['displayName'] . '</a>)' : ' (#0)'; $redButtons[BUTTON_VIEW3D] = ['type' => TYPE_OBJECT, 'displayId' => $summon['displayId']]; } $foo['name'] .= $_; break; case 74: // Apply Glyph if ($_ = DB::Aowow()->selectCell('SELECT spellId FROM ?_glyphproperties WHERE id = ?d', $effMV)) { if ($n = SpellList::getName($_)) { $foo['name'] .= '(<a href="?spell=' . $_ . '">' . $n . '</a>)'; } else { $foo['name'] .= Util::ucFirst(Lang::game('spell')) . ' #' . $effMV; } } else { $foo['name'] .= ' #' . $effMV; } break; case 95: // Skinning switch ($effMV) { case 0: $_ = Lang::game('ct', 1) . ', ' . Lang::game('ct', 2); break; // Beast, Dragonkin // Beast, Dragonkin case 1: case 2: $_ = Lang::game('ct', 4); break; // Elemental (nature based, earth based) // Elemental (nature based, earth based) case 3: $_ = Lang::game('ct', 9); break; // Mechanic // Mechanic default: $_ = ''; } if (User::isInGroup(U_GROUP_EMPLOYEE)) { $_ = sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_); } else { $_ = $effMV; } $foo['name'] .= ' (' . $_ . ')'; break; case 108: // Dispel Mechanic $_ = Lang::game('me', $effMV); if ($_ && User::isInGroup(U_GROUP_EMPLOYEE)) { $_ = sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_); } else { if (!$_) { $_ = $effMV; } } $foo['name'] .= ' (' . $_ . ')'; break; case 118: // Require Skill if ($_ = SkillList::getName($effMV)) { $foo['name'] .= '(<a href="?skill=' . $effMV . '">' . $_ . '</a>)'; } else { $foo['name'] .= Util::ucFirst(Lang::game('skill')) . ' #' . $effMV; } break; case 146: // Activate Rune $_ = Lang::spell('powerRunes', $effMV); if ($_ && User::isInGroup(U_GROUP_EMPLOYEE)) { $_ = sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_); } else { if (!$_) { $_ = $effMV; } } $foo['name'] .= ' (' . $_ . ')'; break; case 123: // Send Taxi - effMV is taxiPathId. We only use paths for flightmasters for now, so spell-triggered paths are not in the table // Send Taxi - effMV is taxiPathId. We only use paths for flightmasters for now, so spell-triggered paths are not in the table default: if (($effMV || $effId == 97) && $effId != 155) { $foo['name'] .= ' (' . $effMV . ')'; } // Aura // Aura case 6: // Simple // Simple case 27: // AA Persistent // AA Persistent case 35: // AA Party // AA Party case 65: // AA Raid // AA Raid case 119: // AA Pet // AA Pet case 128: // AA Friend // AA Friend case 129: // AA Enemy // AA Enemy case 143: if ($effAura > 0 && isset(Util::$spellAuraStrings[$effAura])) { $foo['name'] .= User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'AuraId: ' . $effAura, Util::$spellAuraStrings[$effAura]) : Util::$spellAuraStrings[$effAura]; $bar = $effMV; switch ($effAura) { case 17: // Mod Stealth Detection if ($_ = Lang::spell('stealthType', $effMV)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } break; case 19: // Mod Invisibility Detection if ($_ = Lang::spell('invisibilityType', $effMV)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } break; case 24: // Periodic Energize // Periodic Energize case 21: // Obsolete Mod Power // Obsolete Mod Power case 35: // Mod Increase Power // Mod Increase Power case 85: // Mod Power Regeneration // Mod Power Regeneration case 110: // Mod Power Regeneration Pct if ($_ = Lang::spell('powerTypes', $effMV)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } break; case 29: // Mod Stat // Mod Stat case 80: // Mod Stat % // Mod Stat % case 137: // Mod Total Stat % // Mod Total Stat % case 175: // Mod Spell Healing Of Stat Percent // Mod Spell Healing Of Stat Percent case 212: // Mod Ranged Attack Power Of Stat Percent // Mod Ranged Attack Power Of Stat Percent case 219: // Mod Mana Regeneration from Stat // Mod Mana Regeneration from Stat case 268: // Mod Attack Power Of Stat Percent $mask = $effMV == -1 ? 0x1f : 1 << $effMV; $_ = []; for ($j = 0; $j < 5; $j++) { if ($mask & 1 << $j) { $_[] = Lang::game('stats', $j); } } if ($_ = implode(', ', $_)) { } $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; break; case 36: // Shapeshift if ($st = $this->subject->getModelInfo($this->typeId, $i)) { $redButtons[BUTTON_VIEW3D] = array('type' => TYPE_NPC, 'displayId' => $st['displayId']); if ($st['creatureType'] > 0) { $infobox[] = Lang::game('type') . Lang::main('colon') . Lang::game('ct', $st['creatureType']); } if ($_ = $st['displayName']) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } } break; case 37: // Effect immunity if (isset(Util::$spellEffectStrings[$effMV])) { $_ = Util::$spellEffectStrings[$effMV]; $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } break; case 38: // Aura immunity if (isset(Util::$spellAuraStrings[$effMV])) { $_ = Util::$spellAuraStrings[$effMV]; $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } break; case 41: // Dispel Immunity // Dispel Immunity case 178: // Mod Debuff Resistance // Mod Debuff Resistance case 245: // Mod Aura Duration By Dispel if ($_ = Lang::game('dt', $effMV)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } break; case 44: // Track Creature if ($_ = Lang::game('ct', $effMV)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } break; case 45: // Track Resource if ($_ = Lang::spell('lockType', $effMV)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } break; case 75: // Language if ($_ = Lang::game('languages', $effMV)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } break; case 77: // Mechanic Immunity // Mechanic Immunity case 117: // Mod Mechanic Resistance // Mod Mechanic Resistance case 232: // Mod Mechanic Duration // Mod Mechanic Duration case 234: // Mod Mechanic Duration (no stack) // Mod Mechanic Duration (no stack) case 255: // Mod Mechanic Damage Taken Pct // Mod Mechanic Damage Taken Pct case 276: // Mod Mechanic Damage Done Percent if ($_ = Lang::game('me', $effMV)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . Util::asHex($effMV), $_) : $_; } break; case 147: // Mechanic Immunity Mask $_ = []; foreach (Lang::game('me') as $k => $str) { if ($effMV & 1 << $k - 1) { $_[] = $str; } } if ($_ = implode(', ', $_)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . Util::asHex($effMV), $_) : $_; } break; case 10: // Mod Threat // Mod Threat case 13: // Mod Damage Done // Mod Damage Done case 14: // Mod Damage Taken // Mod Damage Taken case 22: // Mod Resistance // Mod Resistance case 39: // School Immunity // School Immunity case 40: // Damage Immunity // Damage Immunity case 50: // Mod Critical Healing Amount // Mod Critical Healing Amount case 57: // Mod Spell Crit Chance // Mod Spell Crit Chance case 69: // School Absorb // School Absorb case 71: // Mod Spell Crit Chance School // Mod Spell Crit Chance School case 72: // Mod Power Cost School Percent // Mod Power Cost School Percent case 73: // Mod Power Cost School Flat // Mod Power Cost School Flat case 74: // Reflect Spell School // Reflect Spell School case 79: // Mod Damage Done Pct // Mod Damage Done Pct case 81: // Split Damage Pct // Split Damage Pct case 83: // Mod Base Resistance // Mod Base Resistance case 87: // Mod Damage Taken Pct // Mod Damage Taken Pct case 97: // Mana Shield // Mana Shield case 101: // Mod Resistance Pct // Mod Resistance Pct case 115: // Mod Healing Taken // Mod Healing Taken case 118: // Mod Healing Taken Pct // Mod Healing Taken Pct case 123: // Mod Target Resistance // Mod Target Resistance case 135: // Mod Healing Done // Mod Healing Done case 136: // Mod Healing Done Pct // Mod Healing Done Pct case 142: // Mod Base Resistance Pct // Mod Base Resistance Pct case 143: // Mod Resistance Exclusive // Mod Resistance Exclusive case 149: // Reduce Pushback // Reduce Pushback case 163: // Mod Crit Damage Bonus // Mod Crit Damage Bonus case 174: // Mod Spell Damage Of Stat Percent // Mod Spell Damage Of Stat Percent case 182: // Mod Resistance Of Stat Percent // Mod Resistance Of Stat Percent case 186: // Mod Attacker Spell Hit Chance // Mod Attacker Spell Hit Chance case 194: // Mod Target Absorb School // Mod Target Absorb School case 195: // Mod Target Ability Absorb School // Mod Target Ability Absorb School case 199: // Mod Increases Spell Percent to Hit // Mod Increases Spell Percent to Hit case 229: // Mod AoE Damage Avoidance // Mod AoE Damage Avoidance case 271: // Mod Damage Percent Taken Form Caster // Mod Damage Percent Taken Form Caster case 310: // Mod Creature AoE Damage Avoidance if ($_ = Lang::getMagicSchools($effMV)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . Util::asHex($effMV), $_) : $_; } break; case 30: // Mod Skill // Mod Skill case 98: // Mod Skill Value if ($_ = SkillList::getName($effMV)) { $bar = ' (<a href="?skill=' . $effMV . '">' . SkillList::getName($effMV) . '</a>)'; } else { $bar = Lang::main('colon') . Util::ucFirst(Lang::game('skill')) . ' #' . $effMV; } break; case 107: // Flat Modifier // Flat Modifier case 108: // Pct Modifier if ($_ = Lang::spell('spellModOp', $effMV)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } break; case 189: // Mod Rating // Mod Rating case 220: // Combat Rating From Stat $_ = []; foreach (Lang::spell('combatRating') as $k => $str) { if (1 << $k & $effMV) { $_[] = $str; } } if ($_ = implode(', ', $_)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . Util::asHex($effMV), $_) : $_; } break; case 168: // Mod Damage Done Versus // Mod Damage Done Versus case 59: // Mod Damage Done Versus Creature // Mod Damage Done Versus Creature case 102: // Mod Melee Attack Power Versus // Mod Melee Attack Power Versus case 131: // Mod Ranged Attack Power Versus // Mod Ranged Attack Power Versus case 180: // Mod Spell Damage Versus $_ = []; foreach (Lang::game('ct') as $k => $str) { if ($effMV & 1 << $k - 1) { $_[] = $str; } } if ($_ = implode(', ', $_)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . Util::asHex($effMV), $_) : $_; } break; case 249: // Convert Rune $x = $this->subject->getField('effect' . $i . 'MiscValueB'); if ($_ = Lang::spell('powerRunes', $x)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $x, $_) : $_; } break; case 78: // Mounted // Mounted case 56: // Transform if ($transform = $this->subject->getModelInfo($this->typeId, $i)) { $redButtons[BUTTON_VIEW3D] = ['type' => TYPE_NPC, 'displayId' => $transform['displayId']]; $bar = $transform['typeId'] ? ' (<a href="?npc=' . $transform['typeId'] . '">' . $transform['displayName'] . '</a>)' : ' (#0)'; } else { $bar = Lang::main('colon') . Lang::game('npc') . ' #' . $effMV; } break; case 139: // Force Reaction $foo['value'] = sprintf(Util::$dfnString, $foo['value'], Lang::game('rep', $foo['value'])); // DO NOT BREAK // DO NOT BREAK case 190: // Mod Faction Reputation Gain $bar = ' (<a href="?faction=' . $effMV . '">' . FactionList::getName($effMV) . '</a>)'; break; // also breaks for 139 } $foo['name'] .= strstr($bar, 'href') || strstr($bar, '#') ? $bar : ($bar ? ' (' . $bar . ')' : null); if (in_array($effAura, [174, 220, 182])) { $foo['name'] .= ' [' . sprintf(Util::$dfnString, Lang::game('stats', $this->subject->getField('effect' . $i . 'MiscValueB')), $this->subject->getField('effect' . $i . 'MiscValueB')) . ']'; } else { if ($this->subject->getField('effect' . $i . 'MiscValueB') > 0) { $foo['name'] .= ' [' . $this->subject->getField('effect' . $i . 'MiscValueB') . ']'; } } } else { if ($effAura > 0) { $foo['name'] .= Lang::main('colon') . 'Unknown Aura (' . $effAura . ')'; } } break; } // cases where we dont want 'Value' to be displayed if (in_array($effAura, [11, 12, 36, 77]) || in_array($effId, []) || empty($foo['value'])) { unset($foo['value']); } } unset($foo); // clear reference return $effects; }
protected function generateContent() { $conditions = [CFG_SQL_LIMIT_NONE]; $visibleCols = []; $hiddenCols = []; $mapFile = 0; $spawnMap = -1; if (!User::isInGroup(U_GROUP_EMPLOYEE)) { // sub-areas and unused zones $conditions[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0]; } if ($this->category) { $conditions[] = ['z.category', $this->category[0]]; $hiddenCols[] = 'category'; if (isset($this->category[1]) && in_array($this->category[0], [2, 3])) { $conditions[] = ['z.expansion', $this->category[1]]; } if (empty($this->category[1])) { switch ($this->category[0]) { case 0: $mapFile = -3; $spawnMap = 0; break; case 1: $mapFile = -6; $spawnMap = 1; break; case 8: $mapFile = -2; $spawnMap = 530; break; case 10: $mapFile = -5; $spawnMap = 571; break; } } switch ($this->category[0]) { case 6: case 2: case 3: array_push($visibleCols, 'level', 'players'); case 9: $hiddenCols[] = 'territory'; break; } } $zones = new ZoneList($conditions); if (!$zones->hasSetFields(['type'])) { $hiddenCols[] = 'instancetype'; } $tabData = ['data' => array_values($zones->getListviewData())]; if ($visibleCols) { $tabData['visibleCols'] = $visibleCols; } if ($hiddenCols) { $tabData['hiddenCols'] = $hiddenCols; } $this->map = null; $this->lvTabs[] = ['zone', $tabData]; // create flight map if ($mapFile) { $somData = ['flightmaster' => []]; $nodes = DB::Aowow()->select('SELECT id AS ARRAY_KEY, tn.* FROM ?_taxinodes tn WHERE mapId = ?d ', $spawnMap); $paths = DB::Aowow()->select(' SELECT IF(tn1.reactA = tn1.reactH AND tn2.reactA = tn2.reactH, 1, 0) AS neutral, tp.startNodeId AS startId, tn1.posX AS startPosX, tn1.posY AS startPosY, tp.endNodeId AS endId, tn2.posX AS endPosX, tn2.posY AS endPosY FROM ?_taxipath tp, ?_taxinodes tn1, ?_taxinodes tn2 WHERE tn1.Id = tp.endNodeId AND tn2.Id = tp.startNodeId AND (tp.startNodeId IN (?a) OR tp.EndNodeId IN (?a)) ', array_keys($nodes), array_keys($nodes)); foreach ($nodes as $i => $n) { $neutral = $n['reactH'] == $n['reactA']; $data = array('coords' => [[$n['posX'], $n['posY']]], 'level' => 0, 'name' => Util::localizedString($n, 'name'), 'type' => $n['type'], 'id' => $n['typeId'], 'reacthorde' => $n['reactH'], 'reactalliance' => $n['reactA'], 'paths' => []); foreach ($paths as $j => $p) { if ($i != $p['startId'] && $i != $p['endId']) { continue; } if ($i == $p['startId'] && (!$neutral || $p['neutral'])) { $data['paths'][] = [$p['startPosX'], $p['startPosY']]; unset($paths[$j]); } else { if ($i == $p['endId'] && (!$neutral || $p['neutral'])) { $data['paths'][] = [$p['endPosX'], $p['endPosY']]; unset($paths[$j]); } } } if (empty($data['paths'])) { unset($data['paths']); } $somData['flightmaster'][] = $data; } $this->map = array('data' => array('zone' => $mapFile, 'zoom' => 1, 'overlay' => true, 'zoomable' => false, 'parent' => 'mapper-generic'), 'som' => $somData, 'mapperData' => [$mapFile => new stdClass()]); } }
protected function generateContent() { $this->addJS('?data=zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']); /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // Event (ignore events, where the object only gets removed) if ($_ = DB::World()->selectCol('SELECT DISTINCT IF(ge.holiday, ge.holiday, -ge.eventEntry) FROM game_event ge, game_event_gameobject geg, gameobject g WHERE ge.eventEntry = geg.eventEntry AND g.guid = geg.guid AND g.id = ?d', $this->typeId)) { $this->extendGlobalIds(TYPE_WORLDEVENT, $_); $ev = []; foreach ($_ as $i => $e) { $ev[] = ($i % 2 ? '[br]' : ' ') . '[event=' . $e . ']'; } $infobox[] = Util::ucFirst(Lang::game('eventShort')) . Lang::main('colon') . implode(',', $ev); } // Reaction $_ = function ($r) { if ($r == 1) { return 2; } if ($r == -1) { return 10; } return; }; $infobox[] = Lang::npc('react') . Lang::main('colon') . '[color=q' . $_($this->subject->getField('A')) . ']A[/color] [color=q' . $_($this->subject->getField('H')) . ']H[/color]'; // reqSkill switch ($this->subject->getField('typeCat')) { case -3: // Herbalism $infobox[] = sprintf(Lang::game('requires'), Lang::spell('lockType', 2) . ' (' . $this->subject->getField('reqSkill') . ')'); break; case -4: // Mining $infobox[] = sprintf(Lang::game('requires'), Lang::spell('lockType', 3) . ' (' . $this->subject->getField('reqSkill') . ')'); break; case -5: // Lockpicking $infobox[] = sprintf(Lang::game('requires'), Lang::spell('lockType', 1) . ' (' . $this->subject->getField('reqSkill') . ')'); break; default: $locks = Lang::getLocks($this->subject->getField('lockId')); $l = ''; foreach ($locks as $idx => $_) { if ($idx < 0) { continue; } $this->extendGlobalIds(TYPE_ITEM, $idx); $l = Lang::gameObject('key') . Lang::main('colon') . '[item=' . $idx . ']'; } // if no propper item is found use a skill if ($locks) { $infobox[] = $l ? $l : array_pop($locks); } } // linked trap if ($_ = $this->subject->getField('linkedTrap')) { $this->extendGlobalIds(TYPE_OBJECT, $_); $infobox[] = Lang::gameObject('trap') . Lang::main('colon') . '[object=' . $_ . ']'; } // trap for $trigger = new GameObjectList(array(['linkedTrap', $this->typeId])); if (!$trigger->error) { $this->extendGlobalData($trigger->getJSGlobals()); $infobox[] = Lang::gameObject('triggeredBy') . Lang::main('colon') . '[object=' . $trigger->id . ']'; } // SpellFocus if ($_ = $this->subject->getField('spellFocusId')) { if ($sfo = DB::Aowow()->selectRow('SELECT * FROM ?_spellfocusobject WHERE id = ?d', $_)) { $infobox[] = '[tooltip name=focus]' . Lang::gameObject('focusDesc') . '[/tooltip][span class=tip tooltip=focus]' . Lang::gameObject('focus') . Lang::main('colon') . Util::localizedString($sfo, 'name') . '[/span]'; } } // lootinfo: [min, max, restock] if (($_ = $this->subject->getField('lootStack')) && $_[0]) { $buff = Lang::item('charges') . Lang::main('colon') . $_[0]; if ($_[0] < $_[1]) { $buff .= Lang::game('valueDelim') . $_[1]; } // since Veins don't have charges anymore, the timer is questionable $infobox[] = $_[2] > 1 ? '[tooltip name=restock]' . sprintf(Lang::gameObject('restock'), Util::formatTime($_[2] * 1000)) . '[/tooltip][span class=tip tooltip=restock]' . $buff . '[/span]' : $buff; } // meeting stone [minLevel, maxLevel, zone] if ($this->subject->getField('type') == OBJECT_MEETINGSTONE) { if ($_ = $this->subject->getField('mStone')) { $this->extendGlobalIds(TYPE_ZONE, $_[2]); $m = Lang::game('meetingStone') . Lang::main('colon') . '[zone=' . $_[2] . ']'; $l = $_[0]; if ($_[0] > 1 && $_[1] > $_[0]) { $l .= Lang::game('valueDelim') . min($_[1], MAX_LEVEL); } $infobox[] = $l ? '[tooltip name=meetingstone]' . sprintf(Lang::game('reqLevel'), $l) . '[/tooltip][span class=tip tooltip=meetingstone]' . $m . '[/span]' : $m; } } // capture area [minPlayer, maxPlayer, minTime, maxTime, radius] if ($this->subject->getField('type') == OBJECT_CAPTURE_POINT) { if ($_ = $this->subject->getField('capture')) { $buff = Lang::gameObject('capturePoint'); if ($_[2] > 1 || $_[0]) { $buff .= Lang::main('colon') . '[ul]'; } if ($_[2] > 1) { $buff .= '[li]' . Lang::game('duration') . Lang::main('colon') . ($_[3] > $_[2] ? Util::FormatTime($_[3] * 1000, true) . ' - ' : null) . Util::FormatTime($_[2] * 1000, true) . '[/li]'; } if ($_[1]) { $buff .= '[li]' . Lang::main('players') . Lang::main('colon') . $_[0] . ($_[1] > $_[0] ? ' - ' . $_[1] : null) . '[/li]'; } if ($_[4]) { $buff .= '[li]' . sprintf(Lang::spell('range'), $_[4]) . '[/li]'; } if ($_[2] > 1 || $_[0]) { $buff .= '[/ul]'; } } $infobox[] = $buff; } // AI if (User::isInGroup(U_GROUP_EMPLOYEE)) { if ($_ = $this->subject->getField('ScriptName')) { $infobox[] = 'Script' . Lang::main('colon') . $_; } else { if ($_ = $this->subject->getField('AIName')) { $infobox[] = 'AI' . Lang::main('colon') . $_; } } } /****************/ /* Main Content */ /****************/ // pageText $pageText = []; if ($next = $this->subject->getField('pageTextId')) { while ($next) { $row = DB::World()->selectRow('SELECT *, text as Text_loc0 FROM page_text pt LEFT JOIN locales_page_text lpt ON pt.entry = lpt.entry WHERE pt.entry = ?d', $next); $next = $row['next_page']; $pageText[] = Util::parseHtmlText(Util::localizedString($row, 'Text')); } } // add conditional js & css if ($pageText) { $this->addCSS(['path' => 'Book.css']); $this->addJS('Book.js'); } // get spawns and path $map = null; if ($spawns = $this->subject->getSpawns(SPAWNINFO_FULL)) { $map = ['data' => ['parent' => 'mapper-generic'], 'mapperData' => &$spawns]; foreach ($spawns as $areaId => &$areaData) { $map['extra'][$areaId] = ZoneList::getName($areaId); } } // consider pooled spawns $this->infobox = $infobox ? '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]' : null; $this->pageText = $pageText; $this->map = $map; $this->redButtons = array(BUTTON_WOWHEAD => true, BUTTON_LINKS => true, BUTTON_VIEW3D => ['displayId' => $this->subject->getField('displayId'), 'type' => TYPE_OBJECT, 'typeId' => $this->typeId]); /**************/ /* Extra Tabs */ /**************/ // tab: summoned by $conditions = array('OR', ['AND', ['effect1Id', [50, 76, 104, 105, 106, 107]], ['effect1MiscValue', $this->typeId]], ['AND', ['effect2Id', [50, 76, 104, 105, 106, 107]], ['effect2MiscValue', $this->typeId]], ['AND', ['effect3Id', [50, 76, 104, 105, 106, 107]], ['effect3MiscValue', $this->typeId]]); $summons = new SpellList($conditions); if (!$summons->error) { $this->extendGlobalData($summons->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); $this->lvTabs[] = array('file' => 'spell', 'data' => $summons->getListviewData(), 'params' => array('id' => 'summoned-by', 'name' => '$LANG.tab_summonedby')); } // tab: related spells if ($_ = $this->subject->getField('spells')) { $relSpells = new SpellList(array(['id', $_])); if (!$relSpells->error) { $this->extendGlobalData($relSpells->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); $data = $relSpells->getListviewData(); foreach ($data as $relId => $d) { $data[$relId]['trigger'] = array_search($relId, $_); } $this->lvTabs[] = array('file' => 'spell', 'data' => $data, 'params' => array('id' => 'spells', 'name' => '$LANG.tab_spells', 'hiddenCols' => "\$['skill']", 'extraCols' => "\$[Listview.funcBox.createSimpleCol('trigger', 'Condition', '10%', 'trigger')]")); } } // tab: criteria of $acvs = new AchievementList(array(['ac.type', [ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT, ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT]], ['ac.value1', $this->typeId])); if (!$acvs->error) { $this->extendGlobalData($acvs->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); $this->lvTabs[] = array('file' => 'achievement', 'data' => $acvs->getListviewData(), 'params' => array('id' => 'criteria-of', 'name' => '$LANG.tab_criteriaof')); } // tab: starts quest // tab: ends quest $startEnd = new QuestList(array(['qse.type', TYPE_OBJECT], ['qse.typeId', $this->typeId])); if (!$startEnd->error) { $this->extendGlobalData($startEnd->getJSGlobals()); $lvData = $startEnd->getListviewData(); $_ = [[], []]; foreach ($startEnd->iterate() as $id => $__) { $m = $startEnd->getField('method'); if ($m & 0x1) { $_[0][] = $lvData[$id]; } if ($m & 0x2) { $_[1][] = $lvData[$id]; } } if ($_[0]) { $this->lvTabs[] = array('file' => 'quest', 'data' => $_[0], 'params' => array('name' => '$LANG.tab_starts', 'id' => 'starts')); } if ($_[1]) { $this->lvTabs[] = array('file' => 'quest', 'data' => $_[1], 'params' => array('name' => '$LANG.tab_ends', 'id' => 'ends')); } } // tab: related quests if ($_ = $this->subject->getField('reqQuest')) { $relQuest = new QuestList(array(['id', $_])); if (!$relQuest->error) { $this->extendGlobalData($relQuest->getJSGlobals()); $this->lvTabs[] = array('file' => 'quest', 'data' => $relQuest->getListviewData(), 'params' => array('name' => '$LANG.tab_quests', 'id' => 'quests')); } } // tab: contains $reqQuest = []; if ($_ = $this->subject->getField('lootId')) { $goLoot = new Loot(); if ($goLoot->getByContainer(LOOT_GAMEOBJECT, $_)) { $extraCols = $goLoot->extraCols; $hiddenCols = ['source', 'side', 'slot', 'reqlevel']; $this->extendGlobalData($goLoot->jsGlobals); foreach ($goLoot->iterate() as &$lv) { if (!empty($hiddenCols)) { foreach ($hiddenCols as $k => $str) { if (!empty($lv[$str])) { unset($hiddenCols[$k]); } } } if (!$lv['quest']) { continue; } $extraCols[] = 'Listview.extraCols.condition'; $reqQuest[$lv['id']] = 0; $lv['condition'][0][$this->typeId][] = [[CND_QUESTTAKEN, &$reqQuest[$lv['id']]]]; } $extraCols[] = 'Listview.extraCols.percent'; $this->lvTabs[] = array('file' => 'item', 'data' => $goLoot->getResult(), 'params' => array('name' => '$LANG.tab_contains', 'id' => 'contains', 'extraCols' => "\$[" . implode(', ', array_unique($extraCols)) . "]", 'hiddenCols' => $hiddenCols ? '$' . Util::toJSON(array_values($hiddenCols)) : null)); } } if ($reqIds = array_keys($reqQuest)) { $conditions = array('OR', ['reqSourceItemId1', $reqIds], ['reqSourceItemId2', $reqIds], ['reqSourceItemId3', $reqIds], ['reqSourceItemId4', $reqIds], ['reqItemId1', $reqIds], ['reqItemId2', $reqIds], ['reqItemId3', $reqIds], ['reqItemId4', $reqIds], ['reqItemId5', $reqIds], ['reqItemId6', $reqIds]); $reqQuests = new QuestList($conditions); $this->extendGlobalData($reqQuests->getJSGlobals()); foreach ($reqQuests->iterate() as $qId => $__) { if (empty($reqQuests->requires[$qId][TYPE_ITEM])) { continue; } foreach ($reqIds as $rId) { if (in_array($rId, $reqQuests->requires[$qId][TYPE_ITEM])) { $reqQuest[$rId] = $reqQuests->id; } } } } // tab: Same model as .. whats the f*****g point..? $sameModel = new GameObjectList(array(['displayId', $this->subject->getField('displayId')], ['id', $this->typeId, '!'])); if (!$sameModel->error) { $this->extendGlobalData($sameModel->getJSGlobals()); $this->lvTabs[] = array('file' => 'object', 'data' => $sameModel->getListviewData(), 'params' => array('name' => '$LANG.tab_samemodelas', 'id' => 'same-model-as')); } }
public function getModelInfo($spellId = 0, $effIdx = 0) { $displays = [0 => []]; foreach ($this->iterate() as $id => $__) { if ($spellId && $spellId != $id) { continue; } for ($i = 1; $i < 4; $i++) { $effMV = $this->curTpl['effect' . $i . 'MiscValue']; if (!$effMV) { continue; } // GO Model from MiscVal if (in_array($this->curTpl['effect' . $i . 'Id'], [50, 76, 104, 105, 106, 107])) { if (isset($displays[TYPE_OBJECT][$id])) { $displays[TYPE_OBJECT][$id][0][] = $i; } else { $displays[TYPE_OBJECT][$id] = [[$i], $effMV]; } } else { if (in_array($this->curTpl['effect' . $i . 'Id'], [28, 90, 134]) || in_array($this->curTpl['effect' . $i . 'AuraId'], [56, 78])) { if (isset($displays[TYPE_NPC][$id])) { $displays[TYPE_NPC][$id][0][] = $i; } else { $displays[TYPE_NPC][$id] = [[$i], $effMV]; } } else { if ($this->curTpl['effect' . $i . 'AuraId'] == 36) { $subForms = array(892 => [892, 29407, 29406, 29408, 29405], 8571 => [8571, 29410, 29411, 29412], 2281 => [2281, 29413, 29414, 29416, 29417], 2289 => [2289, 29415, 29418, 29419, 29420, 29421]); if ($st = DB::Aowow()->selectRow('SELECT *, displayIdA as model1, displayIdH as model2 FROM ?_shapeshiftforms WHERE id = ?d', $effMV)) { foreach ([1, 2] as $j) { if (isset($subForms[$st['model' . $j]])) { $st['model' . $j] = $subForms[$st['model' . $j]][array_rand($subForms[$st['model' . $j]])]; } } $displays[0][$id][$i] = array('typeId' => 0, 'displayId' => $st['model2'] ? $st['model' . rand(1, 2)] : $st['model1'], 'creatureType' => $st['creatureType'], 'displayName' => Util::localizedString($st, 'name')); } } } } } } $results = $displays[0]; if (!empty($displays[TYPE_NPC])) { $nModels = new CreatureList(array(['id', array_column($displays[TYPE_NPC], 1)])); foreach ($nModels->iterate() as $nId => $__) { $srcId = 0; foreach ($displays[TYPE_NPC] as $srcId => $set) { if ($set[1] == $nId) { break; } } foreach ($set[0] as $idx) { $results[$srcId][$idx] = array('typeId' => $nId, 'displayId' => $nModels->getRandomModelId(), 'displayName' => $nModels->getField('name', true)); } } } if (!empty($displays[TYPE_OBJECT])) { $oModels = new GameObjectList(array(['id', array_column($displays[TYPE_OBJECT], 1)])); foreach ($oModels->iterate() as $oId => $__) { $srcId = 0; foreach ($displays[TYPE_OBJECT] as $srcId => $set) { if ($set[1] == $oId) { break; } } foreach ($set[0] as $idx) { $results[$srcId][$idx] = array('typeId' => $oId, 'displayId' => $oModels->getField('displayId'), 'displayName' => $oModels->getField('name', true)); } } } if ($spellId && $effIdx) { return !empty($results[$spellId][$effIdx]) ? $results[$spellId][$effIdx] : 0; } return $results; }
function profiler() { $success = true; $scripts = []; /**********/ /* Quests */ /**********/ $scripts[] = function () { $success = true; $condition = [CFG_SQL_LIMIT_NONE, 'AND', [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW], 0], [['flags', QUEST_FLAG_DAILY | QUEST_FLAG_WEEKLY | QUEST_FLAG_REPEATABLE | QUEST_FLAG_AUTO_REWARDED, '&'], 0], [['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE | QUEST_FLAG_SPECIAL_DUNGEON_FINDER | QUEST_FLAG_SPECIAL_MONTHLY, '&'], 0]]; $questz = new QuestList($condition); $_ = []; $currencies = array_column($questz->rewards, TYPE_CURRENCY); foreach ($currencies as $curr) { foreach ($curr as $cId => $qty) { $_[] = $cId; } } $relCurr = new CurrencyList(array(['id', $_])); foreach (CLISetup::$localeIds as $l) { set_time_limit(20); User::useLocale($l); Lang::load(Util::$localeStrings[$l]); $buff = "var _ = g_gatheredcurrencies;\n"; foreach ($relCurr->getListviewData() as $id => $data) { $buff .= '_[' . $id . '] = ' . Util::toJSON($data) . ";\n"; } $buff .= "\n\nvar _ = g_quests;\n"; foreach ($questz->getListviewData() as $id => $data) { $buff .= '_[' . $id . '] = ' . Util::toJSON($data) . ";\n"; } $buff .= "\ng_quest_catorder = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n"; if (!CLISetup::writeFile('datasets/' . User::$localeString . '/p-quests', $buff)) { $success = false; } } return $success; }; /****************/ /* Achievements */ /****************/ $scripts[] = function () { $success = true; $condition = array(CFG_SQL_LIMIT_NONE, [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0], [['flags', 1, '&'], 0]); $achievez = new AchievementList($condition); foreach (CLISetup::$localeIds as $l) { set_time_limit(5); User::useLocale($l); Lang::load(Util::$localeStrings[$l]); $sumPoints = 0; $buff = "var _ = g_achievements;\n"; foreach ($achievez->getListviewData(ACHIEVEMENTINFO_PROFILE) as $id => $data) { $sumPoints += $data['points']; $buff .= '_[' . $id . '] = ' . Util::toJSON($data) . ";\n"; } // categories to sort by $buff .= "\ng_achievement_catorder = [92, 14863, 97, 169, 170, 171, 172, 14802, 14804, 14803, 14801, 95, 161, 156, 165, 14806, 14921, 96, 201, 160, 14923, 14808, 14805, 14778, 14865, 14777, 14779, 155, 14862, 14861, 14864, 14866, 158, 162, 14780, 168, 14881, 187, 14901, 163, 14922, 159, 14941, 14961, 14962, 14981, 15003, 15002, 15001, 15041, 15042, 81]"; // sum points $buff .= "\ng_achievement_points = [" . $sumPoints . "];\n"; if (!CLISetup::writeFile('datasets/' . User::$localeString . '/p-achievements', $buff)) { $success = false; } } return $success; }; /**********/ /* Titles */ /**********/ $scripts[] = function () { $success = true; $condition = array(CFG_SQL_LIMIT_NONE, [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0]); $titlez = new TitleList($condition); foreach (CLISetup::$localeIds as $l) { set_time_limit(5); User::useLocale($l); Lang::load(Util::$localeStrings[$l]); foreach ([0, 1] as $g) { $buff = "var _ = g_titles;\n"; foreach ($titlez->getListviewData() as $id => $data) { $data['name'] = Util::localizedString($titlez->getEntry($id), $g ? 'female' : 'male'); unset($data['namefemale']); $buff .= '_[' . $id . '] = ' . Util::toJSON($data) . ";\n"; } if (!CLISetup::writeFile('datasets/' . User::$localeString . '/p-titles-' . $g, $buff)) { $success = false; } } } return $success; }; /**********/ /* Mounts */ /**********/ $scripts[] = function () { $success = true; $condition = array(CFG_SQL_LIMIT_NONE, [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0], ['typeCat', -5]); $mountz = new SpellList($condition); foreach (CLISetup::$localeIds as $l) { set_time_limit(5); User::useLocale($l); Lang::load(Util::$localeStrings[$l]); $buff = "var _ = g_spells;\n"; foreach ($mountz->getListviewData(ITEMINFO_MODEL) as $id => $data) { $data['quality'] = $data['name'][0]; $data['name'] = mb_substr($data['name'], 1); $buff .= '_[' . $id . '] = ' . Util::toJSON($data) . ";\n"; } if (!CLISetup::writeFile('datasets/' . User::$localeString . '/p-mounts', $buff)) { $success = false; } } return $success; }; /**************/ /* Companions */ /**************/ $scripts[] = function () { $success = true; $condition = array(CFG_SQL_LIMIT_NONE, [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0], ['typeCat', -6]); $companionz = new SpellList($condition); foreach (CLISetup::$localeIds as $l) { set_time_limit(5); User::useLocale($l); Lang::load(Util::$localeStrings[$l]); $buff = "var _ = g_spells;\n"; foreach ($companionz->getListviewData(ITEMINFO_MODEL) as $id => $data) { $data['quality'] = $data['name'][0]; $data['name'] = mb_substr($data['name'], 1); $buff .= '_[' . $id . '] = ' . Util::toJSON($data) . ";\n"; } if (!CLISetup::writeFile('datasets/' . User::$localeString . '/p-companions', $buff)) { $success = false; } } return $success; }; /************/ /* Factions */ /************/ $scripts[] = function () { $success = true; $condition = array(CFG_SQL_LIMIT_NONE, [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0]); $factionz = new FactionList($condition); foreach (CLISetup::$localeIds as $l) { set_time_limit(5); User::useLocale($l); Lang::load(Util::$localeStrings[$l]); $buff = "var _ = g_factions;\n"; foreach ($factionz->getListviewData() as $id => $data) { $buff .= '_[' . $id . '] = ' . Util::toJSON($data) . ";\n"; } $buff .= "\ng_faction_order = [0, 469, 891, 1037, 1118, 67, 1052, 892, 936, 1117, 169, 980, 1097];\n"; if (!CLISetup::writeFile('datasets/' . User::$localeString . '/p-factions', $buff)) { $success = false; } } return $success; }; /***********/ /* Recipes */ /***********/ $scripts[] = function () { // special case: secondary skills are always requested, so put them in one single file (185, 129, 356); it also contains g_skill_order $skills = [171, 164, 333, 202, 182, 773, 755, 165, 186, 393, 197, [185, 129, 356]]; $success = true; $baseCnd = array(CFG_SQL_LIMIT_NONE, [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0], ['effect1Id', [6, 45, 57, 127, 33, 158, 99, 28, 95], '!'], ['effect2Id', [118, 60], '!'], ['OR', ['typeCat', 9], ['typeCat', 11]]); foreach ($skills as $s) { $file = is_array($s) ? 'sec' : (string) $s; $cnd = array_merge($baseCnd, [['skillLine1', $s]]); $recipez = new SpellList($cnd); $created = ''; foreach ($recipez->iterate() as $__) { foreach ($recipez->canCreateItem() as $idx) { $id = $recipez->getField('effect' . $idx . 'CreateItemId'); $created .= "g_items.add(" . $id . ", {'icon':'" . $recipez->relItems->getEntry($id)['iconString'] . "'});\n"; } } foreach (CLISetup::$localeIds as $l) { set_time_limit(10); User::useLocale($l); Lang::load(Util::$localeStrings[$l]); $buff = ''; foreach ($recipez->getListviewData() as $id => $data) { $buff .= '_[' . $id . '] = ' . Util::toJSON($data) . ";\n"; } if (!$buff) { // this behaviour is intended, do not create an error CLISetup::log('profiler - file datasets/' . User::$localeString . '/p-recipes-' . $file . ' has no content => skipping', CLISetup::LOG_WARN); continue; } $buff = $created . "\nvar _ = g_spells;\n" . $buff; if (is_array($s)) { $buff .= "\ng_skill_order = [171, 164, 333, 202, 182, 773, 755, 165, 186, 393, 197, 185, 129, 356];\n"; } if (!CLISetup::writeFile('datasets/' . User::$localeString . '/p-recipes-' . $file, $buff)) { $success = false; } } } return $success; }; // check directory-structure foreach (Util::$localeStrings as $dir) { if (!CLISetup::writeDir('datasets/' . $dir)) { $success = false; } } // run scripts foreach ($scripts as $func) { if (!$func()) { $success = false; } } return $success; }
protected function generateContent() { $this->addJS('?data=zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']); /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // City if ($this->subject->getField('flags') & 0x8 && !$this->subject->getField('parentArea')) { $infobox[] = Lang::zone('city'); } // Auto repop if ($this->subject->getField('flags') & 0x1000 && !$this->subject->getField('parentArea')) { $infobox[] = Lang::zone('autoRez'); } // Level if ($_ = $this->subject->getField('levelMin')) { if ($_ < $this->subject->getField('levelMax')) { $_ .= ' - ' . $this->subject->getField('levelMax'); } $infobox[] = Lang::game('level') . Lang::main('colon') . $_; } // required Level if ($_ = $this->subject->getField('levelReq')) { if ($__ = $this->subject->getField('levelReqLFG')) { $buff = sprintf(Lang::zone('reqLevels'), $_, $__); } else { $buff = Lang::main('_reqLevel') . Lang::main('colon') . $_; } $infobox[] = $buff; } // Territory $_ = $this->subject->getField('faction'); $__ = '%s'; if ($_ == 0) { $__ = '[span class=icon-alliance]%s[/span]'; } else { if ($_ == 1) { $__ = '[span class=icon-horde]%s[/span]'; } else { if ($_ == 4) { $__ = '[span class=icon-ffa]%s[/span]'; } } } $infobox[] = Lang::zone('territory') . Lang::main('colon') . sprintf($__, Lang::zone('territories', $_)); // Instance Type $infobox[] = Lang::zone('instanceType') . Lang::main('colon') . '[span class=icon-instance' . $this->subject->getField('type') . ']' . Lang::zone('instanceTypes', $this->subject->getField('type')) . '[/span]'; // Heroic mode if ($_ = $this->subject->getField('levelHeroic')) { $infobox[] = '[icon preset=heroic]' . sprintf(Lang::zone('hcAvailable'), $_) . '[/icon]'; } // number of players if ($_ = $this->subject->getField('maxPlayer')) { $infobox[] = Lang::zone('numPlayers') . Lang::main('colon') . ($_ == -2 ? '10/25' : $_); } // Attunement Quest/Achievements & Keys if ($attmnt = $this->subject->getField('attunes')) { foreach ($attmnt as $type => $ids) { $this->extendGlobalIds($type, array_map('abs', $ids)); foreach ($ids as $id) { if ($type == TYPE_ITEM) { $infobox[] = Lang::zone('key', (int) ($id < 0)) . Lang::main('colon') . '[item=' . abs($id) . ']'; } else { $infobox[] = Lang::zone('attunement', (int) ($id < 0)) . Lang::main('colon') . '[' . Util::$typeStrings[$type] . '=' . abs($id) . ']'; } } } } // Instances if ($_ = DB::Aowow()->selectCol('SELECT id FROM ?_zones WHERE parentAreaId = ?d AND (flags & ?d) = 0', $this->typeId, CUSTOM_EXCLUDE_FOR_LISTVIEW)) { $this->extendGlobalIds(TYPE_ZONE, $_); $infobox[] = Lang::maps('Instances') . Lang::main('colon') . "\n[zone=" . implode("], \n[zone=", $_) . ']'; } // location (if instance) if ($pa = $this->subject->getField('parentAreaId')) { $paO = new ZoneList(array(['id', $pa])); if (!$paO->error) { $pins = str_pad($this->subject->getField('parentX') * 10, 3, '0', STR_PAD_LEFT) . str_pad($this->subject->getField('parentY') * 10, 3, '0', STR_PAD_LEFT); $infobox[] = Lang::zone('location') . Lang::main('colon') . '[lightbox=map zone=' . $pa . ' pins=' . $pins . ']' . $paO->getField('name', true) . '[/lightbox]'; } } /* has to be defined in an article, i think // faction(s) / Reputation Hub / Raid Faction // [li]Raid faction: [faction=1156][/li] || [li]Factions: [faction=1156]/[faction=1156][/li] // final boss // [li]Final boss: [icon preset=boss][npc=37226][/icon][/li] */ /****************/ /* Main Content */ /****************/ $addToMap = function ($what, $entry) use(&$som) { // entry always contains: type, id, name, level, coords[] if (!isset($som[$what][$entry['name']])) { // not found yet $som[$what][$entry['name']][] = $entry; } else { // check for identical floors foreach ($som[$what][$entry['name']] as &$byFloor) { if ($byFloor['level'] != $entry['level']) { continue; } // found existing floor, ammending coords $byFloor['coords'][] = $entry['coords'][0]; break; } // floor not used yet, create it $som[$what][$entry['name']][] = $entry; } }; if ($_ = $this->subject->getField('parentArea')) { $this->extraText = sprintf(Lang::zone('zonePartOf'), $_); $this->extendGlobalIds(TYPE_ZONE, $_); } // we cannot fetch spawns via lists. lists are grouped by entry $oSpawns = DB::Aowow()->select('SELECT * FROM ?_spawns WHERE areaId = ?d AND type = ?d', $this->typeId, TYPE_OBJECT); $cSpawns = DB::Aowow()->select('SELECT * FROM ?_spawns WHERE areaId = ?d AND type = ?d', $this->typeId, TYPE_NPC); $conditions = [CFG_SQL_LIMIT_NONE, ['s.areaId', $this->typeId]]; if (!User::isInGroup(U_GROUP_STAFF)) { $conditions[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0]; } $objectSpawns = new GameObjectList($conditions); $creatureSpawns = new CreatureList($conditions); $questsLV = $rewardsLV = []; // see if we can actually display a map $hasMap = file_exists('static/images/wow/maps/' . Util::$localeStrings[User::$localeId] . '/normal/' . $this->typeId . '.jpg'); if (!$hasMap) { // try multilayered $hasMap = file_exists('static/images/wow/maps/' . Util::$localeStrings[User::$localeId] . '/normal/' . $this->typeId . '-1.jpg'); } if (!$hasMap) { // try english fallback $hasMap = file_exists('static/images/wow/maps/enus/normal/' . $this->typeId . '.jpg'); } if (!$hasMap) { // try english fallback, multilayered $hasMap = file_exists('static/images/wow/maps/enus/normal/' . $this->typeId . '-1.jpg'); } if ($hasMap) { $som = []; foreach ($oSpawns as $spawn) { $tpl = $objectSpawns->getEntry($spawn['typeId']); if (!$tpl) { continue; } $n = Util::localizedString($tpl, 'name'); $what = ''; switch ($tpl['typeCat']) { case -3: $what = 'herb'; break; case -4: $what = 'vein'; break; case 9: $what = 'book'; break; case -6: if ($tpl['spellFocusId'] == 1) { $what = 'anvil'; } else { if ($tpl['spellFocusId'] == 3) { $what = 'forge'; } } break; } if ($what) { $addToMap($what, array('coords' => [[$spawn['posX'], $spawn['posY']]], 'level' => $spawn['floor'], 'name' => $n, 'type' => TYPE_OBJECT, 'id' => $tpl['id'])); } if ($tpl['startsQuests']) { $started = new QuestList(array(['qse.method', 1, '&'], ['qse.type', TYPE_OBJECT], ['qse.typeId', $tpl['id']])); if ($started->error) { continue; } // store data for misc tabs foreach ($started->getListviewData() as $id => $data) { if (!empty($started->rewards[$id][TYPE_ITEM])) { $rewardsLV = array_merge($rewardsLV, array_keys($started->rewards[$id][TYPE_ITEM])); } if (!empty($started->choices[$id][TYPE_ITEM])) { $rewardsLV = array_merge($rewardsLV, array_keys($started->choices[$id][TYPE_ITEM])); } $questsLV[$id] = $data; } $this->extendGlobalData($started->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_REWARDS)); if ($tpl['A'] != -1 & ($_ = $started->getSOMData(SIDE_ALLIANCE))) { $addToMap('alliancequests', array('coords' => [[$spawn['posX'], $spawn['posY']]], 'level' => $spawn['floor'], 'name' => $n, 'type' => TYPE_OBJECT, 'id' => $tpl['id'], 'side' => ($tpl['A'] < 0 ? 0 : 0x1) | ($tpl['H'] < 0 ? 0 : 0x2), 'quests' => array_values($_))); } if ($tpl['H'] != -1 & ($_ = $started->getSOMData(SIDE_HORDE))) { $addToMap('hordequests', array('coords' => [[$spawn['posX'], $spawn['posY']]], 'level' => $spawn['floor'], 'name' => $n, 'type' => TYPE_OBJECT, 'id' => $tpl['id'], 'side' => ($tpl['A'] < 0 ? 0 : 0x1) | ($tpl['H'] < 0 ? 0 : 0x2), 'quests' => array_values($_))); } } } $flightNodes = []; foreach ($cSpawns as $spawn) { $tpl = $creatureSpawns->getEntry($spawn['typeId']); if (!$tpl) { continue; } $n = Util::localizedString($tpl, 'name'); $sn = Util::localizedString($tpl, 'subname'); $what = ''; if ($tpl['npcflag'] & NPC_FLAG_REPAIRER) { $what = 'repair'; } else { if ($tpl['npcflag'] & NPC_FLAG_AUCTIONEER) { $what = 'auctioneer'; } else { if ($tpl['npcflag'] & NPC_FLAG_BANKER) { $what = 'banker'; } else { if ($tpl['npcflag'] & NPC_FLAG_BATTLEMASTER) { $what = 'battlemaster'; } else { if ($tpl['npcflag'] & NPC_FLAG_INNKEEPER) { $what = 'innkeeper'; } else { if ($tpl['npcflag'] & NPC_FLAG_TRAINER) { $what = 'trainer'; } else { if ($tpl['npcflag'] & NPC_FLAG_VENDOR) { $what = 'vendor'; } else { if ($tpl['npcflag'] & NPC_FLAG_FLIGHT_MASTER) { $flightNodes[$tpl['id']] = [$spawn['posX'], $spawn['posY']]; $what = 'flightmaster'; } else { if ($tpl['npcflag'] & NPC_FLAG_STABLE_MASTER) { $what = 'stablemaster'; } else { if ($tpl['npcflag'] & NPC_FLAG_GUILD_MASTER) { $what = 'guildmaster'; } else { if ($tpl['npcflag'] & (NPC_FLAG_SPIRIT_HEALER | NPC_FLAG_SPIRIT_GUIDE)) { $what = 'spirithealer'; } else { if ($creatureSpawns->isBoss()) { $what = 'boss'; } else { if ($tpl['rank'] == 2 || $tpl['rank'] == 4) { $what = 'rare'; } } } } } } } } } } } } } if ($what) { $addToMap($what, array('coords' => [[$spawn['posX'], $spawn['posY']]], 'level' => $spawn['floor'], 'name' => $n, 'type' => TYPE_NPC, 'id' => $tpl['id'], 'reacthorde' => $tpl['H'] ?: 1, 'reactalliance' => $tpl['A'] ?: 1, 'description' => $sn)); } if ($tpl['startsQuests']) { $started = new QuestList(array(['qse.method', 1, '&'], ['qse.type', TYPE_NPC], ['qse.typeId', $tpl['id']])); if ($started->error) { continue; } // store data for misc tabs foreach ($started->getListviewData() as $id => $data) { if (!empty($started->rewards[$id][TYPE_ITEM])) { $rewardsLV = array_merge($rewardsLV, array_keys($started->rewards[$id][TYPE_ITEM])); } if (!empty($started->choices[$id][TYPE_ITEM])) { $rewardsLV = array_merge($rewardsLV, array_keys($started->choices[$id][TYPE_ITEM])); } $questsLV[$id] = $data; } if ($tpl['A'] != -1 & ($_ = $started->getSOMData(SIDE_ALLIANCE))) { $addToMap('alliancequests', array('coords' => [[$spawn['posX'], $spawn['posY']]], 'level' => $spawn['floor'], 'name' => $n, 'type' => TYPE_NPC, 'id' => $tpl['id'], 'reacthorde' => $tpl['H'], 'reactalliance' => $tpl['A'], 'side' => ($tpl['A'] < 0 ? 0 : SIDE_ALLIANCE) | ($tpl['H'] < 0 ? 0 : SIDE_HORDE), 'quests' => array_values($_))); } if ($tpl['H'] != -1 & ($_ = $started->getSOMData(SIDE_HORDE))) { $addToMap('hordequests', array('coords' => [[$spawn['posX'], $spawn['posY']]], 'level' => $spawn['floor'], 'name' => $n, 'type' => TYPE_NPC, 'id' => $tpl['id'], 'reacthorde' => $tpl['H'], 'reactalliance' => $tpl['A'], 'side' => ($tpl['A'] < 0 ? 0 : SIDE_ALLIANCE) | ($tpl['H'] < 0 ? 0 : SIDE_HORDE), 'quests' => array_values($_))); } } } // remove unwanted indizes foreach ($som as $what => &$dataz) { if (empty($som[$what])) { continue; } foreach ($dataz as &$data) { $data = array_values($data); } if (!in_array($what, ['vein', 'herb', 'rare'])) { $foo = []; foreach ($dataz as $d) { foreach ($d as $_) { $foo[] = $_; } } $dataz = $foo; } } // append paths between nodes if ($flightNodes) { // neutral nodes come last as the line is colored by the node it's attached to usort($som['flightmaster'], function ($a, $b) { $n1 = $a['reactalliance'] == $a['reacthorde']; $n2 = $b['reactalliance'] == $b['reacthorde']; if ($n1 && !$n2) { return 1; } if (!$n1 && $n2) { return -1; } return 0; }); $paths = DB::Aowow()->select('SELECT n1.typeId AS "0", n2.typeId AS "1" FROM ?_taxipath p JOIN ?_taxinodes n1 ON n1.id = p.startNodeId JOIN ?_taxinodes n2 ON n2.id = p.endNodeId WHERE n1.typeId IN (?a) AND n2.typeId IN (?a)', array_keys($flightNodes), array_keys($flightNodes)); foreach ($paths as $k => $path) { foreach ($som['flightmaster'] as &$fm) { if ($fm['id'] != $path[0] && $fm['id'] != $path[1]) { continue; } if ($fm['id'] == $path[0]) { $fm['paths'][] = $flightNodes[$path[1]]; } if ($fm['id'] == $path[1]) { $fm['paths'][] = $flightNodes[$path[0]]; } unset($paths[$k]); break; } } } // preselect bosses for raids/dungeons if (in_array($this->subject->getField('type'), [2, 3, 4, 5, 7, 8])) { $som['instance'] = true; } $this->map = array('data' => ['parent' => 'mapper-generic', 'zone' => $this->typeId], 'som' => $som); } else { $this->map = false; } $this->infobox = $infobox ? '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]' : null; $this->expansion = Util::$expansionString[$this->subject->getField('expansion')]; $this->redButtons = array(BUTTON_WOWHEAD => true, BUTTON_LINKS => true); /* - associated with holiday? */ /**************/ /* Extra Tabs */ /**************/ // tab: NPCs if ($cSpawns && !$creatureSpawns->error) { $lvData = array('file' => 'creature', 'data' => $creatureSpawns->getListviewData(), 'params' => ['note' => sprintf(Util::$filterResultString, '?npcs&filter=cr=6;crs=' . $this->typeId . ';crv=0')]); if ($creatureSpawns->getMatches() > CFG_SQL_LIMIT_DEFAULT) { $lvData['params']['_truncated'] = 1; } $this->extendGlobalData($creatureSpawns->getJSGlobals(GLOBALINFO_SELF)); $this->lvTabs[] = $lvData; } // tab: Objects if ($oSpawns && !$objectSpawns->error) { $lvData = array('file' => 'object', 'data' => $objectSpawns->getListviewData(), 'params' => ['note' => sprintf(Util::$filterResultString, '?objects&filter=cr=1;crs=' . $this->typeId . ';crv=0')]); if ($objectSpawns->getMatches() > CFG_SQL_LIMIT_DEFAULT) { $lvData['params']['_truncated'] = 1; } $this->extendGlobalData($objectSpawns->getJSGlobals(GLOBALINFO_SELF)); $this->lvTabs[] = $lvData; } // tab: Quests [data collected by SOM-routine] if ($questsLV) { $this->lvTabs[] = array('file' => 'quest', 'data' => $questsLV, 'params' => ['note' => '$$WH.sprintf(LANG.lvnote_zonequests, ' . $this->subject->getField('mapId') . ', ' . $this->typeId . ', \'' . Util::jsEscape($this->subject->getField('name', true)) . '\', ' . $this->typeId . ')']); } // tab: item-quest starter // select every quest starter, that is a drop $questStartItem = DB::Aowow()->select(' SELECT qse.typeId AS ARRAY_KEY, moreType, moreTypeId, moreZoneId FROM ?_quests_startend qse JOIN ?_source src ON src.type = qse.type AND src.typeId = qse.typeId WHERE src.src2 IS NOT NULL AND qse.type = ?d AND (moreZoneId = ?d OR (moreType = ?d AND moreTypeId IN (?a)) OR (moreType = ?d AND moreTypeId IN (?a)))', TYPE_ITEM, $this->typeId, TYPE_NPC, array_unique(array_column($cSpawns, 'typeId')) ?: [0], TYPE_OBJECT, array_unique(array_column($oSpawns, 'typeId')) ?: [0]); if ($questStartItem) { $qsiList = new ItemList(array(['id', array_keys($questStartItem)])); if (!$qsiList->error) { $this->lvTabs[] = array('file' => 'item', 'data' => $qsiList->getListviewData(), 'params' => ['name' => '$LANG.tab_startsquest', 'id' => 'starts-quest']); $this->extendGlobalData($qsiList->getJSGlobals(GLOBALINFO_SELF)); } } // tab: Quest Rewards [ids collected by SOM-routine] if ($rewardsLV) { $rewards = new ItemList(array(['id', array_unique($rewardsLV)])); if (!$rewards->error) { $this->lvTabs[] = array('file' => 'item', 'data' => $rewards->getListviewData(), 'params' => ['name' => '$LANG.tab_questrewards', 'id' => 'quest-rewards', 'note' => sprintf(Util::$filterResultString, '?items&filter=cr=126;crs=' . $this->typeId . ';crv=0')]); $this->extendGlobalData($rewards->getJSGlobals(GLOBALINFO_SELF)); } } // tab: achievements // tab: fished in zone $fish = new Loot(); if ($fish->getByContainer(LOOT_FISHING, $this->typeId)) { $this->extendGlobalData($fish->jsGlobals); $xCols = array_merge(['Listview.extraCols.percent'], $fish->extraCols); foreach ($fish->iterate() as $lv) { if (!$lv['quest']) { continue; } $xCols = array_merge($xCols, ['Listview.extraCols.condition']); $reqQuest[$lv['id']] = 0; $lv['condition'][0][$this->typeId][] = [[CND_QUESTTAKEN, &$reqQuest[$lv['id']]]]; } $this->lvTabs[] = array('file' => 'item', 'data' => $fish->getResult(), 'params' => ['name' => '$LANG.tab_fishing', 'id' => 'fishing', 'extraCols' => $xCols ? "\$[" . implode(', ', array_unique($xCols)) . "]" : null, 'hiddenCols' => "\$['side']"]); } // tab: spells if ($saData = DB::World()->select('SELECT * FROM spell_area WHERE area = ?d', $this->typeId)) { $spells = new SpellList(array(['id', array_column($saData, 'spell')])); if (!$spells->error) { $lvSpells = $spells->getListviewData(); $this->extendGlobalData($spells->getJSGlobals()); $extra = false; foreach ($saData as $a) { if (empty($lvSpells[$a['spell']])) { continue; } $condition = []; if ($a['aura_spell']) { $this->extendGlobalIds(TYPE_SPELL, abs($a['aura_spell'])); $condition[0][$this->typeId][] = [[$a['aura_spell'] > 0 ? CND_AURA : -CND_AURA, abs($a['aura_spell'])]]; } if ($a['quest_start']) { $this->extendGlobalIds(TYPE_QUEST, $a['quest_start']); $group = []; for ($i = 0; $i < 7; $i++) { if (!($a['quest_start_status'] & 1 << $i)) { continue; } if ($i == 0) { $group[] = [CND_QUEST_NONE, $a['quest_start']]; } else { if ($i == 1) { $group[] = [CND_QUEST_COMPLETE, $a['quest_start']]; } else { if ($i == 3) { $group[] = [CND_QUESTTAKEN, $a['quest_start']]; } else { if ($i == 6) { $group[] = [CND_QUESTREWARDED, $a['quest_start']]; } } } } } if ($group) { $condition[0][$this->typeId][] = $group; } } if ($a['quest_end'] && $a['quest_end'] != $a['quest_start']) { $this->extendGlobalIds(TYPE_QUEST, $a['quest_end']); $group = []; for ($i = 0; $i < 7; $i++) { if (!($a['quest_end_status'] & 1 << $i)) { continue; } if ($i == 0) { $group[] = [-CND_QUEST_NONE, $a['quest_end']]; } else { if ($i == 1) { $group[] = [-CND_QUEST_COMPLETE, $a['quest_end']]; } else { if ($i == 3) { $group[] = [-CND_QUESTTAKEN, $a['quest_end']]; } else { if ($i == 6) { $group[] = [-CND_QUESTREWARDED, $a['quest_end']]; } } } } } if ($group) { $condition[0][$this->typeId][] = $group; } } if ($a['racemask']) { $foo = []; for ($i = 0; $i < 11; $i++) { if ($a['racemask'] & 1 << $i) { $foo[] = $i + 1; } } $this->extendGlobalIds(TYPE_RACE, $foo); $condition[0][$this->typeId][] = [[CND_RACE, $a['racemask']]]; } if ($a['gender'] != 2) { // 2: both $condition[0][$this->typeId][] = [[CND_GENDER, $a['gender'] + 1]]; } if ($condition) { $extra = true; $lvSpells[$a['spell']] = array_merge($lvSpells[$a['spell']], ['condition' => $condition]); } } $this->lvTabs[] = array('file' => 'spell', 'data' => $lvSpells, 'params' => array('extraCols' => $extra ? '$[Listview.extraCols.condition]' : null, 'hiddenCols' => "\$['skill']")); } } // tab: subzones $subZones = new ZoneList(array(['parentArea', $this->typeId])); if (!$subZones->error) { $this->lvTabs[] = array('file' => 'zone', 'data' => $subZones->getListviewData(), 'params' => ['name' => '$LANG.tab_zones', 'id' => 'subzones', 'hiddenCols' => "\$['territory', 'instancetype']"]); $this->extendGlobalData($subZones->getJSGlobals(GLOBALINFO_SELF)); } }
protected function generateTitle() { array_unshift($this->title, Util::ucFirst(Lang::game('achievements'))); if ($this->category) { $catrow = DB::Aowow()->SelectRow('SELECT * FROM ?_achievementcategory WHERE id = ?d', end($this->category)); array_unshift($this->title, Util::localizedString($catrow, 'name')); } }
protected function createSQLForCriterium(&$cr) { if (in_array($cr[0], array_keys($this->genericFilter))) { if ($genCr = $this->genericCriterion($cr)) { return $genCr; } unset($cr); $this->error = true; return [1]; } switch ($cr[0]) { case 1: // health [num] if (!$this->isSaneNumeric($cr[2]) || !$this->int2Op($cr[1])) { break; } // remap OP for this special case switch ($cr[1]) { case '=': // min > max is totally possible $this->extraOpts['ct']['h'][] = 'healthMin = healthMax AND healthMin = ' . $cr[2]; break; case '>': $this->extraOpts['ct']['h'][] = 'IF(healthMin > healthMax, healthMax, healthMin) > ' . $cr[2]; break; case '>=': $this->extraOpts['ct']['h'][] = 'IF(healthMin > healthMax, healthMax, healthMin) >= ' . $cr[2]; break; case '<': $this->extraOpts['ct']['h'][] = 'IF(healthMin > healthMax, healthMin, healthMax) < ' . $cr[2]; break; case '<=': $this->extraOpts['ct']['h'][] = 'IF(healthMin > healthMax, healthMin, healthMax) <= ' . $cr[2]; break; } return [1]; // always true, use post-filter // always true, use post-filter case 2: // mana [num] if (!$this->isSaneNumeric($cr[2]) || !$this->int2Op($cr[1])) { break; } // remap OP for this special case switch ($cr[1]) { case '=': $this->extraOpts['ct']['h'][] = 'manaMin = manaMax AND manaMin = ' . $cr[2]; break; case '>': $this->extraOpts['ct']['h'][] = 'IF(manaMin > manaMax, manaMin, manaMax) > ' . $cr[2]; break; case '>=': $this->extraOpts['ct']['h'][] = 'IF(manaMin > manaMax, manaMin, manaMax) >= ' . $cr[2]; break; case '<': $this->extraOpts['ct']['h'][] = 'IF(manaMin > manaMax, manaMax, manaMin) < ' . $cr[2]; break; case '<=': $this->extraOpts['ct']['h'][] = 'IF(manaMin > manaMax, manaMax, manaMin) <= ' . $cr[2]; break; } return [1]; // always true, use post-filter // always true, use post-filter case 7: // startsquest [enum] switch ($cr[1]) { case 1: // any return ['AND', ['qse.method', 0x1, '&'], ['qse.questId', null, '!']]; case 2: // alliance return ['AND', ['qse.method', 0x1, '&'], ['qse.questId', null, '!'], [['qt.reqRaceMask', RACE_MASK_HORDE, '&'], 0], ['qt.reqRaceMask', RACE_MASK_ALLIANCE, '&']]; case 3: // horde return ['AND', ['qse.method', 0x1, '&'], ['qse.questId', null, '!'], [['qt.reqRaceMask', RACE_MASK_ALLIANCE, '&'], 0], ['qt.reqRaceMask', RACE_MASK_HORDE, '&']]; case 4: // both return ['AND', ['qse.method', 0x1, '&'], ['qse.questId', null, '!'], ['OR', ['AND', ['qt.reqRaceMask', RACE_MASK_ALLIANCE, '&'], ['qt.reqRaceMask', RACE_MASK_HORDE, '&']], ['qt.reqRaceMask', 0]]]; case 5: // none $this->extraOpts['ct']['h'][] = 'startsQuests = 0'; return [1]; } break; case 8: // endsquest [enum] switch ($cr[1]) { case 1: // any return ['AND', ['qse.method', 0x2, '&'], ['qse.questId', null, '!']]; case 2: // alliance return ['AND', ['qse.method', 0x2, '&'], ['qse.questId', null, '!'], [['qt.reqRaceMask', RACE_MASK_HORDE, '&'], 0], ['qt.reqRaceMask', RACE_MASK_ALLIANCE, '&']]; case 3: // horde return ['AND', ['qse.method', 0x2, '&'], ['qse.questId', null, '!'], [['qt.reqRaceMask', RACE_MASK_ALLIANCE, '&'], 0], ['qt.reqRaceMask', RACE_MASK_HORDE, '&']]; case 4: // both return ['AND', ['qse.method', 0x2, '&'], ['qse.questId', null, '!'], ['OR', ['AND', ['qt.reqRaceMask', RACE_MASK_ALLIANCE, '&'], ['qt.reqRaceMask', RACE_MASK_HORDE, '&']], ['qt.reqRaceMask', 0]]]; case 5: // none $this->extraOpts['ct']['h'][] = 'endsQuests = 0'; return [1]; } break; case 3: // faction [enum] if (in_array($cr[1], $this->enums[$cr[0]])) { $facTpls = []; $facs = new FactionList(array('OR', ['parentFactionId', $cr[1]], ['id', $cr[1]])); foreach ($facs->iterate() as $__) { $facTpls = array_merge($facTpls, $facs->getField('templateIds')); } if (!$facTpls) { return [0]; } return ['faction', $facTpls]; } break; case 38: // relatedevent if (!$this->isSaneNumeric($cr[1])) { break; } if ($cr[1] == FILTER_ENUM_ANY) { $eventIds = DB::Aowow()->selectCol('SELECT id FROM ?_events WHERE holidayId <> 0'); $cGuids = DB::World()->selectCol('SELECT DISTINCT guid FROM game_event_creature WHERE eventEntry IN (?a)', $eventIds); return ['s.guid', $cGuids]; } else { if ($cr[1] == FILTER_ENUM_NONE) { $eventIds = DB::Aowow()->selectCol('SELECT id FROM ?_events WHERE holidayId <> 0'); $cGuids = DB::World()->selectCol('SELECT DISTINCT guid FROM game_event_creature WHERE eventEntry IN (?a)', $eventIds); return ['s.guid', $cGuids, '!']; } else { if ($cr[1]) { $eventIds = DB::Aowow()->selectCol('SELECT id FROM ?_events WHERE holidayId = ?d', $cr[1]); $cGuids = DB::World()->selectCol('SELECT DISTINCT guid FROM game_event_creature WHERE eventEntry IN (?a)', $eventIds); return ['s.guid', $cGuids]; } } } break; case 42: // increasesrepwith [enum] if (in_array($cr[1], $this->enums[3])) { if ($_ = DB::Aowow()->selectRow('SELECT * FROM ?_factions WHERE id = ?d', $cr[1])) { $this->formData['reputationCols'][] = [$cr[1], Util::localizedString($_, 'name')]; } if ($cIds = DB::World()->selectCol('SELECT creature_id FROM creature_onkill_reputation WHERE (RewOnKillRepFaction1 = ?d AND RewOnKillRepValue1 > 0) OR (RewOnKillRepFaction2 = ?d AND RewOnKillRepValue2 > 0)', $cr[1], $cr[1])) { return ['id', $cIds]; } else { return [0]; } } break; case 43: // decreasesrepwith [enum] if (in_array($cr[1], $this->enums[3])) { if ($_ = DB::Aowow()->selectRow('SELECT * FROM ?_factions WHERE id = ?d', $cr[1])) { $this->formData['reputationCols'][] = [$cr[1], Util::localizedString($_, 'name')]; } if ($cIds = DB::World()->selectCol('SELECT creature_id FROM creature_onkill_reputation WHERE (RewOnKillRepFaction1 = ?d AND RewOnKillRepValue1 < 0) OR (RewOnKillRepFaction2 = ?d AND RewOnKillRepValue2 < 0)', $cr[1], $cr[1])) { return ['id', $cIds]; } else { return [0]; } } break; case 12: // averagemoneydropped [op] [int] if (!$this->isSaneNumeric($cr[2]) || !$this->int2Op($cr[1])) { break; } return ['AND', ['((minGold + maxGold) / 2)', $cr[2], $cr[1]]]; case 15: // gatherable [yn] if ($this->int2Bool($cr[1])) { if ($cr[1]) { return ['AND', ['skinLootId', 0, '>'], ['typeFlags', NPC_TYPEFLAG_HERBLOOT, '&']]; } else { return ['OR', ['skinLootId', 0], [['typeFlags', NPC_TYPEFLAG_HERBLOOT, '&'], 0]]; } } break; case 44: // salvageable [yn] if ($this->int2Bool($cr[1])) { if ($cr[1]) { return ['AND', ['skinLootId', 0, '>'], ['typeFlags', NPC_TYPEFLAG_ENGINEERLOOT, '&']]; } else { return ['OR', ['skinLootId', 0], [['typeFlags', NPC_TYPEFLAG_ENGINEERLOOT, '&'], 0]]; } } break; case 16: // minable [yn] if ($this->int2Bool($cr[1])) { if ($cr[1]) { return ['AND', ['skinLootId', 0, '>'], ['typeFlags', NPC_TYPEFLAG_MININGLOOT, '&']]; } else { return ['OR', ['skinLootId', 0], [['typeFlags', NPC_TYPEFLAG_MININGLOOT, '&'], 0]]; } } break; case 10: // skinnable [yn] if ($this->int2Bool($cr[1])) { if ($cr[1]) { return ['AND', ['skinLootId', 0, '>'], [['typeFlags', NPC_TYPEFLAG_SPECIALLOOT, '&'], 0]]; } else { return ['OR', ['skinLootId', 0], [['typeFlags', NPC_TYPEFLAG_SPECIALLOOT, '&'], 0, '!']]; } } break; case 34: // usemodel [str] // displayId -> id:creatureDisplayInfo.dbc/model -> id:cratureModelData.dbc/modelPath // usemodel [str] // displayId -> id:creatureDisplayInfo.dbc/model -> id:cratureModelData.dbc/modelPath case 41: // haslocation [yn] [staff] /* todo */ return [1]; } unset($cr); $this->error = true; return [1]; }
public static function getName($id) { $n = DB::Aowow()->SelectRow('SELECT name_loc0, name_loc2, name_loc3, name_loc6, name_loc8 FROM ?_itemenchantment WHERE id = ?d', $id); return Util::localizedString($n, 'name'); }
public function renderTooltip() { $criteria = $this->getCriteria(); $tmp = []; $rows = []; $i = 0; foreach ($criteria as $_row) { if ($i++ % 2) { $tmp[] = $_row; } else { $rows[] = $_row; } } if ($tmp) { $rows = array_merge($rows, $tmp); } $description = $this->getField('description', true); $name = $this->getField('name', true); $criteria = ''; $i = 0; foreach ($rows as $crt) { $obj = (int) $crt['value1']; $qty = (int) $crt['value2']; // we could show them, but the tooltips are cluttered if ($crt['completionFlags'] & ACHIEVEMENT_CRITERIA_FLAG_HIDDEN && User::$perms <= 0) { continue; } $crtName = Util::localizedString($crt, 'name'); switch ($crt['type']) { // link to title - todo (low): crosslink case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE: $crtName = Util::ucFirst(Lang::game('title')) . Lang::main('colon') . $crtName; break; // link to quest // link to quest case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: if (!$crtName) { $crtName = QuestList::getName($obj); } break; // link to spell (/w icon) // link to spell (/w icon) case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET: case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2: case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL: case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL: case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: if (!$crtName) { $crtName = SpellList::getName($obj); } break; // link to item (/w icon) // link to item (/w icon) case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM: case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM: case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM: if (!$crtName) { $crtName = ItemList::getName($obj); } break; // link to faction (/w target reputation) // link to faction (/w target reputation) case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION: if (!$crtName) { $crtName = FactionList::getName($obj); } break; } if ($crt['completionFlags'] & ACHIEVEMENT_CRITERIA_FLAG_MONEY_COUNTER) { $criteria .= '- ' . Util::jsEscape($crtName) . ' <span class="moneygold">' . number_format($crt['value2'] / 10000) . '</span><br />'; } else { $criteria .= '- ' . Util::jsEscape($crtName) . '<br />'; } if (++$i == round(count($rows) / 2)) { $criteria .= '</small></td><th class="q0" style="white-space: nowrap; text-align: left"><small>'; } } $x = '<table><tr><td><b class="q">'; $x .= Util::jsEscape($name); $x .= '</b></td></tr></table>'; if ($description || $criteria) { $x .= '<table><tr><td>'; } if ($description) { $x .= '<br />' . Util::jsEscape($description) . '<br />'; } if ($criteria) { $x .= '<br /><span class="q">' . Lang::achievement('criteria') . ':</span>'; $x .= '<table width="100%"><tr><td class="q0" style="white-space: nowrap"><small>' . $criteria . '</small></th></tr></table>'; } if ($description || $criteria) { $x .= '</td></tr></table>'; } return $x; }
protected function createSQLForCriterium(&$cr) { if (in_array($cr[0], array_keys($this->genericFilter))) { if ($genCr = $this->genericCriterion($cr)) { return $genCr; } unset($cr); $this->error = true; return [1]; } switch ($cr[0]) { case 1: // increasesrepwith if ($this->isSaneNumeric($cr[1]) && $cr[1] > 0) { if ($_ = DB::Aowow()->selectRow('SELECT * FROM ?_factions WHERE id = ?d', $cr[1])) { $this->formData['reputationCols'][] = [$cr[1], Util::localizedString($_, 'name')]; } return ['OR', ['AND', ['rewardFactionId1', $cr[1]], ['rewardFactionValue1', 0, '>']], ['AND', ['rewardFactionId2', $cr[1]], ['rewardFactionValue2', 0, '>']], ['AND', ['rewardFactionId3', $cr[1]], ['rewardFactionValue3', 0, '>']], ['AND', ['rewardFactionId4', $cr[1]], ['rewardFactionValue4', 0, '>']], ['AND', ['rewardFactionId5', $cr[1]], ['rewardFactionValue5', 0, '>']]]; } break; case 10: // decreasesrepwith if ($this->isSaneNumeric($cr[1]) && $cr[1] > 0) { if ($_ = DB::Aowow()->selectRow('SELECT * FROM ?_factions WHERE id = ?d', $cr[1])) { $this->formData['reputationCols'][] = [$cr[1], Util::localizedString($_, 'name')]; } return ['OR', ['AND', ['rewardFactionId1', $cr[1]], ['rewardFactionValue1', 0, '<']], ['AND', ['rewardFactionId2', $cr[1]], ['rewardFactionValue2', 0, '<']], ['AND', ['rewardFactionId3', $cr[1]], ['rewardFactionValue3', 0, '<']], ['AND', ['rewardFactionId4', $cr[1]], ['rewardFactionValue4', 0, '<']], ['AND', ['rewardFactionId5', $cr[1]], ['rewardFactionValue5', 0, '<']]]; } break; case 43: // currencyrewarded if ($this->isSaneNumeric($cr[1]) && $cr[1] > 0) { return ['OR', ['rewardItemId1', $cr[1]], ['rewardItemId2', $cr[1]], ['rewardItemId3', $cr[1]], ['rewardItemId4', $cr[1]], ['rewardChoiceItemId1', $cr[1]], ['rewardChoiceItemId2', $cr[1]], ['rewardChoiceItemId3', $cr[1]], ['rewardChoiceItemId4', $cr[1]], ['rewardChoiceItemId5', $cr[1]], ['rewardChoiceItemId6', $cr[1]]]; } break; case 34: // availabletoplayers if ($this->int2Bool($cr[1])) { if ($cr[1]) { return ['AND', [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0], [['flags', QUEST_FLAG_UNAVAILABLE, '&'], 0]]; } else { return ['OR', ['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], ['flags', QUEST_FLAG_UNAVAILABLE, '&']]; } } break; case 23: // itemchoices [op] [int] if (!$this->isSaneNumeric($cr[2], false) || !$this->int2Op($cr[1])) { break; } $this->extraOpts['q']['s'][] = ', (IF(rewardChoiceItemId1, 1, 0) + IF(rewardChoiceItemId2, 1, 0) + IF(rewardChoiceItemId3, 1, 0) + IF(rewardChoiceItemId4, 1, 0) + IF(rewardChoiceItemId5, 1, 0) + IF(rewardChoiceItemId6, 1, 0)) as numChoices'; $this->extraOpts['q']['h'][] = 'numChoices ' . $cr[1] . ' ' . $cr[2]; return [1]; case 22: // itemrewards [op] [int] if (!$this->isSaneNumeric($cr[2], false) || !$this->int2Op($cr[1])) { break; } $this->extraOpts['q']['s'][] = ', (IF(rewardItemId1, 1, 0) + IF(rewardItemId2, 1, 0) + IF(rewardItemId3, 1, 0) + IF(rewardItemId4, 1, 0)) as numRewards'; $this->extraOpts['q']['h'][] = 'numRewards ' . $cr[1] . ' ' . $cr[2]; return [1]; case 44: // countsforloremaster_stc [bool] if ($this->int2Bool($cr[1])) { if ($cr[1]) { return ['AND', ['zoneOrSort', 0, '>'], [['flags', QUEST_FLAG_DAILY | QUEST_FLAG_WEEKLY | QUEST_FLAG_REPEATABLE, '&'], 0], [['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE | QUEST_FLAG_SPECIAL_MONTHLY, '&'], 0]]; } else { return ['OR', ['zoneOrSort', 0, '<'], ['flags', QUEST_FLAG_DAILY | QUEST_FLAG_WEEKLY | QUEST_FLAG_REPEATABLE, '&'], ['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE | QUEST_FLAG_SPECIAL_MONTHLY, '&']]; } } break; case 4: // spellrewarded [bool] if ($this->int2Bool($cr[1])) { if ($cr[1]) { return ['OR', ['sourceSpellId', 0, '>'], ['rewardSpell', 0, '>'], ['rsc.effect1Id', SpellList::$effects['teach']], ['rsc.effect2Id', SpellList::$effects['teach']], ['rsc.effect3Id', SpellList::$effects['teach']]]; } else { return ['AND', ['sourceSpellId', 0], ['rewardSpell', 0], ['rewardSpellCast', 0]]; } } break; case 9: // objectiveearnrepwith [enum] $_ = intVal($cr[1]); if ($_ > 0) { return ['OR', ['reqFactionId1', $_], ['reqFactionId2', $_]]; } else { if ($cr[1] == FILTER_ENUM_ANY) { // any return ['OR', ['reqFactionId1', 0, '>'], ['reqFactionId2', 0, '>']]; } else { if ($cr[1] == FILTER_ENUM_NONE) { // none return ['AND', ['reqFactionId1', 0], ['reqFactionId2', 0]]; } } } break; case 37: // classspecific [enum] $_ = isset($this->enums[$cr[0]][$cr[1]]) ? $this->enums[$cr[0]][$cr[1]] : null; if ($_ !== null) { if ($_ === true) { return ['AND', ['reqClassMask', 0, '!'], [['reqClassMask', CLASS_MASK_ALL, '&'], CLASS_MASK_ALL, '!']]; } else { if ($_ === false) { return ['OR', ['reqClassMask', 0], [['reqClassMask', CLASS_MASK_ALL, '&'], CLASS_MASK_ALL]]; } else { if (is_int($_)) { return ['AND', ['reqClassMask', 1 << $_ - 1, '&'], [['reqClassMask', CLASS_MASK_ALL, '&'], CLASS_MASK_ALL, '!']]; } } } } break; case 38: // racespecific [enum] $_ = isset($this->enums[$cr[0]][$cr[1]]) ? $this->enums[$cr[0]][$cr[1]] : null; if ($_ !== null) { if ($_ === true) { return ['AND', ['reqRaceMask', 0, '!'], [['reqRaceMask', RACE_MASK_ALL, '&'], RACE_MASK_ALL, '!'], [['reqRaceMask', RACE_MASK_ALLIANCE, '&'], RACE_MASK_ALLIANCE, '!'], [['reqRaceMask', RACE_MASK_HORDE, '&'], RACE_MASK_HORDE, '!']]; } else { if ($_ === false) { return ['OR', ['reqRaceMask', 0], ['reqRaceMask', RACE_MASK_ALL], ['reqRaceMask', RACE_MASK_ALLIANCE], ['reqRaceMask', RACE_MASK_HORDE]]; } else { if (is_int($_)) { return ['AND', ['reqRaceMask', 1 << $_ - 1, '&'], [['reqRaceMask', RACE_MASK_ALLIANCE, '&'], RACE_MASK_ALLIANCE, '!'], [['reqRaceMask', RACE_MASK_HORDE, '&'], RACE_MASK_HORDE, '!']]; } } } } break; case 19: // startsfrom [enum] switch ($cr[1]) { case 1: // npc return ['AND', ['qse.type', TYPE_NPC], ['qse.method', 0x1, '&']]; case 2: // object return ['AND', ['qse.type', TYPE_OBJECT], ['qse.method', 0x1, '&']]; case 3: // item return ['AND', ['qse.type', TYPE_ITEM], ['qse.method', 0x1, '&']]; } break; case 21: // endsat [enum] switch ($cr[1]) { case 1: // npc return ['AND', ['qse.type', TYPE_NPC], ['qse.method', 0x2, '&']]; case 2: // object return ['AND', ['qse.type', TYPE_OBJECT], ['qse.method', 0x2, '&']]; } break; case 24: // lacksstartend [bool] $missing = DB::Aowow()->selectCol('SELECT questId, max(method) a, min(method) b FROM ?_quests_startend GROUP BY questId HAVING (a | b) <> 3'); if ($this->int2Bool($cr[1])) { if ($cr[1]) { return ['id', $missing]; } else { return ['id', $missing, '!']; } } break; case 7: // firstquestseries // firstquestseries case 15: // lastquestseries // lastquestseries case 16: // partseries /* todo */ return [1]; // self-joining eats substential amounts of time: should restructure that and also incorporate reqQ and openQ cases from infobox // self-joining eats substential amounts of time: should restructure that and also incorporate reqQ and openQ cases from infobox default: break; } unset($cr); $this->error = 1; return [1]; }
function itemset() { $locales = [LOCALE_EN, LOCALE_FR, LOCALE_DE, LOCALE_ES, LOCALE_RU]; $setToHoliday = array(761 => 141, 762 => 372, 785 => 341, 812 => 181); // find events associated with holidayIds if ($pairs = DB::World()->selectCol('SELECT holiday AS ARRAY_KEY, eventEntry FROM game_event WHERE holiday IN (?a)', array_values($setToHoliday))) { foreach ($setToHoliday as &$hId) { $hId = !empty($pairs[$hId]) ? $pairs[$hId] : 0; } } // tags where refId == virtualId // in pve sets are not recycled beyond the contentGroup $tagsById = array(1 => [181, 182, 183, 184, 185, 186, 187, 188, 189], 2 => [511, 512, 513, 514, 515, 516, 517, 518, 519], 3 => [201, 202, 203, 204, 205, 206, 207, 208, 209], 4 => [210, 211, 212, 213, 214, 215, 216, 217, 218], 5 => [521, 523, 524, 525, 526, 527, 528, 529, 530], 6 => [522, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 697, 718], 7 => [281, 282, 301, 341, 342, 343, 344, 345, 346, 347, 348, 361, 362, 381, 382, 401], 8 => [383, 384, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 402, 717, 698], 9 => [494, 495, 498, 500, 502, 504, 506, 508, 510], 10 => [493, 496, 497, 499, 501, 503, 505, 507, 509], 11 => [477, 480, 474, 475, 476, 478, 479, 481, 482], 12 => [621, 624, 625, 626, 631, 632, 633, 638, 639, 640, 645, 648, 651, 654, 655, 663, 664], 13 => [622, 627, 628, 629, 634, 635, 636, 641, 642, 643, 646, 649, 652, 656, 657, 665, 666], 14 => [620, 623, 630, 637, 644, 647, 650, 653, 658, 659, 660, 661, 662], 15 => [467, 468, 469, 470, 471, 472, 473, 483, 484, 485, 486, 487, 488, 908], 16 => [587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 688, 689, 691, 692, 693, 694, 695, 696], 18 => [668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684], 21 => [738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752], 23 => [795, 805, 804, 803, 802, 801, 800, 799, 798, 797, 796, 794, 793, 792, 791, 790, 789, 788, 787], 25 => [838, 837, 836, 835, 834, 833, 832, 831, 830, 829, 828, 827, 826, 825, 824, 823, 822, 821, 820], 27 => [880, 879, 878, 877, 876, 875, 874, 873, 872, 871, 870, 869, 868, 867, 866, 865, 864, 863, 862, 861, 860, 859, 858, 857, 856, 855, 854, 853, 852, 851, 850, 849, 848, 847, 846, 845, 844, 843], 29 => [901, 900, 899, 898, 897, 896, 895, 894, 893, 892, 891, 890, 889, 888, 887, 886, 885, 884, 883]); // well .. f**k $tagsByNamePart = array(17 => ['gladiator'], 19 => ['merciless'], 20 => ['vengeful'], 22 => ['brutal'], 24 => ['deadly', 'hateful', 'savage'], 26 => ['furious'], 28 => ['relentless'], 30 => ['wrathful']); DB::Aowow()->query('TRUNCATE TABLE ?_itemset'); $vIdx = 0; $virtualId = 0; $sets = DB::Aowow()->select('SELECT *, id AS ARRAY_KEY FROM dbc_itemset'); foreach ($sets as $setId => $setData) { $spells = $items = $mods = $descText = $name = $gains = []; $max = $reqLvl = $min = $quality = $heroic = $nPieces = []; $classMask = $type = 0; $hasRing = false; $holiday = isset($setToHoliday[$setId]) ? $setToHoliday[$setId] : 0; $canReuse = !$holiday; // can't reuse holiday-sets $slotList = []; $pieces = DB::World()->select('SELECT *, IF(InventoryType = 15, 26, IF(InventoryType = 5, 20, InventoryType)) AS slot, entry AS ARRAY_KEY FROM item_template WHERE itemset = ?d AND (class <> 4 OR subclass NOT IN (1, 2, 3, 4) OR armor > 0 OR Quality = 1) ORDER BY itemLevel, subclass, slot ASC', $setId); /****************************************/ /* determine type and reuse from pieces */ /****************************************/ // make the first vId always same as setId $firstPiece = reset($pieces); $tmp = [$firstPiece['Quality'] . $firstPiece['ItemLevel'] => $setId]; // walk through all items associated with the set foreach ($pieces as $itemId => $piece) { $classMask |= $piece['AllowableClass'] & CLASS_MASK_ALL; $key = $piece['Quality'] . str_pad($piece['ItemLevel'], 3, 0, STR_PAD_LEFT); if (!isset($tmp[$key])) { $tmp[$key] = --$vIdx; } $vId = $tmp[$key]; // check only actual armor in rare quality or higher (or inherits holiday) if ($piece['class'] != ITEM_CLASS_ARMOR || $piece['subclass'] == 0) { $canReuse = false; } /* gather relevant stats for use */ if (!isset($quality[$vId]) || $piece['Quality'] > $quality[$vId]) { $quality[$vId] = $piece['Quality']; } if ($piece['Flags'] & ITEM_FLAG_HEROIC) { $heroic[$vId] = true; } if (!isset($reqLvl[$vId]) || $piece['RequiredLevel'] > $reqLvl[$vId]) { $reqLvl[$vId] = $piece['RequiredLevel']; } if (!isset($min[$vId]) || $piece['ItemLevel'] < $min[$vId]) { $min[$vId] = $piece['ItemLevel']; } if (!isset($max[$vId]) || $piece['ItemLevel'] > $max[$vId]) { $max[$vId] = $piece['ItemLevel']; } if (!isset($items[$vId][$piece['slot']]) || !$canReuse) { if (!isset($nPieces[$vId])) { $nPieces[$vId] = 1; } else { $nPieces[$vId]++; } } if (isset($items[$vId][$piece['slot']])) { // not reusable -> insert anyway on unique keys if (!$canReuse) { $items[$vId][$piece['slot'] . $itemId] = $itemId; } else { CLISetup::log("set: " . $setId . " ilvl: " . $piece['ItemLevel'] . " - conflict between item: " . $items[$vId][$piece['slot']] . " and item: " . $itemId . " choosing lower itemId", CLISetup::LOG_WARN); if ($items[$vId][$piece['slot']] > $itemId) { $items[$vId][$piece['slot']] = $itemId; } } } else { $items[$vId][$piece['slot']] = $itemId; } /* check for type */ // skip cloaks, they mess with armor classes if ($piece['slot'] == 16) { continue; } // skip event-sets if ($piece['Quality'] == 1) { continue; } if ($piece['class'] == 2 && $piece['subclass'] == 0) { $type = 8; } else { if ($piece['class'] == 2 && $piece['subclass'] == 4) { $type = 9; } else { if ($piece['class'] == 2 && $piece['subclass'] == 7) { $type = 10; } else { if ($piece['class'] == 2 && $piece['subclass'] == 13) { $type = 7; } else { if ($piece['class'] == 2 && $piece['subclass'] == 15) { $type = 5; } } } } } // Dagger if (!$type) { if ($piece['class'] == 4 && $piece['slot'] == 12) { $type = 11; } else { if ($piece['class'] == 4 && $piece['slot'] == 2) { $type = 12; } else { if ($piece['class'] == 4 && $piece['subclass'] != 0) { $type = $piece['subclass']; } } } // 'armor' set if ($piece['class'] == 4 && $piece['slot'] == 11) { $hasRing = true; } // contains ring } } if ($hasRing && !$type) { $type = 6; } // pure ring-set $isMultiSet = false; $oldSlotMask = 0x0; foreach ($items as $subset) { $curSlotMask = 0x0; foreach ($subset as $slot => $item) { $curSlotMask |= 1 << $slot; } if ($oldSlotMask && $oldSlotMask == $curSlotMask) { $isMultiSet = true; break; } $oldSlotMask = $curSlotMask; } if (!$isMultiSet || !$canReuse || $setId == 555) { $temp = []; foreach ($items as $subset) { foreach ($subset as $slot => $item) { if (isset($temp[$slot]) && $temp[$slot] < $item) { CLISetup::log("set: " . $setId . " - conflict between item: " . $item . " and item: " . $temp[$slot] . " choosing lower itemId", CLISetup::LOG_WARN); } else { if ($slot == 13 || ($slot = 11)) { // special case $temp[] = $item; } else { $temp[$slot] = $item; } } } } $items = [$temp]; $heroic = [reset($heroic)]; $nPieces = [count($temp)]; $quality = [reset($quality)]; $reqLvl = [reset($reqLvl)]; $max = $max ? [max($max)] : [0]; $min = $min ? [min($min)] : [0]; } foreach ($items as &$subsets) { $subsets = array_pad($subsets, 10, 0); } /********************/ /* calc statbonuses */ /********************/ for ($i = 1; $i < 9; $i++) { if ($setData['spellId' . $i] > 0 && $setData['itemCount' . $i] > 0) { $spells[] = [$setData['spellId' . $i], $setData['itemCount' . $i]]; } } $bonusSpells = new SpellList(array(['s.id', array_column($spells, 0)])); $mods = $bonusSpells->getStatGain(); $spells = array_pad($spells, 8, [0, 0]); for ($i = 1; $i < 9; $i++) { if ($setData['itemCount' . $i] > 0 && !empty($mods[$setData['spellId' . $i]])) { $gains[$setData['itemCount' . $i]] = $mods[$setData['spellId' . $i]]; } } /**************************/ /* get name & description */ /**************************/ foreach ($locales as $loc) { User::useLocale($loc); $name[$loc] = Util::localizedString($setData, 'name'); foreach ($bonusSpells->iterate() as $__) { if (!isset($descText[$loc])) { $descText[$loc] = ''; } $descText[$loc] .= $bonusSpells->parseText()[0] . "\n"; } // strip rating blocks - e.g. <!--rtg19-->14 <small>(<!--rtg%19-->0.30% @ L<!--lvl-->80)</small> $descText[$loc] = preg_replace('/<!--rtg\\d+-->(\\d+) .*?<\\/small>/i', '\\1', $descText[$loc]); } /****************************/ /* finalaize data and write */ /****************************/ foreach ($items as $vId => $vSet) { $note = 0; foreach ($tagsById as $tag => $sets) { if (!in_array($setId, $sets)) { continue; } $note = $tag; } if (!$note && $min > 120 && $classMask && $classMask != CLASS_MASK_ALL) { foreach ($tagsByNamePart as $tag => $strings) { foreach ($strings as $str) { if (isset($pieces[reset($vSet)]) && stripos($pieces[reset($vSet)]['name'], $str) === 0) { $note = $tag; break 2; } } } } $row = []; $row[] = $vId < 0 ? --$virtualId : $setId; $row[] = $setId; // refSetId $row[] = 0; // cuFlags $row = array_merge($row, $name, $vSet); foreach (array_column($spells, 0) as $spellId) { $row[] = $spellId; } foreach (array_column($spells, 1) as $nItems) { $row[] = $nItems; } $row = array_merge($row, $descText); $row[] = serialize($gains); $row[] = $nPieces[$vId]; $row[] = $min[$vId]; $row[] = $max[$vId]; $row[] = $reqLvl[$vId]; $row[] = $classMask == CLASS_MASK_ALL ? 0 : $classMask; $row[] = !empty($heroic[$vId]) ? 1 : 0; $row[] = $quality[$vId]; $row[] = $type; $row[] = $note; // contentGroup $row[] = $holiday; $row[] = $setData['reqSkillId']; $row[] = $setData['reqSkillLevel']; DB::Aowow()->query('REPLACE INTO ?_itemset VALUES (?a)', array_values($row)); } } // hide empty sets DB::Aowow()->query('UPDATE ?_itemset SET cuFlags = cuFlags | ?d WHERE item1 = 0', CUSTOM_EXCLUDE_FOR_LISTVIEW); return true; }
protected function generateXML($asError = false) { $root = new SimpleXML('<aowow />'); if ($asError) { $root->addChild('error', 'Item not found!'); } else { // item root $xml = $root->addChild('item'); $xml->addAttribute('id', $this->subject->id); // name $xml->addChild('name')->addCData($this->subject->getField('name', true)); // itemlevel $xml->addChild('level', $this->subject->getField('itemLevel')); // quality $xml->addChild('quality', Lang::item('quality', $this->subject->getField('quality')))->addAttribute('id', $this->subject->getField('quality')); // class $x = Lang::item('cat', $this->subject->getField('class')); $xml->addChild('class')->addCData(is_array($x) ? $x[0] : $x)->addAttribute('id', $this->subject->getField('class')); // subclass $x = $this->subject->getField('class') == 2 ? Lang::spell('weaponSubClass') : Lang::item('cat', $this->subject->getField('class'), 1); $xml->addChild('subclass')->addCData(is_array($x) ? is_array($x[$this->subject->getField('subClass')]) ? $x[$this->subject->getField('subClass')][0] : $x[$this->subject->getField('subClass')] : null)->addAttribute('id', $this->subject->getField('subClass')); // icon + displayId $xml->addChild('icon', $this->subject->getField('iconString'))->addAttribute('displayId', $this->subject->getField('displayId')); // inventorySlot $xml->addChild('inventorySlot', Lang::item('inventoryType', $this->subject->getField('slot')))->addAttribute('id', $this->subject->getField('slot')); // tooltip $xml->addChild('htmlTooltip')->addCData($this->subject->renderTooltip()); $this->subject->extendJsonStats(); // json $fields = ["classs", "displayid", "dps", "id", "level", "name", "reqlevel", "slot", "slotbak", "source", "sourcemore", "speed", "subclass"]; $json = ''; foreach ($fields as $f) { if (isset($this->subject->json[$this->subject->id][$f])) { $_ = $this->subject->json[$this->subject->id][$f]; if ($f == 'name') { $_ = 7 - $this->subject->getField('quality') . $_; } $json .= ',"' . $f . '":' . $_; } } $xml->addChild('json')->addCData(substr($json, 1)); // jsonEquip missing: avgbuyout, cooldown, source, sourcemore $json = ''; if ($_ = $this->subject->getField('sellPrice')) { // sellprice $json .= ',"sellprice":' . $_; } if ($_ = $this->subject->getField('requiredLevel')) { // reqlevel $json .= ',"reqlevel":' . $_; } if ($_ = $this->subject->getField('requiredSkill')) { // reqskill $json .= ',"reqskill":' . $_; } if ($_ = $this->subject->getField('requiredSkillRank')) { // reqskillrank $json .= ',"reqskillrank":' . $_; } foreach ($this->subject->itemMods[$this->subject->id] as $mod => $qty) { $json .= ',"' . $mod . '":' . $qty; } foreach ($_ = $this->subject->json[$this->subject->id] as $name => $qty) { if (in_array($name, Util::$itemFilter)) { $json .= ',"' . $name . '":' . $qty; } } $xml->addChild('jsonEquip')->addCData(substr($json, 1)); // jsonUse if ($onUse = $this->subject->getOnUseStats()) { $j = ''; foreach ($onUse as $idx => $qty) { $j .= ',"' . Util::$itemMods[$idx] . '":' . $qty; } $xml->addChild('jsonUse')->addCData(substr($j, 1)); } // reagents $cnd = array('OR', ['AND', ['effect1CreateItemId', $this->subject->id], ['OR', ['effect1Id', SpellList::$effects['itemCreate']], ['effect1AuraId', SpellList::$auras['itemCreate']]]], ['AND', ['effect2CreateItemId', $this->subject->id], ['OR', ['effect2Id', SpellList::$effects['itemCreate']], ['effect2AuraId', SpellList::$auras['itemCreate']]]], ['AND', ['effect3CreateItemId', $this->subject->id], ['OR', ['effect3Id', SpellList::$effects['itemCreate']], ['effect3AuraId', SpellList::$auras['itemCreate']]]]); $spellSource = new SpellList($cnd); if (!$spellSource->error) { $cbNode = $xml->addChild('createdBy'); foreach ($spellSource->iterate() as $sId => $__) { foreach ($spellSource->canCreateItem() as $idx) { if ($spellSource->getField('effect' . $idx . 'CreateItemId') != $this->subject->id) { continue; } $splNode = $cbNode->addChild('spell'); $splNode->addAttribute('id', $sId); $splNode->addAttribute('name', $spellSource->getField('name', true)); $splNode->addAttribute('icon', $this->subject->getField('iconString')); $splNode->addAttribute('minCount', $spellSource->getField('effect' . $idx . 'BasePoints') + 1); $splNode->addAttribute('maxCount', $spellSource->getField('effect' . $idx . 'BasePoints') + $spellSource->getField('effect' . $idx . 'DieSides')); foreach ($spellSource->getReagentsForCurrent() as $rId => $qty) { if ($reagent = $spellSource->relItems->getEntry($rId)) { $rgtNode = $splNode->addChild('reagent'); $rgtNode->addAttribute('id', $rId); $rgtNode->addAttribute('name', Util::localizedString($reagent, 'name')); $rgtNode->addAttribute('quality', $reagent['quality']); $rgtNode->addAttribute('icon', $reagent['iconString']); $rgtNode->addAttribute('count', $qty[1]); } } break; } } } // link $xml->addChild('link', HOST_URL . '?item=' . $this->subject->id); } return $root->asXML(); }
protected function generateContent() { /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // reqLevel if ($_ = $this->subject->getField('requiredLevel')) { $infobox[] = sprintf(Lang::game('reqLevel'), $_); } // reqskill if ($_ = $this->subject->getField('skillLine')) { $this->extendGlobalIds(TYPE_SKILL, $_); $foo = sprintf(Lang::game('requires'), ' [skill=' . $_ . ']'); if ($_ = $this->subject->getField('skillLevel')) { $foo .= ' (' . $_ . ')'; } $infobox[] = $foo; } /****************/ /* Main Content */ /****************/ $this->infobox = $infobox ? '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]' : null; $this->effects = []; // 3 effects for ($i = 1; $i < 4; $i++) { $_ty = $this->subject->getField('type' . $i); $_qty = $this->subject->getField('amount' . $i); $_obj = $this->subject->getField('object' . $i); switch ($_ty) { case 1: case 3: case 7: $sArr = $this->subject->getField('spells')[$i]; $spl = $this->subject->getRelSpell($sArr[0]); $this->effects[$i]['name'] = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'Type: ' . $_ty, Lang::item('trigger', $sArr[1])) : Lang::item('trigger', $sArr[1]); $this->effects[$i]['proc'] = $sArr[3]; $this->effects[$i]['value'] = $_qty ?: null; $this->effects[$i]['icon'] = array('name' => !$spl ? Util::ucFirst(Lang::game('spell')) . ' #' . $sArr[0] : Util::localizedString($spl, 'name'), 'id' => $sArr[0], 'count' => $sArr[2]); break; case 5: if ($_obj < 2) { // [mana, health] are on [0, 1] respectively and are expected on [1, 2] .. $_obj++; } // 0 is weaponDmg .. ehh .. i messed up somewhere $this->effects[$i]['tip'] = [$_obj, Util::$itemMods[$_obj]]; // DO NOT BREAK! // DO NOT BREAK! case 2: case 6: case 8: case 4: $this->effects[$i]['name'] = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'Type: ' . $_ty, Lang::enchantment('types', $_ty)) : Lang::enchantment('types', $_ty); $this->effects[$i]['value'] = $_qty; if ($_ty == 4) { $this->effects[$i]['name'] .= Lang::main('colon') . '(' . (User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'Object: ' . $_obj, Lang::getMagicSchools(1 << $_obj)) : Lang::getMagicSchools(1 << $_obj)) . ')'; } } } // activation conditions if ($_ = $this->subject->getField('conditionId')) { $x = ''; if ($gemCnd = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantmentcondition WHERE id = ?d', $_)) { for ($i = 1; $i < 6; $i++) { if (!$gemCnd['color' . $i]) { continue; } $fiColors = function ($idx) { $foo = ''; switch ($idx) { case 2: $foo = '0:3:5'; break; // red // red case 3: $foo = '2:4:5'; break; // yellow // yellow case 4: $foo = '1:3:4'; break; // blue } return $foo; }; $bLink = $gemCnd['color' . $i] ? '<a href="?items=3&filter=ty=' . $fiColors($gemCnd['color' . $i]) . '">' . Lang::item('gemColors', $gemCnd['color' . $i] - 1) . '</a>' : ''; $cLink = $gemCnd['cmpColor' . $i] ? '<a href="?items=3&filter=ty=' . $fiColors($gemCnd['cmpColor' . $i]) . '">' . Lang::item('gemColors', $gemCnd['cmpColor' . $i] - 1) . '</a>' : ''; switch ($gemCnd['comparator' . $i]) { case 2: // requires less <color> than (<value> || <comparecolor>) gems // requires less <color> than (<value> || <comparecolor>) gems case 5: // requires at least <color> than (<value> || <comparecolor>) gems $sp = (int) $gemCnd['value' . $i] > 1; $x .= '<span class="q0">' . Lang::achievement('reqNumCrt') . ' ' . sprintf(Lang::item('gemConditions', $gemCnd['comparator' . $i], $sp), $gemCnd['value' . $i], $bLink) . '</span><br />'; break; case 3: // requires more <color> than (<value> || <comparecolor>) gems $link = '<a href="?items=3&filter=ty=' . $fiColors($gemCnd['cmpColor' . $i]) . '">' . Lang::item('gemColors', $gemCnd['cmpColor' . $i] - 1) . '</a>'; $x .= '<span class="q0">' . Lang::achievement('reqNumCrt') . ' ' . sprintf(Lang::item('gemConditions', 3), $bLink, $cLink) . '</span><br />'; break; } } } $this->activateCondition = $x; } /**************/ /* Extra Tabs */ /**************/ // used by gem $gemList = new ItemList(array(['gemEnchantmentId', $this->typeId])); if (!$gemList->error) { $this->lvTabs[] = ['item', array('data' => array_values($gemList->getListviewData()), 'name' => '$LANG.tab_usedby + \' \' + LANG.gems', 'id' => 'used-by-gem')]; $this->extendGlobalData($gemList->getJsGlobals()); } // used by socket bonus $socketsList = new ItemList(array(['socketBonus', $this->typeId])); if (!$socketsList->error) { $this->lvTabs[] = ['item', array('data' => array_values($socketsList->getListviewData()), 'name' => '$LANG.tab_usedby + \' \' + \'' . Lang::item('socketBonus') . '\'', 'id' => 'used-by-socketbonus')]; $this->extendGlobalData($socketsList->getJsGlobals()); } // used by spell // used by useItem $cnd = array('OR', ['AND', ['effect1Id', [53, 54, 156, 92]], ['effect1MiscValue', $this->typeId]], ['AND', ['effect2Id', [53, 54, 156, 92]], ['effect2MiscValue', $this->typeId]], ['AND', ['effect3Id', [53, 54, 156, 92]], ['effect3MiscValue', $this->typeId]]); $spellList = new SpellList($cnd); if (!$spellList->error) { $spellData = $spellList->getListviewData(); $this->extendGlobalData($spellList->getJsGlobals()); $spellIds = $spellList->getFoundIDs(); $conditions = array('OR', ['AND', ['spellTrigger1', [0, 5]], ['spellId1', $spellIds]], ['AND', ['spellTrigger2', [0, 5]], ['spellId2', $spellIds]], ['AND', ['spellTrigger3', [0, 5]], ['spellId3', $spellIds]], ['AND', ['spellTrigger4', [0, 5]], ['spellId4', $spellIds]], ['AND', ['spellTrigger5', [0, 5]], ['spellId5', $spellIds]]); $ubItems = new ItemList($conditions); if (!$ubItems->error) { $this->lvTabs[] = ['item', array('data' => array_values($ubItems->getListviewData()), 'name' => '$LANG.tab_usedby + \' \' + LANG.types[3][0]', 'id' => 'used-by-item')]; $this->extendGlobalData($ubItems->getJSGlobals(GLOBALINFO_SELF)); } // remove found spells if they are used by an item if (!$ubItems->error) { foreach ($spellList->iterate() as $sId => $__) { // if Perm. Enchantment has a createItem its a Scroll of Enchantment (display both) for ($i = 1; $i < 4; $i++) { if ($spellList->getField('effect' . $i . 'Id') == 53 && $spellList->getField('effect' . $i . 'CreateItemId')) { continue 2; } } foreach ($ubItems->iterate() as $__) { for ($i = 1; $i < 6; $i++) { if ($ubItems->getField('spellId' . $i) == $sId) { unset($spellData[$sId]); break 2; } } } } } $this->lvTabs[] = ['spell', array('data' => array_values($spellData), 'name' => '$LANG.tab_usedby + \' \' + LANG.types[6][0]', 'id' => 'used-by-spell')]; } // used by randomAttrItem $ire = DB::Aowow()->select('SELECT *, ABS(id) AS ARRAY_KEY FROM ?_itemrandomenchant WHERE enchantId1 = ?d OR enchantId2 = ?d OR enchantId3 = ?d OR enchantId4 = ?d OR enchantId5 = ?d', $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId); if ($ire) { if ($iet = DB::World()->select('SELECT entry AS ARRAY_KEY, ench, chance FROM item_enchantment_template WHERE ench IN (?a)', array_keys($ire))) { $randIds = []; // transform back to signed format foreach ($iet as $tplId => $data) { $randIds[$ire[$data['ench']]['id'] > 0 ? $tplId : -$tplId] = $ire[$data['ench']]['id']; } $randItems = new ItemList(array(CFG_SQL_LIMIT_NONE, ['randomEnchant', array_keys($randIds)])); if (!$randItems->error) { $data = $randItems->getListviewData(); foreach ($randItems->iterate() as $iId => $__) { $re = $randItems->getField('randomEnchant'); $data[$iId]['percent'] = $iet[abs($re)]['chance']; $data[$iId]['count'] = 1; // expected by js or the pct-col becomes unsortable $data[$iId]['rel'] = 'rand=' . $ire[$iet[abs($re)]['ench']]['id']; $data[$iId]['name'] .= ' ' . Util::localizedString($ire[$iet[abs($re)]['ench']], 'name'); } $this->lvTabs[] = ['item', array('data' => array_values($data), 'id' => 'used-by-rand', 'name' => '$LANG.tab_usedby + \' \' + \'' . Lang::item('_rndEnchants') . '\'', 'extraCols' => ['$Listview.extraCols.percent'])]; $this->extendGlobalData($randItems->getJSGlobals(GLOBALINFO_SELF)); } } } }
protected function generateTitle() { if ($_ = DB::Aowow()->selectRow('SELECT * FROM ?_home_titles WHERE active = 1 AND title_loc?d <> "" ORDER BY RAND() LIMIT 1', User::$localeId)) { $this->title[0] .= Lang::main('colon') . Util::localizedString($_, 'title'); } }
private function createMail(&$reqCss = false) { $mail = []; if ($_ = $this->subject->getField('mailTemplate')) { $letter = DB::Aowow()->selectRow('SELECT * FROM ?_mailtemplate WHERE id = ?d', $_); if (!$letter) { return []; } $reqCss = true; $mail = array('delay' => null, 'sender' => null, 'subject' => Util::parseHtmlText(Util::localizedString($letter, 'subject', true)), 'text' => Util::parseHtmlText(Util::localizedString($letter, 'text', true))); } else { if ($_ = Util::parseHtmlText($this->subject->getField('text', true, true))) { $reqCss = true; $mail = array('delay' => null, 'sender' => null, 'subject' => Util::parseHtmlText($this->subject->getField('subject', true, true)), 'text' => $_); } } if ($_ = CreatureList::getName($this->subject->getField('sender'))) { $mail['sender'] = sprintf(Lang::quest('mailBy'), $this->subject->getField('sender'), $_); } return $mail; }
function talents() { $success = true; $buildTree = function ($class) use(&$petFamIcons, &$tSpells) { $petCategories = []; $mask = $class ? 1 << $class - 1 : 0; // All "tabs" of a given class talent $tabs = DB::Aowow()->select('SELECT * FROM dbc_talenttab WHERE classMask = ?d ORDER BY `tabNumber`, `creatureFamilyMask`', $mask); $result = []; for ($l = 0; $l < count($tabs); $l++) { $talents = DB::Aowow()->select('SELECT t.id AS tId, t.*, s.name_loc0, s.name_loc2, s.name_loc3, s.name_loc6, s.name_loc8, LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1)) AS iconString FROM dbc_talent t, dbc_spell s, dbc_spellicon si WHERE si.`Id` = s.`iconId` AND t.`tabId`= ?d AND s.`Id` = t.`rank1` ORDER by t.`row`, t.`column`', $tabs[$l]['Id']); $result[$l] = array('n' => Util::localizedString($tabs[$l], 'name'), 't' => []); if (!$class) { $petFamId = log($tabs[$l]['creatureFamilyMask'], 2); $result[$l]['icon'] = $petFamIcons[$petFamId]; $petCategories = DB::Aowow()->SelectCol('SELECT Id AS ARRAY_KEY, categoryEnumID FROM dbc_creaturefamily WHERE petTalentType = ?d', $petFamId); $result[$l]['f'] = array_keys($petCategories); } // talent dependencies go here $depLinks = []; $tNums = []; for ($j = 0; $j < count($talents); $j++) { $tNums[$talents[$j]['tId']] = $j; $d = []; $s = []; $i = $talents[$j]['tId']; $n = Util::localizedString($talents[$j], 'name'); $x = $talents[$j]['column']; $y = $talents[$j]['row']; $r = null; $t = []; $icon = $talents[$j]['iconString']; $m = $talents[$j]['rank2'] == 0 ? 1 : ($talents[$j]['rank3'] == 0 ? 2 : ($talents[$j]['rank4'] == 0 ? 3 : ($talents[$j]['rank5'] == 0 ? 4 : 5))); // duplet handling $f = []; foreach ($petCategories as $k => $v) { // cant handle 64bit integer .. split if ($v >= 32 && 1 << $v - 32 & $talents[$j]['petCategory2']) { $f[] = $k; } else { if ($v < 32 && 1 << $v & $talents[$j]['petCategory1']) { $f[] = $k; } } } for ($k = 0; $k <= $m - 1; $k++) { if (!$tSpells->getEntry($talents[$j]['rank' . ($k + 1)])) { continue; } $d[] = $tSpells->parseText()[0]; $s[] = $talents[$j]['rank' . ($k + 1)]; if ($talents[$j]['talentSpell']) { $t[] = $tSpells->getTalentHeadForCurrent(); } } if ($talents[$j]['reqTalent']) { // we didn't encounter the required talent yet => create reference if (!isset($tNums[$talents[$j]['reqTalent']])) { $depLinks[$talents[$j]['reqTalent']] = $j; } $r = @[$tNums[$talents[$j]['reqTalent']], $talents[$j]['reqRank'] + 1]; } $result[$l]['t'][$j] = array('i' => $i, 'n' => $n, 'm' => $m, 'd' => $d, 's' => $s, 'x' => $x, 'y' => $y); if (isset($r)) { $result[$l]['t'][$j]['r'] = $r; } if (!empty($t)) { $result[$l]['t'][$j]['t'] = $t; } if (!empty($f)) { $result[$l]['t'][$j]['f'] = $f; } if ($class) { $result[$l]['t'][$j]['iconname'] = $icon; } // If this talent is a reference, add it to the array of talent dependencies if (isset($depLinks[$talents[$j]['tId']])) { $result[$l]['t'][$depLinks[$talents[$j]['tId']]]['r'][0] = $j; unset($depLinks[$talents[$j]['tId']]); } } // Remove all dependencies for which the talent has not been found foreach ($depLinks as $dep_link) { unset($result[$l]['t'][$dep_link]['r']); } } return $result; }; // my neighbour is noisy as f**k and my head hurts, so .. $petFamIcons = ['Ability_Druid_KingoftheJungle', 'Ability_Druid_DemoralizingRoar', 'Ability_EyeOfTheOwl']; // .. i've no idea where to fetch these from $classes = [CLASS_WARRIOR, CLASS_PALADIN, CLASS_HUNTER, CLASS_ROGUE, CLASS_PRIEST, CLASS_DEATHKNIGHT, CLASS_SHAMAN, CLASS_MAGE, CLASS_WARLOCK, CLASS_DRUID]; $petIcons = ''; // check directory-structure foreach (Util::$localeStrings as $dir) { if (!CLISetup::writeDir('datasets/' . $dir)) { $success = false; } } $tSpellIds = DB::Aowow()->selectCol('SELECT rank1 FROM dbc_talent UNION SELECT rank2 FROM dbc_talent UNION SELECT rank3 FROM dbc_talent UNION SELECT rank4 FROM dbc_talent UNION SELECT rank5 FROM dbc_talent'); $tSpells = new SpellList(array(['s.id', $tSpellIds], CFG_SQL_LIMIT_NONE)); foreach (CLISetup::$localeIds as $lId) { User::useLocale($lId); Lang::load(Util::$localeStrings[$lId]); // TalentCalc foreach ($classes as $cMask) { set_time_limit(20); $cId = log($cMask, 2) + 1; $file = 'datasets/' . User::$localeString . '/talents-' . $cId; $toFile = '$WowheadTalentCalculator.registerClass(' . $cId . ', ' . Util::toJSON($buildTree($cId)) . ')'; if (!CLISetup::writeFile($file, $toFile)) { $success = false; } } // PetCalc if (empty($petIcons)) { $pets = DB::Aowow()->SelectCol('SELECT Id AS ARRAY_KEY, LOWER(SUBSTRING_INDEX(iconString, "\\\\", -1)) AS iconString FROM dbc_creaturefamily WHERE petTalentType IN (0, 1, 2)'); $petIcons = Util::toJSON($pets); } $toFile = "var g_pet_icons = " . $petIcons . ";\n\n"; $toFile .= 'var g_pet_talents = ' . Util::toJSON($buildTree(0)) . ';'; $file = 'datasets/' . User::$localeString . '/pet-talents'; if (!CLISetup::writeFile($file, $toFile)) { $success = false; } } return $success; }
private function createMail(&$attachmentTab, $startEnd) { $mail = []; if ($_ = $this->subject->getField('rewardMailTemplateId')) { $delay = $this->subject->getField('rewardMailDelay'); $letter = DB::Aowow()->selectRow('SELECT * FROM ?_mailtemplate WHERE id = ?d', $_); $mail = array('delay' => $delay ? sprintf(Lang::quest('mailIn'), Util::formatTime($delay * 1000)) : null, 'sender' => null, 'text' => $letter ? Util::parseHtmlText(Util::localizedString($letter, 'text')) : null, 'subject' => Util::parseHtmlText(Util::localizedString($letter, 'subject'))); foreach ($startEnd as $se) { if (!($se['method'] & 0x2) || $se['type'] != TYPE_NPC) { continue; } if ($_ = CreatureList::getName($se['typeId'])) { $mail['sender'] = sprintf(Lang::quest('mailBy'), $se['typeId'], $_); break; } } $extraCols = ['Listview.extraCols.percent']; $mailLoot = new Loot(); if ($mailLoot->getByContainer(LOOT_MAIL, $_)) { $this->extendGlobalData($mailLoot->jsGlobals); $attachmentTab = array('file' => 'item', 'data' => $mailLoot->getResult(), 'params' => array('name' => '[Mail Attachments]', 'id' => 'mail-attachments', 'extraCols' => "\$[" . implode(', ', array_merge($extraCols, $mailLoot->extraCols)) . "]", 'hiddenCols' => "\$['side', 'slot', 'reqlevel']")); } } return $mail; }
function enchants() { // from g_item_slots: 13:"One-Hand", 26:"Ranged", 17:"Two-Hand", $slotPointer = [13, 17, 26, 26, 13, 17, 17, 13, 17, null, 17, null, null, 13, null, 13, null, null, null, null, 17]; $castItems = []; $successs = true; $enchantSpells = new SpellList([['effect1Id', 53], ['name_loc0', 'QA%', '!'], CFG_SQL_LIMIT_NONE]); // enchantItemPermanent && !qualityAssurance // check directory-structure foreach (Util::$localeStrings as $dir) { if (!CLISetup::writeDir('datasets/' . $dir)) { $success = false; } } $enchIds = []; foreach ($enchantSpells->iterate() as $__) { $enchIds[] = $enchantSpells->getField('effect1MiscValue'); } $enchMisc = []; $enchJSON = Util::parseItemEnchantment($enchIds, false, $enchMisc); foreach (CLISetup::$localeIds as $lId) { set_time_limit(120); User::useLocale($lId); Lang::load(Util::$localeStrings[$lId]); $enchantsOut = []; foreach ($enchantSpells->iterate() as $__) { // slots have to be recalculated $slot = 0; if ($enchantSpells->getField('equippedItemClass') == 4) { if ($invType = $enchantSpells->getField('equippedItemInventoryTypeMask')) { $slot = $invType >> 1; } else { /* if (equippedItemSubClassMask == 64) */ // shields have it their own way <_< $slot = 1 << 14 - 1; } } else { if ($enchantSpells->getField('equippedItemClass') == 2) { foreach ($slotPointer as $i => $sp) { if (!$sp) { continue; } if (1 << $i & $enchantSpells->getField('equippedItemSubClassMask')) { if ($sp == 13) { // also mainHand & offHand *siiigh* $slot |= 1 << 21 - 1 | 1 << 22 - 1; } $slot |= 1 << $sp - 1; } } } } $eId = $enchantSpells->getField('effect1MiscValue'); // defaults $ench = array('name' => [], 'quality' => -1, 'icon' => strToLower($enchantSpells->getField('iconString')), 'source' => [], 'skill' => -1, 'slots' => [], 'enchantment' => Util::localizedString($enchMisc[$eId]['text'], 'text'), 'jsonequip' => @$enchJSON[$eId] ?: [], 'temp' => 0, 'classes' => 0); if (isset($enchMisc[$eId]['reqskill'])) { $ench['jsonequip']['reqskill'] = $enchMisc[$eId]['reqskill']; } if (isset($enchMisc[$eId]['reqskillrank'])) { $ench['jsonequip']['reqskill'] = $enchMisc[$eId]['reqskillrank']; } if (isset($enchMisc[$eId]['requiredLevel'])) { $ench['jsonequip']['requiredLevel'] = $enchMisc[$eId]['requiredLevel']; } // check if the spell has an entry in skill_line_ability -> Source:Profession if ($skills = $enchantSpells->getField('skillLines')) { $ench['name'][] = $enchantSpells->getField('name', true); $ench['source'][] = $enchantSpells->id; $ench['skill'] = $skills[0]; $ench['slots'][] = $slot; } // check if this spell can be cast via item -> Source:Item if (!isset($castItems[$enchantSpells->id])) { $castItems[$enchantSpells->id] = new ItemList([['spellId1', $enchantSpells->id], ['name_loc0', 'Scroll of Enchant%', '!']]); } // do not reuse enchantment scrolls $cI =& $castItems[$enchantSpells->id]; // this construct is a bit .. unwieldy foreach ($cI->iterate() as $__) { $ench['name'][] = $cI->getField('name', true); $ench['source'][] = -$cI->id; $ench['icon'] = strTolower($cI->getField('iconString')); $ench['slots'][] = $slot; if ($cI->getField('quality') > $ench['quality']) { $ench['quality'] = $cI->getField('quality'); } if ($cI->getField('requiredClass') > 0) { $ench['classes'] = $cI->getField('requiredClass'); $ench['jsonequip']['classes'] = $cI->getField('requiredClass'); } if (!isset($ench['jsonequip']['reqlevel'])) { if ($cI->getField('requiredLevel') > 0) { $ench['jsonequip']['reqlevel'] = $cI->getField('requiredLevel'); } } } // enchant spell not in use if (empty($ench['source'])) { continue; } // everything gathered if (isset($enchantsOut[$eId])) { foreach ($enchantsOut[$eId] as $k => $v) { if (is_array($v)) { while ($pop = array_pop($ench[$k])) { $enchantsOut[$eId][$k][] = $pop; } } else { if ($k == 'quality') { if ($enchantsOut[$eId]['source'][0] > 0 && $ench['source'][0] < 0) { $enchantsOut[$eId][$k] = -1; } else { if ($enchantsOut[$eId]['source'][0] < 0 && $ench['source'][0] > 0) { $enchantsOut[$eId][$k] = -1; } else { $enchantsOut[$eId][$k] = $ench[$k]; } } } else { if ($enchantsOut[$eId][$k] <= 0) { $enchantsOut[$eId][$k] = $ench[$k]; } } } } } else { // nothing yet, create new $enchantsOut[$eId] = $ench; } } // walk over each entry and strip single-item arrays foreach ($enchantsOut as &$ench) { foreach ($ench as $k => $v) { if (is_array($v) && count($v) == 1 && $k != 'jsonequip') { $ench[$k] = $v[0]; } } } $toFile = "var g_enchants = " . Util::toJSON($enchantsOut) . ";"; $file = 'datasets/' . User::$localeString . '/enchants'; if (!CLISetup::writeFile($file, $toFile)) { $success = false; } } return $successs; }
public function initSubItems() { if (!array_keys($this->templates)) { return; } $subItemIds = []; foreach ($this->iterate() as $__) { if ($_ = $this->getField('randomEnchant')) { $subItemIds[abs($_)] = $_; } } if (!$subItemIds) { return; } // remember: id < 0: randomSuffix; id > 0: randomProperty $subItemTpls = DB::World()->select(' SELECT CAST( entry as SIGNED) AS ARRAY_KEY, CAST( ench as SIGNED) AS ARRAY_KEY2, chance FROM item_enchantment_template WHERE entry IN (?a) UNION SELECT CAST(-entry as SIGNED) AS ARRAY_KEY, CAST(-ench as SIGNED) AS ARRAY_KEY2, chance FROM item_enchantment_template WHERE entry IN (?a)', array_keys(array_filter($subItemIds, function ($v) { return $v > 0; })) ?: [0], array_keys(array_filter($subItemIds, function ($v) { return $v < 0; })) ?: [0]); $randIds = []; foreach ($subItemTpls as $tpl) { $randIds = array_merge($randIds, array_keys($tpl)); } if (!$randIds) { return; } $randEnchants = DB::Aowow()->select('SELECT *, id AS ARRAY_KEY FROM ?_itemrandomenchant WHERE id IN (?a)', $randIds); $enchIds = array_unique(array_merge(array_column($randEnchants, 'enchantId1'), array_column($randEnchants, 'enchantId2'), array_column($randEnchants, 'enchantId3'), array_column($randEnchants, 'enchantId4'), array_column($randEnchants, 'enchantId5'))); $enchants = new EnchantmentList(array(['id', $enchIds], CFG_SQL_LIMIT_NONE)); foreach ($enchants->iterate() as $eId => $_) { $this->rndEnchIds[$eId] = array('text' => $enchants->getField('name', true), 'stats' => $enchants->getStatGain()); } foreach ($this->iterate() as $mstItem => $__) { if (!$this->getField('randomEnchant')) { continue; } if (empty($subItemTpls[$this->getField('randomEnchant')])) { continue; } foreach ($subItemTpls[$this->getField('randomEnchant')] as $subId => $data) { if (empty($randEnchants[$subId])) { continue; } $data = array_merge($randEnchants[$subId], $data); $jsonEquip = []; $jsonText = []; for ($i = 1; $i < 6; $i++) { $enchId = $data['enchantId' . $i]; if ($enchId <= 0 || empty($this->rndEnchIds[$enchId])) { continue; } if ($data['allocationPct' . $i] > 0) { $qty = intVal($data['allocationPct' . $i] * $this->generateEnchSuffixFactor()); $stats = array_fill_keys(array_keys($this->rndEnchIds[$enchId]['stats']), $qty); $jsonText[$enchId] = str_replace('$i', $qty, $this->rndEnchIds[$enchId]['text']); Util::arraySumByKey($jsonEquip, $stats); } else { $jsonText[$enchId] = $this->rndEnchIds[$enchId]['text']; Util::arraySumByKey($jsonEquip, $this->rndEnchIds[$enchId]['stats']); } } $this->subItems[$mstItem][$subId] = array('name' => Util::localizedString($data, 'name'), 'enchantment' => $jsonText, 'jsonequip' => $jsonEquip, 'chance' => $data['chance']); } if (!empty($this->subItems[$mstItem])) { $this->json[$mstItem]['subitems'] = $this->subItems[$mstItem]; } } }
private function getQuotes() { $nQuotes = 0; $quotes = []; $quoteSrc = DB::World()->select(' SELECT ct.groupid AS ARRAY_KEY, ct.id as ARRAY_KEY2, ct.`type`, ct.TextRange AS `range`, IFNULL(bct.`Language`, ct.`language`) AS lang, IFNULL(NULLIF(bct.MaleText, ""), IFNULL(NULLIF(bct.FemaleText, ""), IFNULL(ct.`text`, ""))) AS text_loc0, IFNULL(NULLIF(lbct.MaleText_loc2, ""), IFNULL(NULLIF(lbct.FemaleText_loc2, ""), IFNULL(lct.text_loc2, ""))) AS text_loc2, IFNULL(NULLIF(lbct.MaleText_loc3, ""), IFNULL(NULLIF(lbct.FemaleText_loc3, ""), IFNULL(lct.text_loc3, ""))) AS text_loc3, IFNULL(NULLIF(lbct.MaleText_loc6, ""), IFNULL(NULLIF(lbct.FemaleText_loc6, ""), IFNULL(lct.text_loc6, ""))) AS text_loc6, IFNULL(NULLIF(lbct.MaleText_loc8, ""), IFNULL(NULLIF(lbct.FemaleText_loc8, ""), IFNULL(lct.text_loc8, ""))) AS text_loc8 FROM creature_text ct LEFT JOIN locales_creature_text lct ON ct.entry = lct.entry AND ct.groupid = lct.groupid AND ct.id = lct.id LEFT JOIN broadcast_text bct ON ct.BroadcastTextId = bct.ID LEFT JOIN locales_broadcast_text lbct ON ct.BroadcastTextId = lbct.ID WHERE ct.entry = ?d', $this->typeId); foreach ($quoteSrc as $text) { $group = []; foreach ($text as $t) { $msg = Util::localizedString($t, 'text'); if (!$msg) { continue; } // fixup .. either set %s for emotes or dont >.< if (in_array($t['type'], [2, 16]) && strpos($msg, '%s') === false) { $msg = '%s ' . $msg; } // fixup: bad case-insensivity $msg = str_replace('%S', '%s', $msg); $line = array('range' => $t['range'], 'type' => 2, 'lang' => !empty($t['language']) ? Lang::game('languages', $t['language']) : null, 'text' => sprintf(Util::parseHtmlText(htmlentities($msg)), $this->name)); switch ($t['type']) { case 1: // yell: // yell: case 14: $line['type'] = 1; break; // - dark red // - dark red case 2: // emote: // emote: case 16: // " // " case 3: // boss emote: // boss emote: case 41: $line['type'] = 4; break; // - orange // - orange case 4: // whisper: // whisper: case 15: // " // " case 5: // boss whisper: // boss whisper: case 42: $line['type'] = 3; break; // - pink-ish } $nQuotes++; $group[] = $line; } if ($group) { $quotes[] = $group; } } return [$quotes, $nQuotes]; }
private function addAnnouncements() { if (!isset($this->announcements)) { $this->announcements = []; } // display occured notices if ($_ = Util::getNotes()) { array_unshift($_, 'One or more errors occured, while generating this page.'); $this->announcements[0] = array('parent' => 'announcement-0', 'id' => 0, 'mode' => 1, 'status' => 1, 'name' => 'internal error', 'style' => 'padding-left: 40px; background-image: url(' . STATIC_URL . '/images/announcements/warn-small.png); background-size: 15px 15px; background-position: 12px center; border: dashed 2px #C03030;', 'text' => '[span id=inputbox-error]' . implode("[br]", $_) . '[/span]'); } // fetch announcements if ($this->pageTemplate['pageName']) { $ann = DB::Aowow()->Select('SELECT ABS(id) AS ARRAY_KEY, a.* FROM ?_announcements a WHERE status = 1 AND (page = ? OR page = "*") AND (groupMask = 0 OR groupMask & ?d)', $this->pageTemplate['pageName'], User::$groups); foreach ($ann as $k => $v) { if ($t = Util::localizedString($v, 'text')) { $replace = array('HOST_URL' => HOST_URL, 'STATIC_URL' => STATIC_URL); $_ = array('parent' => 'announcement-' . $k, 'id' => $v['id'], 'mode' => $v['mode'], 'status' => $v['status'], 'name' => $v['name'], 'text' => strtr($t, $replace)); if ($v['style']) { // may be empty $_['style'] = strtr($v['style'], $replace); } $this->announcements[$k] = $_; } } } }
public function getField($field, $localized = false, $silent = false) { if (!$this->curTpl || !$localized && !isset($this->curTpl[$field])) { return ''; } if ($localized) { return Util::localizedString($this->curTpl, $field, $silent); } $value = $this->curTpl[$field]; Util::checkNumeric($value); return $value; }