From 08f4d84b6d9768dc35b807261176281bc12d42ae Mon Sep 17 00:00:00 2001 From: Sarjuuk Date: Wed, 19 Jun 2013 21:28:53 +0200 Subject: [PATCH] objects: - preparing tooltips (locks to Util & localization) quests & npcs: - implemented tooltips spells: - fixed tooltip-header - stat gain inclued periodic healing auras (item: 17743 for example) and spellHeal no longer applies spellPower achievements: - path is less prone to errors events: - disabled tab as it was causing js-errors obligatory cleaning up everywhere --- includes/class.creature.php | 2 + includes/class.item.php | 42 +- includes/class.quest.php | 97 +++- includes/class.spell.php | 185 +++--- includes/utilities.php | 37 ++ localization/locale_dede.php | 11 +- localization/locale_enus.php | 11 +- localization/locale_eses.php | 11 +- localization/locale_frfr.php | 11 +- localization/locale_ruru.php | 11 +- pages/achievement.php | 51 +- pages/achievements.php | 2 +- pages/events.php | 2 +- pages/item.php | 74 +-- pages/itemsets.php | 10 +- pages/npc.php | 491 ++++++++++++++++ pages/quest.php | 622 +++++++++++++++++++++ pages/spell.php | 19 +- pages/zones.php | 1 + setup/tools/dataset-assembler/enchants.php | 8 +- 20 files changed, 1463 insertions(+), 235 deletions(-) create mode 100644 pages/npc.php create mode 100644 pages/quest.php diff --git a/includes/class.creature.php b/includes/class.creature.php index a354a680..32d217ef 100644 --- a/includes/class.creature.php +++ b/includes/class.creature.php @@ -6,6 +6,8 @@ if (!defined('AOWOW_REVISION')) class CreatureList extends BaseType { + use spawnHelper; + public $tooltips = []; protected $setupQuery = 'SELECT *, ct.entry AS ARRAY_KEY, ct.entry AS id FROM creature_template ct LEFT JOIN locales_creature lc ON lc.entry = ct.entry LEFT JOIN creature_template_addon cta on cta.entry = ct.entry WHERE [filter] [cond]'; diff --git a/includes/class.item.php b/includes/class.item.php index e17adcd7..d3788264 100644 --- a/includes/class.item.php +++ b/includes/class.item.php @@ -524,34 +524,9 @@ class ItemList extends BaseType $x .= '
'.sprintf(Lang::$game['requires'], 'curTpl['RequiredReputationFaction'].'">'.Faction::getName($this->curTpl['RequiredReputationFaction']).' - '.Lang::$game['rep'][$this->curTpl['RequiredReputationRank']]); // locked - if ($this->curTpl['lockid']) - { - $lock = DB::Aowow()->selectRow(' - SELECT - * - FROM - ?_lock - WHERE - lockID = ?d', - $this->curTpl['lockid'] - ); - // only use first useful entry - for ($j = 1; $j <= 5; $j++) - { - if ($lock['type'.$j] == 1) // opened by item - { - $l = sprintf(Lang::$game['requires'], ''.Util::getItemName($lock['lockproperties'.$j]).''); - break; - } - else if ($lock['type'.$j] == 2) // opened by skill - { - $lockText = DB::Aowow()->selectRow('SELECT ?# FROM ?_locktype WHERE id = ?d', $lock['lockproperties'.$j]); - $l = sprintf(Lang::$game['requires'], Util::localizedString($lockText, 'name').' ('.$lock['requiredskill'.$j].')'); - break; - } - } - $x .= '
'.Lang::$item['locked'].'
'.$l.'
'; - } + if ($lId = $this->curTpl['lockid']) + if ($locks = Lang::getLocks($lId)) + $x .= '
'.Lang::$item['locked'].'
'.implode('
', $locks).'
'; // upper table: done if (!$subT) @@ -819,10 +794,15 @@ class ItemList extends BaseType // convert ItemMods for ($h = 1; $h <= 10; $h++) { - if (!$this->curTpl['stat_type'.$h]) + $mod = $this->curTpl['stat_type'.$h]; + $val = $this->curTpl['stat_value'.$h]; + if (!$mod ||!$val) continue; - @$this->itemMods[$this->id][$this->curTpl['stat_type'.$h]] += $this->curTpl['stat_value'.$h]; + if ($mod == ITEM_MOD_ATTACK_POWER) + @$this->itemMods[$this->id][ITEM_MOD_RANGED_ATTACK_POWER] += $val; + + @$this->itemMods[$this->id][$mod] += $val; } // convert Spells @@ -855,7 +835,7 @@ class ItemList extends BaseType $this->json[$this->id]['socketbonusstat'] = Util::parseItemEnchantment($enh); // gather random Enchantments - // todo: !important! extremly high sql-load + // todo (high): extremly high sql-load if (@$this->json[$this->id]['commondrop'] && isset($this->subItems[$this->id])) { foreach ($this->subItems[$this->id] as $k => $sI) diff --git a/includes/class.quest.php b/includes/class.quest.php index 96d2f97a..60290ee2 100644 --- a/includes/class.quest.php +++ b/includes/class.quest.php @@ -8,8 +8,8 @@ class QuestList extends BaseType public $cat1 = 0; public $cat2 = 0; - protected $setupQuery = 'SELECT *, id AS ARRAY_KEY FROM quest_template a LEFT JOIN locales_quest b ON a.Id = b.entry WHERE [filter] [cond] ORDER BY Id ASC'; - protected $matchQuery = 'SELECT COUNT(1) FROM quest_template a LEFT JOIN locales_quest b ON a.Id = b.entry WHERE [filter] [cond]'; + protected $setupQuery = 'SELECT *, id AS ARRAY_KEY FROM quest_template qt LEFT JOIN locales_quest lq ON qt.Id = lq.entry WHERE [filter] [cond] ORDER BY Id ASC'; + protected $matchQuery = 'SELECT COUNT(1) FROM quest_template WHERE [filter] [cond]'; // parent::__construct does the job @@ -167,9 +167,100 @@ class QuestList extends BaseType (new TitleList(array(['id', $titles])))->addGlobalsToJscript($refs); } + private function parseText($type = 'Objectives') + { + $replace = array( + '$c' => '<'.Util::ucFirst(Lang::$game['class']).'>', + '$C' => '<'.Util::ucFirst(Lang::$game['class']).'>', + '$r' => '<'.Util::ucFirst(Lang::$game['race']).'>', + '$R' => '<'.Util::ucFirst(Lang::$game['race']).'>', + '$n' => '<'.Util::ucFirst(Lang::$main['name']).'>', + '$N' => '<'.Util::ucFirst(Lang::$main['name']).'>', + '$b' => '
', + '$B' => '
' + ); + + $text = $this->getField($type, true); + if (!$text) + return ''; + + $text = strtr($text, $replace); + + // gender switch + $text = preg_replace('/$g([^:;]+):([^:;]+);/ui', '<\1/\2<', $text); + + // nonesense, that the client apparently ignores + $text = preg_replace('/$t([^;]+);/ui', '', $text); + + return Util::jsEscape($text); + } + public function renderTooltip() { - // todo + if (!$this->curTpl) + return null; + + if (isset($this->tooltips[$this->id])) + return $this->tooltips[$this->id]; + + $title = Util::jsEscape($this->getField('Title', true)); + $level = $this->curTpl['Level']; + if ($level < 0) + $level = 0; + + $x = ''; + if ($level) + { + $level = sprintf(Lang::$quest['level'], $level); + + if ($this->curTpl['Flags'] & 0x1000) // daily + $level .= ' '.Lang::$quest['daily']; + + $x .= '
'.$title.''.$level.'
'; + } + else + $x .= '
'.$title.'
'; + + + $x .= '

'.$this->parseText('Objectives').'

'.Lang::$quest['requirements'].Lang::$colon.''; + + + for ($i = 1; $i < 5; $i++) + { + $ot = $this->getField('ObjectiveText'.$i, true); + $rng = $this->curTpl['RequiredNpcOrGo'.$i]; + $rngQty = $this->curTpl['RequiredNpcOrGoCount'.$i]; + + if ($rngQty < 1 && (!$rng || $ot)) + continue; + + if ($ot) + $name = $ot; + else + $name = $rng > 0 ? CreatureList::getName($rng) : GameObjectList::getName(-$rng); + + $x .= '
- '.Util::jsEscape($name).($rngQty > 1 ? ' x '.$rngQty : null); + } + + for ($i = 1; $i < 7; $i++) + { + $ri = $this->curTpl['RequiredItemId'.$i]; + $riQty = $this->curTpl['RequiredItemCount'.$i]; + + if (!$ri || $riQty < 1) + continue; + + $x .= '
- '.Util::jsEscape(ItemList::getName($ri)).($riQty > 1 ? ' x '.$riQty : null); + } + + if ($et = $this->getField('EndText', true)) + $x .= '
- '.$et; + + $x .= '
'; + + $this->tooltips[$this->id] = $x; + + return $x; } public function addGlobalsToJScript(&$refs) diff --git a/includes/class.spell.php b/includes/class.spell.php index ecf67efd..cf2270c0 100644 --- a/includes/class.spell.php +++ b/includes/class.spell.php @@ -70,7 +70,7 @@ class SpellList extends BaseType foreach ($sources as $src) { $src = explode(':', $src); - if ($src[0] != -3) // todo: sourcemore - implement after items + if ($src[0] != -3) // todo (high): sourcemore - implement after items $this->sources[$this->id][$src[0]][] = $src[1]; } } @@ -124,7 +124,7 @@ class SpellList extends BaseType for ($i = 1; $i <= 3; $i++) { - if (!in_array($this->curTpl["effect".$i."AuraId"], [13, 22, 29, 34, 35, 83, 84, 85, 99, 124, 135, 143, 158, 161, 189, 230, 235, 240, 250])) + if (!in_array($this->curTpl["effect".$i."AuraId"], [8, 13, 22, 29, 34, 35, 83, 84, 85, 99, 124, 135, 143, 158, 161, 189, 230, 235, 240, 250])) continue; $mv = $this->curTpl["effect".$i."MiscValue"]; @@ -197,7 +197,6 @@ class SpellList extends BaseType } case 135: // healing splpwr (healing & any) .. not as a mask.. { - @$stats[ITEM_MOD_SPELL_POWER] += $bp; @$stats[ITEM_MOD_SPELL_HEALING_DONE] += $bp; break; @@ -271,7 +270,8 @@ class SpellList extends BaseType } } break; - case 84: // hp5 + case 8: // hp5 + case 84: case 161: @$stats[ITEM_MOD_HEALTH_REGEN] += $bp; break; @@ -387,7 +387,7 @@ class SpellList extends BaseType if ($this->curTpl['powerPerSecond'] > 0) $str .= sprintf(Lang::$spell['costPerSec'], $this->curTpl['powerPerSecond']); - // append level cost (todo: (low) work in as scaling cost) + // append level cost (todo (low): work in as scaling cost) if ($this->curTpl['powerCostPerLevel'] > 0) $str .= sprintf(Lang::$spell['costPerLevel'], $this->curTpl['powerCostPerLevel']); @@ -400,11 +400,11 @@ class SpellList extends BaseType return Lang::$spell['channeled']; else if ($this->curTpl['castTime'] > 0) return $short ? sprintf(Lang::$spell['castIn'], $this->curTpl['castTime'] / 1000) : Util::formatTime($this->curTpl['castTime']); - // show instant only for player/pet/npc abilities (todo: (low) unsure when really hidden (like talent-case)) - else if ($noInstant && !in_array($this->curTpl['typeCat'], [7, -3, -8, 0]) && !($this->curTpl['cuFlags'] & SPELL_CU_TALENTSPELL)) + // show instant only for player/pet/npc abilities (todo (low): unsure when really hidden (like talent-case)) + else if ($noInstant && !in_array($this->curTpl['typeCat'], [11, 7, -3, -8, 0]) && !($this->curTpl['cuFlags'] & SPELL_CU_TALENTSPELL)) return ''; - // SPELL_ATTR0_ABILITY instant ability.. yeah, wording thing only - else if ($this->curTpl['damageClass'] == 0 || $this->curTpl['attributes0'] & 0x10) + // SPELL_ATTR0_ABILITY instant ability.. yeah, wording thing only (todo (low): rule is imperfect) + else if ($this->curTpl['damageClass'] != 1 || $this->curTpl['attributes0'] & 0x10) return Lang::$spell['instantPhys']; else // instant cast return Lang::$spell['instantMagic']; @@ -437,7 +437,7 @@ class SpellList extends BaseType $sps = $SPS = $this->interactive ? sprintf(Util::$dfnString, 'LANG.traits.shasplpwr[0]', Lang::$spell['traitShort']['shasplpwr']) : Lang::$spell['traitShort']['shasplpwr']; $bh = $BH = $this->interactive ? sprintf(Util::$dfnString, 'LANG.traits.splheal[0]', Lang::$spell['traitShort']['splheal']) : Lang::$spell['traitShort']['splheal']; - $HND = $hnd = $this->interactive ? sprintf(Util::$dfnString, '[Hands required by weapon]', 'HND') : 'HND'; // todo: localize this one + $HND = $hnd = $this->interactive ? sprintf(Util::$dfnString, '[Hands required by weapon]', 'HND') : 'HND'; // todo (med): localize this one $MWS = $mws = $this->interactive ? sprintf(Util::$dfnString, 'LANG.traits.mlespeed[0]', 'MWS') : 'MWS'; $mw = $this->interactive ? sprintf(Util::$dfnString, 'LANG.traits.dmgmin1[0]', 'mw') : 'mw'; $MW = $this->interactive ? sprintf(Util::$dfnString, 'LANG.traits.dmgmax1[0]', 'MW') : 'MW'; @@ -508,7 +508,7 @@ class SpellList extends BaseType switch ($var) { case 'a': // EffectRadiusMin - case 'A': // EffectRadiusMax (ToDo) + case 'A': // EffectRadiusMax if ($lookup) $base = $this->refSpells[$lookup]->getField('effect'.$effIdx.'RadiusMax'); else @@ -530,7 +530,7 @@ class SpellList extends BaseType return $base; case 'd': // SpellDuration - case 'D': // todo: min/max?; /w unit? + case 'D': // todo (med): min/max?; /w unit? if ($lookup) $base = $this->refSpells[$lookup]->getField('duration'); else @@ -542,7 +542,6 @@ class SpellList extends BaseType if ($op && is_numeric($oparg) && is_numeric($base)) eval("\$base = $base $op $oparg;"); - // todo: determine WHEN the unit is needed >.< return explode(' ', Util::formatTime(abs($base), true)); case 'e': // EffectValueMultiplier case 'E': @@ -997,7 +996,7 @@ class SpellList extends BaseType } // step 2: resolving conditions - // aura- or spell-conditions cant be resolved for our purposes, so force them to false for now (todo: strg+f "know" in aowowPower.js ^.^) + // aura- or spell-conditions cant be resolved for our purposes, so force them to false for now (todo (low): strg+f "know" in aowowPower.js ^.^) // \1: full pattern match; \2: any sequence, that may include an aura/spell-ref; \3: any other sequence, between "?$" and "[" while (preg_match('/\$\?(([\W\D]*[as]\d+)|([^\[]*))/i', $data, $matches)) { @@ -1017,7 +1016,7 @@ class SpellList extends BaseType $condCurPos = $condStartPos; } - else if (!empty($matches[2])) // aura/spell-condition .. use false; TODO (low priority) catch cases and port "know"-param for tooltips from 5.0 + else if (!empty($matches[2])) // aura/spell-condition .. use false; TODO (low): catch cases and port "know"-param for tooltips from 5.0 { // tooltip_enus: Charge to an enemy, stunning it for 1 sec.; spells_enus: {"58377": [["", "and 2 additional nearby targets "]], "103828": [["1 sec", "3 sec"]]}; $condStartPos = strpos($data, $matches[2]) - 2; $condCurPos = $condStartPos; @@ -1150,7 +1149,7 @@ class SpellList extends BaseType // step 5: variable-depentant variable-text // special case $lONE:ELSE; - // todo: russian uses THREE (wtf?! oO) cases ($l[singular]:[plural1]:[plural2]) .. explode() chooses always the first plural option :/ + // todo (low): russian uses THREE (wtf?! oO) cases ($l[singular]:[plural1]:[plural2]) .. explode() chooses always the first plural option :/ while (preg_match('/([\d\.]+)([^\d]*)(\$l:*)([^:]*):([^;]*);/i', $str, $m)) $str = str_ireplace($m[1].$m[2].$m[3].$m[4].':'.$m[5].';', $m[1].$m[2].($m[1] == 1 ? $m[4] : explode(':', $m[5])[0]), $str); @@ -1215,6 +1214,16 @@ class SpellList extends BaseType $this->interactive = $interactive; + // fetch needed texts + $name = $this->getField('name', true); + $rank = $this->getField('rank', true); + $desc = $this->parseText('description', $level, $this->interactive); + $tools = $this->getToolsForCurrent(); + $cool = $this->createCooldownForCurrent(); + $cast = $this->createCastTimeForCurrent(); + $cost = $this->createPowerCostForCurrent(); + $range = $this->createRangesForCurrent(); + // get reagents $reagents = []; for ($j = 1; $j <= 8; $j++) @@ -1230,18 +1239,6 @@ class SpellList extends BaseType } $reagents = array_reverse($reagents); - // get tools - $tools = $this->getToolsForCurrent(); - - // get description - $desc = $this->parseText('description', $level, $this->interactive); - - // get cooldown - $cool = $this->createCooldownForCurrent(); - - // get cast time - $cast = $this->createCastTimeForCurrent(); - // get stances (check: SPELL_ATTR2_NOT_NEED_SHAPESHIFT) $stances = ''; if ($this->curTpl['stanceMask'] && !($this->curTpl['attributes2'] & 0x80000)) @@ -1273,46 +1270,23 @@ class SpellList extends BaseType } } - $reqWrapper = $this->curTpl['rangeMaxHostile'] && ($this->curTpl['powerCost'] > 0 || $this->curTpl['powerCostPercent'] > 0 || ($this->curTpl['powerCostRunes'] & 0x333)); - $reqWrapper2 = $reagents || $tools || $desc || $reqItems || $createItem; - $x = ''; $x .= '
'; - $rankText = Util::localizedString($this->curTpl, 'rank'); + // name & rank + if ($rank) + $x .= '
'.$name.''.$rank.'
'; + else + $x .= ''.$name.'
'; - if (!empty($rankText)) - $x .= '
'; + // powerCost & ranges + if ($range && $cost) + $x .= '
'.$cost.''.$range.'
'; + else if ($cost || $range) + $x .= $range.$cost.'
'; - // name - $x .= ''.$this->getField('name', true).''; - - // rank - if (!empty($rankText)) - $x .= '
'.$rankText.'
'; - - // power cost - $c = $this->createPowerCostForCurrent(); - - // ranges - $r = $this->createRangesForCurrent(); - - if ($reqWrapper) - $x .= '
'.$c.''.$r.'
'; - else if ($c || $r) - { - if (empty($rankText)) - $x .= '
'; - - $x .= $r; - - if ($c && $r) - $x .= '
'; - - $x .= $c; - } - - if ($cool) // tabled layout + // castTime & cooldown + if ($cast && $cool) // tabled layout { $x .= ''; $x .= ''; @@ -1321,91 +1295,68 @@ class SpellList extends BaseType $x .= '
'.$cast.''.$cool.'
'; } - else if ($cast || $stances) // line-break layout + else if ($cast || $cool) // line-break layout { - if (!$reqWrapper && !$c && empty($rankText)) - $x .= '
'; + $x .= $cast.$cool; - $x .= $cast; - - if ($cast && $stances) - $x .= '
'; - - $x .= $stances; + if ($stances) + $x .= '
'.$stances; } $x .= '
'; - if ($reqWrapper2) - $x .= '
'; + $xTmp = []; if ($tools) { - $x .= Lang::$spell['tools'].':
'; + $_ = Lang::$spell['tools'].':
'; while ($tool = array_pop($tools)) { if (isset($tool['itemId'])) - $x .= ''.$tool['name'].''; + $_ .= ''.$tool['name'].''; else if (isset($tool['id'])) - $x .= ''.$tool['name'].''; + $_ .= ''.$tool['name'].''; else - $x .= $tool['name']; + $_ .= $tool['name']; if (!empty($tools)) - $x .= ', '; + $_ .= ', '; else - $x .= '
'; + $_ .= '
'; } - $x .= '
'; + + $xTmp[] = $_.'
'; } if ($reagents) { - if ($tools) - $x .= "
"; - - $x .= Lang::$spell['reagents'].':
'; + $_ = Lang::$spell['reagents'].':
'; while ($reagent = array_pop($reagents)) { - $x .= ''.$reagent['name'].''; + $_ .= ''.$reagent['name'].''; if ($reagent['count'] > 1) - $x .= ' ('.$reagent['count'].')'; + $_ .= ' ('.$reagent['count'].')'; if(!empty($reagents)) - $x .= ', '; + $_ .= ', '; else - $x .= '
'; + $_ .= '
'; } - $x .= '
'; + + $xTmp[] = $_.'
'; } if ($reqItems) - { - if ($tools || $reagents) - $x .= "
"; - - $x .= Lang::$game['requires2'].' '.$reqItems; - } + $xTmp[] = Lang::$game['requires2'].' '.$reqItems; if ($desc) - { - if ($tools || $reagents || $reqItems) - $x .= "
"; - - $x .= ''.$desc.''; - } + $xTmp[] = ''.$desc.''; if ($createItem) - { - if ($tools || $reagents || $reqItems || $desc) - $x .= "
"; - - $x .= '
'.$createItem; - } - - if ($reqWrapper2) - $x .= "
"; + $xTmp[] = '
'.$createItem; + if ($tools || $reagents || $reqItems || $desc || $createItem) + $x .= '
'.implode('
', $xTmp).'
'; $this->tooltips[$this->id] = $x; @@ -1421,7 +1372,7 @@ class SpellList extends BaseType $range = $this->createRangesForCurrent(); // cast times - $time = $this->createCastTimeForCurrent(); + $cast = $this->createCastTimeForCurrent(); // cooldown or categorycooldown $cool = $this->createCooldownForCurrent(); @@ -1435,16 +1386,16 @@ class SpellList extends BaseType if ($cost && $range) $x .= '
'.$cost.''.$range.'
'; else - $x .= $cost . $range; + $x .= $cost.$range; - if (($cost xor $range) && ($time xor $cool)) + if (($cost xor $range) && ($cast xor $cool)) $x .= '
'; // lower - if ($time && $cool) - $x .= '
'.$time.''.$cool.'
'; + if ($cast && $cool) + $x .= '
'.$cast.''.$cool.'
'; else - $x .= $time . $cool; + $x .= $cast.$cool; return $x; } diff --git a/includes/utilities.php b/includes/utilities.php index 15eed1fc..5cc62b18 100644 --- a/includes/utilities.php +++ b/includes/utilities.php @@ -354,6 +354,43 @@ class Lang return $tmp; } + public static function getLocks($lockId, $interactive = false) + { + $locks = []; + $lock = DB::Aowow()->selectRow('SELECT * FROM ?_lock WHERE id = ?d', $this->curTpl['lockid']); + + for ($i = 1; $i <= 5; $i++) + { + $prop = $lock['lockproperties'.$i]; + $rnk = $lock['requiredskill'.$i]; + $name = ''; + + if ($lock['type'.$i] == 1) // opened by item + { + $name = ItemList::getName($prop); + if (!$name) + continue; + + if ($interactive) + $name = ''.$name.''; + } + else if ($lock['type'.$i] == 2) // opened by skill + { + $txt = DB::Aowow()->selectRow('SELECT * FROM ?_locktype WHERE id = ?d', $prop); // todo (low): convert to static text + $name = Util::localizedString($txts, 'name'); + if (!$name) + continue; + + if ($rnk > 0) + $name .= ' ('.$rnk.')'; + } + + $locks[] = sprintf(Lang::$game['requires'], $n); + } + + return $locks; + } + public static function getReputationLevelForPoints($pts) { if ($pts >= 41999) diff --git a/localization/locale_dede.php b/localization/locale_dede.php index 865c02bd..7466c1f0 100644 --- a/localization/locale_dede.php +++ b/localization/locale_dede.php @@ -83,6 +83,8 @@ $lang = array( 'tryAgain' => "Bitte versucht es mit anderen Suchbegriffen oder überprüft deren Schreibweise.", ), 'game' => array( + 'achievement' => "Erfolg", + 'achievements' => "Erfolge", 'class' => "Klasse", 'classes' => "Klassen", 'currency' => "Währung", @@ -90,6 +92,8 @@ $lang = array( 'difficulty' => "Modus", 'dispelType' => "Bannart", 'duration' => "Dauer", + 'gameObject' => "Objekt", + 'gameObjects' => "Objekte", 'glyphType' => "Glyphenart", 'race' => "Volk", 'races' => "Völker", @@ -218,9 +222,7 @@ $lang = array( 'rank' => ['Normal', 'Elite', 'Rar Elite', 'Boss', 'Rar'] ), 'achievement' => array( - 'achievements' => "Erfolge", 'criteria' => "Kriterien", - 'achievement' => "Erfolg", 'points' => "Punkte", 'series' => "Reihe", 'outOf' => "von", @@ -263,6 +265,11 @@ $lang = array( "Schlachtfelder", null, "Scherbenwelt", "Arenen", "Nordend" ) ), + 'quest' => array( + 'level' => 'Stufe %s', + 'daily' => 'Täglich', + 'requirements' => 'Anforderungen' + ), 'title' => array( 'cat' => array( 'Allgemein', 'Spieler gegen Spieler', 'Ruf', 'Dungeon & Schlachtzug', 'Quests', 'Berufe', 'Weltereignisse' diff --git a/localization/locale_enus.php b/localization/locale_enus.php index baab0fee..fd8765ba 100644 --- a/localization/locale_enus.php +++ b/localization/locale_enus.php @@ -78,6 +78,8 @@ $lang = array( 'tryAgain' => "Please try some different keywords or check your spelling.", ), 'game' => array( + 'achievement' => "achievement", + 'achievements' => "Achievements", 'class' => "class", 'classes' => "Classes", 'currency' => "currency", @@ -85,6 +87,8 @@ $lang = array( 'difficulty' => "Difficulty", 'dispelType' => "Dispel type", 'duration' => "Duration", + 'gameObject' => "objects", + 'gameObjects' => "Objects", 'glyphType' => "Glyph type", 'race' => "race", 'races' => "Races", @@ -213,9 +217,7 @@ $lang = array( 'category' => array("Uncategorized", "Holidays", "Recurring", "Player vs. Player") ), 'achievement' => array( - 'achievements' => "achievements", 'criteria' => "Criteria", - 'achievement' => "achievement", 'points' => "Points", 'series' => "Series", 'outOf' => "out of", @@ -258,6 +260,11 @@ $lang = array( "Battlegrounds", null, "Outland", "Arenas", "Northrend" ) ), + 'quest' => array( + 'level' => 'Level %s', + 'daily' => 'Daily', + 'requirements' => 'Requirements' + ), 'title' => array( 'cat' => array( 'General', 'Player vs. Player', 'Reputation', 'Dungeons & Raids', 'Quests', 'Professions', 'World Events' diff --git a/localization/locale_eses.php b/localization/locale_eses.php index 403e1293..7048c167 100644 --- a/localization/locale_eses.php +++ b/localization/locale_eses.php @@ -75,6 +75,8 @@ $lang = array( 'tryAgain' => "Por favor, introduzca otras palabras claves o verifique el término ingresado.", ), 'game' => array( + 'achievement' => "logro", + 'achievements' => "Logros", 'class' => "clase", 'classes' => "Clases", 'currency' => "monedas", @@ -82,6 +84,8 @@ $lang = array( 'difficulty' => "Dificultad", 'dispelType' => "Tipo de disipación", 'duration' => "Duración", + 'gameObject' => "entidad", + 'gameObjects' => "Entidades", 'glyphType' => "Tipo de glifo", 'race' => "raza", 'races' => "Razas", @@ -171,9 +175,7 @@ $lang = array( 'rank' => ['Normal', 'Élite', 'Élite raro', 'Jefe', 'Raro'] ), 'achievement' => array( - 'achievements' => "logros", 'criteria' => "Requisitos", - 'achievement' => "logro", 'points' => "Puntos", 'series' => "Serie", 'outOf' => "de", @@ -216,6 +218,11 @@ $lang = array( "Campos de batalla", null, "Terrallende", "Arenas", "Rasganorte" ) ), + 'quest' => array( + 'level' => 'Nivel %s', + 'daily' => 'Diaria', + 'requirements' => 'Requisitos' + ), 'title' => array( 'cat' => array( 'General', 'Jugador contra Jugador', 'Reputación', 'Mazmorras y bandas', 'Misiones', 'Profesiones', 'Eventos del mundo' diff --git a/localization/locale_frfr.php b/localization/locale_frfr.php index 778269ba..05f9be56 100644 --- a/localization/locale_frfr.php +++ b/localization/locale_frfr.php @@ -75,6 +75,8 @@ $lang = array( 'tryAgain' => "Veuillez essayer d'autres mots ou vérifiez l'orthographe des termes de recherche.", ), 'game' => array ( + 'achievement' => "haut fait", + 'achievements' => "Hauts faits", 'class' => "classe", 'classes' => "Classes", 'currency' => "monnaies", @@ -82,6 +84,8 @@ $lang = array( 'difficulty' => "Difficulté", 'dispelType' => "Type de dissipation", 'duration' => "Durée", + 'gameObject' => "entité", + 'gameObjects' => "Entités", 'glyphType' => "Type de glyphe", 'race' => "race", 'races' => "Races", @@ -170,9 +174,7 @@ $lang = array( 'rank' => ['Standard', 'Élite', 'Élite rare', 'Boss', 'Rare'] ), 'achievement' => array( - 'achievements' => "hauts faits", 'criteria' => "Critères", - 'achievement' => "haut fait", 'points' => "Points", 'series' => "Série", 'outOf' => "sur", @@ -215,6 +217,11 @@ $lang = array( "Champs de bataille", null, "Outreterre", "Arènes", "Norfendre" ) ), + 'quest' => array( + 'level' => 'Niveau %s', + 'daily' => 'Journalière', + 'requirements' => 'Conditions' + ), 'title' => array( 'cat' => array( 'Général', 'Joueur ctr. Joueur', 'Réputation', 'Donjons & raids', 'Quêtes', 'Métiers', 'Évènements mondiaux' diff --git a/localization/locale_ruru.php b/localization/locale_ruru.php index 93e0c734..f21ce03c 100644 --- a/localization/locale_ruru.php +++ b/localization/locale_ruru.php @@ -75,6 +75,8 @@ $lang = array( 'tryAgain' => "Пожалуйста, попробуйте другие ключевые слова или проверьте правильность запроса.", ), 'game' => array( + 'achievement' => "достижение", + 'achievements' => "Достижения", 'class' => "класс", 'classes' => "Классы", 'currency' => "валюта", @@ -82,6 +84,8 @@ $lang = array( 'difficulty' => "Сложность", 'dispelType' => "Тип рассеивания", 'duration' => "Длительность", + 'gameObject' => "объект", + 'gameObjects' => "Объекты", 'glyphType' => "Тип символа", 'race' => "раса", 'races' => "Расы", @@ -170,9 +174,7 @@ $lang = array( 'rank' => ['Обычный', 'Элитный', 'Редкий элитный', 'Босс', 'Редкий'] ), 'achievement' => array( - 'achievements' => "достижения", 'criteria' => "Критерий", - 'achievement' => "достижение", 'points' => "Очки", 'series' => "Серии", 'outOf' => "из", @@ -215,6 +217,11 @@ $lang = array( "Поля боя", null, "Запределье", "Арены", "Нордскол" ) ), + 'quest' => array( + 'level' => '%s-го уровня', + 'daily' => '', // empty on purpose .. wtf guys?! + 'requirements' => 'Требования' + ), 'title' => array( 'cat' => array( 'Общее', 'PvP', 'Репутация', 'Подземелья и рейды', 'Задания', 'Профессии', 'Игровые события' diff --git a/pages/achievement.php b/pages/achievement.php index b034010e..59ab56d6 100644 --- a/pages/achievement.php +++ b/pages/achievement.php @@ -22,7 +22,6 @@ if (!defined('AOWOW_REVISION')) require 'includes/class.community.php'; $id = intVal($pageParam); -$acv = new AchievementList(array(['id', $id])); $cacheKeyPage = implode('_', [CACHETYPE_PAGE, TYPE_ACHIEVEMENT, $id, -1, User::$localeId]); $cacheKeyTooltip = implode('_', [CACHETYPE_TOOLTIP, TYPE_ACHIEVEMENT, $id, -1, User::$localeId]); @@ -34,15 +33,16 @@ if (isset($_GET['power'])) Util::powerUseLocale(@$_GET['domain']); - if ($acv->error) - die('$WowheadPower.registerAchievement(\''.$id.'\', '.User::$localeId.', {})'); - if (!$smarty->loadCache($cacheKeyTooltip, $x)) { + $acv = new AchievementList(array(['id', $id])); + if ($acv->error) + die('$WowheadPower.registerAchievement(\''.$id.'\', '.User::$localeId.', {})'); + $x = '$WowheadPower.registerAchievement('.$id.', '.User::$localeId.",{\n"; $x .= "\tname_".User::$localeString.": '".Util::jsEscape($acv->getField('name', true))."',\n"; - $x .= "\ticon: '".$acv->getField('iconString')."',\n"; - $x .= "\ttooltip_".User::$localeString.': \''.$acv->renderTooltip()."'\n"; + $x .= "\ticon: '".Util::jsEscape($acv->getField('iconString'))."',\n"; + $x .= "\ttooltip_".User::$localeString.": '".$acv->renderTooltip()."'\n"; $x .= "});"; $smarty->saveCache($cacheKeyTooltip, $x); @@ -53,22 +53,25 @@ if (isset($_GET['power'])) // regular page if (!$smarty->loadCache($cacheKeyPage, $pageData)) { + $acv = new AchievementList(array(['id', $id])); if ($acv->error) - $smarty->notFound(Lang::$achievement['achievement']); + $smarty->notFound(Lang::$game['achievement']); - $pageData['path'] = []; - $pageData['title'] = [Util::ucfirst(Lang::$achievement['achievement'])]; + $pageData['path'] = [0, 9]; + $pageData['title'] = [Util::ucfirst(Lang::$game['achievement'])]; // create page title and path - $curCat = $acv->getField('category'); + $curCat = $acv->getField('category'); + $tmpPath = []; do { - $pageData['path'][] = $curCat; + $tmpPath[] = $curCat; $curCat = DB::Aowow()->SelectCell('SELECT parentCategory FROM ?_achievementcategory WHERE id = ?d', $curCat); } while ($curCat > 0); - $pageData['path'] = array_reverse(array_merge($pageData['path'], [9, 0])); + if (!empty($tmpPath)) + $pageData['path'] = array_merge($pageData['path'], array_reverse($tmpPath)); array_unshift($pageData['title'], $acv->getField('name', true)); @@ -370,20 +373,24 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) $smarty->saveCache($cacheKeyPage, $pageData); } +// menuId 9: Achievement g_initPath() +// tabId 0: Database g_initHeader() +$smarty->updatePageVars(array( + 'title' => implode(" - ", $pageData['title']), + 'path' => json_encode($pageData['path'], JSON_NUMERIC_CHECK), + 'tab' => 0, + 'type' => TYPE_ACHIEVEMENT, + 'typeId' => $id +)); -$vars = array( - 'title' => implode(" - ", $pageData['title']), - 'path' => "[".implode(", ", $pageData['path'])."]",// menuId 9: Achievement (g_initPath) - 'tab' => 0, // tabId 0: Database for g_initHeader($tab) - 'type' => TYPE_ACHIEVEMENT, - 'typeId' => $id, -); - -$smarty->updatePageVars($vars); $smarty->assign('community', CommunityContent::getAll(TYPE_ACHIEVEMENT, $id)); // comments, screenshots, videos $smarty->assign('lang', array_merge(Lang::$main, Lang::$game, Lang::$achievement)); $smarty->assign('lvData', $pageData); + +// Mysql query execution statistics $smarty->assign('mysql', DB::Aowow()->getStatistics()); + +// load the page $smarty->display('achievement.tpl'); -?> \ No newline at end of file +?> diff --git a/pages/achievements.php b/pages/achievements.php index d1913fe1..28b16efb 100644 --- a/pages/achievements.php +++ b/pages/achievements.php @@ -72,7 +72,7 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter)) $path[] = $cat['id']; $title[] = Util::localizedString($cat, 'name'); } - array_unshift($title, Util::ucFirst(Lang::$achievement['achievements'])); + array_unshift($title, Util::ucFirst(Lang::$game['achievements'])); } // fill g_items, g_titles, g_achievements diff --git a/pages/events.php b/pages/events.php index a46916d1..f440969f 100644 --- a/pages/events.php +++ b/pages/events.php @@ -53,7 +53,7 @@ if (!$smarty->loadCache($cacheKey, $pageData)) 'deps' => $deps, 'calendar' => false, // todo (med): fix it Felix! 'params' => array( - 'tabs' => '$myTabs' + // 'tabs' => '$myTabs' ) ); diff --git a/pages/item.php b/pages/item.php index 2fd5c458..80e70dad 100644 --- a/pages/item.php +++ b/pages/item.php @@ -4,20 +4,16 @@ if (!defined('AOWOW_REVISION')) die('illegal access'); -// require 'includes/game.php'; -// require 'includes/allquests.php'; -// require 'includes/allnpcs.php'; -// require 'includes/allobjects.php'; -// require 'includes/class.community.php'; // wo dont need those .. yet - -$id = intVal($pageParam); -$item = new ItemList(array(['i.entry', $id])); - -$cacheKeyPage = implode('_', [CACHETYPE_PAGE, TYPE_ITEM, $id, -1, User::$localeId]); - if (isset($_GET['xml'])) die('unsupported, as i do not see the point'); +require 'includes/class.community.php'; + +$id = intVal($pageParam); + +$cacheKeyPage = implode('_', [CACHETYPE_PAGE, TYPE_ITEM, $id, -1, User::$localeId]); + +// AowowPower-request if (isset($_GET['power'])) { header('Content-type: application/x-javascript; charsetUTF-8'); @@ -53,6 +49,7 @@ if (isset($_GET['power'])) // output json for tooltips if (!$smarty->loadCache($cacheKeyTooltip, $x)) { + $item = new ItemList(array(['i.entry', $id])); if ($item->error) die('$WowheadPower.registerItem(\''.$itemString.'\', '.User::$localeId.', {})'); @@ -69,19 +66,25 @@ if (isset($_GET['power'])) die($x); } -// didn't die... -// build regular page - -// v there be dragons v - -$cacheKey = generateCacheKey($id); - -if(!$smarty->loadCache($cacheKeyPage, $item)) +// regular page +if (!$smarty->loadCache($cacheKeyPage, $item)) { + $item = new ItemList(array(['i.entry', $id])); + if ($item->error) + $smarty->notFound(Lang::$game['item']); + + + + // not yet implemented -> chicken out + $smarty->error(); + + + unset($item); // Информация о вещи... $item = iteminfo($id, 1); + $path = [0, 0, $item['classs'], $item['subclass'], $item['type']]; // Поиск мобов с которых эта вещь лутится $drops_cr = drop('creature_loot_template', $item['entry']); @@ -803,25 +806,28 @@ if(!$smarty->loadCache($cacheKeyPage, $item)) $item['color'] = colorByQuality($item['quality']); - $smarty->saveCache($cacheKeyPage, $item); + $smarty->saveCache($cacheKeyPage, $pageData); } -$page = array( - 'Book' => $item['pagetext'] ? true : false, - 'Title' => $item['name'].' - '.$smarty->get_config_vars('Items'), +// menuId 0: Item g_initPath() +// tabId 0: Database g_initHeader() +$smarty->updatePageVars(array( + 'book' => $pageData['page']['pagetext'] ? true : false, + 'title' => implode(" - ", $pageData['title']), + 'path' => json_encode($pageData['path'], JSON_NUMERIC_CHECK), 'tab' => 0, - 'type' => 3, - 'typeid' => $item['entry'], - 'path' => path(0, 0, $item['classs'], $item['subclass'], $item['type']) -); + 'type' => TYPE_ITEM, + 'typeid' => $id +)); -$smarty->updatePageVars($page); +$smarty->assign('community', CommunityContent::getAll(TYPE_ITEM, $id)); // comments, screenshots, videos +$smarty->assign('lang', array_merge(Lang::$main, Lang::$game, Lang::$item, ['colon' => Lang::$colon])); +$smarty->assign('lvData', $pageData); -// Комментарии -$smarty->assign('community', Community::getAll($page['type'], $page['typeid'])); - -// Количество MySQL запросов +// Mysql query execution statistics $smarty->assign('mysql', $DB->getStatistics()); -$smarty->assign('item', $item); + +// load the page $smarty->display('item.tpl'); -?> \ No newline at end of file + +?> diff --git a/pages/itemsets.php b/pages/itemsets.php index 2472f394..5601aec3 100644 --- a/pages/itemsets.php +++ b/pages/itemsets.php @@ -15,6 +15,11 @@ if (!$smarty->loadCache($cacheKey, $pageData)) { $itemsets = new ItemsetList([], true); // class selection is via filter, nothing applies here + $pageData = array( + 'data' => $itemsets->getListviewData(), // listview content + 'params' => [] + ); + $itemsets->addGlobalsToJscript($pageData); // recreate form selection @@ -25,9 +30,6 @@ if (!$smarty->loadCache($cacheKey, $pageData)) if (isset($filter['cl'])) $path[] = $filter['cl']; - // listview content - $pageData['data'] = $itemsets->getListviewData(); - // create note if search limit was exceeded if ($itemsets->getMatches() > $AoWoWconf['sqlLimit']) { @@ -49,7 +51,7 @@ $page = array( 'path' => json_encode($path, JSON_NUMERIC_CHECK), 'reqJS' => array( array('path' => 'template/js/filters.js', 'conditional' => false), - array('path' => '?data=weight-presets', 'conditional' => false), + array('path' => '?data=weight-presets', 'conditional' => false), ) ); diff --git a/pages/npc.php b/pages/npc.php new file mode 100644 index 00000000..11553d05 --- /dev/null +++ b/pages/npc.php @@ -0,0 +1,491 @@ +loadCache($cacheKeyTooltip, $x)) + { + $npc = new CreatureList(array(['ct.entry', $id])); + if ($npc->error) + die('$WowheadPower.registerNpc(\''.$id.'\', '.User::$localeId.', {})'); + + $s = $npc->getSpawns(true); + + $x = '$WowheadPower.registerNpc('.$id.', '.User::$localeId.", {\n"; + $x .= "\tname_".User::$localeString.": '".Util::jsEscape($npc->getField('name', true))."',\n"; + $x .= "\ttooltip_".User::$localeString.': \''.$npc->renderTooltip()."',\n"; + $x .= "\tmap: ".($s ? '{zone: '.$s[0].', coords: {0:'.json_encode($s[1], JSON_NUMERIC_CHECK).'}' : '{}')."\n"; + $x .= "});"; + + $smarty->saveCache($cacheKeyTooltip, $x); + } + + die($x); +} + +// regular page +if (!$smarty->loadCache($cacheKeyPage, $pageData)) +{ + $npc = new CreatureList(array(['ct.entry', $id])); + if ($npc->error) + $smarty->notFound(Lang::$game['npc']); + + + + // not yet implemented -> chicken out + $smarty->error(); + + + + unset($npc); + + // Ищем NPC: + $npc = array(); + $path = [0, 4, $npc['type']]; + + $row = $DB->selectRow(' + SELECT + ?#, c.entry, c.name, + { + l.name_loc'.$_SESSION['locale'].' as `name_loc`, + l.subname_loc'.$_SESSION['locale'].' as `subname_loc`, + ?, + } + f.name_loc'.$_SESSION['locale'].' as `faction-name`, ft.factionID as `factionID`, + ((CASE exp WHEN 0 THEN mincls.basehp0 WHEN 1 THEN mincls.basehp1 WHEN 2 THEN mincls.basehp2 END)*Health_mod) AS minhealth, + ((CASE exp WHEN 0 THEN maxcls.basehp0 WHEN 1 THEN maxcls.basehp1 WHEN 2 THEN maxcls.basehp2 END)*Health_mod) AS maxhealth, + (mincls.basemana*Mana_mod) AS minmana, + (maxcls.basemana*Mana_mod) AS maxmana, + (maxcls.basearmor*Armor_mod) AS armor + FROM ?_factiontemplate ft, ?_factions f, creature_template c + LEFT JOIN creature_classlevelstats mincls ON mincls.level=minlevel AND mincls.class=unit_class + LEFT JOIN creature_classlevelstats maxcls ON maxcls.level=maxlevel AND maxcls.class=unit_class + { + LEFT JOIN (locales_creature l) + ON l.entry = c.entry AND ? + } + WHERE + c.entry = ? + AND ft.factiontemplateID = c.faction_A + AND f.factionID = ft.factionID + LIMIT 1 + ', + $npc_cols[1], + ($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP, + ($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP, + $id + ); + + if($row) + { + $npc = $row; + $npc['name'] = localizedName($row); + $npc['subname'] = localizedName($row, 'subname'); + if($npc['rank'] == 3) + { + $npc['minlevel'] = '??'; + $npc['maxlevel'] = '??'; + } + $npc['mindmg'] = round(($row['mindmg'] + $row['attackpower']) * $row['dmg_multiplier']); + $npc['maxdmg'] = round(($row['maxdmg'] + $row['attackpower']) * $row['dmg_multiplier']); + + $toDiv = array('minhealth', 'maxmana', 'minmana', 'maxhealth', 'armor', 'mindmg', 'maxdmg'); + // Разделяем на тысячи (ххххххххх => ххх,ххх,ххх) + foreach($toDiv as $e) + $npc[$e] = number_format($npc[$e]); + + $npc['rank'] = $smarty->get_config_vars('rank'.$npc['rank']); + // faction_A = faction_H + $npc['faction_num'] = $row['factionID']; + $npc['faction'] = $row['faction-name']; + // Деньги + $money = ($row['mingold']+$row['maxgold']) / 2; + $npc = array_merge($npc, money2coins($money)); + // Героик/нормал копия НПС + if($npc['difficulty_entry_1']) + { + // это нормал НПС, ищем героика + if($tmp = creatureinfo($npc['difficulty_entry_1'])) + { + $npc['heroic'] = array( + 'type' => 0, + 'entry' => $tmp['entry'], + 'name' => str_replace(LOCALE_HEROIC, '', $tmp['name']) + ); + + unset($tmp); + } + } + else + { + // А может быть героик НПС одним для нескольких нормалов? + // считаем что нет + $tmp = $DB->selectRow(' + SELECT c.entry, c.name + { + , l.name_loc?d as `name_loc` + } + FROM creature_template c + { + LEFT JOIN (locales_creature l) + ON l.entry = c.entry AND ? + } + WHERE + c.difficulty_entry_1 = ?d + LIMIT 1 + ', + ($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP, + ($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP, + $npc['entry'] + ); + if($tmp) + { + $npc['heroic'] = array( + 'type' => 1, + 'entry' => $tmp['entry'], + 'name' => localizedName($tmp) + ); + $npc['name'] = str_replace(' (1)', '', $npc['name']); + $normal_entry = $tmp['entry']; + unset($tmp); + } + } + // Дроп + $lootid=$row['lootid']; + $skinid=$row['skinloot']; + $pickpocketid=$row['pickpocketloot']; + // Используемые спеллы + $npc['ablities'] = array(); + $tmp = array(); + for($j=0;$j<=4;++$j) + { + if($row['spell'.$j] && !in_array($row['spell'.$j], $tmp)) + { + $tmp[] = $row['spell'.$j]; + if($data = spellinfo($row['spell'.$j], 0)) + { + if($data['name']) + $npc['abilities'][] = $data; + } + } + } + for($j=1;$j<4;$j++) + { + $tmp2 = $DB->select(' + SELECT action?d_param1 + FROM creature_ai_scripts + WHERE + creature_id=?d + AND action?d_type=11 + ', + $j, + $npc['entry'], + $j + ); + if($tmp2) + foreach($tmp2 as $i=>$tmp3) + if(!in_array($tmp2[$i]['action'.$j.'_param1'], $tmp)) + { + $tmp[] = $tmp2[$i]['action'.$j.'_param1']; + if($data = spellinfo($tmp2[$i]['action'.$j.'_param1'], 0)) + { + if($data['name']) + $npc['abilities'][] = $data; + } + } + } + if(!$npc['ablities']) + unset($npc['ablities']); + + // Обучает: + // Если это пет со способностью: + /* // Временно закомментировано + $row = $DB->selectRow(' + SELECT Spell1, Spell2, Spell3, Spell4 + FROM petcreateinfo_spell + WHERE + entry=?d + ', + $npc['entry'] + ); + if($row) + { + $npc['teaches'] = array(); + for($j=1;$j<=4;$j++) + if($row['Spell'.$j]) + for($k=1;$k<=3;$k++) + { + $spellrow = $DB->selectRow(' + SELECT ?#, spellID + FROM ?_spell, ?_spellicons + WHERE + spellID=(SELECT effect'.$k.'triggerspell FROM ?_spell WHERE spellID=?d AND (effect'.$k.'id IN (36,57))) + AND id=spellicon + LIMIT 1 + ', + $spell_cols[2], + $row['Spell'.$j] + ); + if($spellrow) + { + $num = count($npc['teaches']); + $npc['teaches'][$num] = array(); + $npc['teaches'][$num] = spellinfo2($spellrow); + } + } + } + unset ($row);*/ + + // Если это просто тренер + $teachspells = $DB->select(' + SELECT ?#, spellID + FROM npc_trainer, ?_spell, ?_spellicons + WHERE + ( + -entry IN (SELECT spell FROM npc_trainer WHERE entry = ?) + OR (entry = ? AND npc_trainer.spell > 0) + ) + AND spellID = npc_trainer.spell + AND id=spellicon + ', + $spell_cols[2], + $npc['entry'], + $npc['entry'] + ); + if($teachspells) + { + if(!(IsSet($npc['teaches']))) + $npc['teaches'] = array(); + foreach($teachspells as $teachspell) + { + $num = count($npc['teaches']); + $npc['teaches'][$num] = array(); + $npc['teaches'][$num] = spellinfo2($teachspell); + } + } + unset ($teachspells); + + // Продает: + $rows_s = $DB->select(' + SELECT ?#, i.entry, i.maxcount, n.`maxcount` as `drop-maxcount`, n.ExtendedCost + {, l.name_loc?d AS `name_loc`} + FROM npc_vendor n, ?_icons, item_template i + {LEFT JOIN (locales_item l) ON l.entry=i.entry AND ?d} + WHERE + n.entry=? + AND i.entry=n.item + AND id=i.displayid + ', + $item_cols[2], + ($_SESSION['locale'])? $_SESSION['locale']: DBSIMPLE_SKIP, + ($_SESSION['locale'])? 1: DBSIMPLE_SKIP, + $id + ); + if($rows_s) + { + $npc['sells'] = array(); + foreach($rows_s as $numRow=>$row) + { + $npc['sells'][$numRow] = array(); + $npc['sells'][$numRow] = iteminfo2($row); + $npc['sells'][$numRow]['maxcount'] = $row['drop-maxcount']; + $npc['sells'][$numRow]['cost'] = array(); + if($row['ExtendedCost']) + { + $extcost = $DB->selectRow('SELECT * FROM ?_item_extended_cost WHERE extendedcostID=?d LIMIT 1', abs($row['ExtendedCost'])); + if($extcost['reqhonorpoints']>0) + $npc['sells'][$numRow]['cost']['honor'] = (($npc['A']==1)? 1: -1) * $extcost['reqhonorpoints']; + if($extcost['reqarenapoints']>0) + $npc['sells'][$numRow]['cost']['arena'] = $extcost['reqarenapoints']; + $npc['sells'][$numRow]['cost']['items'] = array(); + for($j=1;$j<=5;$j++) + if(($extcost['reqitem'.$j]>0) and ($extcost['reqitemcount'.$j]>0)) + { + allitemsinfo($extcost['reqitem'.$j], 0); + $npc['sells'][$numRow]['cost']['items'][] = array('item' => $extcost['reqitem'.$j], 'count' => $extcost['reqitemcount'.$j]); + } + } + if($row['BuyPrice']>0) + $npc['sells'][$numRow]['cost']['money'] = $row['BuyPrice']; + } + unset ($row); + unset ($numRow); + unset ($extcost); + } + unset ($rows_s); + + // Дроп + if(!($npc['drop'] = loot('creature_loot_template', $lootid))) + unset ($npc['drop']); + + // Кожа + if(!($npc['skinning'] = loot('skinning_loot_template', $skinid))) + unset ($npc['skinning']); + + // Воруеццо + if(!($npc['pickpocketing'] = loot('pickpocketing_loot_template', $pickpocketid))) + unset ($npc['pickpocketing']); + + // Начиниают квесты... + $rows_qs = $DB->select(' + SELECT q.?# + FROM quest_template q + LEFT JOIN creature_questrelation c on q.id = c.quest + WHERE + c.id=? + ', + $quest_cols[2], + $id + ); + if($rows_qs) + { + $npc['starts'] = array(); + foreach($rows_qs as $numRow=>$row) { + $npc['starts'][] = GetQuestInfo($row, 0xFFFFFF); + } + } + unset ($rows_qs); + + // Начиниают event-only квесты... + $rows_qse = event_find(array('quest_creature_id' => $id)); + if($rows_qse) + { + if (!isset($npc['starts'])) + $npc['starts'] = array(); + foreach($rows_qse as $event) + foreach($event['creatures_quests_id'] as $ids) + $npc['starts'][] = GetDBQuestInfo($ids['quest'], 0xFFFFFF); + } + unset ($rows_qse); + + // Заканчивают квесты... +$rows_qe = $DB->select(' + SELECT q.?# + FROM quest_template q + LEFT JOIN creature_involvedrelation c on q.id = c.quest + WHERE + c.id=? + ', + $quest_cols[2], + $id + ); + if($rows_qe) + { + $npc['ends'] = array(); + foreach($rows_qe as $numRow=>$row) { + $npc['ends'][] = GetQuestInfo($row, 0xFFFFFF); + } + } + unset ($rows_qe); + + // Необходимы для квеста.. + $rows_qo = $DB->select(' + SELECT ?# + FROM quest_template + WHERE + RequiredNpcOrGo1=? + OR RequiredNpcOrGo2=? + OR RequiredNpcOrGo3=? + OR RequiredNpcOrGo4=? + ', + $quest_cols[2], + $id, $id, $id, $id + ); + if($rows_qo) + { + $npc['objectiveof'] = array(); + foreach($rows_qo as $numRow=>$row) + $npc['objectiveof'][] = GetQuestInfo($row, 0xFFFFFF); + } + unset ($rows_qo); + + // Цель критерии + $rows = $DB->select(' + SELECT a.id, a.faction, a.name_loc?d AS name, a.description_loc?d AS description, a.category, a.points, s.iconname, z.areatableID + FROM ?_spellicons s, ?_achievementcriteria c, ?_achievement a + LEFT JOIN (?_zones z) ON a.map != -1 AND a.map = z.mapID + WHERE + a.icon = s.id + AND a.id = c.refAchievement + AND c.type IN (?a) + AND c.value1 = ?d + GROUP BY a.id + ORDER BY a.name_loc?d + ', + $_SESSION['locale'], + $_SESSION['locale'], + array(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE), + $npc['entry'], + $_SESSION['locale'] + ); + if($rows) + { + $npc['criteria_of'] = array(); + foreach($rows as $row) + { + allachievementsinfo2($row['id']); + $npc['criteria_of'][] = achievementinfo2($row); + } + } + + // Положения созданий божих (для героик НПС не задана карта, юзаем из нормала): + if($normal_entry) + // мы - героик НПС, определяем позицию по нормалу + $npc['position'] = position($normal_entry, 'creature', 2); + else + // мы - нормал НПС или НПС без сложности + $npc['position'] = position($npc['entry'], 'creature', 1); + + // Исправить type, чтобы подсвечивались event-овые NPC + if ($npc['position']) + foreach ($npc['position'] as $z => $zone) + foreach ($zone['points'] as $p => $pos) + if ($pos['type'] == 0 && ($events = event_find(array('creature_guid' => $pos['guid'])))) + { + $names = array_select_key(event_name($events), 'name'); + $npc['position'][$z]['points'][$p]['type'] = 4; + $npc['position'][$z]['points'][$p]['events'] = implode(", ", $names); + } + + } + + $smarty->saveCache($cacheKeyPage, $pageData); +} + +// menuId 4: Npc g_initPath() +// tabId 0: Database g_initHeader() +$smarty->updatePageVars(array( + 'mapper' => true, + 'title' => implode(" - ", $pageData['title']), + 'path' => json_encode($pageData['path'], JSON_NUMERIC_CHECK), + 'tab' => 0, + 'type' => TYPE_NPC, + 'typeId' => $id +)); + +$smarty->assign('community', CommunityContent::getAll(TYPE_NPC, $id)); // comments, screenshots, videos +$smarty->assign('lang', array_merge(Lang::$main, Lang::$game, Lang::$npc, ['colon' => Lang::$colon])); +$smarty->assign('lvData', $pageData); + +// Mysql query execution statistics +$smarty->assign('mysql', $DB->getStatistics()); + +// load the page +$smarty->display('npc.tpl'); + +?> diff --git a/pages/quest.php b/pages/quest.php new file mode 100644 index 00000000..89ee60c8 --- /dev/null +++ b/pages/quest.php @@ -0,0 +1,622 @@ +loadCache($cacheKeyTooltip, $x)) + { + $quest = new QuestList(array(['qt.id', $id])); + if ($quest->error) + die('$WowheadPower.registerQuest(\''.$id.'\', '.User::$localeId.', {})'); + + $x = '$WowheadPower.registerQuest('.$id.', '.User::$localeId.", {\n"; + $x .= "\tname_".User::$localeString.": '".Util::jsEscape($quest->getField('Title', true))."',\n"; + $x .= "\ttooltip_".User::$localeString.': \''.$quest->renderTooltip()."'\n"; // daily: 1 ... not used in wowheadPower => omitted here + $x .= "});"; + + $smarty->saveCache($cacheKeyTooltip, $x); + } + + die($x); +} + +// regular page +if (!$smarty->loadCache($cacheKeyPage, $pageData)) +{ + $quest = new QuestList(array(['qt.id', $id])); + if ($quest->error) + $smarty->notFound(Lang::$game['quest']); + + + + // not yet implemented -> chicken out + $smarty->error(); + + + + unset($quest); + + // Основная инфа + $quest = GetDBQuestInfo($id, 0xFFFFFF); + $path = [0, 3]; // TODO + + /* ЦЕПОЧКА КВЕСТОВ */ + // Добавляем сам квест в цепочку + $quest['series'] = array( + array( + 'Id' => $quest['Id'], + 'Title' => $quest['Title'], + 'NextQuestIdChain' => $quest['NextQuestIdChain'] + ) + ); + // Квесты в цепочке до этого квеста + $tmp = $quest['series'][0]; + while($tmp) + { + $tmp = $DB->selectRow(' + SELECT q.Id, q.Title + {, l.Title_loc?d as Title_loc} + FROM quest_template q + {LEFT JOIN (locales_quest l) ON l.Id=q.Id AND ?d} + WHERE q.NextQuestIdChain=?d + LIMIT 1 + ', + ($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP, + ($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP, + $quest['series'][0]['Id'] + ); + if($tmp) + { + $tmp['Title'] = localizedName($tmp, 'Title'); + array_unshift($quest['series'], $tmp); + } + } + // Квесты в цепочке после этого квеста + $tmp = end($quest['series']); + while($tmp) + { + $tmp = $DB->selectRow(' + SELECT q.Id, q.Title, q.NextQuestIdChain + {, l.Title_loc?d as Title_loc} + FROM quest_template q + {LEFT JOIN (locales_quest l) ON l.Id=q.Id AND ?} + WHERE q.Id=?d + LIMIT 1 + ', + ($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP, + ($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP, + $quest['series'][count($quest['series'])-1]['NextQuestIdChain'] + ); + if($tmp) + { + $tmp['Title'] = localizedName($tmp, 'Title'); + array_push($quest['series'], $tmp); + } + } + unset($tmp); + if(count($quest['series'])<=1) + unset($quest['series']); + + + /* ДРУГИЕ КВЕСТЫ */ + // (после их нахождения проверяем их тайтлы на наличие локализации) + + + // Квесты, которые необходимо выполнить, что бы получить этот квест + if(!$quest['req'] = $DB->select(' + SELECT q.Id, q.Title, q.NextQuestIdChain + {, l.Title_loc?d as Title_loc} + FROM quest_template q + {LEFT JOIN (locales_quest l) ON l.Id=q.Id AND ?} + WHERE + (q.NextQuestId=?d AND q.ExclusiveGroup<0) + OR (q.Id=?d AND q.NextQuestIdChain<>?d) + LIMIT 20', + ($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP, ($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP, + $quest['Id'], $quest['PrevQuestId'], $quest['Id'] + ) + ) + unset($quest['req']); + else + $questItems[] = 'req'; + + // Квесты, которые становятся доступными, только после того как выполнен этот квест (необязательно только он) + if(!$quest['open'] = $DB->select(' + SELECT q.Id, q.Title + {, l.Title_loc?d as Title_loc} + FROM quest_template q + {LEFT JOIN (locales_quest l) ON l.Id=q.Id AND ?} + WHERE + (q.PrevQuestId=?d AND q.Id<>?d) + OR q.Id=?d + LIMIT 20', + ($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP, ($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP, + $quest['Id'], $quest['NextQuestIdChain'], $quest['NextQuestId'] + ) + ) + unset($quest['open']); + else + $questItems[] = 'open'; + + // Квесты, которые становятся недоступными после выполнения этого квеста + if($quest['ExclusiveGroup']>0) + if(!$quest['closes'] = $DB->select(' + SELECT q.Id, q.Title + {, l.Title_loc?d as Title_loc} + FROM quest_template q + {LEFT JOIN (locales_quest l) ON l.Id=q.Id AND ?} + WHERE + q.ExclusiveGroup=?d AND q.Id<>?d + LIMIT 20 + ', + ($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP, ($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP, + $quest['ExclusiveGroup'], $quest['Id'] + ) + ) + unset($quest['closes']); + else + $questItems[] = 'closes'; + + // Требует выполнения одного из квестов, на выбор: + if(!$quest['reqone'] = $DB->select(' + SELECT q.Id, q.Title + {, l.Title_loc?d as Title_loc} + FROM quest_template q + {LEFT JOIN (locales_quest l) ON l.Id=q.Id AND ?} + WHERE + q.ExclusiveGroup>0 AND q.NextQuestId=?d + LIMIT 20 + ', + ($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP, ($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP, + $quest['Id'] + ) + ) + unset($quest['reqone']); + else + $questItems[] = 'reqone'; + + // Квесты, которые доступны, только во время выполнения этого квеста + if(!$quest['enables'] = $DB->select(' + SELECT q.Id, q.Title + {, l.Title_loc?d as Title_loc} + FROM quest_template q + {LEFT JOIN (locales_quest l) ON l.Id=q.Id AND ?} + WHERE q.PrevQuestId=?d + LIMIT 20 + ', + ($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP, ($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP, + -$quest['Id'] + ) + ) + unset($quest['enables']); + else + $questItems[] = 'enables'; + + // Квесты, во время выполнения которых доступен этот квест + if($quest['PrevQuestId']<0) + if(!$quest['enabledby'] = $DB->select(' + SELECT q.Id, q.Title + {, l.Title_loc?d as Title_loc} + FROM quest_template q + {LEFT JOIN (locales_quest l) ON l.Id=q.Id AND ?} + WHERE q.Id=?d + LIMIT 20 + ', + ($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP, ($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP, + -$quest['PrevQuestId'] + ) + ) + unset($quest['enabledby']); + else + $questItems[] = 'enabledby'; + + // Теперь локализуем все тайтлы квестов + if($questItems) + foreach($questItems as $item) + foreach($quest[$item] as $i => $x) + $quest[$item][$i]['Title'] = localizedName($quest[$item][$i], 'Title'); + + + + /* НАГРАДЫ И ТРЕБОВАНИЯ */ + + if($quest['RequiredSkillPoints']>0 && $quest['SkillOrClassMask']>0) + { + // Требуемый уровень скилла, что бы получить квест + /* + $skills = array( + -264 => 197, // Tailoring + -182 => 165, // Leatherworking + -24 => 182, // Herbalism + -101 => 356, // Fishing + -324 => 129, // First Aid + -201 => 202, // Engineering + -304 => 185, // Cooking + -121 => 164, // Blacksmithing + -181 => 171 // Alchemy + ); + */ + + // TODO: skill localization + $quest['reqskill'] = array( + 'name' => $DB->selectCell('SELECT name_loc'.$_SESSION['locale'].' FROM ?_skill WHERE skillID=?d LIMIT 1',$quest['SkillOrClassMask']), + 'value' => $quest['RequiredSkillPoints'] + ); + } + elseif($quest['SkillOrClassMask']<0) + { + $s = array(); + foreach($classes as $i => $class) + if (intval(-$quest['SkillOrClassMask'])==$i) + $s[] = $class; + + if (!count($s) == 0) + // Требуемый класс, что бы получить квест + $quest['reqclass'] = implode(", ", $s); + } + + // Требуемые отношения с фракциями, что бы начать квест + if($quest['RequiredMinRepFaction']) + $quest['RequiredMinRep'] = array( + 'name' => $DB->selectCell('SELECT name_loc'.$_SESSION['locale'].' FROM ?_factions WHERE factionID=?d LIMIT 1', $quest['RequiredMinRepFaction']), + 'entry' => $quest['RequiredMinRepFaction'], + 'value' => reputations($quest['RequiredMinRepValue']) + ); + if($quest['RequiredMaxRepFaction']) + $quest['RequiredMaxRep'] = array( + 'name' => $DB->selectCell('SELECT name_loc'.$_SESSION['locale'].' FROM ?_factions WHERE factionID=?d LIMIT 1', $quest['RequiredMaxRepFaction']), + 'entry' => $quest['RequiredMaxRepFaction'], + 'value' => reputations($quest['RequiredMaxRepValue']) + ); + + // Спеллы не требуют локализации, их инфа берется из базы + // Хранить в базе все локализации - задачка на будующее + + // Спелл, кастуемый на игрока в начале квеста + if($quest['SourceSpell']) + { + $tmp = $DB->selectRow(' + SELECT ?#, s.spellname_loc'.$_SESSION['locale'].' + FROM ?_spell s, ?_spellicons si + WHERE + s.spellID=?d + AND si.id=s.spellicon + LIMIT 1', + $spell_cols[0], + $quest['SourceSpell'] + ); + if($tmp) + { + $quest['SourceSpell'] = array( + 'name' => $tmp['spellname_loc'.$_SESSION['locale']], + 'entry' => $tmp['spellID']); + allspellsinfo2($tmp); + } + unset($tmp); + } + + // Итем, выдаваемый игроку в начале квеста + if($quest['SourceItemId']) + { + $quest['SourceItemId'] = iteminfo($quest['SourceItemId']); + $quest['SourceItemId']['SourceItemCount'] = $quest['SourceItemCount']; + } + + // Дополнительная информация о квесте (флаги, повторяемость, скрипты) + $quest['flagsdetails'] = GetFlagsDetails($quest); + if (!$quest['flagsdetails']) + unset($quest['flagsdetails']); + + // Спелл, кастуемый на игрока в награду за выполнение + if($quest['RewardSpellCast']>0 || $quest['RewardSpell']>0) + { + $tmp = $DB->SelectRow(' + SELECT ?#, s.spellname_loc'.$_SESSION['locale'].' + FROM ?_spell s, ?_spellicons si + WHERE + s.spellID=?d + AND si.id=s.spellicon + LIMIT 1', + $spell_cols[0], + $quest['RewardSpell']>0?$quest['RewardSpell']:$quest['RewardSpellCast'] + ); + if($tmp) + { + $quest['spellreward'] = array( + 'name' => $tmp['spellname_loc'.$_SESSION['locale']], + 'entry' => $tmp['spellID'], + 'realentry' => $quest['RewardSpellCast']>0 ? $quest['RewardSpellCast'] : $quest['RewardSpell']); + allspellsinfo2($tmp); + } + unset($tmp); + } + + // Создания, необходимые для квеста + //$quest['creaturereqs'] = array(); + //$quest['objectreqs'] = array(); + $quest['coreqs'] = array(); + for($i=0;$i<=4;++$i) + { + //echo $quest['ReqCreatureOrGOCount'.$i].'
'; + if($quest['RequiredNpcOrGo'.$i] != 0 && $quest['RequiredNpcOrGoCount'.$i] != 0) + { + if($quest['RequiredNpcOrGo'.$i] > 0) + { + // Необходимо какое-либо взамодействие с созданием + $quest['coreqs'][$i] = array_merge( + creatureinfo($quest['RequiredNpcOrGo'.$i]), + array('req_type' => 'npc') + ); + } + else + { + // необходимо какое-то взаимодействие с объектом + $quest['coreqs'][$i] = array_merge( + objectinfo(-$quest['RequiredNpcOrGo'.$i]), + array('req_type' => 'object') + ); + } + // Количество + $quest['coreqs'][$i]['count'] = $quest['RequiredNpcOrGoCount'.$i]; + // Спелл + if($quest['RequiredSpellCast'.$i]) + $quest['coreqs'][$i]['spell'] = array( + 'name' => $DB->selectCell('SELECT spellname_loc'.$_SESSION['locale'].' FROM ?_spell WHERE spellid=?d LIMIT 1', $quest['RequiredSpellCast'.$i]), + 'entry' => $quest['RequiredSpellCast'.$i] + ); + } + } + if(!$quest['coreqs']) + unset($quest['coreqs']); + + // Вещи, необходимые для квеста + $quest['itemreqs'] = array(); + for($i=0;$i<=4;++$i) + { + if($quest['RequiredItemId'.$i]!=0 && $quest['RequiredItemCount'.$i]!=0) + $quest['itemreqs'][] = array_merge(iteminfo($quest['RequiredItemId'.$i]), array('count' => $quest['RequiredItemCount'.$i])); + } + if(!$quest['itemreqs']) + unset($quest['itemreqs']); + + // Фракции необходимые для квеста + if($quest['RepObjectiveFaction']>0) + { + $quest['factionreq'] = array( + 'name' => $DB->selectCell('SELECT name_loc'.$_SESSION['locale'].' FROM ?_factions WHERE factionID=?d LIMIT 1', $quest['RepObjectiveFaction']), + 'entry' => $quest['RepObjectiveFaction'], + 'value' => reputations($quest['RepObjectiveValue']) + ); + } + + /* КВЕСТГИВЕРЫ И КВЕСТТЕЙКЕРЫ */ + + // КВЕСТГИВЕРЫ + // НПС + $rows = $DB->select(' + SELECT c.entry, c.name, A, H + {, l.name_loc?d AS name_loc} + FROM creature_questrelation q, ?_factiontemplate, creature_template c + {LEFT JOIN (locales_creature l) ON l.entry=c.entry AND ?} + WHERE + q.quest=?d + AND c.entry=q.id + AND factiontemplateID=c.faction_A + ', + ($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP, + ($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP, + $quest['Id'] + ); + if($rows) + { + foreach($rows as $tmp) + { + $tmp['name'] = localizedName($tmp); + if($tmp['A'] == -1 && $tmp['H'] == 1) + $tmp['side'] = 'horde'; + elseif($tmp['A'] == 1 && $tmp['H'] == -1) + $tmp['side'] = 'alliance'; + $quest['start'][] = array_merge($tmp, array('type' => 'npc')); + } + } + unset($rows); + + // НПС-ивентовые + $rows = event_find(array('quest_id' => $quest['Id'])); + if ($rows) + { + foreach ($rows as $event) + foreach ($event['creatures_quests_id'] as $ids) + if ($ids['quest'] == $quest['Id']) + { + $tmp = creatureinfo($ids['creature']); + if($tmp['react'] == '-1,1') + $tmp['side'] = 'horde'; + elseif($tmp['react'] == '1,-1') + $tmp['side'] = 'alliance'; + $tmp['type'] = 'npc'; + $tmp['event'] = $event['entry']; + $quest['start'][] = $tmp; + } + } + unset($rows); + + // ГО + $rows = $DB->select(' + SELECT g.entry, g.name + {, l.name_loc?d AS name_loc} + FROM gameobject_questrelation q, gameobject_template g + {LEFT JOIN (locales_gameobject l) ON l.entry = g.entry AND ?} + WHERE + q.quest=?d + AND g.entry=q.id + ', + ($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP, + ($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP, + $quest['Id'] + ); + if($rows) + { + foreach($rows as $tmp) + { + $tmp['name'] = localizedName($tmp); + $quest['start'][] = array_merge($tmp, array('type' => 'object')); + } + } + unset($rows); + + // итем + $rows = $DB->select(' + SELECT i.name, i.entry, i.quality, LOWER(a.iconname) AS iconname + {, l.name_loc?d AS name_loc} + FROM ?_icons a, item_template i + {LEFT JOIN (locales_item l) ON l.entry=i.entry AND ?} + WHERE + startquest = ?d + AND id = displayid + ', + ($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP, + ($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP, + $quest['Id'] + ); + if($rows) + { + foreach($rows as $tmp) + { + $tmp['name'] = localizedName($tmp); + $quest['start'][] = array_merge($tmp, array('type' => 'item')); + } + } + unset($rows); + + // КВЕСТТЕЙКЕРЫ + // НПС + $rows = $DB->select(' + SELECT c.entry, c.name, A, H + {, l.name_loc?d AS name_loc} + FROM creature_involvedrelation q, ?_factiontemplate, creature_template c + {LEFT JOIN (locales_creature l) ON l.entry=c.entry AND ?} + WHERE + q.quest=?d + AND c.entry=q.id + AND factiontemplateID=c.faction_A + ', + ($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP, + ($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP, + $quest['Id'] + ); + if($rows) + { + foreach($rows as $tmp) + { + $tmp['name'] = localizedName($tmp); + if($tmp['A'] == -1 && $tmp['H'] == 1) + $tmp['side'] = 'horde'; + elseif($tmp['A'] == 1 && $tmp['H'] == -1) + $tmp['side'] = 'alliance'; + $quest['end'][] = array_merge($tmp, array('type' => 'npc')); + } + } + unset($rows); + + // ГО + $rows = $DB->select(' + SELECT g.entry, g.name + {, l.name_loc?d AS name_loc} + FROM gameobject_involvedrelation q, gameobject_template g + {LEFT JOIN (locales_gameobject l) ON l.entry = g.entry AND ?} + WHERE + q.quest=?d + AND g.entry=q.id + ', + ($_SESSION['locale']>0)? $_SESSION['locale']: DBSIMPLE_SKIP, + ($_SESSION['locale']>0)? 1: DBSIMPLE_SKIP, + $quest['Id'] + ); + if($rows) + { + foreach($rows as $tmp) + { + $tmp['name'] = localizedName($tmp); + $quest['end'][] = array_merge($tmp, array('type' => 'object')); + } + } + unset($rows); + + // Цель критерии + $rows = $DB->select(' + SELECT a.id, a.faction, a.name_loc?d AS name, a.description_loc?d AS description, a.category, a.points, s.iconname, z.areatableID + FROM ?_spellicons s, ?_achievementcriteria c, ?_achievement a + LEFT JOIN (?_zones z) ON a.map != -1 AND a.map = z.mapID + WHERE + a.icon = s.id + AND a.id = c.refAchievement + AND c.type IN (?a) + AND c.value1 = ?d + GROUP BY a.id + ORDER BY a.name_loc?d + ', + $_SESSION['locale'], + $_SESSION['locale'], + array(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST), + $quest['Id'], + $_SESSION['locale'] + ); + if($rows) + { + $quest['criteria_of'] = array(); + foreach($rows as $row) + { + allachievementsinfo2($row['id']); + $quest['criteria_of'][] = achievementinfo2($row); + } + } + + // Награды и благодарности, присылаемые почтой + if ($quest['RewardMailTemplateId']) + { + if(!($quest['mailrewards'] = loot('mail_loot_template', $quest['RewardMailTemplateId']))) + unset ($quest['mailrewards']); + } + if ($quest['RewardMailDelay']) + $quest['maildelay'] = sec_to_time($quest['RewardMailDelay']); + + $smarty->saveCache($cacheKeyPage, $pageData); +} + +// menuId 3: Quest g_initPath() +// tabId 0: Database g_initHeader() +$smarty->updatePageVars(array( + 'title' => implode(" - ", $pageData['title']), + 'path' => json_encode($pageData['path'], JSON_NUMERIC_CHECK), + 'tab' => 0, + 'type' => TYPE_QUEST, + 'typeId' => $id +)); + +$smarty->assign('community', CommunityContent::getAll(TYPE_QUEST, $id)); // comments, screenshots, videos +$smarty->assign('lang', array_merge(Lang::$main, Lang::$game, Lang::$quest, ['colon' => Lang::$colon])); +$smarty->assign('lvData', $pageData); + +// Mysql query execution statistics +$smarty->assign('mysql', $DB->getStatistics()); + +// load the page +$smarty->display('quest.tpl'); + +?> diff --git a/pages/spell.php b/pages/spell.php index efc9f373..dcedcd29 100644 --- a/pages/spell.php +++ b/pages/spell.php @@ -4,13 +4,14 @@ if (!defined('AOWOW_REVISION')) die('illegal access'); -require 'includes/class.community.php'; // not needed .. yet +require 'includes/class.community.php'; -$id = intVal($pageParam); +$id = intVal($pageParam); $cacheKeyPage = implode('_', [CACHETYPE_PAGE, TYPE_SPELL, $id, -1, User::$localeId]); $cacheKeyTooltip = implode('_', [CACHETYPE_TOOLTIP, TYPE_SPELL, $id, -1, User::$localeId]); +// AowowPower-request if (isset($_GET['power'])) { header('Content-type: application/x-javascript; charsetUTF-8'); @@ -20,7 +21,6 @@ if (isset($_GET['power'])) if (!$smarty->loadCache($cacheKeyTooltip, $x)) { $spell = new SpellList(array(['s.id', $id])); - if ($spell->error) die('$WowheadPower.registerSpell('.$id.', '.User::$localeId.', {});'); @@ -42,6 +42,7 @@ if (isset($_GET['power'])) die($x); } +// regular page if (!$smarty->loadCache($cacheKeyPage, $pageData)) { $spell = new SpellList(array(['s.id', $id])); @@ -711,12 +712,14 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) $smarty->saveCache($cacheKeyPage, $pageData); } +// menuId 1: Spell g_initPath() +// tabId 0: Database g_initHeader() $smarty->updatePageVars(array( - 'title' => implode(" - ", $pageData['title']), - 'path' => "[".implode(", ", $pageData['path'])."]", - 'tab' => 0, // for g_initHeader($tab) - 'type' => TYPE_SPELL, - 'typeId' => $id, + 'title' => implode(" - ", $pageData['title']), + 'path' => json_encode($pageData['path'], JSON_NUMERIC_CHECK), + 'tab' => 0, + 'type' => TYPE_SPELL, + 'typeId' => $id )); $smarty->assign('community', CommunityContent::getAll(TYPE_SPELL, $id)); // comments, screenshots, videos diff --git a/pages/zones.php b/pages/zones.php index ee8672fe..c68ff87f 100644 --- a/pages/zones.php +++ b/pages/zones.php @@ -13,6 +13,7 @@ $validCats = array( 1 => true, 2 => [0, 1, 2], 3 => [0, 1, 2], + 4 => true, 6 => true, 8 => true, 9 => true, diff --git a/setup/tools/dataset-assembler/enchants.php b/setup/tools/dataset-assembler/enchants.php index 40e3eafa..99705754 100644 --- a/setup/tools/dataset-assembler/enchants.php +++ b/setup/tools/dataset-assembler/enchants.php @@ -132,9 +132,9 @@ if (!defined('AOWOW_REVISION')) $ench['jsonequip']['reqlevel'] = $enchant['requiredLevel']; // check if the spell has an entry in skill_line_ability -> Source:Profession - if ($skill = DB::Aowow()->SelectCell('SELECT skillId FROM ?_skill_line_ability WHERE spellId = ?d', $enchantSpells->id)) + if ($skill = DB::Aowow()->SelectCell('SELECT skillLineId FROM dbc.skillLineAbility WHERE spellId = ?d', $enchantSpells->id)) { - $ench['name'][] = Util::jsEscape($enchantSpells->getField('name', true))); + $ench['name'][] = $enchantSpells->getField('name', true); $ench['source'][] = $enchantSpells->id; $ench['skill'] = $skill; $ench['slots'][] = $slot; @@ -144,10 +144,10 @@ if (!defined('AOWOW_REVISION')) if (!isset($castItems[$enchantSpells->id])) $castItems[$enchantSpells->id] = new ItemList([['spellid_1', $enchantSpells->id], ['name', 'Scroll of Enchant%', '!']]); // do not reuse enchantment scrolls - $cI &= $castItems[$enchantSpells->id]; // this construct is a bit .. unwieldy + $cI = &$castItems[$enchantSpells->id]; // this construct is a bit .. unwieldy while ($cI->iterate()) { - $ench['name'][] = Util::jsEscape($cI->getField('name', true)); + $ench['name'][] = $cI->getField('name', true); $ench['source'][] = -$cI->id; $ench['icon'] = strTolower($cI->getField('icon')); $ench['slots'][] = $slot;