diff --git a/pages/quest.php b/endpoints/quest/quest.php
similarity index 65%
rename from pages/quest.php
rename to endpoints/quest/quest.php
index dfc37210..305900d6 100644
--- a/pages/quest.php
+++ b/endpoints/quest/quest.php
@@ -6,85 +6,88 @@ if (!defined('AOWOW_REVISION'))
die('illegal access');
-// menuId 3: Quest g_initPath()
-// tabId 0: Database g_initHeader()
-class QuestPage extends GenericPage
+class QuestBaseResponse extends TemplateResponse implements ICache
{
- use TrDetailPage;
+ use TrDetailPage, TrCache;
- protected $objectiveList = [];
- protected $providedItem = [];
- protected $series = [];
- protected $gains = [];
- protected $mail = [];
- protected $rewards = [];
- protected $objectives = '';
- protected $details = '';
- protected $offerReward = '';
- protected $requestItems = '';
- protected $completed = '';
- protected $end = '';
- protected $suggestedPl = 1;
- protected $unavailable = false;
+ protected int $cacheType = CACHE_TYPE_PAGE;
- protected $type = Type::QUEST;
- protected $typeId = 0;
- protected $tpl = 'quest';
- protected $path = [0, 3];
- protected $tabId = 0;
- protected $mode = CACHE_TYPE_PAGE;
- protected $scripts = [[SC_JS_FILE, 'js/ShowOnMap.js'], [SC_CSS_FILE, 'css/Book.css']];
+ protected string $template = 'quest';
+ protected string $pageName = 'quest';
+ protected ?int $activeTab = parent::TAB_DATABASE;
+ protected array $breadcrumb = [0, 3];
- protected $_get = ['domain' => ['filter' => FILTER_CALLBACK, 'options' => 'Aowow\Locale::tryFromDomain']];
+ protected array $scripts = [[SC_JS_FILE, 'js/ShowOnMap.js']];
- private $powerTpl = '$WowheadPower.registerQuest(%d, %d, %s);';
+ public int $type = Type::QUEST;
+ public int $typeId = 0;
+ public array $objectiveList = [];
+ public ?IconElement $providedItem = null;
+ public array $mail = [];
+ public ?array $gains = null; // why array|null ? because destructuring an array with less elements than expected is an error, destructuring null just returns false
+ public ?array $rewards = null; // so " if ([$spells, $items, $choice, $money] = $this->rewards): " will either work or cleanly branch to else
+ public string $objectives = '';
+ public string $details = '';
+ public string $offerReward = '';
+ public string $requestItems = '';
+ public string $completed = '';
+ public string $end = '';
+ public int $suggestedPl = 1;
+ public bool $unavailable = false;
- public function __construct($pageCall, $id)
+ private QuestList $subject;
+
+ public function __construct(string $id)
{
- parent::__construct($pageCall, $id);
+ parent::__construct($id);
- // temp locale
- if ($this->mode == CACHE_TYPE_TOOLTIP && $this->_get['domain'])
- Lang::load($this->_get['domain']);
-
- $this->typeId = intVal($id);
+ $this->typeId = intVal($id);
+ $this->contribute = Type::getClassAttrib($this->type, 'contribute') ?? CONTRIBUTE_NONE;
+ }
+ protected function generate() : void
+ {
$this->subject = new QuestList(array(['id', $this->typeId]));
if ($this->subject->error)
- $this->notFound(Lang::game('quest'), Lang::quest('notFound'));
+ $this->generateNotFound(Lang::game('quest'), Lang::quest('notFound'));
- // may contain htmlesque tags
- $this->name = Lang::unescapeUISequences(Util::htmlEscape($this->subject->getField('name', true)), Lang::FMT_HTML);
- }
+ $this->h1 = Lang::unescapeUISequences(Util::htmlEscape($this->subject->getField('name', true)), Lang::FMT_HTML);
- protected function generatePath()
- {
- // recreate path
- $this->path[] = $this->subject->getField('cat2');
- if ($cat = $this->subject->getField('cat1'))
- {
- foreach (Game::$questSubCats as $parent => $children)
- if (in_array($cat, $children))
- $this->path[] = $parent;
+ $this->gPageInfo += array(
+ 'type' => $this->type,
+ 'typeId' => $this->typeId,
+ 'name' => Lang::unescapeUISequences($this->subject->getField('name', true), Lang::FMT_HTML)
+ );
- $this->path[] = $cat;
- }
- }
-
- protected function generateTitle()
- {
- // page title already escaped
- array_unshift($this->title, Lang::unescapeUISequences($this->subject->getField('name', true), Lang::FMT_RAW), Util::ucFirst(Lang::game('quest')));
- }
-
- protected function generateContent()
- {
$_level = $this->subject->getField('level');
$_minLevel = $this->subject->getField('minLevel');
$_flags = $this->subject->getField('flags');
$_specialFlags = $this->subject->getField('specialFlags');
$_side = ChrRace::sideFromMask($this->subject->getField('reqRaceMask'));
+
+ /*************/
+ /* Menu Path */
+ /*************/
+
+ $this->breadcrumb[] = $this->subject->getField('cat2');
+ if ($cat = $this->subject->getField('cat1'))
+ {
+ foreach (Game::$questSubCats as $parent => $children)
+ if (in_array($cat, $children))
+ $this->breadcrumb[] = $parent;
+
+ $this->breadcrumb[] = $cat;
+ }
+
+
+ /**************/
+ /* Page Title */
+ /**************/
+
+ array_unshift($this->title, Lang::unescapeUISequences($this->subject->getField('name', true), Lang::FMT_RAW), Util::ucFirst(Lang::game('quest')));
+
+
/***********/
/* Infobox */
/***********/
@@ -95,7 +98,7 @@ class QuestPage extends GenericPage
if ($_ = $this->subject->getField('eventId'))
{
$this->extendGlobalIds(Type::WORLDEVENT, $_);
- $infobox[] = Lang::game('eventShort').Lang::main('colon').'[event='.$_.']';
+ $infobox[] = Lang::game('eventShort', ['[event='.$_.']']);
}
// level
@@ -109,7 +112,7 @@ class QuestPage extends GenericPage
if ($_ = $this->subject->getField('maxLevel'))
$lvl .= ' - '.$_;
- $infobox[] = sprintf(Lang::game('reqLevel'), $lvl);
+ $infobox[] = Lang::game('reqLevel', [$lvl]);
}
// loremaster (i dearly hope those flags cover every case...)
@@ -128,10 +131,10 @@ class QuestPage extends GenericPage
case 0:
break;
case 1:
- $infobox[] = Lang::quest('loremaster').Lang::main('colon').'[achievement='.$loremaster->id.']';
+ $infobox[] = Lang::quest('loremaster').'[achievement='.$loremaster->id.']';
break;
default:
- $lm = Lang::quest('loremaster').Lang::main('colon').'[ul]';
+ $lm = Lang::quest('loremaster').'[ul]';
foreach ($loremaster->iterate() as $id => $__)
$lm .= '[li][achievement='.$id.'][/li]';
@@ -153,16 +156,15 @@ class QuestPage extends GenericPage
$_[] = Lang::quest('questInfo', $t);
if ($_)
- $infobox[] = Lang::game('type').Lang::main('colon').implode(' ', $_);
+ $infobox[] = Lang::game('type').implode(' ', $_);
// side
- $_ = Lang::main('side').Lang::main('colon');
- switch ($_side)
+ $infobox[] = Lang::main('side') . match ($this->subject->getField('faction'))
{
- case 3: $infobox[] = $_.Lang::game('si', 3); break;
- case 2: $infobox[] = $_.'[span class=icon-horde]'.Lang::game('si', 2).'[/span]'; break;
- case 1: $infobox[] = $_.'[span class=icon-alliance]'.Lang::game('si', 1).'[/span]'; break;
- }
+ SIDE_ALLIANCE => '[span class=icon-alliance]'.Lang::game('si', SIDE_ALLIANCE).'[/span]',
+ SIDE_HORDE => '[span class=icon-horde]'.Lang::game('si', SIDE_HORDE).'[/span]',
+ default => Lang::game('si', SIDE_BOTH) // 0, 3
+ };
$jsg = [];
// races
@@ -189,17 +191,17 @@ class QuestPage extends GenericPage
if ($_ = $this->subject->getField('reqSkillPoints'))
$sk .= ' ('.$_.')';
- $infobox[] = Lang::quest('profession').Lang::main('colon').$sk;
+ $infobox[] = Lang::quest('profession').$sk;
}
// timer
if ($_ = $this->subject->getField('timeLimit'))
- $infobox[] = Lang::quest('timer').Lang::main('colon').Util::formatTime($_ * 1000);
+ $infobox[] = Lang::quest('timer').Util::formatTime($_ * 1000);
- $startEnd = DB::Aowow()->select('SELECT * FROM ?_quests_startend WHERE questId = ?d', $this->typeId);
+ $startEnd = DB::Aowow()->select('SELECT * FROM ?_quests_startend WHERE `questId` = ?d', $this->typeId);
// start
- $start = '[icon name=quest_start'.($this->subject->isRepeatable() ? '_daily' : '').']'.Lang::event('start').Lang::main('colon').'[/icon]';
+ $start = '[icon name=quest_start'.($this->subject->isRepeatable() ? '_daily' : '').']'.Lang::event('start').'[/icon]';
$s = [];
foreach ($startEnd as $se)
{
@@ -214,7 +216,7 @@ class QuestPage extends GenericPage
$infobox[] = implode('[br]', $s);
// end
- $end = '[icon name=quest_end'.($this->subject->isRepeatable() ? '_daily' : '').']'.Lang::event('end').Lang::main('colon').'[/icon]';
+ $end = '[icon name=quest_end'.($this->subject->isRepeatable() ? '_daily' : '').']'.Lang::event('end').'[/icon]';
$e = [];
foreach ($startEnd as $se)
{
@@ -266,98 +268,13 @@ class QuestPage extends GenericPage
$_[] = '[color=r4]'.($_level + 3 + ceil(12 * $_level / MAX_LEVEL)).'[/color]';
if ($_)
- $infobox[] = Lang::game('difficulty').Lang::main('colon').implode('[small] [/small]', $_);
+ $infobox[] = Lang::game('difficulty').implode('[small] [/small]', $_);
}
- $this->infobox = '[ul][li]'.implode('[/li][li]', $infobox).'[/li][/ul]';
+ if ($infobox)
+ $this->infobox = new InfoboxMarkup($infobox, ['allow' => Markup::CLASS_STAFF, 'dbpage' => true], 'infobox-contents0');
- /**********/
- /* Series */
- /**********/
-
- // Assumption
- // a chain always ends in a single quest, but can have an arbitrary amount of quests leading into it.
- // so we fast forward to the last quest and go backwards from there.
-
- $lastQuestId = $this->subject->getField('nextQuestIdChain');
- while ($newLast = DB::Aowow()->selectCell('SELECT `nextQuestIdChain` FROM ?_quests WHERE `id` = ?d AND `id` <> `nextQuestIdChain`', $lastQuestId))
- $lastQuestId = $newLast;
-
- $end = DB::Aowow()->selectRow('SELECT `id`, `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8`, `reqRaceMask` FROM ?_quests WHERE `id` = ?d', $lastQuestId ?: $this->typeId);
- $chain = array(array(array( // series / step / quest
- 'side' => ChrRace::sideFromMask($end['reqRaceMask']),
- 'typeStr' => Type::getFileString(Type::QUEST),
- 'typeId' => $end['id'],
- 'name' => Util::htmlEscape(Lang::trimTextClean(Util::localizedString($end, 'name'), 40)),
- )));
-
- $prevStepIds = [$lastQuestId ?: $this->typeId];
- while ($prevQuests = DB::Aowow()->select('SELECT `id`, `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8`, `reqRaceMask` FROM ?_quests WHERE `nextQuestIdChain` IN (?a) AND `id` <> `nextQuestIdChain`', $prevStepIds))
- {
- $step = [];
- foreach ($prevQuests as $pQuest)
- $step[$pQuest['id']] = array(
- 'side' => ChrRace::sideFromMask($pQuest['reqRaceMask']),
- 'typeStr' => Type::getFileString(Type::QUEST),
- 'typeId' => $pQuest['id'],
- 'name' => Util::htmlEscape(Lang::trimTextClean(Util::localizedString($pQuest, 'name'), 40)),
- );
-
- $prevStepIds = array_keys($step);
- $chain[] = $step;
- }
-
- if (count($chain) > 1)
- $this->series[] = [array_reverse($chain), null];
-
-
- // todo (low): sensibly merge the following lists into 'series'
- $listGen = function($cnd)
- {
- $chain = [];
- $list = new QuestList($cnd);
- if ($list->error)
- return null;
-
- foreach ($list->iterate() as $id => $__)
- {
- $n = $list->getField('name', true);
- $chain[] = array(array(
- 'side' => ChrRace::sideFromMask($list->getField('reqRaceMask')),
- 'typeStr' => Type::getFileString(Type::QUEST),
- 'typeId' => $id,
- 'name' => Util::htmlEscape(Lang::trimTextClean($n, 40))
- ));
- }
-
- return $chain;
- };
-
- $extraLists = array(
- // Requires all of these quests (Quests that you must follow to get this quest)
- ['reqQ', array('OR', ['AND', ['nextQuestId', $this->typeId], ['exclusiveGroup', 0, '<']], ['AND', ['id', $this->subject->getField('prevQuestId')], ['nextQuestIdChain', $this->typeId, '!']])],
-
- // Requires one of these quests (Requires one of the quests to choose from)
- ['reqOneQ', array('OR', ['AND', ['exclusiveGroup', 0, '>'], ['nextQuestId', $this->typeId]], ['breadCrumbForQuestId', $this->typeId])],
-
- // Opens Quests (Quests that become available only after complete this quest (optionally only one))
- ['opensQ', array('OR', ['AND', ['prevQuestId', $this->typeId], ['id', $this->subject->getField('nextQuestIdChain'), '!']], ['id', $this->subject->getField('nextQuestId')], ['id', $this->subject->getField('breadcrumbForQuestId')])],
-
- // Closes Quests (Quests that become inaccessible after completing this quest)
- ['closesQ', array(['exclusiveGroup', 0, '>'], ['exclusiveGroup', $this->subject->getField('exclusiveGroup')], ['id', $this->typeId, '!'])],
-
- // During the quest available these quests (Quests that are available only at run time this quest)
- ['enablesQ', array(['prevQuestId', -$this->typeId])],
-
- // Requires an active quest (Quests during the execution of which is available on the quest)
- ['enabledByQ', array(['id', -$this->subject->getField('prevQuestId')])]
- );
-
- foreach ($extraLists as $el)
- if ($_ = $listGen($el[1]))
- $this->series[] = [$_, sprintf(Util::$dfnString, Lang::quest($el[0].'Desc'), Lang::quest($el[0]))];
-
/*******************/
/* Objectives List */
/*******************/
@@ -391,31 +308,45 @@ class QuestPage extends GenericPage
$providedRequired = false;
foreach ($olItems as $i => [$itemId, $qty, $provided])
{
- if (!$i || !$itemId || !in_array($itemId, $olItemData->getFoundIDs()))
+ if (!$i || !$itemId)
continue;
if ($provided)
$providedRequired = true;
- $this->objectiveList[] = array(
- 'typeStr' => Type::getFileString(Type::ITEM),
- 'id' => $itemId,
- 'name' => Lang::unescapeUISequences($olItemData->json[$itemId]['name'], Lang::FMT_HTML),
- 'qty' => $qty > 1 ? $qty : 0,
- 'quality' => 7 - $olItemData->json[$itemId]['quality'],
- 'extraText' => $provided ? ' ('.Lang::quest('provided').')' : ''
- );
+ if (!$olItemData->getEntry($itemId))
+ {
+ $this->objectiveList[] = [0, new IconElement(0, 0, Util::ucFirst(Lang::game('item')).' #'.$itemId, $qty > 1 ? $qty : '', extraText: $provided ? Lang::quest('provided') : null)];
+ continue;
+ }
+
+ $this->objectiveList[] = [0, new IconElement(
+ Type::ITEM,
+ $itemId,
+ Lang::unescapeUISequences($olItemData->json[$itemId]['name'], Lang::FMT_HTML),
+ num: $qty > 1 ? $qty : '',
+ quality: 7 - $olItemData->json[$itemId]['quality'],
+ size: IconElement::SIZE_SMALL,
+ element: 'iconlist-icon',
+ extraText: $provided ? Lang::quest('provided') : null
+ )];
}
// if providd item is not required by quest, list it below other requirements
- if (!$providedRequired && $olItems[0][0] && in_array($olItems[0][0], $olItemData->getFoundIDs()))
+ if (!$providedRequired && $olItems[0][0])
{
- $this->providedItem = array(
- 'id' => $olItems[0][0],
- 'name' => Lang::unescapeUISequences($olItemData->json[$olItems[0][0]]['name'], Lang::FMT_HTML),
- 'qty' => $olItems[0][1] > 1 ? $olItems[0][1] : 0,
- 'quality' => 7 - $olItemData->json[$olItems[0][0]]['quality']
- );
+ if (!$olItemData->getEntry($olItems[0][0]))
+ $this->providedItem = new IconElement(0, 0, Util::ucFirst(Lang::game('item')).' #'.$itemId, $olItems[0][1] > 1 ? $olItems[0][1] : '');
+ else
+ $this->providedItem = new IconElement(
+ Type::ITEM,
+ $olItems[0][0],
+ Lang::unescapeUISequences($olItemData->json[$olItems[0][0]]['name'], Lang::FMT_HTML),
+ num: $olItems[0][1] > 1 ? $olItems[0][1] : '',
+ quality: 7 - $olItemData->json[$olItems[0][0]]['quality'],
+ size: IconElement::SIZE_SMALL,
+ element: 'iconlist-icon'
+ );
}
}
@@ -449,24 +380,40 @@ class QuestPage extends GenericPage
$olNPCs[$p][2][$id] = $olNPCData->getField('name', true);
}
- foreach ($olNPCs as $i => $pair)
+ foreach ($olNPCs as $i => [$qty, $altText, $proxies])
{
- if (!$i || !in_array($i, $olNPCData->getFoundIDs()))
+ if (!$i)
continue;
- $ol = array(
- 'typeStr' => Type::getFileString(Type::NPC),
- 'id' => $i,
- 'name' => $pair[1] ?: Util::localizedString($olNPCData->getEntry($i), 'name'),
- 'qty' => $pair[0] > 1 ? $pair[0] : 0,
- 'extraText' => (($_specialFlags & QUEST_FLAG_SPECIAL_SPELLCAST) || $pair[1]) ? '' : ' '.Lang::achievement('slain'),
- 'proxy' => $pair[2]
- );
+ if ($proxies) // has proxies assigned, add yourself as another proxy
+ {
+ $proxies[$i] = Util::localizedString($olNPCData->getEntry($i), 'name');
- if ($pair[2]) // has proxies assigned, add yourself as another proxy
- $ol['proxy'][$i] = Util::localizedString($olNPCData->getEntry($i), 'name');
+ // split in two blocks for display
+ $proxies = array(
+ array_slice($proxies, 0, ceil(count($proxies) / 2), true),
+ array_slice($proxies, ceil(count($proxies) / 2), null, true)
+ );
- $this->objectiveList[] = $ol;
+ $this->objectiveList[] = [2, array(
+ 'id' => $i,
+ 'text' => ($altText ?: Util::localizedString($olNPCData->getEntry($i), 'name')) . ((($_specialFlags & QUEST_FLAG_SPECIAL_SPELLCAST) || $altText) ? '' : ' '.Lang::achievement('slain')),
+ 'qty' => $qty > 1 ? $qty : 0,
+ 'proxy' => array_filter($proxies)
+ )];
+ }
+ else if (!$olNPCData->getEntry($i))
+ $this->objectiveList[] = [0, new IconElement(0, 0, Util::ucFirst(Lang::game('npc')).' #'.$i, $qty > 1 ? $qty : '')];
+ else
+ $this->objectiveList[] = [0, new IconElement(
+ Type::NPC,
+ $i,
+ $altText ?: Util::localizedString($olNPCData->getEntry($i), 'name'),
+ $qty > 1 ? $qty : '',
+ size: IconElement::SIZE_SMALL,
+ element: 'iconlist-icon',
+ extraText: (($_specialFlags & QUEST_FLAG_SPECIAL_SPELLCAST) || $altText) ? '' : Lang::achievement('slain'),
+ )];
}
}
@@ -476,18 +423,22 @@ class QuestPage extends GenericPage
$olGOData = new GameObjectList(array(['id', $ids]));
$this->extendGlobalData($olGOData->getJSGlobals(GLOBALINFO_SELF));
- foreach ($olGOs as $i => $pair)
+ foreach ($olGOs as $i => [$qty, $altText])
{
- if (!$i || !in_array($i, $olGOData->getFoundIDs()))
+ if (!$i)
continue;
- $this->objectiveList[] = array(
- 'typeStr' => Type::getFileString(Type::OBJECT),
- 'id' => $i,
- 'name' => $pair[1] ?: Lang::unescapeUISequences(Util::localizedString($olGOData->getEntry($i), 'name'), Lang::FMT_HTML),
- 'qty' => $pair[0] > 1 ? $pair[0] : 0,
- 'extraText' => ''
- );
+ if (!$olGOData->getEntry($i))
+ $this->objectiveList[] = [0, new IconElement(0, 0, Util::ucFirst(Lang::game('object')).' #'.$i, $qty > 1 ? $qty : '')];
+ else
+ $this->objectiveList[] = [0, new IconElement(
+ Type::OBJECT,
+ $i,
+ $altText ?: Lang::unescapeUISequences(Util::localizedString($olGOData->getEntry($i), 'name'), Lang::FMT_HTML),
+ $qty > 1 ? $qty : '',
+ size: IconElement::SIZE_SMALL,
+ element: 'iconlist-icon',
+ )];
}
}
@@ -512,13 +463,14 @@ class QuestPage extends GenericPage
if (!$i || !in_array($i, $olFactionsData->getFoundIDs()))
continue;
- $this->objectiveList[] = array(
- 'typeStr' => Type::getFileString(Type::FACTION),
- 'id' => $i,
- 'name' => Util::localizedString($olFactionsData->getEntry($i), 'name'),
- 'qty' => sprintf(Util::$dfnString, $val.' '.Lang::achievement('points'), Lang::getReputationLevelForPoints($val)),
- 'extraText' => ''
- );
+ $this->objectiveList[] = [0, new IconElement(
+ Type::FACTION,
+ $i,
+ Util::localizedString($olFactionsData->getEntry($i), 'name'),
+ size: IconElement::SIZE_SMALL,
+ element: 'iconlist-icon',
+ extraText: sprintf(Util::$dfnString, $val.' '.Lang::achievement('points'), '('.Lang::getReputationLevelForPoints($val).')')
+ )];
}
}
@@ -526,29 +478,22 @@ class QuestPage extends GenericPage
if ($_ = $this->subject->getField('sourceSpellId'))
{
$this->extendGlobalIds(Type::SPELL, $_);
- $this->objectiveList[] = array(
- 'typeStr' => Type::getFileString(Type::SPELL),
- 'id' => $_,
- 'name' => SpellList::getName($_),
- 'qty' => 0,
- 'extraText' => ' ('.Lang::quest('provided').')'
- );
+ $this->objectiveList[] = [0, new IconElement(Type::SPELL, $_, SpellList::getName($_), extraText: Lang::quest('provided'), element: 'iconlist-icon')];
}
// required money
if ($this->subject->getField('rewardOrReqMoney') < 0)
- $this->objectiveList[] = ['text' => Lang::quest('reqMoney').Lang::main('colon').Util::formatMoney(abs($this->subject->getField('rewardOrReqMoney')))];
+ $this->objectiveList[] = [1, Lang::quest('reqMoney', [Util::formatMoney(abs($this->subject->getField('rewardOrReqMoney')))])];
// required pvp kills
if ($_ = $this->subject->getField('reqPlayerKills'))
- $this->objectiveList[] = ['text' => Lang::quest('playerSlain').' ('.$_.')'];
+ $this->objectiveList[] = [1, Lang::quest('playerSlain', [$_])];
+
/**********/
/* Mapper */
/**********/
- $this->addScript([SC_JS_FILE, '?data=zones']);
-
// gather points of interest
$mapNPCs = $mapGOs = []; // [typeId, start|end|objective, startItemId]
@@ -560,7 +505,7 @@ class QuestPage extends GenericPage
{
/*
todo (med): sanity check:
- there are loot templates that are absolute tosh, containing hundrets of random items (e.g. Peacebloom for Quest "The Horde Needs Peacebloom!")
+ there are loot templates that are absolute tosh, containing hundreds of random items (e.g. Peacebloom for Quest "The Horde Needs Peacebloom!")
even without these .. consider quests like "A Donation of Runecloth" .. oh my .....
should we...
.. display only a maximum of sources?
@@ -637,7 +582,7 @@ class QuestPage extends GenericPage
$mObjectives[$zoneId]['levels'][$floor][] = $processing($objId, $objData);
}
}
- };
+ };
// POI: start + end
@@ -674,10 +619,13 @@ class QuestPage extends GenericPage
if ($_specialFlags & QUEST_FLAG_SPECIAL_EXT_COMPLETE)
{
// areatrigger
- if ($atir = DB::Aowow()->selectCol('SELECT id FROM ?_areatrigger WHERE type = ?d AND quest = ?d', AT_TYPE_OBJECTIVE, $this->typeId))
+ if ($atir = DB::Aowow()->selectCol('SELECT `id` FROM ?_areatrigger WHERE `type` = ?d AND `quest` = ?d', AT_TYPE_OBJECTIVE, $this->typeId))
{
- if ($atSpawns = DB::AoWoW()->select('SELECT typeId AS ARRAY_KEY, posX, posY, floor, areaId FROM ?_spawns WHERE `type` = ?d AND `typeId` IN (?a)', Type::AREATRIGGER, $atir))
+ if ($atSpawns = DB::AoWoW()->select('SELECT `typeId` AS ARRAY_KEY, `posX`, `posY`, `floor`, `areaId` FROM ?_spawns WHERE `type` = ?d AND `typeId` IN (?a)', Type::AREATRIGGER, $atir))
{
+ if (User::isInGroup(U_GROUP_STAFF))
+ $endTextWrapper = '%s';
+
foreach ($atSpawns as $atId => $atsp)
{
$atSpawn = array (
@@ -705,7 +653,7 @@ class QuestPage extends GenericPage
}
}
// complete-spell
- else if ($endSpell = new SpellList(array('OR', ['AND', ['effect1Id', 16], ['effect1MiscValue', $this->typeId]], ['AND', ['effect2Id', 16], ['effect2MiscValue', $this->typeId]], ['AND', ['effect3Id', 16], ['effect3MiscValue', $this->typeId]])))
+ else if ($endSpell = new SpellList(array('OR', ['AND', ['effect1Id', SPELL_EFFECT_QUEST_COMPLETE], ['effect1MiscValue', $this->typeId]], ['AND', ['effect2Id', SPELL_EFFECT_QUEST_COMPLETE], ['effect2MiscValue', $this->typeId]], ['AND', ['effect3Id', SPELL_EFFECT_QUEST_COMPLETE], ['effect3MiscValue', $this->typeId]])))
if (!$endSpell->error)
$endTextWrapper = '%s';
}
@@ -901,24 +849,30 @@ class QuestPage extends GenericPage
}
}
- $this->map = $mObjectives ? array(
- 'mapperData' => [], // always empty
- 'data' => array(
- 'parent' => 'mapper-generic',
- 'objectives' => $mObjectives,
- 'zoneparent' => 'mapper-zone-generic',
- 'zones' => $mZones,
- 'missing' => count($mZones) > 1 || $hasStartEnd != 0x3 ? 1 : 0 // 0 if everything happens in one zone, else 1
- )
- ) : null;
+ if ($mObjectives)
+ {
+ $this->addDataLoader('zones');
+ $this->map = array(
+ array( // Mapper
+ 'parent' => 'mapper-generic',
+ 'objectives' => $mObjectives,
+ 'zoneparent' => 'mapper-zone-generic',
+ 'zones' => $mZones,
+ 'missing' => count($mZones) > 1 || $hasStartEnd != 0x3 ? 1 : 0 // 0 if everything happens in one zone, else 1
+ ),
+ new \StdClass(), // mapperData
+ null, // ShowOnMap
+ null // foundIn
+ );
+ }
/****************/
/* Main Content */
/****************/
+ $this->series = $this->createSeries($_side);
$this->gains = $this->createGains();
- $this->mail = $this->createMail($startEnd);
$this->rewards = $this->createRewards($_side);
$this->objectives = $this->subject->parseText('objectives', false);
$this->details = $this->subject->parseText('details', false);
@@ -939,36 +893,41 @@ class QuestPage extends GenericPage
)
);
+ if ($this->createMail($startEnd))
+ $this->addScript([SC_CSS_FILE, 'css/Book.css']);
+
// factionchange-equivalent
- if ($pendant = DB::World()->selectCell('SELECT IF(horde_id = ?d, alliance_id, -horde_id) FROM player_factionchange_quests WHERE alliance_id = ?d OR horde_id = ?d', $this->typeId, $this->typeId, $this->typeId))
+ if ($pendant = DB::World()->selectCell('SELECT IF(`horde_id` = ?d, `alliance_id`, -`horde_id`) FROM player_factionchange_quests WHERE `alliance_id` = ?d OR `horde_id` = ?d', $this->typeId, $this->typeId, $this->typeId))
{
$altQuest = new QuestList(array(['id', abs($pendant)]));
if (!$altQuest->error)
{
- $this->transfer = sprintf(
- Lang::quest('_transfer'),
+ $this->transfer = Lang::quest('_transfer', array(
$altQuest->id,
$altQuest->getField('name', true),
$pendant > 0 ? 'alliance' : 'horde',
- $pendant > 0 ? Lang::game('si', 1) : Lang::game('si', 2)
- );
+ $pendant > 0 ? Lang::game('si', SIDE_ALLIANCE) : Lang::game('si', SIDE_HORDE)
+ ));
}
}
+
/**************/
/* Extra Tabs */
/**************/
+ $this->lvTabs = new Tabs(['parent' => "\$\$WH.ge('tabs-generic')"], 'tabsRelated', true);
+
// tab: see also
$seeAlso = new QuestList(array(['name_loc'.Lang::getLocale()->value, '%'.Util::htmlEscape($this->subject->getField('name', true)).'%'], ['id', $this->typeId, '!']));
if (!$seeAlso->error)
{
$this->extendGlobalData($seeAlso->getJSGlobals());
- $this->lvTabs[] = [QuestList::$brickFile, array(
- 'data' => array_values($seeAlso->getListviewData()),
+ $this->lvTabs->addListviewTab(new Listview(array(
+ 'data' => $seeAlso->getListviewData(),
'name' => '$LANG.tab_seealso',
'id' => 'see-also'
- )];
+ ), QuestList::$brickFile));
}
// tab: criteria of
@@ -976,27 +935,27 @@ class QuestPage extends GenericPage
if (!$criteriaOf->error)
{
$this->extendGlobalData($criteriaOf->getJSGlobals());
- $this->lvTabs[] = [AchievementList::$brickFile, array(
- 'data' => array_values($criteriaOf->getListviewData()),
+ $this->lvTabs->addListviewTab(new Listview(array(
+ 'data' => $criteriaOf->getListviewData(),
'name' => '$LANG.tab_criteriaof',
'id' => 'criteria-of'
- )];
+ ), AchievementList::$brickFile));
}
// tab: spawning pool (for the swarm)
- if ($qp = DB::World()->selectCol('SELECT qpm2.questId FROM quest_pool_members qpm1 JOIN quest_pool_members qpm2 ON qpm1.poolId = qpm2.poolId WHERE qpm1.questId = ?d', $this->typeId))
+ if ($qp = DB::World()->selectCol('SELECT qpm2.`questId` FROM quest_pool_members qpm1 JOIN quest_pool_members qpm2 ON qpm1.`poolId` = qpm2.`poolId` WHERE qpm1.`questId` = ?d', $this->typeId))
{
- $max = DB::World()->selectCell('SELECT numActive FROM quest_pool_template qpt JOIN quest_pool_members qpm ON qpm.poolId = qpt.poolId WHERE qpm.questId = ?d', $this->typeId);
+ $max = DB::World()->selectCell('SELECT `numActive` FROM quest_pool_template qpt JOIN quest_pool_members qpm ON qpm.`poolId` = qpt.`poolId` WHERE qpm.`questId` = ?d', $this->typeId);
$pooledQuests = new QuestList(array(['id', $qp]));
if (!$pooledQuests->error)
{
$this->extendGlobalData($pooledQuests->getJSGlobals());
- $this->lvTabs[] = [QuestList::$brickFile, array(
- 'data' => array_values($pooledQuests->getListviewData()),
+ $this->lvTabs->addListviewTab(new Listview(array(
+ 'data' => $pooledQuests->getListviewData(),
'name' => 'Quest Pool',
'id' => 'quest-pool',
'note' => Lang::quest('questPoolDesc', [$max])
- )];
+ ), QuestList::$brickFile));
}
}
@@ -1015,27 +974,15 @@ class QuestPage extends GenericPage
if ($tab = $cnd->toListviewTab())
{
$this->extendGlobalData($cnd->getJsGlobals());
- $this->lvTabs[] = $tab;
- }
- }
-
- protected function generateTooltip()
- {
- $power = new \StdClass();
- if (!$this->subject->error)
- {
- $power->{'name_'.Lang::getLocale()->json()} = Lang::unescapeUISequences($this->subject->getField('name', true), Lang::FMT_RAW);
- $power->{'tooltip_'.Lang::getLocale()->json()} = $this->subject->renderTooltip();
- if ($this->subject->isDaily())
- $power->daily = 1;
+ $this->lvTabs->addDataTab(...$tab);
}
- return sprintf($this->powerTpl, $this->typeId, Lang::getLocale()->value, Util::toJSON($power, JSON_AOWOW_POWER));
+ parent::generate();
}
- private function createRewards($side)
+ private function createRewards(int $side) : ?array
{
- $rewards = [];
+ $rewards = [[], [], [], '']; // [spells, items, choice, money]
// moneyReward / maxLevelCompensation
$comp = $this->subject->getField('rewardMoneyMaxLevel');
@@ -1043,75 +990,68 @@ class QuestPage extends GenericPage
$realComp = max($comp, $questMoney);
if ($questMoney > 0)
{
- $rewards['money'] = Util::formatMoney($questMoney);
+ $rewards[3] = Util::formatMoney($questMoney);
if ($realComp > $questMoney)
- $rewards['money'] .= ' ' . sprintf(Lang::quest('expConvert'), Util::formatMoney($realComp), MAX_LEVEL);
+ $rewards[3] .= ' ' . Lang::quest('expConvert', [Util::formatMoney($realComp), MAX_LEVEL]);
}
else if ($questMoney <= 0 && $realComp > 0)
- $rewards['money'] = sprintf(Lang::quest('expConvert2'), Util::formatMoney($realComp), MAX_LEVEL);
+ $rewards[3] = Lang::quest('expConvert2', [Util::formatMoney($realComp), MAX_LEVEL]);
// itemChoices
if (!empty($this->subject->choices[$this->typeId][Type::ITEM]))
{
- $c = $this->subject->choices[$this->typeId][Type::ITEM];
- $choiceItems = new ItemList(array(['id', array_keys($c)]));
+ $choices = $this->subject->choices[$this->typeId][Type::ITEM];
+ $choiceItems = new ItemList(array(['id', array_keys($choices)]));
if (!$choiceItems->error)
{
$this->extendGlobalData($choiceItems->getJSGlobals());
- foreach ($choiceItems->Iterate() as $id => $__)
- {
- $rewards['choice'][] = array(
- 'typeStr' => Type::getFileString(Type::ITEM),
- 'id' => $id,
- 'name' => $choiceItems->getField('name', true),
- 'quality' => $choiceItems->getField('quality'),
- 'qty' => $c[$id],
- 'globalStr' => Type::getJSGlobalString(Type::ITEM)
- );
- }
+ foreach ($choices as $id => $num) // itr over $choices to preserve display order
+ if ($choiceItems->getEntry($id))
+ $rewards[2][] = new IconElement(
+ Type::ITEM,
+ $id,
+ Lang::unescapeUISequences($choiceItems->getField('name', true), Lang::FMT_HTML),
+ quality: $choiceItems->getField('quality'),
+ num: $num
+ );
}
}
// itemRewards
if (!empty($this->subject->rewards[$this->typeId][Type::ITEM]))
{
- $ri = $this->subject->rewards[$this->typeId][Type::ITEM];
- $rewItems = new ItemList(array(['id', array_keys($ri)]));
+ $reward = $this->subject->rewards[$this->typeId][Type::ITEM];
+ $rewItems = new ItemList(array(['id', array_keys($reward)]));
if (!$rewItems->error)
{
$this->extendGlobalData($rewItems->getJSGlobals());
- foreach ($rewItems->Iterate() as $id => $__)
- {
- $rewards['items'][] = array(
- 'typeStr' => Type::getFileString(Type::ITEM),
- 'id' => $id,
- 'name' => Lang::unescapeUISequences($rewItems->getField('name', true), Lang::FMT_HTML),
- 'quality' => $rewItems->getField('quality'),
- 'qty' => $ri[$id],
- 'globalStr' => Type::getJSGlobalString(Type::ITEM)
- );
- }
+ foreach ($reward as $id => $num) // itr over $reward to preserve display order
+ if ($rewItems->getEntry($id))
+ $rewards[1][] = new IconElement(
+ Type::ITEM,
+ $id,
+ Lang::unescapeUISequences($rewItems->getField('name', true), Lang::FMT_HTML),
+ quality: $rewItems->getField('quality'),
+ num: $num
+ );
}
}
if (!empty($this->subject->rewards[$this->typeId][Type::CURRENCY]))
{
- $rc = $this->subject->rewards[$this->typeId][Type::CURRENCY];
- $rewCurr = new CurrencyList(array(['id', array_keys($rc)]));
+ $currency = $this->subject->rewards[$this->typeId][Type::CURRENCY];
+ $rewCurr = new CurrencyList(array(['id', array_keys($currency)]));
if (!$rewCurr->error)
{
$this->extendGlobalData($rewCurr->getJSGlobals());
- foreach ($rewCurr->Iterate() as $id => $__)
- {
- $rewards['items'][] = array(
- 'typeStr' => Type::getFileString(Type::CURRENCY),
- 'id' => $id,
- 'name' => $rewCurr->getField('name', true),
- 'quality' => 1,
- 'qty' => $rc[$id] * ($side == 2 ? -1 : 1), // toggles the icon
- 'globalStr' => Type::getJSGlobalString(Type::CURRENCY)
+ foreach ($rewCurr->iterate() as $id => $__)
+ $rewards[1][] = new IconElement(
+ Type::CURRENCY,
+ $id,
+ $rewCurr->getField('name', true),
+ quality: ITEM_QUALITY_NORMAL,
+ num: $currency[$id] * ($side == SIDE_HORDE ? -1 : 1), // toggles the icon
);
- }
}
}
@@ -1133,18 +1073,14 @@ class QuestPage extends GenericPage
{
$extra = null;
if ($_ = $rewSpells->getEntry($displ))
- $extra = sprintf(Lang::quest('spellDisplayed'), $displ, Util::localizedString($_, 'name'));
+ $extra = Lang::quest('spellDisplayed', [$displ, Util::localizedString($_, 'name')]);
if ($_ = $rewSpells->getEntry($cast))
- {
- $rewards['spells']['extra'] = $extra;
- $rewards['spells']['cast'][] = array(
- 'typeStr' => Type::getFileString(Type::SPELL),
- 'id' => $cast,
- 'name' => Util::localizedString($_, 'name'),
- 'globalStr' => Type::getJSGlobalString(Type::SPELL)
+ $rewards[0] = array(
+ 'title' => Lang::quest('rewardAura'),
+ 'cast' => [new IconElement(Type::SPELL, $cast, Util::localizedString($_, 'name'))],
+ 'extra' => $extra
);
- }
}
else // if it has effect:learnSpell display the taught spell instead
{
@@ -1154,114 +1090,102 @@ class QuestPage extends GenericPage
foreach ($_ as $idx)
$teach[$rewSpells->getField('effect'.$idx.'TriggerSpell')] = $id;
- if ($_ = $rewSpells->getEntry($displ))
- {
- $rewards['spells']['extra'] = null;
- $rewards['spells'][$teach ? 'learn' : 'cast'][] = array(
- 'typeStr' => Type::getFileString(Type::SPELL),
- 'id' => $displ,
- 'name' => Util::localizedString($_, 'name'),
- 'globalStr' => Type::getJSGlobalString(Type::SPELL)
- );
- }
- else if (($_ = $rewSpells->getEntry($cast)) && !$teach)
- {
- $rewards['spells']['extra'] = null;
- $rewards['spells']['cast'][] = array(
- 'typeStr' => Type::getFileString(Type::SPELL),
- 'id' => $cast,
- 'name' => Util::localizedString($_, 'name'),
- 'globalStr' => Type::getJSGlobalString(Type::SPELL)
- );
- }
- else
+ if ($teach)
{
$taught = new SpellList(array(['id', array_keys($teach)]));
if (!$taught->error)
{
$this->extendGlobalData($taught->getJSGlobals());
- $rewards['spells']['extra'] = null;
+ $rewards[0] = ['cast' => [], 'extra' => null];
+
+ $isTradeSkill = 0;
foreach ($taught->iterate() as $id => $__)
{
- $rewards['spells']['learn'][] = array(
- 'typeStr' => Type::getFileString(Type::SPELL),
- 'id' => $id,
- 'name' => $taught->getField('name', true),
- 'globalStr' => Type::getJSGlobalString(Type::SPELL)
- );
+ $isTradeSkill |= array_intersect($taught->getField('skillLines'), array_merge(SKILLS_TRADE_PRIMARY, SKILLS_TRADE_SECONDARY)) ? 1 : 0;
+ $rewards[0]['cast'][] = new IconElement(Type::SPELL, $id, $taught->getField('name', true));
}
+
+ $rewards[0]['title'] = $isTradeSkill ? Lang::quest('rewardTradeSkill') : Lang::quest('rewardSpell');
}
}
- }
- }
-
- return $rewards;
- }
-
- private function createMail($startEnd)
- {
- $mail = [];
-
- if ($rmtId = $this->subject->getField('rewardMailTemplateId'))
- {
- $delay = $this->subject->getField('rewardMailDelay');
- $letter = DB::Aowow()->selectRow('SELECT * FROM ?_mails WHERE id = ?d', $rmtId);
-
- $mail = array(
- 'id' => $rmtId,
- 'delay' => $delay ? sprintf(Lang::mail('mailIn'), Util::formatTime($delay * 1000)) : null,
- 'sender' => null,
- 'attachments' => [],
- 'text' => $letter ? Util::parseHtmlText(Util::localizedString($letter, 'text')) : null,
- 'subject' => Util::parseHtmlText(Util::localizedString($letter, 'subject'))
- );
-
- $senderTypeId = 0;
- if ($_= DB::World()->selectCell('SELECT RewardMailSenderEntry FROM quest_mail_sender WHERE QuestId = ?d', $this->typeId))
- $senderTypeId = $_;
- else
- foreach ($startEnd as $se)
- if (($se['method'] & 0x2) && $se['type'] == Type::NPC)
- $senderTypeId = $se['typeId'];
-
- if ($ti = CreatureList::getName($senderTypeId))
- $mail['sender'] = sprintf(Lang::mail('mailBy'), $senderTypeId, $ti);
-
- // while mail attachemnts are handled as loot, it has no variance. Always 100% chance, always one item.
- $mailLoot = new Loot();
- if ($mailLoot->getByContainer(LOOT_MAIL, $rmtId))
- {
- $this->extendGlobalData($mailLoot->jsGlobals);
- foreach ($mailLoot->getResult() as $loot)
+ else if (($_ = $rewSpells->getEntry($displ)) || ($_ = $rewSpells->getEntry($cast)))
{
- $mail['attachments'][] = array(
- 'typeStr' => Type::getFileString(Type::ITEM),
- 'id' => $loot['id'],
- 'name' => substr($loot['name'], 1),
- 'quality' => 7 - $loot['name'][0],
- 'qty' => $loot['stack'][0],
- 'globalStr' => Type::getJSGlobalString(Type::ITEM)
+ $rewards[0] = array(
+ 'title' => Lang::quest('rewardAura'),
+ 'cast' => [new IconElement(Type::SPELL, $cast, Util::localizedString($_, 'name'))],
+ 'extra' => null
);
}
}
}
- return $mail;
+ if (!array_filter($rewards))
+ return null;
+
+ return $rewards;
}
- private function createGains()
+ private function createMail(array $startEnd) : bool
+ {
+ $rmtId = $this->subject->getField('rewardMailTemplateId');
+ if (!$rmtId)
+ return false;
+
+ $delay = $this->subject->getField('rewardMailDelay');
+ $letter = DB::Aowow()->selectRow('SELECT * FROM ?_mails WHERE `id` = ?d', $rmtId);
+
+ $this->mail = array(
+ 'attachments' => [],
+ 'text' => $letter ? Util::parseHtmlText(Util::localizedString($letter, 'text')) : null,
+ 'subject' => Util::parseHtmlText(Util::localizedString($letter, 'subject')),
+ 'header' => array(
+ $rmtId,
+ null,
+ $delay ? Lang::mail('mailIn', [Util::formatTime($delay * 1000)]) : null,
+ )
+ );
+
+ $senderTypeId = 0;
+ if ($_= DB::World()->selectCell('SELECT `RewardMailSenderEntry` FROM quest_mail_sender WHERE `QuestId` = ?d', $this->typeId))
+ $senderTypeId = $_;
+ else
+ foreach ($startEnd as $se)
+ if (($se['method'] & 0x2) && $se['type'] == Type::NPC)
+ $senderTypeId = $se['typeId'];
+
+ if ($ti = CreatureList::getName($senderTypeId))
+ $this->mail['header'][1] = Lang::mail('mailBy', [$senderTypeId, $ti]);
+
+ // while mail attachemnts are handled as loot, it has no variance. Always 100% chance, always one item.
+ $mailLoot = new Loot();
+ if ($mailLoot->getByContainer(LOOT_MAIL, $rmtId))
+ {
+ $this->extendGlobalData($mailLoot->jsGlobals);
+ foreach ($mailLoot->getResult() as $loot)
+ $this->mail['attachments'][] = new IconElement(Type::ITEM, $loot['id'], substr($loot['name'], 1), $loot['stack'][0], quality: 7 - $loot['name'][0]);
+ }
+
+ return true;
+ }
+
+ private function createGains() : ?array
{
$gains = [];
// xp
- if ($_ = $this->subject->getField('rewardXP'))
- $gains['xp'] = $_;
+ $gains[0] = $this->subject->getField('rewardXP');
// talent points
- if ($_ = $this->subject->getField('rewardTalents'))
- $gains['tp'] = $_;
+ $gains[3] = $this->subject->getField('rewardTalents');
+
+ // title
+ if ($tId = $this->subject->getField('rewardTitleId'))
+ $gains[2] = [$tId, (new TitleList(array(['id', $tId])))->getHtmlizedName()];
+ else
+ $gains[2] = null;
// reputation
+ $repGains = [];
for ($i = 1; $i < 6; $i++)
{
$fac = $this->subject->getField('rewardFactionId'.$i);
@@ -1275,32 +1199,114 @@ class QuestPage extends GenericPage
'name' => FactionList::getName($fac)
);
- if ($cuRates = DB::World()->selectRow('SELECT * FROM reputation_reward_rate WHERE faction = ?d', $fac))
+ if ($cuRates = DB::World()->selectRow('SELECT * FROM reputation_reward_rate WHERE `faction` = ?d', $fac))
{
- if ($dailyType = $this->subject->isDaily())
- {
- if ($dailyType == 1 && $cuRates['quest_daily_rate'] != 1.0)
- $rep['qty'][1] = $rep['qty'][0] * ($cuRates['quest_daily_rate'] - 1);
- else if ($dailyType == 2 && $cuRates['quest_weekly_rate'] != 1.0)
- $rep['qty'][1] = $rep['qty'][0] * ($cuRates['quest_weekly_rate'] - 1);
- else if ($dailyType == 3 && $cuRates['quest_monthly_rate'] != 1.0)
- $rep['qty'][1] = $rep['qty'][0] * ($cuRates['quest_monthly_rate'] - 1);
- }
- else if ($this->subject->isRepeatable() && $cuRates['quest_repeatable_rate'] != 1.0)
+ if ($this->subject->isRepeatable())
$rep['qty'][1] = $rep['qty'][0] * ($cuRates['quest_repeatable_rate'] - 1);
- else if ($cuRates['quest_rate'] != 1.0)
- $rep['qty'][1] = $rep['qty'][0] * ($cuRates['quest_rate'] - 1);
+ else
+ $rep['qty'][1] = $rep['qty'][0] * match ($this->subject->isDaily())
+ {
+ 1 => $cuRates['quest_daily_rate'] - 1,
+ 2 => $cuRates['quest_weekly_rate'] - 1,
+ 3 => $cuRates['quest_monthly_rate'] - 1,
+ default => $cuRates['quest_rate'] - 1
+ };
}
- $gains['rep'][] = $rep;
- }
+ if (User::isInGroup(U_GROUP_STAFF))
+ $rep['qty'][1] = $rep['qty'][0] . ($rep['qty'][1] ? $this->fmtStaffTip(($rep['qty'][1] > 0 ? '+' : '').$rep['qty'][1], Lang::faction('customRewRate')) : '');
+ else
+ $rep['qty'][1] += $rep['qty'][0];
- // title
- if ($_ = (new TitleList(array(['id', $this->subject->getField('rewardTitleId')])))->getHtmlizedName())
- $gains['title'] = $_;
+ $repGains[] = $rep;
+ }
+ $gains[1] = $repGains;
+
+ if (!array_filter($gains))
+ return null;
return $gains;
}
+
+ private function createSeries() : array
+ {
+ $series = [];
+
+ $makeSeriesItem = function (array $questData) : array
+ {
+ return array(
+ 'side' => ChrRace::sideFromMask($questData['reqRaceMask']),
+ 'typeStr' => Type::getFileString(Type::QUEST),
+ 'typeId' => $questData['id'],
+ 'name' => Util::htmlEscape(Lang::trimTextClean(Util::localizedString($questData, 'name'), 40)),
+ );
+ };
+
+ // Assumption
+ // a chain always ends in a single quest, but can have an arbitrary amount of quests leading into it.
+ // so we fast forward to the last quest and go backwards from there.
+
+ $lastQuestId = $this->subject->getField('nextQuestIdChain');
+ while ($newLast = DB::Aowow()->selectCell('SELECT `nextQuestIdChain` FROM ?_quests WHERE `id` = ?d AND `id` <> `nextQuestIdChain`', $lastQuestId))
+ $lastQuestId = $newLast;
+
+ $end = DB::Aowow()->selectRow('SELECT `id`, `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8`, `reqRaceMask` FROM ?_quests WHERE `id` = ?d', $lastQuestId ?: $this->typeId);
+ $chain = array(array($makeSeriesItem($end))); // series / step / quest
+
+ $prevStepIds = [$lastQuestId ?: $this->typeId];
+ while ($prevQuests = DB::Aowow()->select('SELECT `id`, `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8`, `reqRaceMask` FROM ?_quests WHERE `nextQuestIdChain` IN (?a) AND `id` <> `nextQuestIdChain`', $prevStepIds))
+ {
+ $step = [];
+ foreach ($prevQuests as $pQuest)
+ $step[$pQuest['id']] = $makeSeriesItem($pQuest);
+
+ $prevStepIds = array_keys($step);
+ $chain[] = $step;
+ }
+
+ if (count($chain) > 1)
+ $series[] = [array_reverse($chain), null];
+
+ // todo (low): sensibly merge the following lists into 'series'
+ $listGen = function($cnd) use ($makeSeriesItem)
+ {
+ $chain = [];
+ $list = new QuestList($cnd);
+ if ($list->error)
+ return null;
+
+ foreach ($list->iterate() as $tpl)
+ $chain[] = [$makeSeriesItem($tpl)];
+
+ return $chain;
+ };
+
+ $extraLists = array(
+ // Requires all of these quests (Quests that you must follow to get this quest)
+ ['reqQ', array('OR', ['AND', ['nextQuestId', $this->typeId], ['exclusiveGroup', 0, '<']], ['AND', ['id', $this->subject->getField('prevQuestId')], ['nextQuestIdChain', $this->typeId, '!']])],
+
+ // Requires one of these quests (Requires one of the quests to choose from)
+ ['reqOneQ', array('OR', ['AND', ['exclusiveGroup', 0, '>'], ['nextQuestId', $this->typeId]], ['breadCrumbForQuestId', $this->typeId])],
+
+ // Opens Quests (Quests that become available only after complete this quest (optionally only one))
+ ['opensQ', array('OR', ['AND', ['prevQuestId', $this->typeId], ['id', $this->subject->getField('nextQuestIdChain'), '!']], ['id', $this->subject->getField('nextQuestId')], ['id', $this->subject->getField('breadcrumbForQuestId')])],
+
+ // Closes Quests (Quests that become inaccessible after completing this quest)
+ ['closesQ', array(['exclusiveGroup', 0, '>'], ['exclusiveGroup', $this->subject->getField('exclusiveGroup')], ['id', $this->typeId, '!'])],
+
+ // During the quest available these quests (Quests that are available only at run time this quest)
+ ['enablesQ', array(['prevQuestId', -$this->typeId])],
+
+ // Requires an active quest (Quests during the execution of which is available on the quest)
+ ['enabledByQ', array(['id', -$this->subject->getField('prevQuestId')])]
+ );
+
+ foreach ($extraLists as [$section, $condition])
+ if ($_ = $listGen($condition))
+ $series[] = [$_, sprintf(Util::$dfnString, Lang::quest($section.'Desc'), Lang::quest($section))];
+
+ return $series;
+ }
}
?>
diff --git a/endpoints/quest/quest_power.php b/endpoints/quest/quest_power.php
new file mode 100644
index 00000000..d0eccf52
--- /dev/null
+++ b/endpoints/quest/quest_power.php
@@ -0,0 +1,50 @@
+ ['filter' => FILTER_CALLBACK, 'options' => [Locale::class, 'tryFromDomain']]
+ );
+
+ public function __construct(string $id)
+ {
+ parent::__construct($id);
+
+ // temp locale
+ if ($this->_get['domain'])
+ Lang::load($this->_get['domain']);
+
+ $this->typeId = intVal($id);
+ }
+
+ protected function generate() : void
+ {
+ $quest = new QuestList(array(['id', $this->typeId]));
+ if ($quest->error)
+ $this->cacheType = CACHE_TYPE_NONE;
+ else
+ $opts = array(
+ 'name' => Lang::unescapeUISequences($quest->getField('name', true), Lang::FMT_RAW),
+ 'tooltip' => $quest->renderTooltip(),
+ 'daily' => $quest->isDaily() ? 1 : null
+ );
+
+ $this->result = new Tooltip(self::POWER_TEMPLATE, $this->typeId, $opts ?? []);
+ }
+}
+
+?>
diff --git a/endpoints/quests/quests.php b/endpoints/quests/quests.php
new file mode 100644
index 00000000..fb4d944f
--- /dev/null
+++ b/endpoints/quests/quests.php
@@ -0,0 +1,142 @@
+ 3519, 4024 => 3537, 25 => 46, 1769 => 361,
+ // Startzones: Horde
+ 132 => 1, 9 => 12, 3431 => 3430, 154 => 85,
+ // Startzones: Alliance
+ 3526 => 3524, 363 => 14, 220 => 215, 188 => 141,
+ // Group: Caverns of Time
+ 2366 => 1941, 2367 => 1941, 4100 => 1941,
+ // Group: Hellfire Citadell
+ 3562 => 3535, 3713 => 3535, 3714 => 3535,
+ // Group: Auchindoun
+ 3789 => 3688, 3790 => 3688, 3791 => 3688, 3792 => 3688,
+ // Group: Tempest Keep
+ 3847 => 3842, 3848 => 3842, 3849 => 3842,
+ // Group: Coilfang Reservoir
+ 3715 => 3905, 3716 => 3905, 3717 => 3905,
+ // Group: Icecrown Citadel
+ 4809 => 4522, 4813 => 4522, 4820 => 4522
+ );
+
+ protected int $type = Type::QUEST;
+ protected int $cacheType = CACHE_TYPE_PAGE;
+
+ protected string $template = 'quests';
+ protected string $pageName = 'quests';
+ protected ?int $activeTab = parent::TAB_DATABASE;
+ protected array $breadcrumb = [0, 3];
+
+ protected array $scripts = [[SC_JS_FILE, 'js/filters.js']];
+ protected array $expectedGET = array(
+ 'filter' => ['filter' => FILTER_VALIDATE_REGEXP, 'options' => ['regexp' => Filter::PATTERN_PARAM]]
+ );
+ protected array $validCats = Game::QUEST_CLASSES;
+
+ public function __construct(string $pageParam)
+ {
+ $this->getCategoryFromUrl($pageParam);
+
+ parent::__construct($pageParam);
+
+ $this->subCat = $pageParam !== '' ? '='.$pageParam : '';
+ $this->filter = new QuestListFilter($this->_get['filter'] ?? '', ['parentCats' => $this->category]);
+ $this->filterError = $this->filter->error;
+ }
+
+ protected function generate() : void
+ {
+ $this->h1 = Util::ucFirst(Lang::game('quests'));
+
+ $conditions = [];
+ if (!User::isInGroup(U_GROUP_EMPLOYEE))
+ $conditions[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0];
+
+ $this->filter->evalCriteria();
+
+ if ($_ = $this->filter->getConditions())
+ $conditions[] = $_;
+
+ $this->filterError = $this->filter->error; // maybe the evalX() caused something
+
+ if (isset($this->category[1]))
+ $conditions[] = ['zoneOrSort', $this->category[1]];
+ else if (isset($this->category[0]))
+ $conditions[] = ['zoneOrSort', $this->validCats[$this->category[0]]];
+
+
+ /*************/
+ /* Menu Path */
+ /*************/
+
+ foreach ($this->category as $c)
+ $this->breadcrumb[] = $c;
+
+ if (isset($this->category[1]) && isset(self::SUB_SUB_CAT[$this->category[1]]))
+ array_splice($this->breadcrumb, 3, 0, self::SUB_SUB_CAT[$this->category[1]]);
+
+
+ /**************/
+ /* Page Title */
+ /**************/
+
+ array_unshift($this->title, $this->h1);
+
+ if (isset($this->category[1]))
+ array_unshift($this->title, Lang::quest('cat', $this->category[0], $this->category[1]));
+ else if (isset($this->category[0]))
+ {
+ $c0 = Lang::quest('cat', $this->category[0]);
+ array_unshift($this->title, is_array($c0) ? $c0[0] : $c0);
+ }
+
+
+ /****************/
+ /* Main Content */
+ /****************/
+
+ $this->redButtons[BUTTON_WOWHEAD] = true;
+ if ($fiQuery = $this->filter->buildGETParam())
+ $this->wowheadLink .= '&filter='.$fiQuery;
+
+ $quests = new QuestList($conditions, ['extraOpts' => $this->filter->extraOpts, 'calcTotal' => true]);
+
+ $this->extendGlobalData($quests->getJSGlobals());
+
+ $tabData = ['data' => $quests->getListviewData()];
+
+ if ($rc = $this->filter->fiReputationCols)
+ $tabData['extraCols'] = '$fi_getReputationCols('.json_encode($rc, JSON_NUMERIC_CHECK | JSON_UNESCAPED_UNICODE).')';
+ else if ($this->filter->fiExtraCols)
+ $tabData['extraCols'] = '$fi_getExtraCols(fi_extraCols, 0, 0)';
+
+ // create note if search limit was exceeded
+ if ($quests->getMatches() > Cfg::get('SQL_LIMIT_DEFAULT'))
+ {
+ $tabData['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_questsfound', $quests->getMatches(), Cfg::get('SQL_LIMIT_DEFAULT'));
+ $tabData['_truncated'] = 1;
+ }
+ else if (isset($this->category[1]) && $this->category[1] > 0)
+ $tabData['note'] = '$$WH.sprintf(LANG.lvnote_questgivers, '.$this->category[1].', g_zones['.$this->category[1].'], '.$this->category[1].')';
+
+ $this->lvTabs = new Tabs(['parent' => "\$\$WH.ge('tabs-generic')"]);
+
+ $this->lvTabs->addListviewTab(new Listview($tabData, QuestList::$brickFile));
+
+ parent::generate();
+ }
+}
+
+?>
diff --git a/includes/dbtypes/quest.class.php b/includes/dbtypes/quest.class.php
index f46a6ec5..5cd13bb7 100644
--- a/includes/dbtypes/quest.class.php
+++ b/includes/dbtypes/quest.class.php
@@ -36,7 +36,7 @@ class QuestList extends DBTypeList
$_curTpl['cat1'] = $_curTpl['zoneOrSort']; // should probably be in a method...
$_curTpl['cat2'] = 0;
- foreach (Game::$questClasses as $k => $arr)
+ foreach (Game::QUEST_CLASSES as $k => $arr)
{
if (in_array($_curTpl['cat1'], $arr))
{
diff --git a/includes/game/misc.php b/includes/game/misc.php
index 44d6727d..67bfc553 100644
--- a/includes/game/misc.php
+++ b/includes/game/misc.php
@@ -31,7 +31,7 @@ class Game
1 => ['ability_rogue_eviscerate', 'ability_warrior_innerrage', 'ability_warrior_defensivestance' ]
);
- public static $questClasses = array(
+ public const /* array */ QUEST_CLASSES = array(
-2 => [ 0],
0 => [ 1, 3, 4, 8, 9, 10, 11, 12, 25, 28, 33, 36, 38, 40, 41, 44, 45, 46, 47, 51, 85, 130, 132, 139, 154, 267, 1497, 1519, 1537, 2257, 3430, 3431, 3433, 3487, 4080, 4298],
1 => [ 14, 15, 16, 17, 141, 148, 188, 215, 220, 331, 357, 361, 363, 400, 405, 406, 440, 490, 493, 618, 1377, 1637, 1638, 1657, 1769, 3524, 3525, 3526, 3557],
diff --git a/localization/lang.class.php b/localization/lang.class.php
index 62a54838..1bde86d4 100644
--- a/localization/lang.class.php
+++ b/localization/lang.class.php
@@ -490,7 +490,7 @@ class Lang
public static function formatSkillBreakpoints(array $bp, int $fmt = self::FMT_MARKUP) : string
{
- $tmp = self::game('difficulty').self::main('colon');
+ $tmp = self::game('difficulty');
$base = match ($fmt)
{
diff --git a/localization/locale_dede.php b/localization/locale_dede.php
index 2cd40810..ccf542bb 100644
--- a/localization/locale_dede.php
+++ b/localization/locale_dede.php
@@ -330,7 +330,7 @@ $lang = array(
'mails' => "Briefe",
'cooldown' => "%s Abklingzeit",
- 'difficulty' => "Modus",
+ 'difficulty' => "Modus: ",
'dispelType' => "Bannart",
'duration' => "Dauer",
'eventShort' => "Ereignis: %s",
@@ -1135,8 +1135,8 @@ $lang = array(
),
'event' => array(
'notFound' => "Dieses Weltereignis existiert nicht.",
- 'start' => "Anfang",
- 'end' => "Ende",
+ 'start' => "Anfang: ",
+ 'end' => "Ende: ",
'interval' => "Intervall",
'inProgress' => "Ereignis findet gerade statt",
'category' => ["Nicht kategorisiert", "Feiertage", "Wiederkehrend", "Spieler vs. Spieler"]
@@ -1272,22 +1272,22 @@ $lang = array(
'_transfer' => 'Dieses Quest wird mit %s vertauscht, wenn Ihr zur %s wechselt.',
'questLevel' => "Stufe %s",
'requirements' => "Anforderungen",
- 'reqMoney' => "Benötigtes Geld",
+ 'reqMoney' => "Benötigtes Geld: %s",
'money' => "Geld",
'additionalReq' => "Zusätzliche Anforderungen um das Quest zu erhalten",
'reqRepWith' => 'Eure Reputation mit %s %s %s sein',
'reqRepMin' => "muss mindestens",
'reqRepMax' => "darf höchstens",
'progress' => "Fortschritt",
- 'provided' => "Bereitgestellt",
+ 'provided' => "(Bereitgestellt)",
'providedItem' => "Bereitgestellter Gegenstand",
'completion' => "Abschluss",
'description' => "Beschreibung",
- 'playerSlain' => "Spieler getötet",
- 'profession' => "Beruf",
- 'timer' => "Zeitbegrenzung",
- 'loremaster' => "Meister der Lehren",
- 'suggestedPl' => "Empfohlene Spielerzahl",
+ 'playerSlain' => "Spieler getötet (%d)",
+ 'profession' => "Beruf: ",
+ 'timer' => "Zeitbegrenzung: ",
+ 'loremaster' => "Meister der Lehren: ",
+ 'suggestedPl' => "Empfohlene Spielerzahl: %d",
'keepsPvpFlag' => "Hält Euch im PvP",
'daily' => 'Täglich',
'weekly' => "Wöchentlich",
@@ -1308,16 +1308,17 @@ $lang = array(
'enabledByQ' => "Aktiviert durch",
'enabledByQDesc'=> "Ihr könnt diese Quest nur annehmen, wenn eins der nachfolgenden Quests aktiv ist",
'gainsDesc' => "Bei Abschluss dieser Quest erhaltet Ihr",
- 'theTitle' => 'den Titel "%s"',
'unavailable' => "Diese Quest wurde als nicht genutzt markiert und kann weder erhalten noch vollendet werden.",
'experience' => "Erfahrung",
'expConvert' => "(oder %s, wenn auf Stufe %d vollendet)",
'expConvert2' => "%s, wenn auf Stufe %d vollendet",
- 'chooseItems' => "Auf Euch wartet eine dieser Belohnungen",
- 'receiveItems' => "Ihr bekommt",
- 'receiveAlso' => "Ihr bekommt außerdem",
- 'spellCast' => "Der folgende Zauber wird auf Euch gewirkt",
- 'spellLearn' => "Ihr erlernt",
+ 'rewardChoices' => "Auf Euch wartet eine dieser Belohnungen:", // REWARD_CHOICES
+ 'rewardItems' => "Ihr bekommt:", // REWARD_ITEMS_ONLY
+ 'rewardAlso' => "Ihr bekommt außerdem:", // REWARD_ITEMS
+ 'rewardSpell' => "Ihr erlernt:", // REWARD_SPELL
+ 'rewardAura' => "Der folgende Zauber wird auf Euch gewirkt:", // REWARD_AURA
+ 'rewardTradeSkill'=>"Ihr erlernt die Herstellung von:", // REWARD_TRADESKILL_SPELL
+ 'rewardTitle' => 'Euch wird folgender Titel verliehen: "%s"', // REWARD_TITLE
'bonusTalents' => "%d |4Talentpunkt:Talentpunkte;",
'spellDisplayed'=> ' (%s wird angezeigt)',
'questPoolDesc' => 'Nur %d |4Quest kann:Quests können; aus diesem Tab gleichzeitig aktiv sein',
@@ -1444,8 +1445,8 @@ $lang = array(
'mailDelivery' => 'Ihr werdet diesen Brief%s%s erhalten',
'mailBy' => ' von %s',
'mailIn' => " nach %s",
- 'delay' => "Verzögerung",
- 'sender' => "Absender",
+ 'delay' => "Verzögerung: %s",
+ 'sender' => "Absender: %s",
'untitled' => "Unbetitelter Brief #%d"
),
'pet' => array(
diff --git a/localization/locale_enus.php b/localization/locale_enus.php
index ba489eef..e250a297 100644
--- a/localization/locale_enus.php
+++ b/localization/locale_enus.php
@@ -330,7 +330,7 @@ $lang = array(
'mails' => "Mails",
'cooldown' => "%s cooldown",
- 'difficulty' => "Difficulty",
+ 'difficulty' => "Difficulty: ",
'dispelType' => "Dispel type",
'duration' => "Duration",
'eventShort' => "Event: %s",
@@ -1135,8 +1135,8 @@ $lang = array(
),
'event' => array(
'notFound' => "This world event doesn't exist.",
- 'start' => "Start",
- 'end' => "End",
+ 'start' => "Start: ",
+ 'end' => "End: ",
'interval' => "Interval",
'inProgress' => "Event is currently in progress",
'category' => ["Uncategorized", "Holidays", "Recurring", "Player vs. Player"]
@@ -1272,22 +1272,22 @@ $lang = array(
'_transfer' => 'This quest will be converted to %s if you transfer to %s.',
'questLevel' => "Level %s",
'requirements' => "Requirements",
- 'reqMoney' => "Required money", // REQUIRED_MONEY
+ 'reqMoney' => "Required money: %s", // REQUIRED_MONEY
'money' => "Money",
'additionalReq' => "Additional requirements to obtain this quest",
'reqRepWith' => 'Your reputation with %s must be %s %s',
'reqRepMin' => "at least",
'reqRepMax' => "lower than",
'progress' => "Progress",
- 'provided' => "Provided",
+ 'provided' => "(Provided)",
'providedItem' => "Provided item",
'completion' => "Completion",
'description' => "Description",
- 'playerSlain' => "Players slain",
- 'profession' => "Profession",
- 'timer' => "Timer",
- 'loremaster' => "Loremaster",
- 'suggestedPl' => "Suggested players",
+ 'playerSlain' => "Players slain (%d)",
+ 'profession' => "Profession: ",
+ 'timer' => "Timer: ",
+ 'loremaster' => "Loremaster: ",
+ 'suggestedPl' => "Suggested players: %d",
'keepsPvpFlag' => "Keeps you PvP flagged",
'daily' => "Daily",
'weekly' => "Weekly",
@@ -1308,17 +1308,18 @@ $lang = array(
'enabledByQ' => "Enabled by",
'enabledByQDesc'=> "This quest is available only, when one of these quests are active",
'gainsDesc' => "Upon completion of this quest you will gain",
- 'theTitle' => 'the title "%s"', // partly REWARD_TITLE
'unavailable' => "This quest was marked obsolete and cannot be obtained or completed.",
'experience' => "experience",
'expConvert' => "(or %s if completed at level %d)",
'expConvert2' => "%s if completed at level %d",
- 'chooseItems' => "You will be able to choose one of these rewards", // REWARD_CHOICES
- 'receiveItems' => "You will receive", // REWARD_ITEMS_ONLY
- 'receiveAlso' => "You will also receive", // REWARD_ITEMS
- 'spellCast' => "The following spell will be cast on you", // REWARD_AURA
- 'spellLearn' => "You will learn", // REWARD_SPELL
- 'bonusTalents' => "%d talent |4point:points;", // partly LEVEL_UP_CHAR_POINTS
+ 'rewardChoices' => "You will be able to choose one of these rewards:", // REWARD_CHOICES
+ 'rewardItems' => "You will receive:", // REWARD_ITEMS_ONLY
+ 'rewardAlso' => "You will also receive:", // REWARD_ITEMS
+ 'rewardSpell' => "You will learn:", // REWARD_SPELL
+ 'rewardAura' => "The following spell will be cast on you:", // REWARD_AURA
+ 'rewardTradeSkill'=>"You will learn how to create:", // REWARD_TRADESKILL_SPELL
+ 'rewardTitle' => 'You shall be granted the title: "%s"', // REWARD_TITLE
+ 'bonusTalents' => "%d talent |4point:points;", // partly LEVEL_UP_CHAR_POINTS
'spellDisplayed'=> ' (%s is displayed)',
'questPoolDesc' => 'Only %d |4Quest:Quests; from this tab will be available at a time',
'autoaccept' => 'Auto Accept',
@@ -1444,8 +1445,8 @@ $lang = array(
'mailDelivery' => 'You will receive this letter%s%s',
'mailBy' => ' by %s',
'mailIn' => " after %s",
- 'delay' => "Delay",
- 'sender' => "Sender",
+ 'delay' => "Delay: %s",
+ 'sender' => "Sender: %s",
'untitled' => "Untitled Mail #%d"
),
'pet' => array(
diff --git a/localization/locale_eses.php b/localization/locale_eses.php
index 84353d5f..b38316b9 100644
--- a/localization/locale_eses.php
+++ b/localization/locale_eses.php
@@ -330,7 +330,7 @@ $lang = array(
'mails' => "Mails",
'cooldown' => "%s de reutilización",
- 'difficulty' => "Dificultad",
+ 'difficulty' => "Dificultad: ",
'dispelType' => "Tipo de disipación",
'duration' => "Duración",
'eventShort' => "Evento: %s",
@@ -1135,8 +1135,8 @@ $lang = array(
),
'event' => array(
'notFound' => "Este evento del mundo no existe.",
- 'start' => "Empieza",
- 'end' => "Termina",
+ 'start' => "Empieza: ",
+ 'end' => "Termina: ",
'interval' => "Intervalo",
'inProgress' => "El evento está en progreso actualmente",
'category' => ["Sin categoría", "Vacacionales", "Periódicos", "Jugador contra Jugador"]
@@ -1272,22 +1272,22 @@ $lang = array(
'_transfer' => 'Esta misión será convertido a %s si lo transfieres a la %s.',
'questLevel' => 'Nivel %s',
'requirements' => 'Requisitos',
- 'reqMoney' => 'Dinero necesario',
+ 'reqMoney' => 'Dinero necesario: %s',
'money' => 'Dinero',
'additionalReq' => "Requerimientos adicionales para obtener esta misión",
'reqRepWith' => 'Tu reputación con %s debe ser %s %s',
'reqRepMin' => "de al menos",
'reqRepMax' => "menor que",
'progress' => "Progreso",
- 'provided' => "Provisto",
+ 'provided' => "(Provisto)",
'providedItem' => "Objeto provisto",
'completion' => "Terminación",
'description' => "Descripción",
- 'playerSlain' => "Jugadores derrotados",
- 'profession' => "Profesión",
- 'timer' => "Tiempo",
- 'loremaster' => "Maestro cultural",
- 'suggestedPl' => "Jugadores sugeridos",
+ 'playerSlain' => "Jugadores derrotados (%d)",
+ 'profession' => "Profesión: ",
+ 'timer' => "Tiempo: ",
+ 'loremaster' => "Maestro cultural: ",
+ 'suggestedPl' => "Jugadores sugeridos: %d",
'keepsPvpFlag' => "Mantiene el JcJ activado",
'daily' => 'Diaria',
'weekly' => "Semanal",
@@ -1308,16 +1308,17 @@ $lang = array(
'enabledByQ' => "Activada por",
'enabledByQDesc'=> "Para aceptar esta misión debes haber tener activa alguna de estas misiones",
'gainsDesc' => "Cuando completes esta misión ganarás",
- 'theTitle' => 'el título "%s"',
'unavailable' => "Esta misión fue marcada como obsoleta y no puede ser obtenida o completada.",
'experience' => "experiencia",
'expConvert' => "(o %s si se completa al nivel %d)",
'expConvert2' => "%s si se completa al nivel %d",
- 'chooseItems' => "Podrás elegir una de estas recompensas",
- 'receiveItems' => "Recibirás",
- 'receiveAlso' => "También recibirás",
- 'spellCast' => "Te van a lanzar el siguiente hechizo",
- 'spellLearn' => "Aprenderás",
+ 'rewardChoices' => "Podrás elegir una de estas recompensas:", // REWARD_CHOICES
+ 'rewardItems' => "Recibirás:", // REWARD_ITEMS_ONLY
+ 'rewardAlso' => "También recibirás:", // REWARD_ITEMS
+ 'rewardSpell' => "Aprenderás:", // REWARD_SPELL
+ 'rewardAura' => "Te van a lanzar el siguiente hechizo:", // REWARD_AURA
+ 'rewardTradeSkill'=>"Aprenderás a crear:", // REWARD_TRADESKILL_SPELL
+ 'rewardTitle' => 'Se te otorga el título de: "%s"', // REWARD_TITLE
'bonusTalents' => "%d |4punto:puntos; de talento",
'spellDisplayed'=> ' (mostrando %s)',
'questPoolDesc' => 'Solo %d |4misión:misiones; de esta pestaña estarán disponibles a la vez',
@@ -1444,8 +1445,8 @@ $lang = array(
'mailDelivery' => "Usted recibirá esta carta%s%s",
'mailBy' => ' del %s',
'mailIn' => " después de %s",
- 'delay' => "Retraso",
- 'sender' => "Remitente",
+ 'delay' => "Retraso: %s",
+ 'sender' => "Remitente: %s",
'untitled' => "Correo sin título #%d"
),
'pet' => array(
diff --git a/localization/locale_frfr.php b/localization/locale_frfr.php
index a1f7d19a..bf728dd6 100644
--- a/localization/locale_frfr.php
+++ b/localization/locale_frfr.php
@@ -330,7 +330,7 @@ $lang = array(
'mails' => "Mails",
'cooldown' => "%s de recharge",
- 'difficulty' => "Difficulté",
+ 'difficulty' => "Difficulté : ",
'dispelType' => "Type de dissipation",
'duration' => "Durée",
'eventShort' => "Évènement : %s",
@@ -1135,8 +1135,8 @@ $lang = array(
),
'event' => array(
'notFound' => "Cet évènement mondial n'existe pas.",
- 'start' => "Début",
- 'end' => "Fin",
+ 'start' => "Début : ",
+ 'end' => "Fin : ",
'interval' => "Intervalle",
'inProgress' => "L'évènement est présentement en cours",
'category' => ["Non classés", "Vacances", "Récurrent", "Joueur ctr. Joueur"]
@@ -1272,22 +1272,22 @@ $lang = array(
'_transfer' => 'Cette quête sera converti en %s si vous transférez en %s.',
'questLevel' => "Niveau %s",
'requirements' => "Conditions",
- 'reqMoney' => "Argent requis",
+ 'reqMoney' => "Argent requis : %s",
'money' => "Argent",
'additionalReq' => "Conditions additionnelles requises pour obtenir cette quête",
'reqRepWith' => 'Votre reputation avec %s doît être %s %s',
'reqRepMin' => "d'au moins",
'reqRepMax' => "moins que",
'progress' => "Progrès",
- 'provided' => "Fourni",
+ 'provided' => "(Fourni)",
'providedItem' => "Objet fourni",
'completion' => "Achèvement",
'description' => "Description",
- 'playerSlain' => "Joueurs tués",
- 'profession' => "Métier",
- 'timer' => "Temps",
- 'loremaster' => "Maitre des traditions",
- 'suggestedPl' => "Joueurs suggérés",
+ 'playerSlain' => "Joueurs tués (%d)",
+ 'profession' => "Métier : ",
+ 'timer' => "Temps : ",
+ 'loremaster' => "Maitre des traditions : ",
+ 'suggestedPl' => "Joueurs suggérés : %d",
'keepsPvpFlag' => "Vous garde en mode JvJ",
'daily' => "Journalière",
'weekly' => "Chaque semaine",
@@ -1308,16 +1308,17 @@ $lang = array(
'enabledByQ' => "Autorisée par",
'enabledByQDesc'=> "Vous pouvez faire cette quête seulement quand cette quête est active",
'gainsDesc' => "Lors de l'achèvement de cette quête vous gagnerez",
- 'theTitle' => '"%s"', // empty on purpose!
'unavailable' => "Cette quête est marquée comme obsolète et ne peut être obtenue ou accomplie.",
'experience' => "points d'expérience",
'expConvert' => "(ou %s si completé au niveau %d)",
'expConvert2' => "%s si completé au niveau %d",
- 'chooseItems' => "Vous pourrez choisir une de ces récompenses",
- 'receiveItems' => "Vous recevrez",
- 'receiveAlso' => "Vous recevrez également",
- 'spellCast' => "Vous allez être la cible du sort suivant",
- 'spellLearn' => "Vous apprendrez",
+ 'rewardChoices' => "Vous pourrez choisir une de ces récompenses :", // REWARD_CHOICES
+ 'rewardItems' => "Vous recevrez :", // REWARD_ITEMS_ONLY
+ 'rewardAlso' => "Vous recevrez également :", // REWARD_ITEMS (Ainsi que :)
+ 'rewardSpell' => "Vous apprendrez :", // REWARD_SPELL
+ 'rewardAura' => "Vous allez être la cible du sort suivant :", // REWARD_AURA
+ 'rewardTradeSkill'=>"Vous apprendrez comment créer :", // REWARD_TRADESKILL_SPELL
+ 'rewardTitle' => 'Vous allez recevoir le titre suivant : "%s"', // REWARD_TITLE
'bonusTalents' => "%d |4point:points; de talent",
'spellDisplayed'=> ' (%s affichés)',
'questPoolDesc' => 'Only %d |4Quest:Quests; from this tab will be available at a time',
@@ -1444,8 +1445,8 @@ $lang = array(
'mailDelivery' => "Vous recevrez cette lettre%s%s",
'mailBy' => ' de %s',
'mailIn' => " après %s",
- 'delay' => "Delay",
- 'sender' => "Sender",
+ 'delay' => "Delay : %s",
+ 'sender' => "Sender : %s",
'untitled' => "Untitled Mail #%d"
),
'pet' => array(
diff --git a/localization/locale_ruru.php b/localization/locale_ruru.php
index a16699f7..8adbaec2 100644
--- a/localization/locale_ruru.php
+++ b/localization/locale_ruru.php
@@ -330,7 +330,7 @@ $lang = array(
'mails' => "Mails",
'cooldown' => "Восстановление: %s",
- 'difficulty' => "Сложность",
+ 'difficulty' => "Сложность: ",
'dispelType' => "Тип рассеивания",
'duration' => "Длительность",
'eventShort' => "Игровое событие: %s",
@@ -1135,8 +1135,8 @@ $lang = array(
),
'event' => array(
'notFound' => "Это игровое событие не существует.",
- 'start' => "Начало",
- 'end' => "Конец",
+ 'start' => "Начало: ",
+ 'end' => "Конец: ",
'interval' => "[Interval]",
'inProgress' => "Событие активно в данный момент",
'category' => array("Разное", "Праздники", "Периодические", "PvP")
@@ -1272,22 +1272,22 @@ $lang = array(
'_transfer' => 'Этот предмет превратится в %s, если вы перейдете за %s.',
'questLevel' => "%s-го уровня",
'requirements' => "Требования",
- 'reqMoney' => "Требуется денег",
+ 'reqMoney' => "Требуется денег: %s",
'money' => "Деньги",
'additionalReq' => "Дополнительные условия для получения данного задания",
'reqRepWith' => 'Ваша репутация с %s должна быть %s %s',
'reqRepMin' => "не менее",
'reqRepMax' => "меньше чем",
'progress' => "Прогресс",
- 'provided' => "Прилагается",
+ 'provided' => "(Прилагается)",
'providedItem' => "Прилагается предмет",
'completion' => "Завершение",
'description' => "Описание",
- 'playerSlain' => "Убито игроков",
- 'profession' => "Профессия",
- 'timer' => "Таймер",
- 'loremaster' => "Хранитель мудрости",
- 'suggestedPl' => "Рекомендуемое количество игроков",
+ 'playerSlain' => "Убито игроков (%d)",
+ 'profession' => "Профессия: ",
+ 'timer' => "Таймер: ",
+ 'loremaster' => "Хранитель мудрости: ",
+ 'suggestedPl' => "Рекомендуемое количество игроков: %d",
'keepsPvpFlag' => "Включает доступность PvP",
'daily' => "Ежедневно",
'weekly' => "Раз в неделю",
@@ -1308,16 +1308,17 @@ $lang = array(
'enabledByQ' => "Включена по",
'enabledByQDesc'=> "Вы можете получить это задание, только когда эти задания доступны",
'gainsDesc' => "По завершении этого задания, вы получите",
- 'theTitle' => '"%s"', // empty on purpose!
'unavailable' => "пометили это задание как устаревшее — его нельзя получить или выполнить.",
'experience' => "опыта",
'expConvert' => "(или %s на %d-м уровне)",
'expConvert2' => "%s на %d-м уровне",
- 'chooseItems' => "Вам дадут возможность выбрать одну из следующих наград",
- 'receiveItems' => "Вы получите",
- 'receiveAlso' => "Вы также получите",
- 'spellCast' => "Следующее заклинание будет наложено на вас",
- 'spellLearn' => "Вы изучите",
+ 'rewardChoices' => "Вы сможете выбрать одну из наград:", // REWARD_CHOICES
+ 'rewardItems' => "Вы получите:", // REWARD_ITEMS_ONLY
+ 'rewardAlso' => "Вы также получите:", // REWARD_ITEMS
+ 'rewardSpell' => "Вы узнаете:", // REWARD_SPELL
+ 'rewardAura' => "На вас будет наложено заклинание:", // REWARD_AURA
+ 'rewardTradeSkill'=>"Вы узнаете, как создавать:", // REWARD_TRADESKILL_SPELL
+ 'rewardTitle' => 'Вам будет присвоено звание: "%s"', // REWARD_TITLE
'bonusTalents' => "%d |4очко талантов:очка талантов:очков талантов;",
'spellDisplayed'=> ' (показано: %s)',
'questPoolDesc' => 'Only %d |4Quest:Quests; from this tab will be available at a time',
@@ -1439,14 +1440,14 @@ $lang = array(
)
),
'mail' => array(
- 'notFound' => "This mail doesn't exist.",
+ 'notFound' => "[This mail doesn't exist].",
'attachment' => "[Attachment]",
'mailDelivery' => "Вы получите это письмо%s%s",
'mailBy' => ' от %s',
'mailIn' => " через %s",
- 'delay' => "Delay",
- 'sender' => "Sender",
- 'untitled' => "Untitled Mail #%d"
+ 'delay' => "[Delay]: %s",
+ 'sender' => "[Sender]: %s",
+ 'untitled' => "[Untitled Mail] #%d"
),
'pet' => array(
'notFound' => "Такой породы питомцев не существует.",
diff --git a/localization/locale_zhcn.php b/localization/locale_zhcn.php
index 2098281e..0ea4e318 100644
--- a/localization/locale_zhcn.php
+++ b/localization/locale_zhcn.php
@@ -329,7 +329,7 @@ $lang = array(
'mails' => "邮件",
'cooldown' => "%s冷却时间",
- 'difficulty' => "难度",
+ 'difficulty' => "难度:",
'dispelType' => "驱散类型",
'duration' => "持续时间",
'eventShort' => "事件:%s",
@@ -1134,8 +1134,8 @@ $lang = array(
),
'event' => array(
'notFound' => "这个世界事件不存在。",
- 'start' => "开始",
- 'end' => "结束",
+ 'start' => "开始:",
+ 'end' => "结束:",
'interval' => "间隔",
'inProgress' => "事件正在进行中",
'category' => ["未分类", "节日", "循环", "PvP"]
@@ -1271,22 +1271,22 @@ $lang = array(
'_transfer' => '这个任务将被转换到%s,如果你转移到%s。',
'questLevel' => "等级%s",
'requirements' => "要求",
- 'reqMoney' => "需要金钱",
+ 'reqMoney' => "需要金钱:%s",
'money' => "金钱",
'additionalReq' => "获得这个任务的额外要求",
'reqRepWith' => '你%s的声望需要%s %s',
'reqRepMin' => "至少",
'reqRepMax' => "低于",
'progress' => "进行",
- 'provided' => "提供的",
+ 'provided' => "(提供的)",
'providedItem' => "提供的物品",
'completion' => "完成",
'description' => "描述",
- 'playerSlain' => "玩家被杀",
- 'profession' => "专业",
- 'timer' => "计时器",
- 'loremaster' => "博学者",
- 'suggestedPl' => "建议玩家数",
+ 'playerSlain' => "玩家被杀(%d)",
+ 'profession' => "专业:",
+ 'timer' => "计时器:",
+ 'loremaster' => "博学者:",
+ 'suggestedPl' => "建议玩家数:%d",
'keepsPvpFlag' => "保持你的PvP标记",
'daily' => "每日",
'weekly' => "每周",
@@ -1307,16 +1307,17 @@ $lang = array(
'enabledByQ' => "启用自",
'enabledByQDesc'=> "只有当这些任务中的一个活跃时,这个任务才可用",
'gainsDesc' => "完成这个任务后,你将获得",
- 'theTitle' => '头衔 "%s"',
'unavailable' => "这项任务已被标记为过时,无法获得或完成。",
'experience' => "经验",
'expConvert' => "(或%s如果在等级%d完成)",
'expConvert2' => "%s如果在等级%d完成",
- 'chooseItems' => "你可以从这些奖励品中选择一件",
- 'receiveItems' => "你将得到",
- 'receiveAlso' => "你还将得到",
- 'spellCast' => "该法术将被施放在你身上",
- 'spellLearn' => "你将学会",
+ 'rewardChoices' => "你可以从这些奖励品中选择一件:", // REWARD_CHOICES
+ 'rewardItems' => "你将得到:", // REWARD_ITEMS_ONLY
+ 'rewardAlso' => "你还将得到:", // REWARD_ITEMS
+ 'rewardSpell' => "你将学会:", // REWARD_SPELL
+ 'rewardAura' => "该法术将被施放在你身上:", // REWARD_AURA
+ 'rewardTradeSkill'=>"你将学会如何制造:", // REWARD_TRADESKILL_SPELL
+ 'rewardTitle' => '你将获得头衔:"%s"', // REWARD_TITLE
'bonusTalents' => "%d天赋|4点数:点数;",
'spellDisplayed'=> ' (%s 已显示)',
'questPoolDesc' => '每次只能同时提供 %d 个任务',
@@ -1443,8 +1444,8 @@ $lang = array(
'mailDelivery' => '你将收到 这封信%s%s', // "你会收到这封信%s%s",
'mailBy' => '发件人:%s',
'mailIn' => "在 %s 后",
- 'delay' => "延迟",
- 'sender' => "寄件人",
+ 'delay' => "延迟:%s",
+ 'sender' => "寄件人:%s",
'untitled' => "无标题邮件 #%d"
),
'pet' => array(
diff --git a/pages/quests.php b/pages/quests.php
deleted file mode 100644
index a69f6210..00000000
--- a/pages/quests.php
+++ /dev/null
@@ -1,125 +0,0 @@
- ['filter' => FILTER_UNSAFE_RAW]];
-
- public function __construct($pageCall, $pageParam)
- {
- $this->validCats = Game::$questClasses; // not allowed to set this as default
-
- $this->getCategoryFromUrl($pageParam);
-
- parent::__construct($pageCall, $pageParam);
-
- $this->filterObj = new QuestListFilter($this->_get['filter'] ?? '', ['parentCats' => $this->category]);
-
- $this->name = Util::ucFirst(Lang::game('quests'));
- $this->subCat = $pageParam ? '='.$pageParam : '';
- }
-
- protected function generateContent()
- {
- $conditions = [];
-
- if (!User::isInGroup(U_GROUP_EMPLOYEE))
- $conditions[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0];
-
- if (isset($this->category[1]))
- $conditions[] = ['zoneOrSort', $this->category[1]];
- else if (isset($this->category[0]))
- $conditions[] = ['zoneOrSort', $this->validCats[$this->category[0]]];
-
- $this->filterObj->evalCriteria();
-
- if ($_ = $this->filterObj->getConditions())
- $conditions[] = $_;
-
- $quests = new QuestList($conditions, ['extraOpts' => $this->filterObj->extraOpts, 'calcTotal' => true]);
-
- $this->extendGlobalData($quests->getJSGlobals());
-
- $tabData = ['data' => array_values($quests->getListviewData())];
-
- if ($rCols = $this->filterObj->fiReputationCols) // never use pretty-print
- $tabData['extraCols'] = '$fi_getReputationCols('.Util::toJSON($rCols, JSON_NUMERIC_CHECK | JSON_UNESCAPED_UNICODE).')';
- else if ($this->filterObj->fiExtraCols)
- $tabData['extraCols'] = '$fi_getExtraCols(fi_extraCols, 0, 0)';
-
- // create note if search limit was exceeded
- if ($quests->getMatches() > Cfg::get('SQL_LIMIT_DEFAULT'))
- {
- $tabData['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_questsfound', $quests->getMatches(), Cfg::get('SQL_LIMIT_DEFAULT'));
- $tabData['_truncated'] = 1;
- }
- else if (isset($this->category[1]) && $this->category[1] > 0)
- $tabData['note'] = '$$WH.sprintf(LANG.lvnote_questgivers, '.$this->category[1].', g_zones['.$this->category[1].'], '.$this->category[1].')';
-
- if ($this->filterObj->error)
- $tabData['_errors'] = 1;
-
- $this->lvTabs[] = [QuestList::$brickFile, $tabData];
- }
-
- protected function generateTitle()
- {
- array_unshift($this->title, $this->name);
-
- if (isset($this->category[1]))
- array_unshift($this->title, Lang::quest('cat', $this->category[0], $this->category[1]));
- else if (isset($this->category[0]))
- {
- $c0 = Lang::quest('cat', $this->category[0]);
- array_unshift($this->title, is_array($c0) ? $c0[0] : $c0);
- }
- }
-
- protected function generatePath()
- {
- foreach ($this->category as $c)
- $this->path[] = $c;
-
- $hubs = array(
- // Quest Hubs
- 3679 => 3519, 4024 => 3537, 25 => 46, 1769 => 361,
- // Startzones: Horde
- 132 => 1, 9 => 12, 3431 => 3430, 154 => 85,
- // Startzones: Alliance
- 3526 => 3524, 363 => 14, 220 => 215, 188 => 141,
- // Group: Caverns of Time
- 2366 => 1941, 2367 => 1941, 4100 => 1941,
- // Group: Hellfire Citadell
- 3562 => 3535, 3713 => 3535, 3714 => 3535,
- // Group: Auchindoun
- 3789 => 3688, 3790 => 3688, 3791 => 3688, 3792 => 3688,
- // Group: Tempest Keep
- 3847 => 3842, 3848 => 3842, 3849 => 3842,
- // Group: Coilfang Reservoir
- 3715 => 3905, 3716 => 3905, 3717 => 3905,
- // Group: Icecrown Citadel
- 4809 => 4522, 4813 => 4522, 4820 => 4522
- );
-
- if (isset($this->category[1]) && isset($hubs[$this->category[1]]))
- array_splice($this->path, 3, 0, $hubs[$this->category[1]]);
- }
-}
-
-?>
diff --git a/pages/zone.php b/pages/zone.php
index 0469ac78..03020585 100644
--- a/pages/zone.php
+++ b/pages/zone.php
@@ -592,7 +592,7 @@ class ZonePage extends GenericPage
{
$tabData = ['data' => array_values($questsLV)];
- foreach (Game::$questClasses as $parent => $children)
+ foreach (Game::QUEST_CLASSES as $parent => $children)
{
if (!in_array($this->typeId, $children))
continue;
diff --git a/setup/tools/filegen/profiler.ss.php b/setup/tools/filegen/profiler.ss.php
index 8adf0f32..576d057b 100644
--- a/setup/tools/filegen/profiler.ss.php
+++ b/setup/tools/filegen/profiler.ss.php
@@ -63,7 +63,7 @@ CLISetup::registerSetup("build", new class extends SetupScript
[['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE | QUEST_FLAG_SPECIAL_DUNGEON_FINDER | QUEST_FLAG_SPECIAL_MONTHLY, '&'], 0]
];
- foreach (Game::$questClasses as $cat2 => $cat)
+ foreach (Game::QUEST_CLASSES as $cat2 => $cat)
{
if ($cat2 < 0)
continue;
diff --git a/template/pages/quest.tpl.php b/template/pages/quest.tpl.php
index 6343a1f8..95c1a2d7 100644
--- a/template/pages/quest.tpl.php
+++ b/template/pages/quest.tpl.php
@@ -1,7 +1,10 @@
-
+brick('header'); ?>
+ use \Aowow\Lang;
+ $this->brick('header');
+?>
@@ -17,7 +20,7 @@
brick('redButtons'); ?>
-
=$this->name; ?>
+
=$this->h1; ?>
unavailable): ?>
=Lang::quest('unavailable'); ?>
@@ -35,80 +38,61 @@ elseif ($this->offerReward):
echo $this->offerReward."\n";
endif;
+$iconOffset = 0;
if ($this->end || $this->objectiveList):
?>
objectiveList as [$type, $data]):
+ switch ($type):
+ case 1: // just text line
+ echo ' | '.$data." |
\n";
+ break;
+ case 2: // proxy npc data
+ ['id' => $id, 'text' => $text, 'qty' => $qty, 'proxy' => $proxies] = $data;
+ echo ' | '.$text.''.($qty ? ' ('.$qty.')' : '').'\n";
+ foreach ($proxies as $block):
+ echo " \n";
+ foreach ($block as $pId => $pName):
+ echo ' | '.$pName." | \n";
+ endforeach;
+ echo " \n";
+ endforeach;
+ echo " |
\n";
+ break;
+ default: // has icon set (spell / item / ...) or unordered linked list
+ echo $data->renderContainer(20, $iconOffset, true);
+ endswitch;
+ endforeach;
+
if ($this->end):
echo " | ".$this->end." |
\n";
endif;
- if ($o = $this->objectiveList):
- foreach ($o as $i => $ol):
- if (isset($ol['text'])):
- echo ' | '.$ol['text']." |
\n";
- elseif (!empty($ol['proxy'])): // this implies creatures
- echo ' | '.$ol['name'].$ol['extraText'].''.($ol['qty'] > 1 ? ' ('.$ol['qty'].')' : null).'\n";
-
- $block1 = array_slice($ol['proxy'], 0, ceil(count($ol['proxy']) / 2), true);
- $block2 = array_slice($ol['proxy'], ceil(count($ol['proxy']) / 2), null, true);
-
- echo " \n";
- foreach ($block1 as $pId => $name):
- echo ' | '.$name." | \n";
- endforeach;
- echo " \n";
-
- if ($block2): // may be empty
- echo " \n";
- foreach ($block2 as $pId => $name):
- echo ' | '.$name." | \n";
- endforeach;
- echo " \n";
- endif;
-
- echo " |
\n";
- elseif (isset($ol['typeStr'])):
- if (in_array($ol['typeStr'], ['item', 'spell'])):
- echo ' | ';
- else /* if (in_array($ol['typeStr'], ['npc', 'object', 'faction'])) */:
- echo '
|---|
| ';
- endif;
-
- echo ''.$ol['name'].''.($ol['extraText']).(!empty($ol['qty']) ? ' ('.$ol['qty'].')' : null)." |
\n";
- endif;
- endforeach;
- endif;
-
if ($this->suggestedPl):
- echo ' | '.Lang::quest('suggestedPl').Lang::main('colon').$this->suggestedPl." |
\n";
+ echo ' | '.Lang::quest('suggestedPl', [$this->suggestedPl])." |
\n";
endif;
?>
providedItem):
- echo "
\n";
- echo ' '.Lang::quest('providedItem').Lang::main('colon')."\n";
- echo "
\n";
- echo ' | ';
- echo ''.$p['name'].''.($p['qty'] ? ' ('.$ol['qty'].')' : null)." |
\n";
+ if ($this->providedItem):
?>
+
+ =Lang::quest('providedItem').Lang::main('colon'); ?>
+
+ =$this->providedItem->renderContainer(20, $iconOffset, true); ?>
offerReward && ($this->requestItems || $this->objectives)):
rewards):
+if ([$spells, $items, $choice, $money] = $this->rewards):
echo ' '.Lang::main('rewards')."
\n";
- if (!empty($r['choice'])):
- $this->brick('rewards', ['rewTitle' => Lang::quest('chooseItems'), 'rewards' => $r['choice'], 'offset' => $offset]);
- $offset += count($r['choice']);
+ if ($choice):
+ $this->brick('rewards', ['rewTitle' => Lang::quest('rewardChoices'), 'rewards' => $choice, 'offset' => $iconOffset]);
+ $iconOffset += count($choice);
endif;
- if (!empty($r['spells'])):
- if (!empty($r['choice'])):
+ if ($spells):
+ if ($choice):
echo " \n";
endif;
- if (!empty($r['spells']['learn'])):
- $this->brick('rewards', ['rewTitle' => Lang::quest('spellLearn'), 'rewards' => $r['spells']['learn'], 'offset' => $offset, 'extra' => $r['spells']['extra']]);
- $offset += count($r['spells']['learn']);
- elseif (!empty($r['spells']['cast'])):
- $this->brick('rewards', ['rewTitle' => Lang::quest('spellCast'), 'rewards' => $r['spells']['cast'], 'offset' => $offset, 'extra' => $r['spells']['extra']]);
- $offset += count($r['spells']['cast']);
- endif;
+ $this->brick('rewards', ['rewTitle' => $spells['title'], 'rewards' => $spells['cast'], 'offset' => $iconOffset, 'extra' => $spells['extra']]);
+ $iconOffset += count($spells['cast']);
endif;
- if (!empty($r['items']) || !empty($r['money'])):
- if (!empty($r['choice']) || !empty($r['spells'])):
+ if ($items || $money):
+ if ($choice || $spells):
echo " \n";
endif;
- $addData = ['rewards' => !empty($r['items']) ? $r['items'] : null, 'offset' => $offset, 'extra' => !empty($r['money']) ? $r['money'] : null];
- $addData['rewTitle'] = empty($r['choice']) ? Lang::quest('receiveItems') : Lang::quest('receiveAlso');
-
- $this->brick('rewards', $addData);
+ $this->brick('rewards', array(
+ 'rewTitle' => $choice ? Lang::quest('rewardAlso') : Lang::quest('rewardItems'),
+ 'rewards' => $items ?: null,
+ 'offset' => $iconOffset,
+ 'extra' => $money ?: null
+ ));
endif;
endif;
-if ($g = $this->gains):
- echo ' '.Lang::main('gains')."
\n";
- echo ' '.Lang::quest('gainsDesc').Lang::main('colon')."\n";
- echo "