diff --git a/pages/spell.php b/endpoints/spell/spell.php
similarity index 75%
rename from pages/spell.php
rename to endpoints/spell/spell.php
index 5c3c5490..05111983 100644
--- a/pages/spell.php
+++ b/endpoints/spell/spell.php
@@ -6,78 +6,77 @@ if (!defined('AOWOW_REVISION'))
die('illegal access');
-// menuId 1: Spell g_initPath()
-// tabId 0: Database g_initHeader()
-class SpellPage extends GenericPage
+class SpellBaseResponse extends TemplateResponse implements ICache
{
- use TrDetailPage;
+ use TrDetailPage, TrCache;
- protected $reagents = [];
- protected $scaling = [];
- protected $items = [];
- protected $tools = [];
- protected $effects = [];
- protected $attributes = [];
- protected $powerCost = '';
- protected $castTime = [];
- protected $level = [];
- protected $rangeName = '';
- protected $range = '';
- protected $gcd = '';
- protected $gcdCat = '';
- protected $school = '';
- protected $dispel = '';
- protected $mechanic = '';
- protected $stances = '';
- protected $cooldown = '';
- protected $duration = '';
+ private const MOD_AURAS = [SPELL_AURA_ADD_FLAT_MODIFIER, SPELL_AURA_ADD_PCT_MODIFIER, SPELL_AURA_NO_REAGENT_USE,
+ SPELL_AURA_ABILITY_PERIODIC_CRIT, SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL, SPELL_AURA_ABILITY_IGNORE_AURASTATE,
+ SPELL_AURA_ALLOW_ONLY_ABILITY, SPELL_AURA_IGNORE_MELEE_RESET, SPELL_AURA_ABILITY_CONSUME_NO_AMMO,
+ SPELL_AURA_MOD_IGNORE_SHAPESHIFT, SPELL_AURA_PERIODIC_HASTE, SPELL_AURA_OVERRIDE_CLASS_SCRIPTS,
+ SPELL_AURA_MOD_DAMAGE_FROM_CASTER, SPELL_AURA_ADD_TARGET_TRIGGER, /* SPELL_AURA_DUMMY ? */];
- protected $type = Type::SPELL;
- protected $typeId = 0;
- protected $tpl = 'spell';
- protected $path = [0, 1];
- protected $tabId = 0;
- protected $mode = CACHE_TYPE_PAGE;
- protected $scripts = [[SC_JS_FILE, 'js/swfobject.js']];
+ protected int $cacheType = CACHE_TYPE_PAGE;
- protected $_get = ['domain' => ['filter' => FILTER_CALLBACK, 'options' => 'Aowow\Locale::tryFromDomain']];
+ protected string $template = 'spell';
+ protected string $pageName = 'spell';
+ protected ?int $activeTab = parent::TAB_DATABASE;
+ protected array $breadcrumb = [0, 1];
- private $difficulties = [];
- private $firstRank = 0;
- private $powerTpl = '$WowheadPower.registerSpell(%d, %d, %s);';
+ protected array $scripts = [[SC_JS_FILE, 'js/swfobject.js']];
- private static $modAuras = [SPELL_AURA_ADD_FLAT_MODIFIER, SPELL_AURA_ADD_PCT_MODIFIER, SPELL_AURA_NO_REAGENT_USE,
- SPELL_AURA_ABILITY_PERIODIC_CRIT, SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL, SPELL_AURA_ABILITY_IGNORE_AURASTATE,
- SPELL_AURA_ALLOW_ONLY_ABILITY, SPELL_AURA_IGNORE_MELEE_RESET, SPELL_AURA_ABILITY_CONSUME_NO_AMMO,
- SPELL_AURA_MOD_IGNORE_SHAPESHIFT, SPELL_AURA_PERIODIC_HASTE, SPELL_AURA_OVERRIDE_CLASS_SCRIPTS,
- SPELL_AURA_MOD_DAMAGE_FROM_CASTER, SPELL_AURA_ADD_TARGET_TRIGGER, /* SPELL_AURA_DUMMY ? */];
+ public int $type = Type::SPELL;
+ public int $typeId = 0;
+ public array $reagents = [false, null];
+ public array $scaling = [];
+ public string $items = '';
+ public array $tools = [];
+ public array $effects = [];
+ public array $attributes = [];
+ public string $powerCost = '';
+ public string $castTime = '';
+ public string $level = '';
+ public string $rangeName = '';
+ public string $range = '';
+ public string $gcd = '';
+ public string $gcdCat = '';
+ public string $school = '';
+ public ?string $dispel = null;
+ public ?string $mechanic = null;
+ public string $stances = '';
+ public string $cooldown = '';
+ public string $duration = '';
+ public array $tooltip = [];
- public function __construct($pageCall, $id)
+ private SpellList $subject;
+ private int $firstRank = 0;
+ private array $modelInfo = [];
+ private array $difficulties = [];
+
+ 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 SpellList(array(['id', $this->typeId]));
if ($this->subject->error)
- $this->notFound(Lang::game('spell'), Lang::spell('notFound'));
+ $this->generateNotFound(Lang::game('spell'), Lang::spell('notFound'));
- $jsg = $this->subject->getJSGlobals(GLOBALINFO_ANY, $extra);
- $this->extendGlobalData($jsg, $extra);
+ if ($jsg = $this->subject->getJSGlobals(GLOBALINFO_ANY, $extra))
+ $this->extendGlobalData($jsg, $extra);
- $this->name = $this->subject->getField('name', true);
-
- // has difficulty versions of itself
- $this->difficulties = DB::Aowow()->selectRow(
- 'SELECT normal10 AS "0", normal25 AS "1",
- heroic10 AS "2", heroic25 AS "3"
+ $this->modelInfo = $this->subject->getModelInfo($this->typeId);
+ $this->difficulties = DB::Aowow()->selectRow( // has difficulty versions of itself
+ 'SELECT `normal10` AS "0", `normal25` AS "1",
+ `heroic10` AS "2", `heroic25` AS "3"
FROM ?_spelldifficulty
- WHERE normal10 = ?d OR normal25 = ?d OR
- heroic10 = ?d OR heroic25 = ?d',
+ WHERE `normal10` = ?d OR `normal25` = ?d OR
+ `heroic10` = ?d OR `heroic25` = ?d',
$this->typeId, $this->typeId, $this->typeId, $this->typeId
);
@@ -86,273 +85,169 @@ class SpellPage extends GenericPage
$this->firstRank = $fr;
else
$this->firstRank = DB::Aowow()->selectCell(
- 'SELECT IF(s1.RankNo <> 1 AND s2.id, s2.id, s1.id)
+ 'SELECT IF(s1.`RankNo` <> 1 AND s2.`id`, s2.`id`, s1.`id`)
FROM ?_spell s1
LEFT JOIN ?_spell s2
- ON s1.SpellFamilyId = s2.SpelLFamilyId AND s1.SpellFamilyFlags1 = s2.SpelLFamilyFlags1 AND
- s1.SpellFamilyFlags2 = s2.SpellFamilyFlags2 AND s1.SpellFamilyFlags3 = s2.SpellFamilyFlags3 AND
- s1.name_loc0 = s2.name_loc0 AND s2.RankNo = 1
- WHERE s1.id = ?d',
+ ON s1.`SpellFamilyId` = s2.`SpelLFamilyId` AND s1.`SpellFamilyFlags1` = s2.`SpelLFamilyFlags1` AND
+ s1.`SpellFamilyFlags2` = s2.`SpellFamilyFlags2` AND s1.`SpellFamilyFlags3` = s2.`SpellFamilyFlags3` AND
+ s1.`name_loc0` = s2.`name_loc0` AND s2.`RankNo` = 1
+ WHERE s1.`id` = ?d',
$this->typeId
);
- }
- protected function generatePath()
- {
- $cat = $this->subject->getField('typeCat');
- $cf = $this->subject->getField('cuFlags');
+ $this->h1 = Util::htmlEscape($this->subject->getField('name', true));
- $this->path[] = $cat;
-
- // reconstruct path
- switch ($cat)
- {
- case -2:
- case 7:
- case -13:
- if ($cl = $this->subject->getField('reqClassMask'))
- $this->path[] = log($cl, 2) + 1;
- else if ($sf = $this->subject->getField('spellFamilyId'))
- foreach (ChrClass::cases() as $cl)
- if ($cl->spellFamily() == $sf)
- {
- $this->path[] = $cl->value;
- break;
- }
-
- if ($cat == -13)
- $this->path[] = ($cf & (SPELL_CU_GLYPH_MAJOR | SPELL_CU_GLYPH_MINOR)) >> 6;
- else
- $this->path[] = $this->subject->getField('skillLines')[0];
-
- break;
- case 9:
- case -3:
- case 11:
- $this->path[] = $this->subject->getField('skillLines')[0];
-
- if ($cat == 11)
- if ($_ = $this->subject->getField('reqSpellId'))
- $this->path[] = $_;
-
- break;
- case -11:
- foreach (SpellList::$skillLines as $line => $skills)
- if (in_array($this->subject->getField('skillLines')[0], $skills))
- $this->path[] = $line;
- break;
- case -7: // only spells unique in skillLineAbility will always point to the right skillLine :/
- if ($cf & SPELL_CU_PET_TALENT_TYPE0)
- $this->path[] = 411; // Ferocity
- else if ($cf & SPELL_CU_PET_TALENT_TYPE1)
- $this->path[] = 409; // Tenacity
- else if ($cf & SPELL_CU_PET_TALENT_TYPE2)
- $this->path[] = 410; // Cunning
- break;
- case -5:
- if ($this->subject->getField('effect2AuraId') == 207 || $this->subject->getField('effect3AuraId') == 207)
- $this->path[] = 2; // flying (also contains 32, so checked first)
- else if ($this->subject->getField('effect2AuraId') == 32 || $this->subject->getField('effect3AuraId') == 32)
- $this->path[] = 1; // ground
- else
- $this->path[] = 3; // misc
- }
- }
-
- protected function generateTitle()
- {
- array_unshift($this->title, $this->name, Util::ucFirst(Lang::game('spell')));
- }
-
- protected function generateContent()
- {
- $this->addScript([SC_JS_FILE, '?data=zones']);
-
- $_cat = $this->subject->getField('typeCat');
-
- $modelInfo = $this->subject->getModelInfo($this->typeId);
-
- $redButtons = array(
- BUTTON_VIEW3D => false,
- BUTTON_WOWHEAD => true,
- BUTTON_LINKS => array(
- 'linkColor' => 'ff71d5ff',
- 'linkId' => Type::getFileString(Type::SPELL).':'.$this->typeId,
- 'linkName' => $this->name,
- 'type' => $this->type,
- 'typeId' => $this->typeId
- )
+ $this->gPageInfo += array(
+ 'type' => $this->type,
+ 'typeId' => $this->typeId,
+ 'name' => $this->subject->getField('name', true)
);
- // could have multiple models set, one per effect
- foreach ($modelInfo as $mI)
- {
- $redButtons[BUTTON_VIEW3D] = ['type' => $mI['type'], 'displayId' => $mI['displayId']];
- if (isset($mI['humanoid']))
- {
- $redButtons[BUTTON_VIEW3D]['typeId'] = $mI['typeId'];
- $redButtons[BUTTON_VIEW3D]['humanoid'] = 1;
- }
+ /*************/
+ /* Menu Path */
+ /*************/
- break;
- }
+ $this->generatePath();
+
+
+ /**************/
+ /* Page Title */
+ /**************/
+
+ array_unshift($this->title, $this->subject->getField('name', true), Util::ucFirst(Lang::game('spell')));
/***********/
/* Infobox */
/***********/
- $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags'));
+ $this->createInfobox();
- // level
- if (!in_array($_cat, [-5, -6])) // not mount or vanity pet
- {
- if ($_ = $this->subject->getField('talentLevel'))
- $infobox[] = (in_array($_cat, [-2, 7, -13]) ? sprintf(Lang::game('reqLevel'), $_) : Lang::game('level').Lang::main('colon').$_);
- else if ($_ = $this->subject->getField('spellLevel'))
- $infobox[] = (in_array($_cat, [-2, 7, -13]) ? sprintf(Lang::game('reqLevel'), $_) : Lang::game('level').Lang::main('colon').$_);
- }
- $jsg = [];
- // races
- if ($_ = Lang::getRaceString($this->subject->getField('reqRaceMask'), $jsg, Lang::FMT_MARKUP))
- {
- $this->extendGlobalIds(Type::CHR_RACE, ...$jsg);
- $t = count($jsg) == 1 ? Lang::game('race') : Lang::game('races');
- $infobox[] = Util::ucFirst($t).Lang::main('colon').$_;
- }
+ /***************/
+ /* Red Buttons */
+ /***************/
- // classes
- if ($_ = Lang::getClassString($this->subject->getField('reqClassMask'), $jsg, Lang::FMT_MARKUP))
- {
- $this->extendGlobalIds(Type::CHR_CLASS, ...$jsg);
- $t = count($jsg) == 1 ? Lang::game('class') : Lang::game('classes');
- $infobox[] = Util::ucFirst($t).Lang::main('colon').$_;
- }
+ $this->redButtons = array(
+ BUTTON_VIEW3D => false,
+ BUTTON_WOWHEAD => true,
+ BUTTON_LINKS => array(
+ 'linkColor' => 'ff71d5ff',
+ 'linkId' => Type::getFileString(Type::SPELL).':'.$this->typeId,
+ 'linkName' => $this->subject->getField('name', true),
+ 'type' => $this->type,
+ 'typeId' => $this->typeId
+ )
+ );
- // spell focus
- if ($_ = $this->subject->getField('spellFocusObject'))
+ // could have multiple models set, one per effect
+ foreach ($this->modelInfo as $mI)
{
- $bar = DB::Aowow()->selectRow('SELECT * FROM ?_spellfocusobject WHERE id = ?d', $_);
- $focus = new GameObjectList(array(['spellFocusId', $_], 1));
- $infobox[] = Lang::game('requires2').' '.($focus->error ? Util::localizedString($bar, 'name') : '[url=?object='.$focus->id.']'.Util::localizedString($bar, 'name').'[/url]');
- }
+ $this->redButtons[BUTTON_VIEW3D] = ['type' => $mI['type'], 'displayId' => $mI['displayId']];
- // primary & secondary trades
- if (in_array($_cat, [9, 11]))
- {
- // skill
- if ($_ = $this->subject->getField('skillLines')[0])
+ if (isset($mI['humanoid']))
{
- $rSkill = new SkillList(array(['id', $_]));
- if (!$rSkill->error)
- {
- $this->extendGlobalData($rSkill->getJSGlobals());
-
- $bar = sprintf(Lang::game('requires'), ' [skill='.$rSkill->id.']');
- if ($_ = $this->subject->getField('learnedAt'))
- $bar .= ' ('.$_.')';
-
- $infobox[] = $bar;
- }
+ $this->redButtons[BUTTON_VIEW3D]['typeId'] = $mI['typeId'];
+ $this->redButtons[BUTTON_VIEW3D]['humanoid'] = 1;
}
- // specialization
- if ($_ = $this->subject->getField('reqSpellId'))
- {
- $rSpell = new SpellList(array(['id', $_]));
- if (!$rSpell->error)
- {
- $this->extendGlobalData($rSpell->getJSGlobals());
- $infobox[] = Lang::game('requires2').' [spell='.$rSpell->id.']';
- }
- }
-
- // difficulty
- if ($_ = $this->subject->getColorsForCurrent())
- $infobox[] = Lang::formatSkillBreakpoints($_);
- }
-
- // accquisition.. 10: starter spell; 7: discovery
- if ($this->subject->getSources($s))
- {
- if (in_array(SRC_STARTER, $s))
- $infobox[] = Lang::spell('starter');
- else if (in_array(SRC_DISCOVERY, $s))
- $infobox[] = Lang::spell('discovered');
- }
-
- // training cost
- if ($cost = $this->subject->getField('trainingCost'))
- $infobox[] = Lang::spell('trainingCost').Lang::main('colon').'[money='.$cost.']';
-
- // icon
- if ($_ = $this->subject->getField('iconId'))
- {
- $infobox[] = Util::ucFirst(lang::game('icon')).Lang::main('colon').'[icondb='.$_.' name=true]';
- $this->extendGlobalIds(Type::ICON, $_);
- }
-
- // used in mode
- foreach ($this->difficulties as $n => $id)
- if ($id == $this->typeId) // "Mode" seems to be multilingual acceptable
- $infobox[] = 'Mode'.Lang::main('colon').Lang::game('modes', $n);
-
- // Creature Type from Aura: Shapeshift
- foreach ($modelInfo as $mI)
- {
- if (!isset($mI['creatureType']))
- continue;
-
- if ($mI['creatureType'] > 0)
- $infobox[] = Lang::game('type').Lang::main('colon').Lang::game('ct', $mI['creatureType']);
-
break;
}
- // spell script
- if (User::isInGroup(U_GROUP_STAFF))
- if ($_ = DB::World()->selectCell('SELECT ScriptName FROM spell_script_names WHERE ABS(spell_id) = ?d', $this->firstRank))
- $infobox[] = 'Script'.Lang::main('colon').$_;
- $infobox = $infobox ? '[ul][li]'.implode('[/li][li]', $infobox).'[/li][/ul]' : '';
+ /*******************/
+ /* Reagent Listing */
+ /*******************/
- // append glyph symbol if available
- $glyphId = 0;
- for ($i = 1; $i < 4; $i++)
- if ($this->subject->getField('effect'.$i.'Id') == SPELL_EFFECT_APPLY_GLYPH)
- $glyphId = $this->subject->getField('effect'.$i.'MiscValue');
+ $this->createReagentList();
- if ($_ = DB::Aowow()->selectCell('SELECT ic.name FROM ?_glyphproperties gp JOIN ?_icons ic ON gp.iconId = ic.id WHERE gp.spellId = ?d { OR gp.id = ?d }', $this->typeId, $glyphId ?: DBSIMPLE_SKIP))
- if (file_exists('static/images/wow/Interface/Spellbook/'.$_.'.png'))
- $infobox .= '[img src='.Cfg::get('STATIC_URL').'/images/wow/Interface/Spellbook/'.$_.'.png border=0 float=center margin=15]';
+
+ /**********************/
+ /* Spell Scaling Info */
+ /**********************/
+
+ $this->createScalingData();
+
+
+ /******************/
+ /* Required Items */
+ /******************/
+
+ $this->createRequiredItems();
+
+
+ /*************************/
+ /* Required Tools/Totems */
+ /*************************/
+
+ // prepare Tools
+ foreach ($this->subject->getToolsForCurrent() as $tool)
+ $this->tools[] = new IconElement(
+ Type::ITEM,
+ $tool['itemId'] ?? 0,
+ $tool['name'],
+ quality: ITEM_QUALITY_NORMAL,
+ size: IconElement::SIZE_SMALL,
+ url: !isset($tool['itemId']) ? '?items&filter=cr=91;crs='.$tool['id'].';crv=0' : '',
+ element: 'iconlist-icon'
+ );
+
+
+ /**********************/
+ /* Spell Effect Block */
+ /**********************/
+
+ $this->createEffects();
+
+
+ /**************************************************/
+ /* Spell Attributes listing and SpellFilter links */
+ /**************************************************/
+
+ $this->createAttributesList();
+
+
+ /*************************/
+ /* Factionchange pendant */
+ /*************************/
+
+ // factionchange-equivalent
+ if ($pendant = DB::World()->selectCell('SELECT IF(`horde_id` = ?d, `alliance_id`, -`horde_id`) FROM player_factionchange_spells WHERE `alliance_id` = ?d OR `horde_id` = ?d', $this->typeId, $this->typeId, $this->typeId))
+ {
+ $altSpell = new SpellList(array(['id', abs($pendant)]));
+ if (!$altSpell->error)
+ {
+ $this->transfer = Lang::spell('_transfer', array(
+ $altSpell->id,
+ ITEM_QUALITY_NORMAL,
+ $altSpell->getField('iconString'),
+ $altSpell->getField('name', true),
+ $pendant > 0 ? 'alliance' : 'horde',
+ $pendant > 0 ? Lang::game('si', SIDE_ALLIANCE) : Lang::game('si', SIDE_HORDE)
+ ));
+ }
+ }
/****************/
/* Main Content */
/****************/
- $this->reagents = $this->createReagentList();
- $this->scaling = $this->createScalingData();
- $this->items = $this->createRequiredItems();
- $this->tools = $this->createTools();
- $this->effects = $this->createEffects();
- $this->attributes = $this->createAttributesList();
- $this->powerCost = $this->subject->createPowerCostForCurrent();
- $this->castTime = $this->subject->createCastTimeForCurrent(false, false);
- $this->level = $this->subject->getField('spellLevel');
- $this->rangeName = $this->subject->getField('rangeText', true);
- $this->range = $this->subject->getField('rangeMaxHostile');
- $this->gcd = Util::formatTime($this->subject->getField('startRecoveryTime'));
- $this->school = $this->fmtStaffTip(Lang::getMagicSchools($this->subject->getField('schoolMask')), Util::asHex($this->subject->getField('schoolMask')));
- $this->dispel = $this->subject->getField('dispelType') ? Lang::game('dt', $this->subject->getField('dispelType')) : null;
- $this->mechanic = $this->subject->getField('mechanic') ? Lang::game('me', $this->subject->getField('mechanic')) : null;
- $this->name = $this->subject->getField('name', true);
- $this->headIcons = [$this->subject->getField('iconString'), $this->subject->getField('stackAmount') ?: ($this->subject->getField('procCharges') > 1 ? $this->subject->getField('procCharges') : '')];
- $this->redButtons = $redButtons;
- $this->infobox = $infobox;
- $this->gcdCat = match((int)$this->subject->getField('startRecoveryCategory'))
+ $this->powerCost = $this->subject->createPowerCostForCurrent();
+ $this->castTime = $this->subject->createCastTimeForCurrent(false, false);
+ $this->level = $this->subject->getField('spellLevel');
+ $this->rangeName = $this->subject->getField('rangeText', true);
+ $this->gcd = Util::formatTime($this->subject->getField('startRecoveryTime'));
+ $this->school = $this->fmtStaffTip(Lang::getMagicSchools($this->subject->getField('schoolMask')), Util::asHex($this->subject->getField('schoolMask')));
+ $this->dispel = $this->subject->getField('dispelType') ? Lang::game('dt', $this->subject->getField('dispelType')) : null;
+ $this->mechanic = $this->subject->getField('mechanic') ? Lang::game('me', $this->subject->getField('mechanic')) : null;
+ $this->tooltip = array(
+ $this->subject->getField('iconString'),
+ $this->subject->getField('stackAmount') ?: ($this->subject->getField('procCharges') > 1 ? $this->subject->getField('procCharges') : 0),
+ $this->subject->getField('buff', true, true) ? 1 : 0
+ );
+ $this->gcdCat = match((int)$this->subject->getField('startRecoveryCategory'))
{
133 => Lang::spell('normal'),
330, // Mounts
@@ -361,15 +256,15 @@ class SpellPage extends GenericPage
1164, // Kessel Run Elek
1173, // Birmingham Test Spells
1178, // Stealth (Druid Cat, Rogue, Hunter Cat Pets) + Charge (Warrior)
- 1244 => Lang::spell('special'), // Argent Tournament Vehicle Jousting Abilities
+ 1244 => Lang::spell('special'), // Argent Tournament Vehcile Jousting Abilities
default => '' // n/a
};
- // minRange exists.. prepend
+ $this->range = $this->subject->getField('rangeMaxHostile');
if ($_ = $this->subject->getField('rangeMinHostile'))
$this->range = $_.' - '.$this->range;
- if (!($this->subject->getField('attributes2') & 0x80000))
+ if (!($this->subject->getField('attributes2') & SPELL_ATTR2_NOT_NEED_SHAPESHIFT))
$this->stances = Lang::getStances($this->subject->getField('stanceMask'));
if (($_ = $this->subject->getField('recoveryTime')) && $_ > 0)
@@ -380,45 +275,29 @@ class SpellPage extends GenericPage
if (($_ = $this->subject->getField('duration')) && $_ > 0)
$this->duration = Util::formatTime($_);
- // factionchange-equivalent
- if ($pendant = DB::World()->selectCell('SELECT IF(horde_id = ?d, alliance_id, -horde_id) FROM player_factionchange_spells WHERE alliance_id = ?d OR horde_id = ?d', $this->typeId, $this->typeId, $this->typeId))
- {
- $altSpell = new SpellList(array(['id', abs($pendant)]));
- if (!$altSpell->error)
- {
- $this->transfer = sprintf(
- Lang::spell('_transfer'),
- $altSpell->id,
- 1, // quality
- $altSpell->getField('iconString'),
- $altSpell->getField('name', true),
- $pendant > 0 ? 'alliance' : 'horde',
- $pendant > 0 ? Lang::game('si', 1) : Lang::game('si', 2)
- );
- }
- }
/**************/
/* Extra Tabs */
/**************/
+ $this->lvTabs = new Tabs(['parent' => "\$\$WH.ge('tabs-generic')"], 'tabsRelated', true);
+
$ubSAI = SmartAI::getOwnerOfSpellCast($this->typeId);
// tab: abilities [of shapeshift form]
+ $formSpells = [];
for ($i = 1; $i < 4; $i++)
+ if ($this->subject->getField('effect'.$i.'AuraId') == SPELL_AURA_MOD_SHAPESHIFT)
+ if ($_ = DB::Aowow()->selectRow('SELECT `spellId1`, `spellId2`, `spellId3`, `spellId4`, `spellId5`, `spellId6`, `spellId7`, `spellId8` FROM ?_shapeshiftforms WHERE `id` = ?d', $this->subject->getField('effect'.$i.'MiscValue')))
+ $formSpells = array_merge($formSpells, $_);
+
+ if ($formSpells)
{
- if ($this->subject->getField('effect'.$i.'AuraId') != 36)
- continue;
-
- $formSpells = DB::Aowow()->selectRow('SELECT spellId1, spellId2, spellId3, spellId4, spellId5, spellId6, spellId7, spellId8 FROM ?_shapeshiftforms WHERE id = ?d', $this->subject->getField('effect'.$i.'MiscValue'));
- if (!$formSpells)
- continue;
-
$abilities = new SpellList(array(['id', $formSpells]));
if (!$abilities->error)
{
$tabData = array(
- 'data' => array_values($abilities->getListviewData()),
+ 'data' => $abilities->getListviewData(),
'id' => 'controlledabilities',
'name' => '$LANG.tab_controlledabilities',
'visibleCols' => ['level'],
@@ -427,7 +306,7 @@ class SpellPage extends GenericPage
if (!$abilities->hasSetFields('skillLines'))
$tabData['hiddenCols'] = ['skill'];
- $this->lvTabs[] = [SpellList::$brickFile, $tabData];
+ $this->lvTabs->addListviewTab(new Listview($tabData, SpellList::$brickFile));
$this->extendGlobalData($abilities->getJSGlobals(GLOBALINFO_SELF));
}
@@ -445,7 +324,7 @@ class SpellPage extends GenericPage
for ($i = 1; $i < 4; $i++)
{
- if (!in_array($this->subject->getField('effect'.$i.'AuraId'), self::$modAuras))
+ if (!in_array($this->subject->getField('effect'.$i.'AuraId'), self::MOD_AURAS))
continue;
$m1 = $this->subject->getField('effect'.$i.'SpellClassMaskA');
@@ -466,21 +345,28 @@ class SpellPage extends GenericPage
foreach ($modSpells->iterate() as $id => $__)
{
if (in_array($modSpells->getField('typeCat'), [-2, 7]))
- $classSpells[$id] = [$id, $modSpells->getField('name', true), 0, 0];
+ $classSpells[$id] = [new IconElement(Type::SPELL, $id, $modSpells->getField('name', true), size: IconElement::SIZE_SMALL), []];
else
- $miscSpells[$id] = [$id, $modSpells->getField('name', true), 0, 0];
+ $miscSpells[$id] = [new IconElement(Type::SPELL, $id, $modSpells->getField('name', true), size: IconElement::SIZE_SMALL), []];
}
if ($classSpells)
- foreach (DB::World()->select('SELECT spell_id AS ARRAY_KEY, first_spell_id AS "0", `rank` AS "1" FROM spell_ranks WHERE spell_id IN (?a)', array_keys($classSpells)) as $spellId => [$firstSpellId, $rank])
+ {
+ foreach (DB::World()->select('SELECT `spell_id` AS ARRAY_KEY, `first_spell_id` AS "0", `rank` AS "1" FROM spell_ranks WHERE `spell_id` IN (?a)', array_keys($classSpells)) as $spellId => [$firstSpellId, $rank])
{
- $classSpells[$firstSpellId][2] = min($classSpells[$firstSpellId][2] ?: $rank, $rank);
- $classSpells[$firstSpellId][3] = max($classSpells[$firstSpellId][3], $rank);
+ $classSpells[$firstSpellId][1][0] = min($classSpells[$firstSpellId][1][0] ?? $rank, $rank);
+ $classSpells[$firstSpellId][1][1] = max($classSpells[$firstSpellId][1][1] ?? $rank, $rank);
if ($spellId != $firstSpellId)
unset($classSpells[$spellId]);
}
+ array_walk($classSpells, function(&$x) {
+ if ($x[1] && $x[1][0] == $x[1][1]) // only one rank => unset
+ $x[1] = null;
+ });
+ }
+
$modifiesData += $modSpells->getListviewData();
if ($modSpells->hasSetFields('skillLines'))
$hideSkillCol = false;
@@ -497,7 +383,7 @@ class SpellPage extends GenericPage
if ($modifiesData)
{
$tabData = array(
- 'data' => array_values($modifiesData),
+ 'data' => $modifiesData,
'id' => 'modifies',
'name' => '$LANG.tab_modifies',
'visibleCols' => ['level'],
@@ -506,7 +392,7 @@ class SpellPage extends GenericPage
if ($hideSkillCol)
$tabData['hiddenCols'] = ['skill'];
- $this->lvTabs[] = [SpellList::$brickFile, $tabData];
+ $this->lvTabs->addListviewTab(new Listview($tabData, SpellList::$brickFile));
}
// tab: [$this is] modified by
@@ -528,7 +414,7 @@ class SpellPage extends GenericPage
$sub[] = array(
'AND',
- ['s.effect'.$i.'AuraId', self::$modAuras],
+ ['s.effect'.$i.'AuraId', self::MOD_AURAS],
[
'OR',
['s.effect'.$i.'SpellClassMaskA', $m1, '&'],
@@ -544,7 +430,7 @@ class SpellPage extends GenericPage
if (!$modsSpell->error)
{
$tabData = array(
- 'data' => array_values($modsSpell->getListviewData()),
+ 'data' => $modsSpell->getListviewData(),
'id' => 'modified-by',
'name' => '$LANG.tab_modifiedby',
'visibleCols' => ['level'],
@@ -553,7 +439,7 @@ class SpellPage extends GenericPage
if (!$modsSpell->hasSetFields('skillLines'))
$tabData['hiddenCols'] = ['skill'];
- $this->lvTabs[] = [SpellList::$brickFile, $tabData];
+ $this->lvTabs->addListviewTab(new Listview($tabData, SpellList::$brickFile));
$this->extendGlobalData($modsSpell->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED));
}
@@ -606,7 +492,7 @@ class SpellPage extends GenericPage
}
$tabData = array(
- 'data' => array_values($data),
+ 'data' => $data,
'id' => 'see-also',
'name' => '$LANG.tab_seealso',
'visibleCols' => ['level'],
@@ -618,7 +504,7 @@ class SpellPage extends GenericPage
if (isset($saE))
$tabData['extraCols'] = $saE;
- $this->lvTabs[] = [SpellList::$brickFile, $tabData];
+ $this->lvTabs->addListviewTab(new Listview($tabData, SpellList::$brickFile));
$this->extendGlobalData($saSpells->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED));
}
@@ -639,18 +525,18 @@ class SpellPage extends GenericPage
$cdSpells = new SpellList($conditions);
if (!$cdSpells->error)
{
- $this->lvTabs[] = [SpellList::$brickFile, array(
- 'data' => array_values($cdSpells->getListviewData()),
+ $this->lvTabs->addListviewTab(new Listview(array(
+ 'data' => $cdSpells->getListviewData(),
'name' => '$LANG.tab_sharedcooldown',
'id' => 'shared-cooldown'
- )];
+ ), SpellList::$brickFile));
$this->extendGlobalData($cdSpells->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED));
}
}
// tab: used by - spell
- if ($so = DB::Aowow()->selectCell('SELECT id FROM ?_spelloverride WHERE spellId1 = ?d OR spellId2 = ?d OR spellId3 = ?d OR spellId4 = ?d OR spellId5 = ?d', $this->subject->id, $this->subject->id, $this->subject->id, $this->subject->id, $this->subject->id))
+ if ($so = DB::Aowow()->selectCell('SELECT `id` FROM ?_spelloverride WHERE `spellId1` = ?d OR `spellId2` = ?d OR `spellId3` = ?d OR `spellId4` = ?d OR `spellId5` = ?d', $this->subject->id, $this->subject->id, $this->subject->id, $this->subject->id, $this->subject->id))
{
$conditions = array(
'OR',
@@ -661,11 +547,11 @@ class SpellPage extends GenericPage
$ubSpells = new SpellList($conditions);
if (!$ubSpells->error)
{
- $this->lvTabs[] = [SpellList::$brickFile, array(
- 'data' => array_values($ubSpells->getListviewData()),
+ $this->lvTabs->addListviewTab(new Listview(array(
+ 'data' => $ubSpells->getListviewData(),
'id' => 'used-by-spell',
'name' => '$LANG.tab_usedby'
- )];
+ ), SpellList::$brickFile));
$this->extendGlobalData($ubSpells->getJSGlobals(GLOBALINFO_SELF));
}
@@ -682,11 +568,11 @@ class SpellPage extends GenericPage
$ubSets = new ItemsetList($conditions);
if (!$ubSets->error)
{
- $this->lvTabs[] = [ItemsetList::$brickFile, array(
- 'data' => array_values($ubSets->getListviewData()),
+ $this->lvTabs->addListviewTab(new Listview(array(
+ 'data' => $ubSets->getListviewData(),
'id' => 'used-by-itemset',
'name' => '$LANG.tab_usedby'
- )];
+ ), ItemsetList::$brickFile));
$this->extendGlobalData($ubSets->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED));
}
@@ -704,11 +590,11 @@ class SpellPage extends GenericPage
$ubItems = new ItemList($conditions);
if (!$ubItems->error)
{
- $this->lvTabs[] = [ItemList::$brickFile, array(
- 'data' => array_values($ubItems->getListviewData()),
+ $this->lvTabs->addListviewTab(new Listview(array(
+ 'data' => $ubItems->getListviewData(),
'id' => 'used-by-item',
'name' => '$LANG.tab_usedby'
- )];
+ ), ItemList::$brickFile));
$this->extendGlobalData($ubItems->getJSGlobals(GLOBALINFO_SELF));
}
@@ -725,11 +611,12 @@ class SpellPage extends GenericPage
$ubObjects = new GameObjectList($conditions);
if (!$ubObjects->error)
{
- $this->lvTabs[] = [GameObjectList::$brickFile, array(
- 'data' => array_values($ubObjects->getListviewData()),
+ $this->addDataLoader('zones');
+ $this->lvTabs->addListviewTab(new Listview(array(
+ 'data' => $ubObjects->getListviewData(),
'id' => 'used-by-object',
'name' => '$LANG.tab_usedby'
- )];
+ ), GameObjectList::$brickFile));
$this->extendGlobalData($ubObjects->getJSGlobals());
}
@@ -742,11 +629,11 @@ class SpellPage extends GenericPage
$ubTriggers = new AreaTriggerList(array(['id', $ubSAI[Type::AREATRIGGER]]));
if (!$ubTriggers->error)
{
- $this->lvTabs[] = [AreaTriggerList::$brickFile, array(
- 'data' => array_values($ubTriggers->getListviewData()),
+ $this->lvTabs->addListviewTab(new Listview(array(
+ 'data' => $ubTriggers->getListviewData(),
'id' => 'used-by-areatrigger',
'name' => '$LANG.tab_usedby'
- ), 'areatrigger'];
+ ), AreaTriggerList::$brickFile, 'areatrigger'));
}
}
}
@@ -761,18 +648,18 @@ class SpellPage extends GenericPage
$coAchievemnts = new AchievementList($conditions);
if (!$coAchievemnts->error)
{
- $this->lvTabs[] = [AchievementList::$brickFile, array(
- 'data' => array_values($coAchievemnts->getListviewData()),
+ $this->lvTabs->addListviewTab(new Listview(array(
+ 'data' => $coAchievemnts->getListviewData(),
'id' => 'criteria-of',
'name' => '$LANG.tab_criteriaof'
- )];
+ ), AchievementList::$brickFile));
$this->extendGlobalData($coAchievemnts->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED));
}
// tab: contains
// spell_loot_template & skill_extra_item_template
- $extraItem = DB::World()->selectRow('SELECT * FROM skill_extra_item_template WHERE spellid = ?d', $this->subject->id);
+ $extraItem = DB::World()->selectRow('SELECT * FROM skill_extra_item_template WHERE `spellid` = ?d', $this->subject->id);
$spellLoot = new Loot();
if ($spellLoot->getByContainer(LOOT_SPELL, $this->subject->id) || $extraItem)
@@ -810,13 +697,13 @@ class SpellPage extends GenericPage
}
}
- $this->lvTabs[] = [ItemList::$brickFile, array(
- 'data' => array_values($lv),
+ $this->lvTabs->addListviewTab(new Listview(array(
+ 'data' => $lv,
'name' => $lvName,
'id' => 'contains',
'hiddenCols' => ['side', 'slot', 'source', 'reqlevel'],
'extraCols' => array_unique($extraCols)
- )];
+ ), ItemList::$brickFile));
}
// tab: exclusive with
@@ -879,7 +766,7 @@ class SpellPage extends GenericPage
if (isset($sH))
$tabData['hiddenCols'] = $sH;
- $this->lvTabs[] = [SpellList::$brickFile, $tabData];
+ $this->lvTabs->addListviewTab(new Listview($tabData, SpellList::$brickFile));
}
}
}
@@ -887,13 +774,10 @@ class SpellPage extends GenericPage
}
// tab: linked with
- $rows = DB::World()->select('
- SELECT spell_trigger AS `trigger`,
- spell_effect AS effect,
- type,
- IF(ABS(spell_effect) = ?d, ABS(spell_trigger), ABS(spell_effect)) AS related
+ $rows = DB::World()->select(
+ 'SELECT `spell_trigger` AS "trigger", `spell_effect` AS "effect", `type`, IF(ABS(`spell_effect`) = ?d, ABS(`spell_trigger`), ABS(`spell_effect`)) AS "related"
FROM spell_linked_spell
- WHERE ABS(spell_effect) = ?d OR ABS(spell_trigger) = ?d',
+ WHERE ABS(`spell_effect`) = ?d OR ABS(`spell_trigger`) = ?d',
$this->typeId, $this->typeId, $this->typeId
);
@@ -922,13 +806,13 @@ class SpellPage extends GenericPage
}
}
- $this->lvTabs[] = [SpellList::$brickFile, array(
- 'data' => array_values($data),
+ $this->lvTabs->addListviewTab(new Listview(array(
+ 'data' => $data,
'id' => 'spell-link',
'name' => Lang::spell('linkedWith'),
'hiddenCols' => ['skill', 'name'],
'visibleCols' => ['linkedTrigger', 'linkedEffect']
- )];
+ ), SpellList::$brickFile));
$this->extendGlobalData($linked->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED));
}
@@ -945,11 +829,11 @@ class SpellPage extends GenericPage
$trigger = new SpellList($conditions);
if (!$trigger->error)
{
- $this->lvTabs[] = [SpellList::$brickFile, array(
- 'data' => array_values($trigger->getListviewData()),
+ $this->lvTabs->addListviewTab(new Listview(array(
+ 'data' => $trigger->getListviewData(),
'id' => 'triggered-by',
'name' => '$LANG.tab_triggeredby'
- )];
+ ), SpellList::$brickFile));
$this->extendGlobalData($trigger->getJSGlobals(GLOBALINFO_SELF));
}
@@ -969,17 +853,18 @@ class SpellPage extends GenericPage
$ubCreature = new CreatureList($conditions);
if (!$ubCreature->error)
{
- $this->lvTabs[] = [CreatureList::$brickFile, array(
- 'data' => array_values($ubCreature->getListviewData()),
+ $this->addDataLoader('zones');
+ $this->lvTabs->addListviewTab(new Listview(array(
+ 'data' => $ubCreature->getListviewData(),
'id' => 'used-by-npc',
'name' => '$LANG.tab_usedby'
- )];
+ ), CreatureList::$brickFile));
$this->extendGlobalData($ubCreature->getJSGlobals(GLOBALINFO_SELF));
}
// tab: zone
- if ($areaSpells = DB::World()->select('SELECT `area` AS ARRAY_KEY, `aura_spell` AS "0", `quest_start` AS "1", `quest_end` AS "2", `quest_start_status` AS "3", `quest_end_status` AS "4", `racemask` AS "5", `gender` AS "6" FROM spell_area WHERE spell = ?d', $this->typeId))
+ if ($areaSpells = DB::World()->select('SELECT `area` AS ARRAY_KEY, `aura_spell` AS "0", `quest_start` AS "1", `quest_end` AS "2", `quest_start_status` AS "3", `quest_end_status` AS "4", `racemask` AS "5", `gender` AS "6" FROM spell_area WHERE `spell` = ?d', $this->typeId))
{
$zones = new ZoneList(array(['id', array_keys($areaSpells)]));
if (!$zones->error)
@@ -1072,7 +957,7 @@ class SpellPage extends GenericPage
if ($cnd->toListviewColumn($resultLv, $extraCols))
$this->extendGlobalData($cnd->getJsGlobals());
- $tabData = ['data' => array_values($resultLv)];
+ $tabData = ['data' => $resultLv];
if ($extraCols)
{
@@ -1080,7 +965,7 @@ class SpellPage extends GenericPage
$tabData['hiddenCols'] = ['instancetype'];
}
- $this->lvTabs[] = [ZoneList::$brickFile, $tabData];
+ $this->lvTabs->addListviewTab(new Listview($tabData, ZoneList::$brickFile));
}
}
@@ -1103,7 +988,7 @@ class SpellPage extends GenericPage
}
$tabData = array(
- 'data' => array_values($teaches->getListviewData()),
+ 'data' => $teaches->getListviewData(),
'id' => 'teaches-spell',
'name' => '$LANG.tab_teaches',
'visibleCols' => $vis,
@@ -1112,18 +997,18 @@ class SpellPage extends GenericPage
if (!$teaches->hasSetFields('skillLines'))
$tabData['hiddenCols'] = ['skill'];
- $this->lvTabs[] = [SpellList::$brickFile, $tabData];
+ $this->lvTabs->addListviewTab(new Listview($tabData, SpellList::$brickFile));
}
}
// tab: taught by npc
if ($this->subject->getSources($s) && in_array(SRC_TRAINER, $s))
{
- $trainers = DB::World()->select('
- SELECT cdt.CreatureId AS ARRAY_KEY, ts.ReqSkillLine AS reqSkillId, ts.ReqSkillRank AS reqSkillValue, ts.ReqLevel AS reqLevel, ts.ReqAbility1 AS reqSpellId1, ts.reqAbility2 AS reqSpellId2
+ $trainers = DB::World()->select(
+ 'SELECT cdt.`CreatureId` AS ARRAY_KEY, ts.`ReqSkillLine` AS "reqSkillId", ts.`ReqSkillRank` AS "reqSkillValue", ts.`ReqLevel` AS "reqLevel", ts.`ReqAbility1` AS "reqSpellId1", ts.`reqAbility2` AS "reqSpellId2"
FROM creature_default_trainer cdt
- JOIN trainer_spell ts ON ts.TrainerId = cdt.TrainerId
- WHERE ts.SpellId = ?d',
+ JOIN trainer_spell ts ON ts.`TrainerId` = cdt.`TrainerId`
+ WHERE ts.`SpellId` = ?d',
$this->typeId
);
@@ -1156,16 +1041,17 @@ class SpellPage extends GenericPage
if ($cnd->toListviewColumn($lvData, $extraCols))
$this->extendGlobalData($cnd->getJsGlobals());
- $lvTab = array(
- 'data' => array_values($lvData),
+ $tabData = array(
+ 'data' => $lvData,
'id' => 'taught-by-npc',
'name' => '$LANG.tab_taughtby',
);
if ($extraCols)
- $lvTab['extraCols'] = $extraCols;
+ $tabData['extraCols'] = $extraCols;
- $this->lvTabs[] = [CreatureList::$brickFile, $lvTab];
+ $this->addDataLoader('zones');
+ $this->lvTabs->addListviewTab(new Listview($tabData, CreatureList::$brickFile));
}
}
}
@@ -1182,12 +1068,11 @@ class SpellPage extends GenericPage
$tbsData = [];
if (!$tbSpell->error)
{
- $tbsData = $tbSpell->getListviewData();
- $this->lvTabs[] = [SpellList::$brickFile, array(
- 'data' => array_values($tbsData),
+ $this->lvTabs->addListviewTab(new Listview(array(
+ 'data' => $tbSpell->getListviewData(),
'id' => 'taught-by-spell',
'name' => '$LANG.tab_taughtby'
- )];
+ ), SpellList::$brickFile));
$this->extendGlobalData($tbSpell->getJSGlobals(GLOBALINFO_SELF));
}
@@ -1206,11 +1091,11 @@ class SpellPage extends GenericPage
$tbQuest = new QuestList($conditions);
if (!$tbQuest->error)
{
- $this->lvTabs[] = [QuestList::$brickFile, array(
- 'data' => array_values($tbQuest->getListviewData()),
+ $this->lvTabs->addListviewTab(new Listview(array(
+ 'data' => $tbQuest->getListviewData(),
'id' => 'reward-from-quest',
'name' => '$LANG.tab_rewardfrom'
- )];
+ ), QuestList::$brickFile));
$this->extendGlobalData($tbQuest->getJSGlobals());
}
@@ -1228,11 +1113,11 @@ class SpellPage extends GenericPage
$tbItem = new ItemList($conditions);
if (!$tbItem->error)
{
- $this->lvTabs[] = [ItemList::$brickFile, array(
- 'data' => array_values($tbItem->getListviewData()),
+ $this->lvTabs->addListviewTab(new Listview(array(
+ 'data' => $tbItem->getListviewData(),
'id' => 'taught-by-item',
'name' => '$LANG.tab_taughtby'
- )];
+ ), ItemList::$brickFile));
$this->extendGlobalData($tbItem->getJSGlobals(GLOBALINFO_SELF));
}
@@ -1240,17 +1125,17 @@ class SpellPage extends GenericPage
// tab: enchantments
$conditions = array(
'OR',
- ['AND', ['type1', [1, 3, 7]], ['object1', $this->typeId]],
- ['AND', ['type2', [1, 3, 7]], ['object2', $this->typeId]],
- ['AND', ['type3', [1, 3, 7]], ['object3', $this->typeId]]
+ ['AND', ['type1', [ENCHANTMENT_TYPE_COMBAT_SPELL, ENCHANTMENT_TYPE_EQUIP_SPELL, ENCHANTMENT_TYPE_USE_SPELL]], ['object1', $this->typeId]],
+ ['AND', ['type2', [ENCHANTMENT_TYPE_COMBAT_SPELL, ENCHANTMENT_TYPE_EQUIP_SPELL, ENCHANTMENT_TYPE_USE_SPELL]], ['object2', $this->typeId]],
+ ['AND', ['type3', [ENCHANTMENT_TYPE_COMBAT_SPELL, ENCHANTMENT_TYPE_EQUIP_SPELL, ENCHANTMENT_TYPE_USE_SPELL]], ['object3', $this->typeId]]
);
$enchList = new EnchantmentList($conditions);
if (!$enchList->error)
{
- $this->lvTabs[] = [EnchantmentList::$brickFile, array(
- 'data' => array_values($enchList->getListviewData()),
+ $this->lvTabs->addListviewTab(new Listview(array(
+ 'data' => $enchList->getListviewData(),
'name' => Util::ucFirst(Lang::game('enchantments'))
- ), 'enchantment'];
+ ), EnchantmentList::$brickFile, 'enchantment'));
$this->extendGlobalData($enchList->getJSGlobals());
}
@@ -1262,7 +1147,7 @@ class SpellPage extends GenericPage
if ($this->subject->getField('effect'.$i.'AuraId') == SPELL_AURA_SCREEN_EFFECT)
$seSounds = DB::Aowow()->selectRow('SELECT `ambienceDay`, `ambienceNight`, `musicDay`, `musicNight` FROM ?_screeneffect_sounds WHERE `id` = ?d', $this->subject->getField('effect'.$i.'MiscValue'));
- $activitySounds = DB::Aowow()->selectRow('SELECT * FROM ?_spell_sounds WHERE id = ?d', $this->subject->getField('spellVisualId'));
+ $activitySounds = DB::Aowow()->selectRow('SELECT * FROM ?_spell_sounds WHERE `id` = ?d', $this->subject->getField('spellVisualId'));
array_shift($activitySounds); // remove id-column
if ($soundIDs = $activitySounds + $seSounds)
{
@@ -1274,16 +1159,15 @@ class SpellPage extends GenericPage
if (isset($data[$id]))
$data[$id]['activity'] = $activity; // no index, js wants a string :(
- $tabData = ['data' => array_values($data)];
+ $tabData = ['data' => $data];
if ($activitySounds)
$tabData['visibleCols'] = ['activity'];
$this->extendGlobalData($sounds->getJSGlobals(GLOBALINFO_SELF));
- $this->lvTabs[] = [SoundList::$brickFile, $tabData];
+ $this->lvTabs->addListviewTab(new Listview($tabData, SoundList::$brickFile));
}
}
-
// find associated NPC, Item and merge results
// taughtbypets (unused..?)
// taughtbyquest (usually the spell casted as quest reward teaches something; exclude those seplls from taughtBySpell)
@@ -1298,29 +1182,17 @@ class SpellPage extends GenericPage
if ($tab = $cnd->toListviewTab())
{
$this->extendGlobalData($cnd->getJsGlobals());
- $this->lvTabs[] = $tab;
- }
- }
-
- protected function generateTooltip()
- {
- $power = new \StdClass();
- if (!$this->subject->error)
- {
- $tooltip = $this->subject->renderTooltip(ttSpells: $ttSpells);
- $buff = $this->subject->renderBuff(buffSpells: $bfSpells);
-
- $power->{'name_'.Lang::getLocale()->json()} = $this->subject->getField('name', true);
- $power->icon = rawurlencode($this->subject->getField('iconString', true, true));
- $power->{'tooltip_'.Lang::getLocale()->json()} = $tooltip;
- $power->{'spells_'.Lang::getLocale()->json()} = $ttSpells;
- $power->{'buff_'.Lang::getLocale()->json()} = $buff;
- $power->{'buffspells_'.Lang::getLocale()->json()} = $bfSpells;
+ $this->lvTabs->addDataTab(...$tab);
}
- return sprintf($this->powerTpl, $this->typeId, Lang::getLocale()->value, Util::toJSON($power, JSON_AOWOW_POWER));
+ parent::generate();
}
+
+ /******************************************/
+ /* SpellLoot recursive dropchance builder */
+ /******************************************/
+
private function buildPctStack(float $baseChance, int $maxStack) : string
{
// note: pctStack does not contain absolute values but chances relative to the overall drop chance
@@ -1336,23 +1208,31 @@ class SpellPage extends GenericPage
$pctStack[$i-1] -= $pctStack[$i];
}
- // cleanup tiny fractions
- $pctStack = array_filter($pctStack, function($x) use ($baseChance) { return $x * $baseChance >= 0.01; });
+ // cleanup rounding errors
+ $pctStack = array_map(fn($x) => round($x, 3), $pctStack);
- return json_encode($pctStack, JSON_NUMERIC_CHECK);
+ // cleanup tiny fractions
+ $pctStack = array_filter($pctStack, fn($x) => ($x * $baseChance) >= 0.01);
+
+ return json_encode($pctStack, JSON_NUMERIC_CHECK); // do not replace with Util::toJSON !
}
- private function appendReagentItem(&$reagentResult, $_iId, $_qty, $_mult, $_level, $_path, $alreadyUsed)
+
+ /**********************************/
+ /* recursive reagent list builder */
+ /**********************************/
+
+ private function appendReagentItem(array &$reagentResult, int $itemId, int $qty, int $mult, int $level, string $path, array $alreadyUsed, int $fromSpell = 0) : bool
{
- if (in_array($_iId, $alreadyUsed))
+ if (in_array($itemId, $alreadyUsed))
return false;
$item = DB::Aowow()->selectRow(
- 'SELECT `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8`, i.`id`, ic.`name` AS `iconString`, `quality`
+ 'SELECT `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8`, i.`id`, ic.`name` AS `iconString`, `quality`, `spellId1`, `spellCharges1`
FROM ?_items i
LEFT JOIN ?_icons ic ON ic.`id` = i.`iconId`
WHERE i.`id` = ?d',
- $_iId
+ $itemId
);
if (!$item)
@@ -1360,34 +1240,35 @@ class SpellPage extends GenericPage
$this->extendGlobalIds(Type::ITEM, $item['id']);
- $_level++;
+ // the spell calling this is also on the item and triggering it destroys the item
+ // so effectively we need one more. (see elemental particles and enchantment essences)
+ if ($fromSpell && $fromSpell == $item['spellId1'] && $item['spellCharges1'] == -1)
+ $qty++;
+
+ $level++;
$data = array(
- 'type' => Type::ITEM,
- 'typeId' => $item['id'],
+ 'path' => $path.'.'.Type::ITEM.'-'.$item['id'],
+ 'level' => $level,
+ 'final' => false,
'typeStr' => Type::getFileString(Type::ITEM),
- 'quality' => $item['quality'],
- 'name' => Util::localizedString($item, 'name'),
- 'icon' => $item['iconString'],
- 'qty' => $_qty * $_mult,
- 'path' => $_path.'.'.Type::ITEM.'-'.$item['id'],
- 'level' => $_level
+ 'icon' => new IconElement(Type::ITEM, $item['id'], Util::localizedString($item, 'name'), $qty * $mult, '', $item['quality'], IconElement::SIZE_SMALL, align: 'right', element: 'iconlist-icon')
);
$idx = count($reagentResult);
$reagentResult[] = $data;
$alreadyUsed[] = $item['id'];
- if (!$this->appendReagentSpell($reagentResult, $item['id'], $data['qty'], $data['level'], $data['path'], $alreadyUsed))
+ if (!$this->appendReagentSpell($reagentResult, $item['id'], $qty * $mult, $data['level'], $data['path'], $alreadyUsed))
$reagentResult[$idx]['final'] = true;
return true;
}
- private function appendReagentSpell(&$reagentResult, $_iId, $_qty, $_level, $_path, $alreadyUsed)
+ private function appendReagentSpell(array &$reagentResult, int $itemId, int $qty, int $level, string $path, array $alreadyUsed) : bool
{
- $_level++;
- // assume that tradeSpells only use the first index to create items, so this runs somewhat efficiently >.<
+ $level++;
+ // assume that tradeSpells only use the first index to create items, so this runs somewhat efficiently >.<
$spells = DB::Aowow()->select(
'SELECT `reagent1`, `reagent2`, `reagent3`, `reagent4`, `reagent5`, `reagent6`, `reagent7`, `reagent8`,
`reagentCount1`, `reagentCount2`, `reagentCount3`, `reagentCount4`, `reagentCount5`, `reagentCount6`, `reagentCount7`, `reagentCount8`,
@@ -1399,7 +1280,7 @@ class SpellPage extends GenericPage
WHERE (`effect1CreateItemId` = ?d AND `effect1Id` = ?d)',// OR
// (`effect2CreateItemId` = ?d AND `effect2Id` = ?d) OR
// (`effect3CreateItemId` = ?d AND `effect3Id` = ?d)',
- $_iId, SPELL_EFFECT_CREATE_ITEM //, $_iId, SPELL_EFFECT_CREATE_ITEM, $_iId, SPELL_EFFECT_CREATE_ITEM
+ $itemId, SPELL_EFFECT_CREATE_ITEM //, $itemId, SPELL_EFFECT_CREATE_ITEM, $itemId, SPELL_EFFECT_CREATE_ITEM
);
if (!$spells)
@@ -1414,14 +1295,11 @@ class SpellPage extends GenericPage
$this->extendGlobalIds(Type::SPELL, $sId);
$data = array(
- 'type' => Type::SPELL,
- 'typeId' => $sId,
+ 'path' => $path.'.'.Type::SPELL.'-'.$sId,
+ 'level' => $level,
+ 'final' => false,
'typeStr' => Type::getFileString(Type::SPELL),
- 'name' => Util::localizedString($row, 'name'),
- 'icon' => $row['iconString'],
- 'qty' => $_qty,
- 'path' => $_path.'.'.Type::SPELL.'-'.$sId,
- 'level' => $_level,
+ 'icon' => new IconElement(Type::SPELL, $sId, Util::localizedString($row, 'name'), $qty, size: IconElement::SIZE_SMALL, align: 'right', element: 'iconlist-icon')
);
$reagentResult[] = $data;
@@ -1434,12 +1312,7 @@ class SpellPage extends GenericPage
if ($row['reagent'.$i] <= 0 || $row['reagentCount'.$i] <= 0)
continue;
- // handle edge case elemental crafting material: Mote of X + Crystalized X
- // on use items, that has require more reagents of itself
- if ($row['reagentCount'.$i] == 9 && ($row['iconIdBak'] == 140 || $row['iconIdBak'] == 1921))
- $row['reagentCount'.$i]++;
-
- if ($this->appendReagentItem($reagentResult, $row['reagent'.$i], $row['reagentCount'.$i], $data['qty'], $data['level'], $data['path'], $_aU))
+ if ($this->appendReagentItem($reagentResult, $row['reagent'.$i], $row['reagentCount'.$i], $qty, $data['level'], $data['path'], $_aU, $sId))
{
$hasUnusedReagents = true;
$didAppendSomething = true;
@@ -1453,49 +1326,55 @@ class SpellPage extends GenericPage
return $didAppendSomething;
}
- private function createReagentList() : array
+ private function createReagentList() : void
{
$reagentResult = [];
$enhanced = false;
+ $reagents = $this->subject->getReagentsForCurrent();
- if ($reagents = $this->subject->getReagentsForCurrent())
+ if (!$reagents)
+ return;
+
+ foreach ($this->subject->relItems->iterate() as $iId => $__)
{
- foreach ($this->subject->relItems->iterate() as $iId => $__)
- {
- if (!in_array($iId, array_keys($reagents)))
- continue;
+ if (!in_array($iId, array_keys($reagents)))
+ continue;
- $data = array(
- 'type' => Type::ITEM,
- 'typeId' => $iId,
- 'typeStr' => Type::getFileString(Type::ITEM),
- 'quality' => $this->subject->relItems->getField('quality'),
- 'name' => $this->subject->relItems->getField('name', true),
- 'icon' => $this->subject->relItems->getField('iconString'),
- 'qty' => $reagents[$iId][1],
- 'path' => Type::ITEM.'-'.$iId, // id of the html-element
- 'level' => 0 // depths in array, used for indentation
- );
+ $data = array(
+ 'path' => Type::ITEM.'-'.$iId, // id of the html-element
+ 'level' => 0, // depths in array, used for indentation
+ 'final' => false,
+ 'typeStr' => Type::getFileString(Type::ITEM),
+ 'icon' => new IconElement(
+ Type::ITEM,
+ $iId,
+ $this->subject->relItems->getField('name', true),
+ $reagents[$iId][1],
+ quality: $this->subject->relItems->getField('quality'),
+ size: IconElement::SIZE_SMALL,
+ align: 'right',
+ element: 'iconlist-icon'
+ )
+ );
- $idx = count($reagentResult);
- $reagentResult[] = $data;
+ $idx = count($reagentResult);
+ $reagentResult[] = $data;
- // start with self and current original item in usedEntries (spell < 0; item > 0)
- if ($this->appendReagentSpell($reagentResult, $iId, $data['qty'], 0, $data['path'], [-$this->typeId, $iId]))
- $enhanced = true;
- else
- $reagentResult[$idx]['final'] = true;
- }
+ // start with self and current original item in usedEntries (spell < 0; item > 0)
+ if ($this->appendReagentSpell($reagentResult, $iId, $reagents[$iId][1], 0, $data['path'], [-$this->typeId, $iId]))
+ $enhanced = true;
+ else
+ $reagentResult[$idx]['final'] = true;
}
// increment all indizes (by prepending null and removing it again)
array_unshift($reagentResult, null);
unset($reagentResult[0]);
- return [$enhanced, $reagentResult];
+ $this->reagents = [$enhanced, $reagentResult];
}
- private function createScalingData() : array // calculation mostly like seen in TC
+ private function createScalingData() : void // calculation mostly like seen in TC
{
$scaling = ['directSP' => 0, 'dotSP' => 0, 'directAP' => 0, 'dotAP' => 0];
$pMask = $this->subject->periodicEffectsMask();
@@ -1517,18 +1396,16 @@ class SpellPage extends GenericPage
$allDoTs = false;
}
- if ($s = DB::World()->selectRow('SELECT `direct_bonus` AS `directSP`, `dot_bonus` AS `dotSP`, `ap_bonus` AS `directAP`, `ap_dot_bonus` AS `dotAP` FROM spell_bonus_data WHERE `entry` = ?d', $this->firstRank))
+ if ($s = DB::World()->selectRow('SELECT `direct_bonus` AS "directSP", `dot_bonus` AS "dotSP", `ap_bonus` AS "directAP", `ap_dot_bonus` AS "dotAP" FROM spell_bonus_data WHERE `entry` = ?d', $this->firstRank))
$scaling = $s;
- if (!$this->subject->isDamagingSpell() && !$this->subject->isHealingSpell())
- return array_filter($scaling, fn($x) => $x > 0);
-
- // only calculate for class/pet spells
- if (!in_array($this->subject->getField('typeCat'), [-2, -3, -7, 7]))
- return array_filter($scaling, fn($x) => $x > 0);
-
- if ($this->subject->getField('damageClass') == SPELL_DAMAGE_CLASS_NONE)
- return array_filter($scaling, fn($x) => $x > 0);
+ if ((!$this->subject->isDamagingSpell() && !$this->subject->isHealingSpell()) ||
+ !in_array($this->subject->getField('typeCat'), [-2, -3, -7, 7]) ||
+ $this->subject->getField('damageClass') == SPELL_DAMAGE_CLASS_NONE)
+ {
+ $this->scaling = array_filter($scaling, fn($x) => $x > 0);
+ return;
+ }
foreach ($scaling as $k => $v)
{
@@ -1555,7 +1432,7 @@ class SpellPage extends GenericPage
else if ($allDoTs) // if all used effects are periodic, dont calculate direct component
continue;
- // Damage over Time spells bonus calculation
+ // damage over time spells bonus calculation
$dotFactor = 1.0;
if ($isDOT)
{
@@ -1570,7 +1447,7 @@ class SpellPage extends GenericPage
}
}
- // Distribute Damage over multiple effects, reduce by AoE
+ // distribute damage over multiple effects, reduce by AoE
$castingTime = $this->subject->getCastingTimeForBonus($isDOT);
// 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
@@ -1593,10 +1470,10 @@ class SpellPage extends GenericPage
$scaling[$k] = 0; // would be 1 ($dotFactor), but we dont want it to be displayed
}
- return array_filter($scaling, fn($x) => $x > 0);
+ $this->scaling = array_filter($scaling, fn($x) => $x > 0);
}
- private function createRequiredItems() : string
+ private function createRequiredItems() : void
{
// parse itemClass & itemSubClassMask
$class = $this->subject->getField('equippedItemClass');
@@ -1604,7 +1481,7 @@ class SpellPage extends GenericPage
$invType = $this->subject->getField('equippedItemInventoryTypeMask');
if ($class <= 0)
- return '';
+ return;
$tip = 'Class: '.$class.'
SubClass: '.Util::asHex($subClass);
$text = Lang::getRequiredItems($class, $subClass, false);
@@ -1631,24 +1508,13 @@ class SpellPage extends GenericPage
$_[] = $str;
$tip .= '
'.Lang::item('slot').Lang::main('colon').Util::asHex($invType);
- $text .= ' '.Lang::spell('_inSlot').Lang::main('colon').implode(', ', $_);
+ $text .= ' '.Lang::spell('_inSlot').implode(', ', $_);
}
- return $this->fmtStaffTip($text, $tip);
+ $this->items = $this->fmtStaffTip($text, $tip);
}
- private function createTools() : array
- {
- $tools = $this->subject->getToolsForCurrent();
-
- // prepare Tools
- foreach ($tools as &$tool)
- $tool['url'] = isset($tool['itemId']) ? '?item='.$tool['itemId'] : '?items&filter=cr=91;crs='.$tool['id'].';crv=0';
-
- return $tools;
- }
-
- private function createEffects() : array
+ private function createEffects() : void
{
// proc data .. maybe use more information..?
$procData = array(
@@ -1656,7 +1522,7 @@ class SpellPage extends GenericPage
'cooldown' => 0
);
- if ($sp = DB::World()->selectRow('SELECT IF(`ProcsPerMinute` > 0, -`ProcsPerMinute`, `Chance`) AS `chance`, `Cooldown` AS `cooldown` FROM `spell_proc` WHERE ABS(`SpellId`) = ?d', $this->firstRank))
+ if ($sp = DB::World()->selectRow('SELECT IF(`ProcsPerMinute` > 0, -`ProcsPerMinute`, `Chance`) AS "chance", `Cooldown` AS "cooldown" FROM `spell_proc` WHERE ABS(`SpellId`) = ?d', $this->firstRank))
{
$procData['chance'] = $sp['chance'] ?: $procData['chance'];
$procData['cooldown'] = $sp['cooldown'] ?: $procData['cooldown'];
@@ -1665,7 +1531,7 @@ class SpellPage extends GenericPage
$effects = [];
$spellIdx = array_unique(array_merge($this->subject->canTriggerSpell(), $this->subject->canTeachSpell()));
$itemIdx = $this->subject->canCreateItem();
- $perfItem = DB::World()->selectRow('SELECT `perfectItemType` AS `itemId`, `requiredSpecialization` AS `reqSpellId`, `perfectCreateChance` AS `chance` FROM skill_perfect_item_template WHERE `spellId` = ?d', $this->typeId);
+ $perfItem = DB::World()->selectRow('SELECT `perfectItemType` AS "itemId", `requiredSpecialization` AS "reqSpellId", `perfectCreateChance` AS "chance" FROM skill_perfect_item_template WHERE `spellId` = ?d', $this->typeId);
// Iterate through all effects:
for ($i = 1; $i < 4; $i++)
@@ -1710,12 +1576,13 @@ class SpellPage extends GenericPage
{
$itemEntry = $this->subject->relItems->getEntry($itemId);
- $_icon = array(
- 'type' => Type::ITEM,
- 'typeId' => $itemId,
- 'name' => $itemEntry ? $this->subject->relItems->getField('name', true) : '',
- 'quality' => $itemEntry ? $this->subject->relItems->getField('quality') : '',
- 'count' => ($effBP + 1) . ($effDS > 1 ? '-' . ($effBP + $effDS) : '')
+ $_icon = new IconElement(
+ Type::ITEM,
+ $itemId,
+ $itemEntry ? $this->subject->relItems->getField('name', true) : Util::ucFirst(Lang::game('item')).' #'.$itemId,
+ ($effBP + 1) . ($effDS > 1 ? '-' . ($effBP + $effDS) : ''),
+ quality: $itemEntry ? $this->subject->relItems->getField('quality') : '',
+ link: !empty($itemEntry)
);
}
@@ -1728,11 +1595,14 @@ class SpellPage extends GenericPage
$_perfItem = array(
'spellId' => $perfItem['reqSpellId'],
'spellName' => $cndSpell->getField('name', true),
- 'itemId' => $perfItem['itemId'],
- 'itemName' => $this->subject->relItems->getField('name', true),
- 'quality' => $this->subject->relItems->getField('quality'),
'icon' => $cndSpell->getField('iconString'),
- 'chance' => $perfItem['chance']
+ 'chance' => $perfItem['chance'],
+ 'item' => new IconElement(
+ Type::ITEM,
+ $perfItem['itemId'],
+ $this->subject->relItems->getField('name', true),
+ quality: $this->subject->relItems->getField('quality')
+ )
);
}
}
@@ -1749,12 +1619,11 @@ class SpellPage extends GenericPage
{
$trig = new SpellList(array(['s.id', (int)$triggeredSpell]));
- $_icon = array(
- 'type' => Type::SPELL,
- 'typeId' => $triggeredSpell,
- 'name' => $trig->error ? '' : $trig->getField('name', true),
- 'quality' => 0,
- 'count' => 0
+ $_icon = new IconElement(
+ Type::SPELL,
+ $triggeredSpell,
+ $trig->error ? Util::ucFirst(Lang::game('spell')).' #'.$triggeredSpell : $trig->getField('name', true),
+ link: !$trig->error
);
$this->extendGlobalData($trig->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED));
@@ -1768,24 +1637,24 @@ class SpellPage extends GenericPage
$_footer['value'] = [$effBP + ($effDS ? 1 : 0), $effBP + $effDS];
if ($this->subject->getField('effect'.$i.'RadiusMax') > 0)
- $_footer['radius'] = Lang::spell('_radius').Lang::main('colon').$this->subject->getField('effect'.$i.'RadiusMax').' '.Lang::spell('_distUnit');;
+ $_footer['radius'] = Lang::spell('_radius').$this->subject->getField('effect'.$i.'RadiusMax').' '.Lang::spell('_distUnit');
if ($this->subject->getField('effect'.$i.'Periode') > 0)
- $_footer['interval'] = Lang::spell('_interval').Lang::main('colon').Util::formatTime($this->subject->getField('effect'.$i.'Periode'));
+ $_footer['interval'] = Lang::spell('_interval').Util::formatTime($this->subject->getField('effect'.$i.'Periode'));
if ($_ = $this->subject->getField('effect'.$i.'Mechanic'))
$_footer['mechanic'] = Lang::game('mechanic').Lang::main('colon').Lang::game('me', $_);
if (in_array($i, $this->subject->canTriggerSpell()) && $procData['chance'] && $procData['chance'] < 100)
{
- $_footer['proc'] = $procData['chance'] < 0 ? Lang::spell('ppm', [Lang::nf(-$procData['chance'], 1)]) : Lang::spell('procChance') . Lang::main('colon') . $procData['chance'] . '%';
+ $_footer['proc'] = $procData['chance'] < 0 ? Lang::spell('ppm', [Lang::nf(-$procData['chance'], 1)]) : Lang::spell('procChance') . $procData['chance'] . '%';
if ($procData['cooldown'])
$_footer['procCD'] = Lang::game('cooldown', [Util::formatTime($procData['cooldown'], true)]);
}
// Effect Name
if ($_ = Lang::spell('effects', $effId))
- $_nameEffect = $this->fmtStaffTip($_, 'EffectId: '.$effId);
+ $_nameEffect = ''.$this->fmtStaffTip($_, 'EffectId: '.$effId).'';
else
$_nameEffect = Lang::spell('unkEffect', [$effId]);
@@ -1806,16 +1675,16 @@ class SpellPage extends GenericPage
case SPELL_EFFECT_BIND:
if ($effMV <= 0)
$_nameMV = $this->fmtStaffTip(Lang::spell('currentArea'), 'MiscValue: '.$effMV);
- else if ($_ = ZoneList::getName($effMV))
- $_nameMV = ''.$_.'';
+ else if ($a = ZoneList::makeLink($effMV))
+ $_nameMV = $a;
else
$_nameMV = Util::ucFirst(Lang::game('zone')).' #'.$effMV;
break;
case SPELL_EFFECT_QUEST_COMPLETE:
case SPELL_EFFECT_CLEAR_QUEST:
case SPELL_EFFECT_QUEST_FAIL:
- if ($_ = QuestList::getName($effMV))
- $_nameMV = ''.$_.'';
+ if ($a = QuestList::makeLink($effMV))
+ $_nameMV = $a;
else
$_nameMV = Util::ucFirst(Lang::game('quest')).' #'.$effMV;
break;
@@ -1829,8 +1698,8 @@ class SpellPage extends GenericPage
case SPELL_EFFECT_SUMMON_DEMON:
case SPELL_EFFECT_KILL_CREDIT:
case SPELL_EFFECT_KILL_CREDIT2:
- if ($_ = CreatureList::getName($effMV))
- $_nameMV = ''.$_.'';
+ if ($a = CreatureList::makeLink($effMV))
+ $_nameMV = $a;
else
$_nameMV = Util::ucFirst(Lang::game('npc')).' #'.$effMV;
break;
@@ -1842,8 +1711,8 @@ class SpellPage extends GenericPage
case SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY:
case SPELL_EFFECT_ENCHANT_HELD_ITEM:
case SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC:
- if ($_ = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantment WHERE id = ?d', $effMV))
- $_nameMV = ''.Util::localizedString($_, 'name').'';
+ if ($a = EnchantmentList::makeLink($effMV, cssClass: 'q2'))
+ $_nameMV = $a;
else
$_nameMV = Util::ucFirst(Lang::game('enchantment')).' #'.$effMV;
break;
@@ -1862,8 +1731,8 @@ class SpellPage extends GenericPage
case SPELL_EFFECT_SUMMON_OBJECT_SLOT2:
case SPELL_EFFECT_SUMMON_OBJECT_SLOT3:
case SPELL_EFFECT_SUMMON_OBJECT_SLOT4:
- if ($_ = GameobjectList::getName($effMV))
- $_nameMV = ''.$_.'';
+ if ($a = GameobjectList::makeLink($effMV))
+ $_nameMV = $a;
else
$_nameMV = Util::ucFirst(Lang::game('object')).' #'.$effMV;
break;
@@ -1874,8 +1743,8 @@ class SpellPage extends GenericPage
case SPELL_EFFECT_APPLY_GLYPH:
if ($_ = DB::Aowow()->selectCell('SELECT `spellId` FROM ?_glyphproperties WHERE `id` = ?d', $effMV))
{
- if ($n = SpellList::getName($_))
- $_nameMV = ''.$n.'';
+ if ($a = SpellList::makeLink($_))
+ $_nameMV = $a;
else
$_nameMV = Util::ucFirst(Lang::game('spell')).' #'.$_;
}
@@ -1897,8 +1766,8 @@ class SpellPage extends GenericPage
break;
case SPELL_EFFECT_SKILL_STEP:
case SPELL_EFFECT_SKILL:
- if ($_ = SkillList::getName($effMV))
- $_nameMV = ''.$_.'';
+ if ($a = SkillList::makeLink($effMV))
+ $_nameMV = $a;
else
$_nameMV = Util::ucFirst(Lang::game('skill')).' #'.$effMV;
break;
@@ -1917,8 +1786,8 @@ class SpellPage extends GenericPage
$_nameMV = Util::ucFirst(Lang::game('sound')).' #'.$effMV;
break;
case SPELL_EFFECT_REPUTATION:
- if ($_ = FactionList::getName($effMV))
- $_nameMV = ''.$_.'';
+ if ($a = FactionList::makeLink($effMV))
+ $_nameMV = $a;
else
$_nameMV = Util::ucFirst(Lang::game('faction')).' #'.$effMV;
@@ -1955,7 +1824,7 @@ class SpellPage extends GenericPage
case SPELL_EFFECT_APPLY_AREA_AURA_OWNER:
{
if ($effAura > 0 && ($_ = Lang::spell('auras', $effAura)))
- $_nameAura = $this->fmtStaffTip($_, 'AuraId: '.$effAura);
+ $_nameAura = ''.$this->fmtStaffTip($_, 'AuraId: '.$effAura).'';
else if ($effAura > 0)
$_nameAura = Lang::spell('unkAura', [$effAura]);
@@ -2102,8 +1971,8 @@ class SpellPage extends GenericPage
break;
case SPELL_AURA_MOD_SKILL:
case SPELL_AURA_MOD_SKILL_TALENT:
- if ($_ = SkillList::getName($effMV))
- $_nameMV = ''.$_.'';
+ if ($a = SkillList::makeLink($effMV))
+ $_nameMV = $a;
else
$_nameMV = Util::ucFirst(Lang::game('skill')).' #'.$effMV;
break;
@@ -2166,8 +2035,8 @@ class SpellPage extends GenericPage
case SPELL_AURA_CHANGE_MODEL_FOR_ALL_HUMANOIDS:
case SPELL_AURA_X_RAY:
case SPELL_AURA_MOD_FAKE_INEBRIATE:
- if ($effMV && $_ = CreatureList::getName($effMV))
- $_nameMV = ''.$_.'';
+ if ($effMV && $a = CreatureList::makeLink($effMV))
+ $_nameMV = $a;
else
$_nameMV = Util::ucFirst(Lang::game('npc')).' #'.$effMV;
break;
@@ -2178,8 +2047,8 @@ class SpellPage extends GenericPage
case SPELL_AURA_MOD_FACTION_REPUTATION_GAIN:
if ($effAura == SPELL_AURA_MOD_FACTION_REPUTATION_GAIN)
$valueFmt = '%s%%';
- if ($_ = FactionList::getName($effMV))
- $_nameMV = ''.$_.'';
+ if ($a = FactionList::makeLink($effMV))
+ $_nameMV = $a;
else
$_nameMV = Util::ucFirst(Lang::game('faction')).' #'.$effMV;
break; // also breaks for SPELL_AURA_FORCE_REACTION
@@ -2221,6 +2090,7 @@ class SpellPage extends GenericPage
break;
case SPELL_AURA_MOD_HEALTH_REGEN_PERCENT:
case SPELL_AURA_OBS_MOD_HEALTH:
+ case SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT:
case SPELL_AURA_MOD_ARMOR_PENETRATION_PCT:
case SPELL_AURA_MOD_SCALE:
case SPELL_AURA_MOD_SCALE_2:
@@ -2263,9 +2133,9 @@ class SpellPage extends GenericPage
if ($_footer['value'][0] != $_footer['value'][1])
$buffer .= Lang::game('valueDelim').sprintf($valueFmt, $_footer['value'][1]);
if ($effRPPL != 0)
- $buffer .= sprintf(Lang::spell('costPerLevel'), sprintf($valueFmt, $effRPPL));
+ $buffer .= Lang::spell('costPerLevel', [sprintf($valueFmt, $effRPPL)]);
if ($effPPCP != 0)
- $buffer .= sprintf(Lang::spell('pointsPerCP'), sprintf($valueFmt, $effPPCP));
+ $buffer .= Lang::spell('pointsPerCP', [sprintf($valueFmt, $effPPCP)]);
if (isset($_footer['value'][2]))
$buffer .= $_footer['value'][2];
@@ -2294,14 +2164,15 @@ class SpellPage extends GenericPage
'perfectItem' => $_perfItem,
'name' => $_header,
'footer' => $_footer,
- 'markup' => $_markup
+ 'markup' => $_markup,
+ 'modifies' => [] // may be set later
);
}
- return $effects;
+ $this->effects = $effects;
}
- private function createAttributesList() : array
+ private function createAttributesList() : void
{
$list = [];
for ($i = 0; $i < 8; $i++)
@@ -2325,7 +2196,198 @@ class SpellPage extends GenericPage
}
}
- return $list;
+ $this->attributes = $list;
+ }
+
+ private function generatePath()
+ {
+ $cat = $this->subject->getField('typeCat');
+ $cf = $this->subject->getField('cuFlags');
+
+ $this->breadcrumb[] = $cat;
+
+ // reconstruct path
+ switch ($cat)
+ {
+ case -2:
+ case 7:
+ case -13:
+ if ($cl = $this->subject->getField('reqClassMask'))
+ $this->breadcrumb[] = ChrClass::fromMask($cl)[0];
+ else if ($sf = $this->subject->getField('spellFamilyId'))
+ foreach (ChrClass::cases() as $cl)
+ if ($cl->spellFamily() == $sf)
+ {
+ $this->breadcrumb[] = $cl->value;
+ break;
+ }
+
+ if ($cat == -13)
+ $this->breadcrumb[] = ($cf & (SPELL_CU_GLYPH_MAJOR | SPELL_CU_GLYPH_MINOR)) >> 6;
+ else
+ $this->breadcrumb[] = $this->subject->getField('skillLines')[0];
+
+ break;
+ case 9:
+ case -3:
+ case 11:
+ $this->breadcrumb[] = $this->subject->getField('skillLines')[0];
+
+ if ($cat == 11)
+ if ($_ = $this->subject->getField('reqSpellId'))
+ $this->breadcrumb[] = $_;
+
+ break;
+ case -11:
+ foreach (SpellList::$skillLines as $line => $skills)
+ if (in_array($this->subject->getField('skillLines')[0], $skills))
+ $this->breadcrumb[] = $line;
+ break;
+ case -7: // only spells unique in skillLineAbility will always point to the right skillLine :/
+ if ($cf & SPELL_CU_PET_TALENT_TYPE0)
+ $this->breadcrumb[] = 411; // Ferocity
+ else if ($cf & SPELL_CU_PET_TALENT_TYPE1)
+ $this->breadcrumb[] = 409; // Tenacity
+ else if ($cf & SPELL_CU_PET_TALENT_TYPE2)
+ $this->breadcrumb[] = 410; // Cunning
+ break;
+ case -5:
+ if ($this->subject->getField('effect2AuraId') == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED ||
+ $this->subject->getField('effect3AuraId') == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED)
+ $this->breadcrumb[] = 2; // flying (also contains SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED, so checked first)
+ else if ($this->subject->getField('effect2AuraId') == SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED ||
+ $this->subject->getField('effect3AuraId') == SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED)
+ $this->breadcrumb[] = 1; // ground
+ else
+ $this->breadcrumb[] = 3; // misc
+ }
+ }
+
+ private function createInfobox() : void
+ {
+ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags'));
+ $typeCat = $this->subject->getField('typeCat');
+
+ // level
+ if (!in_array($typeCat, [-5, -6])) // not mount or vanity pet
+ {
+ if ($_ = $this->subject->getField('talentLevel'))
+ $infobox[] = (in_array($typeCat, [-2, 7, -13]) ? Lang::game('reqLevel', [$_]) : Lang::game('level').Lang::main('colon').$_);
+ else if ($_ = $this->subject->getField('spellLevel'))
+ $infobox[] = (in_array($typeCat, [-2, 7, -13]) ? Lang::game('reqLevel', [$_]) : Lang::game('level').Lang::main('colon').$_);
+ }
+
+ $jsg = [];
+ // races
+ if ($_ = Lang::getRaceString($this->subject->getField('reqRaceMask'), $jsg, Lang::FMT_MARKUP))
+ {
+ $this->extendGlobalIds(Type::CHR_RACE, ...$jsg);
+ $t = count($jsg) == 1 ? Lang::game('race') : Lang::game('races');
+ $infobox[] = Util::ucFirst($t).Lang::main('colon').$_;
+ }
+
+ // classes
+ if ($_ = Lang::getClassString($this->subject->getField('reqClassMask'), $jsg, Lang::FMT_MARKUP))
+ {
+ $this->extendGlobalIds(Type::CHR_CLASS, ...$jsg);
+ $t = count($jsg) == 1 ? Lang::game('class') : Lang::game('classes');
+ $infobox[] = Util::ucFirst($t).Lang::main('colon').$_;
+ }
+
+ // spell focus
+ if ($_ = $this->subject->getField('spellFocusObject'))
+ {
+ if ($sfObj = DB::Aowow()->selectRow('SELECT * FROM ?_spellfocusobject WHERE `id` = ?d', $_))
+ {
+ $n = Util::localizedString($sfObj, 'name');
+ if ($objId = DB::Aowow()->selectCell('SELECT `id` FROM ?_objects WHERE `spellFocusId` = ?d', $_))
+ $n = '[url=?object='.$objId.']'.$n.'[/url]';
+
+ $infobox[] = Lang::game('requires2').' '.$n;
+ }
+ }
+
+ // primary & secondary trades
+ if (in_array($typeCat, [9, 11]))
+ {
+ // skill
+ if ($_ = $this->subject->getField('skillLines')[0])
+ {
+ $this->extendGlobalIds(Type::SKILL, $_);
+
+ $bar = Lang::game('requires', [' [skill='.$_.']']);
+ if ($_ = $this->subject->getField('learnedAt'))
+ $bar .= ' ('.$_.')';
+
+ $infobox[] = $bar;
+ }
+
+ // specialization
+ if ($_ = $this->subject->getField('reqSpellId'))
+ {
+ $this->extendGlobalIds(Type::SPELL, $_);
+ $infobox[] = Lang::game('requires2').' [spell='.$_.']';
+ }
+
+ // difficulty
+ if ($_ = $this->subject->getColorsForCurrent())
+ $infobox[] = Lang::formatSkillBreakpoints($_);
+ }
+
+ // accquisition.. 10: starter spell; 7: discovery
+ if ($this->subject->getSources($s))
+ {
+ if (in_array(SRC_STARTER, $s))
+ $infobox[] = Lang::spell('starter');
+ else if (in_array(SRC_DISCOVERY, $s))
+ $infobox[] = Lang::spell('discovered');
+ }
+
+ // training cost
+ if ($cost = $this->subject->getField('trainingCost'))
+ $infobox[] = Lang::spell('trainingCost').'[money='.$cost.']';
+
+ // icon
+ if ($_ = $this->subject->getField('iconId'))
+ {
+ $this->extendGlobalIds(Type::ICON, $_);
+ $infobox[] = Util::ucFirst(lang::game('icon')).Lang::main('colon').'[icondb='.$_.' name=true]';
+ }
+
+ // used in mode
+ foreach ($this->difficulties as $n => $id)
+ if ($id == $this->typeId)
+ $infobox[] = Lang::game('mode').Lang::game('modes', $n);
+
+ // Creature Type from Aura: Shapeshift
+ foreach ($this->modelInfo as $mI)
+ {
+ if (!isset($mI['creatureType']))
+ continue;
+
+ if ($mI['creatureType'] > 0)
+ $infobox[] = Lang::game('type').Lang::game('ct', $mI['creatureType']);
+
+ break;
+ }
+
+ // spell script
+ if (User::isInGroup(U_GROUP_STAFF))
+ if ($_ = DB::World()->selectCell('SELECT `ScriptName` FROM spell_script_names WHERE ABS(`spell_id`) = ?d', $this->firstRank))
+ $infobox[] = 'Script'.Lang::main('colon').$_;
+
+
+ $this->infobox = new InfoboxMarkup($infobox, ['allow' => Markup::CLASS_STAFF, 'dbpage' => true], 'infobox-contents0');
+
+ // append glyph symbol if available
+ $glyphId = 0;
+ for ($i = 1; $i < 4; $i++)
+ if ($this->subject->getField('effect'.$i.'Id') == SPELL_EFFECT_APPLY_GLYPH)
+ $glyphId = $this->subject->getField('effect'.$i.'MiscValue');
+
+ if ($_ = DB::Aowow()->selectCell('SELECT ic.`name` FROM ?_glyphproperties gp JOIN ?_icons ic ON gp.`iconId` = ic.`id` WHERE gp.`spellId` = ?d { OR gp.`id` = ?d }', $this->typeId, $glyphId ?: DBSIMPLE_SKIP))
+ if (file_exists('static/images/wow/Interface/Spellbook/'.$_.'.png'))
+ $this->infobox->append('[img src='.Cfg::get('STATIC_URL').'/images/wow/Interface/Spellbook/'.$_.'.png border=0 float=center margin=15]');
}
}
diff --git a/endpoints/spell/spell_power.php b/endpoints/spell/spell_power.php
new file mode 100644
index 00000000..957232f0
--- /dev/null
+++ b/endpoints/spell/spell_power.php
@@ -0,0 +1,58 @@
+ ['filter' => FILTER_CALLBACK, 'options' => [Locale::class, 'tryFromDomain']]
+ );
+
+ public function __construct(string $param)
+ {
+ parent::__construct($param);
+
+ // temp locale
+ if ($this->_get['domain'])
+ Lang::load($this->_get['domain']);
+
+ $this->typeId = intVal($param);
+ }
+
+ protected function generate() : void
+ {
+ $spell = new SpellList([['id', $this->typeId]]);
+ if ($spell->error)
+ $this->cacheType = CACHE_TYPE_NONE;
+ else
+ {
+ $tooltip = $spell->renderTooltip(ttSpells: $ttSpells);
+ $buff = $spell->renderBuff(buffSpells: $bfSpells);
+
+ $opts = array(
+ 'name' => $spell->getField('name', true),
+ 'icon' => $spell->getField('iconString'),
+ 'tooltip' => $tooltip,
+ 'spells' => $ttSpells,
+ 'buff' => $buff,
+ 'buffspells' => $bfSpells
+ );
+ }
+
+ $this->result = new Tooltip(self::POWER_TEMPLATE, $this->typeId, $opts ?? []);
+ }
+}
+
+?>
diff --git a/pages/spells.php b/endpoints/spells/spells.php
similarity index 75%
rename from pages/spells.php
rename to endpoints/spells/spells.php
index 25352540..db58d8e9 100644
--- a/pages/spells.php
+++ b/endpoints/spells/spells.php
@@ -6,25 +6,38 @@ if (!defined('AOWOW_REVISION'))
die('illegal access');
-// menuId 1: Spell g_initPath()
-// tabId 0: Database g_initHeader()
-class SpellsPage extends GenericPage
+class SpellsBaseResponse extends TemplateResponse implements ICache
{
- use TrListPage;
+ use TrListPage, TrCache;
- protected $classPanel = false;
- protected $glyphPanel = false;
+ private const SHORT_FILTER = array(
+ SKILL_FIRST_AID => [ 6, 7],
+ SKILL_BLACKSMITHING => [ 2, 4],
+ SKILL_LEATHERWORKING => [ 8, 1],
+ SKILL_ALCHEMY => [ 1, 6],
+ SKILL_COOKING => [ 3, 5],
+ SKILL_MINING => [ 9, 0],
+ SKILL_TAILORING => [10, 2],
+ SKILL_ENGINEERING => [ 5, 3],
+ SKILL_ENCHANTING => [ 4, 8],
+ SKILL_FISHING => [ 0, 9],
+ SKILL_JEWELCRAFTING => [ 7, 10],
+ SKILL_INSCRIPTION => [15, 0],
+ );
- protected $type = Type::SPELL;
- protected $tpl = 'spells';
- protected $path = [0, 1];
- protected $tabId = 0;
- protected $mode = CACHE_TYPE_PAGE;
- protected $scripts = [[SC_JS_FILE, 'js/filters.js']];
+ protected int $type = Type::SPELL;
+ protected int $cacheType = CACHE_TYPE_PAGE;
- protected $_get = ['filter' => ['filter' => FILTER_UNSAFE_RAW]];
+ protected string $template = 'spells';
+ protected string $pageName = 'spells';
+ protected ?int $activeTab = parent::TAB_DATABASE;
+ protected array $breadcrumb = [0, 1];
- protected $validCats = array(
+ 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 = array(
-2 => array( // Talents: Class => Skill
1 => [ 26, 256, 257],
2 => [594, 267, 184],
@@ -59,7 +72,7 @@ class SpellsPage extends GenericPage
9 => [355, 354, 593],
11 => [574, 134, 573]
),
- 9 => SKILLS_TRADE_SECONDARY, // Secondary Skills
+ 9 => [129, 185, 356, 762], // Secondary Skills
11 => array( // Professions: Skill => Spell
SKILL_ALCHEMY => true,
SKILL_BLACKSMITHING => [9788, 9787, 17041, 17040, 17039],
@@ -75,41 +88,87 @@ class SpellsPage extends GenericPage
)
);
- private $shortFilter = array(
- SKILL_FIRST_AID => [ 6, 7],
- SKILL_BLACKSMITHING => [ 2, 4],
- SKILL_LEATHERWORKING => [ 8, 1],
- SKILL_ALCHEMY => [ 1, 6],
- SKILL_COOKING => [ 3, 5],
- SKILL_MINING => [ 9, 0],
- SKILL_TAILORING => [10, 2],
- SKILL_ENGINEERING => [ 5, 3],
- SKILL_ENCHANTING => [ 4, 8],
- SKILL_FISHING => [ 0, 9],
- SKILL_JEWELCRAFTING => [ 7, 10],
- SKILL_INSCRIPTION => [15, 0],
- );
+ public bool $classPanel = false;
+ public bool $glyphPanel = false;
-
- public function __construct($pageCall, $pageParam)
+ public function __construct(string $pageParam)
{
$this->getCategoryFromUrl($pageParam);
- parent::__construct($pageCall, $pageParam);
+ parent::__construct($pageParam);
- $this->filterObj = new SpellListFilter($this->_get['filter'] ?? '', ['parentCats' => $this->category]);
-
- $this->name = Util::ucFirst(Lang::game('spells'));
$this->subCat = $pageParam !== '' ? '='.$pageParam : '';
+ $this->filter = new SpellListFilter($this->_get['filter'] ?? '', ['parentCats' => $this->category]);
+ $this->filterError = $this->filter->error;
}
- protected function generateContent()
+ protected function generate() : void
{
- $conditions = [];
- $visibleCols = [];
- $hiddenCols = [];
- $extraCols = [];
- $tabData = ['data' => []];
+ $this->h1 = Util::ucFirst(Lang::game('spells'));
+
+ $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
+
+
+ /*************/
+ /* Menu Path */
+ /*************/
+
+ foreach ($this->category as $c)
+ $this->breadcrumb[] = $c;
+
+ $fiForm = $this->filter->values;
+ if (count($this->breadcrumb) == 4 && $this->category[0] == -13 && count($fiForm['gl']) == 1)
+ $this->breadcrumb[] = $fiForm['gl'];
+
+
+ /**************/
+ /* Page Title */
+ /**************/
+
+ $foo = [];
+ $c = $this->category; // shothand
+ if (isset($c[2]) && $c[0] == 11)
+ array_unshift($foo, Lang::spell('cat', $c[0], $c[1], $c[2]));
+ else if (isset($c[1]))
+ {
+ $_ = in_array($c[0], [-2, -13, 7]) ? Lang::game('cl') : Lang::spell('cat', $c[0]);
+ array_unshift($foo, is_array($_[$c[1]]) ? $_[$c[1]][0] : $_[$c[1]]);
+ }
+
+ if (isset($c[0]) && count($foo) < 2)
+ {
+ $_ = Lang::spell('cat', $c[0]);
+ array_unshift($foo, is_array($_) ? $_[0] : $_);
+ }
+
+ if (count($foo) < 2)
+ array_unshift($foo, $this->h1);
+
+ foreach ($foo as $bar)
+ array_unshift($this->title, $bar);
+
+
+ /****************/
+ /* Main Content */
+ /****************/
+
+ $visibleCols = [];
+ $hiddenCols = [];
+ $extraCols = [];
+ $tabData = ['data' => []];
+
+ $this->redButtons[BUTTON_WOWHEAD] = true;
+ if ($fiQuery = $this->filter->buildGETParam())
+ $this->wowheadLink .= '&filter='.$fiQuery;
// the next lengthy ~250 lines determine $conditions and lvParams
if ($this->category)
@@ -140,9 +199,9 @@ class SpellsPage extends GenericPage
$xCond = null;
for ($i = -2; $i < 0; $i++)
{
- foreach (Game::$skillLineMask[$i] as $idx => $pair)
+ foreach (Game::$skillLineMask[$i] as $idx => [, $skillLineId])
{
- if ($pair[1] == $this->category[1])
+ if ($skillLineId == $this->category[1])
{
$xCond = ['AND', ['s.skillLine1', $i], ['s.skillLine2OrMask', 1 << $idx, '&']];
break;
@@ -186,15 +245,18 @@ class SpellsPage extends GenericPage
{
case 1:
$conditions[] = ['OR',
- ['AND', ['effect2AuraId', 32], ['effect3AuraId', 207, '!']],
- ['AND', ['effect3AuraId', 32], ['effect2AuraId', 207, '!']]
+ ['AND', ['effect2AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED], ['effect3AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, '!']],
+ ['AND', ['effect3AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED], ['effect2AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, '!']]
];
break;
case 2:
- $conditions[] = ['OR', ['effect2AuraId', 207], ['effect3AuraId', 207]];
+ $conditions[] = ['OR', ['effect2AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED], ['effect3AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED]];
break;
case 3:
- $conditions[] = ['AND', ['effect2AuraId', 32, '!'], ['effect2AuraId', 207, '!'], ['effect3AuraId', 32, '!'],['effect3AuraId', 207, '!']];
+ $conditions[] = ['AND',
+ ['effect2AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED, '!'], ['effect2AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, '!'],
+ ['effect3AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED, '!'], ['effect3AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, '!']
+ ];
break;
}
}
@@ -211,15 +273,15 @@ class SpellsPage extends GenericPage
{
switch ($this->category[1]) // Spells can be used by multiple specs
{
- case 409: // Tenacity
+ case 409: // TalentTab - Tenacity
$conditions[] = ['s.cuFlags', SPELL_CU_PET_TALENT_TYPE1, '&'];
$url = '?pets=1';
break;
- case 410: // Cunning
+ case 410: // TalentTab - Cunning
$conditions[] = ['s.cuFlags', SPELL_CU_PET_TALENT_TYPE2, '&'];
$url = '?pets=2';
break;
- case 411: // Ferocity
+ case 411: // TalentTab - Ferocity
$conditions[] = ['s.cuFlags', SPELL_CU_PET_TALENT_TYPE0, '&'];
$url = '?pets=0';
break;
@@ -228,7 +290,7 @@ class SpellsPage extends GenericPage
$tabData['note'] = '$$WH.sprintf(LANG.lvnote_pettalents, "'.$url.'")';
}
- $tabData['_petTalents'] = 1; // not conviced, this is correct, but .. it works
+ $tabData['_petTalents'] = 1;
break;
case -11: // Proficiencies ... the subIds are actually SkillLineCategories
@@ -309,22 +371,22 @@ class SpellsPage extends GenericPage
['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->category[1]]]
];
- if (!empty($this->shortFilter[$this->category[1]]))
+ if (!empty(self::SHORT_FILTER[$this->category[1]]))
{
- $sf = $this->shortFilter[$this->category[1]];
+ [$crafted, $relItems] = self::SHORT_FILTER[$this->category[1]];
$txt = '';
- if ($sf[0] && $sf[1])
- $txt = sprintf(Lang::spell('relItems', 'crafted'), $sf[0]) . Lang::spell('relItems', 'link') . sprintf(Lang::spell('relItems', 'recipes'), $sf[1]);
- else if ($sf[0])
- $txt = sprintf(Lang::spell('relItems', 'crafted'), $sf[0]);
- else if ($sf[1])
- $txt = sprintf(Lang::spell('relItems', 'recipes'), $sf[1]);
+ if ($crafted && $relItems)
+ $txt = Lang::spell('relItems', 'crafted', [$crafted]) . Lang::spell('relItems', 'link') . Lang::spell('relItems', 'recipes', [$relItems]);
+ else if ($crafted)
+ $txt = Lang::spell('relItems', 'crafted', [$crafted]);
+ else if ($relItems)
+ $txt = Lang::spell('relItems', 'recipes', [$relItems]);
$note = Lang::spell('cat', $this->category[0], $this->category[1]);
if (is_array($note))
$note = $note[0];
- $tabData['note'] = sprintf(Lang::spell('relItems', 'base'), $txt, $note);
+ $tabData['note'] = Lang::spell('relItems', 'base', [$txt, $note]);
$tabData['sort'] = ['skill', 'name'];
}
}
@@ -349,22 +411,22 @@ class SpellsPage extends GenericPage
{
$conditions[] = ['s.skillLine1', $this->category[1]];
- if (!empty($this->shortFilter[$this->category[1]]))
+ if (!empty(self::SHORT_FILTER[$this->category[1]]))
{
- $sf = $this->shortFilter[$this->category[1]];
+ [$crafted, $relItems] = self::SHORT_FILTER[$this->category[1]];
$txt = '';
- if ($sf[0] && $sf[1])
- $txt = sprintf(Lang::spell('relItems', 'crafted'), $sf[0]) . Lang::spell('relItems', 'link') . sprintf(Lang::spell('relItems', 'recipes'), $sf[1]);
- else if ($sf[0])
- $txt = sprintf(Lang::spell('relItems', 'crafted'), $sf[0]);
- else if ($sf[1])
- $txt = sprintf(Lang::spell('relItems', 'recipes'), $sf[1]);
+ if ($crafted && $relItems)
+ $txt = Lang::spell('relItems', 'crafted', [$crafted]) . Lang::spell('relItems', 'link') . Lang::spell('relItems', 'recipes', [$relItems]);
+ else if ($crafted)
+ $txt = Lang::spell('relItems', 'crafted', [$crafted]);
+ else if ($relItems)
+ $txt = Lang::spell('relItems', 'recipes', [$relItems]);
$note = Lang::spell('cat', $this->category[0], $this->category[1]);
if (is_array($note))
$note = $note[0];
- $tabData['note'] = sprintf(Lang::spell('relItems', 'base'), $txt, $note);
+ $tabData['note'] = Lang::spell('relItems', 'base', [$txt, $note]);
$tabData['sort'] = ['skill', 'name'];
}
}
@@ -383,14 +445,6 @@ class SpellsPage extends GenericPage
}
}
- if (!User::isInGroup(U_GROUP_EMPLOYEE))
- $conditions[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0];
-
- $this->filterObj->evalCriteria();
-
- if ($_ = $this->filterObj->getConditions())
- $conditions[] = $_;
-
$spells = new SpellList($conditions, ['calcTotal' => true]);
$this->extendGlobalData($spells->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED));
@@ -404,27 +458,27 @@ class SpellsPage extends GenericPage
{
$lvData[$spellId]['speed'] = 0;
- if (in_array($spells->getField('effect2AuraId'), [32, 207, 58]))
+ if (in_array($spells->getField('effect2AuraId'), [SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED, SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, SPELL_AURA_MOD_INCREASE_SWIM_SPEED]))
$lvData[$spellId]['speed'] = $spells->getField('effect2BasePoints') + 1;
- if (in_array($spells->getField('effect3AuraId'), [32, 207, 58]))
+ if (in_array($spells->getField('effect3AuraId'), [SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED, SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, SPELL_AURA_MOD_INCREASE_SWIM_SPEED]))
$lvData[$spellId]['speed'] = max($lvData[$spellId]['speed'], $spells->getField('effect3BasePoints') + 1);
- if (!$lvData[$spellId]['speed'] && ($spells->getField('effect2AuraId') == 4 || $spells->getField('effect3AuraId') == 4))
+ if (!$lvData[$spellId]['speed'] && ($spells->getField('effect2AuraId') == SPELL_AURA_DUMMY || $spells->getField('effect3AuraId') == SPELL_AURA_DUMMY))
$lvData[$spellId]['speed'] = '?';
else
$lvData[$spellId]['speed'] = '+'.$lvData[$spellId]['speed'].'%';
}
}
- $tabData['data'] = array_values($lvData);
+ $tabData['data'] = $lvData;
- if ($this->filterObj->fiExtraCols)
+ if ($this->filter->fiExtraCols)
$tabData['extraCols'] = '$fi_getExtraCols(fi_extraCols, 0, 0)';
else if ($extraCols)
$tabData['extraCols'] = $extraCols;
// add source to cols if explicitly searching for it
- if ($this->filterObj->getSetCriteria(9) && !in_array('source', $visibleCols))
+ if ($this->filter->getSetCriteria(9) && !in_array('source', $visibleCols))
$visibleCols[] = 'source';
// create note if search limit was exceeded; overwriting 'note' is intentional
@@ -434,10 +488,6 @@ class SpellsPage extends GenericPage
$tabData['_truncated'] = 1;
}
- if ($this->filterObj->error)
- $tabData['_errors'] = 1;
-
-
$mask = $spells->hasSetFields('skillLines', 'trainingCost', 'reqClassMask', null, 'reagent1', 'reagent2', 'reagent3', 'reagent4', 'reagent5', 'reagent6', 'reagent7', 'reagent8');
if (!($mask & 0x1) && $this->category && !in_array($this->category[0], [9, 11]))
$hiddenCols[] = 'skill';
@@ -455,10 +505,15 @@ class SpellsPage extends GenericPage
if ($hiddenCols)
$tabData['hiddenCols'] = array_unique($hiddenCols);
- $this->lvTabs[] = [SpellList::$brickFile, $tabData];
+ $this->lvTabs = new Tabs(['parent' => "\$\$WH.ge('tabs-generic')"]);
+ $this->lvTabs->addListviewTab(new Listview($tabData, SpellList::$brickFile));
+
+ parent::generate();
+
+ $this->setOnCacheLoaded([self::class, 'onBeforeDisplay']);
}
- protected function postCache()
+ protected static function onBeforeDisplay() : void
{
// sort for dropdown-menus
Lang::sort('game', 'ra');
@@ -466,41 +521,6 @@ class SpellsPage extends GenericPage
Lang::sort('game', 'sc');
Lang::sort('game', 'me');
}
-
- protected function generateTitle()
- {
- $foo = [];
- $c = $this->category; // shothand
- if (isset($c[2]) && $c[0] == 11)
- array_unshift($foo, Lang::spell('cat', $c[0], $c[1], $c[2]));
- else if (isset($c[1]))
- {
- $_ = in_array($c[0], [-2, -13, 7]) ? Lang::game('cl') : Lang::spell('cat', $c[0]);
- array_unshift($foo, is_array($_[$c[1]]) ? $_[$c[1]][0] : $_[$c[1]]);
- }
-
- if (isset($c[0]) && count($foo) < 2)
- {
- $_ = Lang::spell('cat', $c[0]);
- array_unshift($foo, is_array($_) ? $_[0] : $_);
- }
-
- if (count($foo) < 2)
- array_unshift($foo, $this->name);
-
- foreach ($foo as $bar)
- array_unshift($this->title, $bar);
- }
-
- protected function generatePath()
- {
- foreach ($this->category as $c)
- $this->path[] = $c;
-
- $form = $this->filterObj->values;
- if (count($this->path) == 4 && $this->category[0] == -13 && count($form['gl']) == 1)
- $this->path[] = $form['gl'][0];
- }
}
?>
diff --git a/includes/components/dbtypelist.class.php b/includes/components/dbtypelist.class.php
index 8f307f40..204a8319 100644
--- a/includes/components/dbtypelist.class.php
+++ b/includes/components/dbtypelist.class.php
@@ -463,13 +463,13 @@ abstract class DBTypeList
return null;
}
- public static function makeLink(int $id, int $fmt = Lang::FMT_HTML) : string
+ public static function makeLink(int $id, int $fmt = Lang::FMT_HTML, string $cssClass = '') : string
{
if ($n = static::getName($id))
{
return match ($fmt)
{
- Lang::FMT_HTML => ''.$n.'',
+ Lang::FMT_HTML => ''.$n.'',
Lang::FMT_MARKUP => '[url=?'.Type::getFileString(static::$type).'='.$id.']'.$n.'[/url]',
default => $n
};
@@ -696,7 +696,7 @@ trait spawnHelper
$info[2] = Lang::game('phases').Lang::main('colon').Util::asHex($s['phaseMask']);
if ($s['spawnMask'] == 15)
- $info[3] = Lang::game('mode').Lang::main('colon').Lang::game('modes', -1);
+ $info[3] = Lang::game('mode').Lang::game('modes', -1);
else if ($s['spawnMask'])
{
$_ = [];
@@ -704,7 +704,7 @@ trait spawnHelper
if ($s['spawnMask'] & 1 << $i)
$_[] = Lang::game('modes', $i);
- $info[4] = Lang::game('mode').Lang::main('colon').implode(', ', $_);
+ $info[4] = Lang::game('mode').implode(', ', $_);
}
if ($s['type'] == Type::AREATRIGGER)
diff --git a/includes/dbtypes/spell.class.php b/includes/dbtypes/spell.class.php
index aef037c7..344fa8d2 100644
--- a/includes/dbtypes/spell.class.php
+++ b/includes/dbtypes/spell.class.php
@@ -891,8 +891,11 @@ class SpellList extends DBTypeList
$max = $MAX = !$this->interactive ? 'MAX' : sprintf(Util::$dfnString, 'MAX(a, b)', 'MAX');
$pl = $PL = !$this->interactive ? 'PL' : sprintf(Util::$dfnString, 'LANG.level', 'PL');
+ // space out operators for better readability
+ $formula = preg_replace('/(\+|-|\*|\/)/', ' \1 ', $formula);
+
// note the " !
- return eval('return "'.$formula.'";');
+ return eval('return "('.$formula.')";');
}
else
return eval('return '.$formula.';');
@@ -2363,13 +2366,13 @@ class SpellListFilter extends Filter
9 => array( // sources index
1 => true, // Any
2 => false, // None
- 3 => 1, // Crafted
- 4 => 2, // Drop
- 6 => 4, // Quest
- 7 => 5, // Vendor
- 8 => 6, // Trainer
- 9 => 7, // Discovery
- 10 => 9 // Talent
+ 3 => SRC_CRAFTED,
+ 4 => SRC_DROP,
+ 6 => SRC_QUEST,
+ 7 => SRC_VENDOR,
+ 8 => SRC_TRAINER,
+ 9 => SRC_DISCOVERY,
+ 10 => SRC_TALENT
),
22 => array(
1 => true, // Weapons
diff --git a/localization/locale_dede.php b/localization/locale_dede.php
index bc1da2fb..09d4fd96 100644
--- a/localization/locale_dede.php
+++ b/localization/locale_dede.php
@@ -335,15 +335,15 @@ $lang = array(
'duration' => "Dauer",
'eventShort' => "Ereignis: %s",
'flags' => "Flags",
- 'glyphType' => "Glyphenart",
+ 'glyphType' => "Glyphenart: ",
'level' => "Stufe",
'mechanic' => "Auswirkung",
- 'mechAbbr' => "Ausw.",
+ 'mechAbbr' => "Ausw.: ",
'meetingStone' => "Versammlungsstein",
'requires' => "Benötigt %s",
'requires2' => "Benötigt",
'reqLevel' => "Benötigt Stufe %s",
- 'reqSkillLevel' => "Benötigte Fertigkeitsstufe",
+ 'reqSkillLevel' => "Benötigte Fertigkeitsstufe: ",
'school' => "Magieart",
'type' => "Art: ",
'valueDelim' => " - ", // " bis "
@@ -360,7 +360,7 @@ $lang = array(
'_roles' => ["Heiler", "Nahkampf-DPS", "Distanz-DPS", "Tank"],
'phases' => "Phasen",
- 'mode' => "Modus",
+ 'mode' => "Modus: ",
'modes' => [-1 => "Beliebig", "Normal / Normal 10", "Heroisch / Normal 25", "Heroisch 10", "Heroisch 25"],
'expansions' => ["Classic", "The Burning Crusade", "Wrath of the Lich King"],
'stats' => ["Stärke", "Beweglichkeit", "Ausdauer", "Intelligenz", "Willenskraft"],
@@ -1481,13 +1481,13 @@ $lang = array(
'_globCD' => "Globale Abklingzeit",
'_gcdCategory' => "GCD-Kategorie",
'_value' => "Wert",
- '_radius' => "Radius",
- '_interval' => "Interval",
- '_inSlot' => "im Platz",
+ '_radius' => "Radius: ",
+ '_interval' => "Interval: ",
+ '_inSlot' => "im Platz: ",
'_collapseAll' => "Alle einklappen",
'_expandAll' => "Alle ausklappen",
'_transfer' => 'Dieser Zauber wird mit %s vertauscht, wenn Ihr zur %s wechselt.',
- '_affected' => "Betroffene Zauber",
+ '_affected' => "Betroffene Zauber: ",
'_seeMore' => "Mehr anzeigen",
'_rankRange' => "Rang: %d - %d",
'_showXmore' => "Zeige %d weitere",
@@ -1499,9 +1499,9 @@ $lang = array(
'currentArea' => '<Momentanes Gebiet>',
'discovered' => "Durch Geistesblitz erlernt",
'ppm' => "(%s Auslösungen pro Minute)",
- 'procChance' => "Procchance",
+ 'procChance' => "Procchance: ",
'starter' => "Basiszauber",
- 'trainingCost' => "Trainingskosten",
+ 'trainingCost' => "Trainingskosten: ",
'channeled' => "Kanalisiert",
'range' => "%s Meter Reichweite",
'meleeRange' => "Nahkampfreichweite",
diff --git a/localization/locale_enus.php b/localization/locale_enus.php
index 83038634..b8d154ab 100644
--- a/localization/locale_enus.php
+++ b/localization/locale_enus.php
@@ -335,15 +335,15 @@ $lang = array(
'duration' => "Duration",
'eventShort' => "Event: %s",
'flags' => "Flags",
- 'glyphType' => "Glyph type",
+ 'glyphType' => "Glyph type: ",
'level' => "Level",
'mechanic' => "Mechanic",
- 'mechAbbr' => "Mech.",
+ 'mechAbbr' => "Mech.: ",
'meetingStone' => "Meeting Stone",
'requires' => "Requires %s",
'requires2' => "Requires",
'reqLevel' => "Requires Level %s",
- 'reqSkillLevel' => "Required skill level",
+ 'reqSkillLevel' => "Required skill level: ",
'school' => "School",
'type' => "Type: ",
'valueDelim' => " to ",
@@ -360,7 +360,7 @@ $lang = array(
'_roles' => ["Healer", "Melee DPS", "Ranged DPS", "Tank"],
'phases' => "Phases",
- 'mode' => "Mode",
+ 'mode' => "Mode: ",
'modes' => [-1 => "Any", "Normal / Normal 10", "Heroic / Normal 25", "Heroic 10", "Heroic 25"],
'expansions' => ["Classic", "The Burning Crusade", "Wrath of the Lich King"],
'stats' => ["Strength", "Agility", "Stamina", "Intellect", "Spirit"],
@@ -1481,13 +1481,13 @@ $lang = array(
'_globCD' => "Global Cooldown",
'_gcdCategory' => "GCD category",
'_value' => "Value",
- '_radius' => "Radius",
- '_interval' => "Interval",
- '_inSlot' => "in slot",
+ '_radius' => "Radius: ",
+ '_interval' => "Interval: ",
+ '_inSlot' => "in slot: ",
'_collapseAll' => "Collapse All",
'_expandAll' => "Expand All",
'_transfer' => 'This spell will be converted to %s if you transfer to %s.',
- '_affected' => "Affected Spells",
+ '_affected' => "Affected Spells: ",
'_seeMore' => "See more",
'_rankRange' => "Rank: %d - %d",
'_showXmore' => "Show %d More",
@@ -1499,9 +1499,9 @@ $lang = array(
'currentArea' => '<current area>',
'discovered' => "Learned via discovery",
'ppm' => "(%s procs per minute)",
- 'procChance' => "Proc chance",
+ 'procChance' => "Proc chance: ",
'starter' => "Starter spell",
- 'trainingCost' => "Training cost",
+ 'trainingCost' => "Training cost: ",
'channeled' => "Channeled", // SPELL_CAST_CHANNELED
'range' => "%s yd range", // SPELL_RANGE / SPELL_RANGE_DUAL
'meleeRange' => "Melee Range", // MELEE_RANGE
diff --git a/localization/locale_eses.php b/localization/locale_eses.php
index 2859056e..a85bec4b 100644
--- a/localization/locale_eses.php
+++ b/localization/locale_eses.php
@@ -335,15 +335,15 @@ $lang = array(
'duration' => "Duración",
'eventShort' => "Evento: %s",
'flags' => "Banderas",
- 'glyphType' => "Tipo de glifo",
+ 'glyphType' => "Tipo de glifo: ",
'level' => "Nivel",
'mechanic' => "Mecanica",
- 'mechAbbr' => "Mec.",
+ 'mechAbbr' => "Mec.: ",
'meetingStone' => "Roca de encuentro",
'requires' => "Requiere %s",
'requires2' => "Requiere",
'reqLevel' => "Necesitas ser de nivel %s",
- 'reqSkillLevel' => "Requiere nivel de habilidad",
+ 'reqSkillLevel' => "Requiere nivel de habilidad: ",
'school' => "Escuela",
'type' => "Tipo: ",
'valueDelim' => " - ",
@@ -360,7 +360,7 @@ $lang = array(
'_roles' => ["Sanador", "DPS cuerpo", "DPS a distancia", "Tanque"],
'phases' => "Fases",
- 'mode' => "Modo",
+ 'mode' => "Modo: ",
'modes' => [-1 => "Cualquiera", "Normal / Normal 10", "Heroico / Normal 25", "Heróico 10", "Heróico 25"],
'expansions' => ["World of Warcraft", "The Burning Crusade", "Wrath of the Lich King"],
'stats' => ["Fuerza", "Agilidad", "Aguante", "Intelecto", "Espíritu"],
@@ -1481,13 +1481,13 @@ $lang = array(
'_globCD' => "Tiempo global de reutilización",
'_gcdCategory' => "Categoría GCD",
'_value' => "Valor",
- '_radius' => "Radio",
- '_interval' => "Intérvalo",
- '_inSlot' => "en la casilla",
+ '_radius' => "Radio: ",
+ '_interval' => "Intérvalo: ",
+ '_inSlot' => "en la casilla: ",
'_collapseAll' => "Contraer todo",
'_expandAll' => "Expandier todo",
'_transfer' => 'Este hechizo será convertido a %s si lo transfieres a la %s.',
- '_affected' => "Hechizos affectados",
+ '_affected' => "Hechizos affectados: ",
'_seeMore' => "Más información",
'_rankRange' => "Rango: %d - %d",
'_showXmore' => "Mostrar %d más",
@@ -1499,9 +1499,9 @@ $lang = array(
'currentArea' => '<current area>',
'discovered' => "Aprendido via descubrimiento",
'ppm' => "(%s procs por minuto)",
- 'procChance' => "Probabilidad de que accione",
+ 'procChance' => "Probabilidad de que accione: ",
'starter' => "Hechizo inicial",
- 'trainingCost' => "Costo de enseñanza",
+ 'trainingCost' => "Costo de enseñanza: ",
'channeled' => "Canalizado",
'range' => "Alcance de %s m",
'meleeRange' => "Alcance de ataques cuerpo a cuerpo",
diff --git a/localization/locale_frfr.php b/localization/locale_frfr.php
index 761c271a..53815027 100644
--- a/localization/locale_frfr.php
+++ b/localization/locale_frfr.php
@@ -335,15 +335,15 @@ $lang = array(
'duration' => "Durée",
'eventShort' => "Évènement : %s",
'flags' => "Marqueurs",
- 'glyphType' => "Type de glyphe",
+ 'glyphType' => "Type de glyphe : ",
'level' => "Niveau",
'mechanic' => "Mécanique",
- 'mechAbbr' => "Mécan.",
+ 'mechAbbr' => "Mécan. : ",
'meetingStone' => "Pierre de rencontre",
'requires' => "%s requis",
'requires2' => "Requiert",
'reqLevel' => "Niveau %s requis",
- 'reqSkillLevel' => "Niveau de compétence requis",
+ 'reqSkillLevel' => "Niveau de compétence requis : ",
'school' => "École",
'type' => "Type : ",
'valueDelim' => " - ",
@@ -360,7 +360,7 @@ $lang = array(
'_roles' => ["Soigneur", "DPS mêlée", "DPS à distance", "Tank"],
'phases' => "Phases",
- 'mode' => "Mode",
+ 'mode' => "Mode : ",
'modes' => [-1 => "Tout", "Standard / Normal 10", "Héroïque / Normal 25", "10 héroïque", "25 héroïque"],
'expansions' => ["Classique", "The Burning Crusade", "Wrath of the Lich King"],
'stats' => ["Force", "Agilité", "Endurance", "Intelligence", "Esprit"],
@@ -1481,13 +1481,13 @@ $lang = array(
'_globCD' => "Temps d'attente universel",
'_gcdCategory' => "Catégorie GCD",
'_value' => "Valeur",
- '_radius' => "Rayon",
- '_interval' => "Intervalle",
- '_inSlot' => "dans l'emplacement",
+ '_radius' => "Rayon : ",
+ '_interval' => "Intervalle : ",
+ '_inSlot' => "dans l'emplacement : ",
'_collapseAll' => "Replier Tout",
'_expandAll' => "Déplier Tout",
'_transfer' => 'Cet sort sera converti en %s si vous transférez en %s.',
- '_affected' => "Sorts affectés",
+ '_affected' => "Sorts affectés : ",
'_seeMore' => "[See more]",
'_rankRange' => "Rang : %d - %d",
'_showXmore' => "En afficher %d de plus",
@@ -1499,9 +1499,9 @@ $lang = array(
'currentArea' => '<current area>',
'discovered' => "Appris via une découverte",
'ppm' => "(%s déclenchements par minute)",
- 'procChance' => "Chance",
+ 'procChance' => "Chance : ",
'starter' => "Sortilège initiaux",
- 'trainingCost' => "Coût d'entraînement",
+ 'trainingCost' => "Coût d'entraînement : ",
'channeled' => "Canalisée",
'range' => "%s m de portée",
'meleeRange' => "Allonge",
diff --git a/localization/locale_ruru.php b/localization/locale_ruru.php
index 3009a5d3..17fb395b 100644
--- a/localization/locale_ruru.php
+++ b/localization/locale_ruru.php
@@ -335,15 +335,15 @@ $lang = array(
'duration' => "Длительность",
'eventShort' => "Игровое событие: %s",
'flags' => "Метки",
- 'glyphType' => "Тип символа",
+ 'glyphType' => "Тип символа: ",
'level' => "Уровень",
'mechanic' => "Механика",
- 'mechAbbr' => "Механика",
+ 'mechAbbr' => "Механика: ",
'meetingStone' => "Камень встреч",
'requires' => "Требует %s",
'requires2' => "Требуется:",
'reqLevel' => "Требуется уровень: %s",
- 'reqSkillLevel' => "Требуется уровень навыка",
+ 'reqSkillLevel' => "Требуется уровень навыка: ",
'school' => "Школа",
'type' => "Тип: ",
'valueDelim' => " - ",
@@ -360,7 +360,7 @@ $lang = array(
'_roles' => ["Лекарь", "Боец ближнего боя", "Боец дальнего боя", "Танк"],
'phases' => "Фазы",
- 'mode' => "Режим",
+ 'mode' => "Режим: ",
'modes' => [-1 => "Все", "Обычный / 10-норм.", "Героический / 25-норм.", "10-героич", "25-героич"],
'expansions' => array("World of Warcraft", "The Burning Crusade", "Wrath of the Lich King"),
'stats' => array("к силе", "к ловкости", "к выносливости", "к интеллекту", "к духу"),
@@ -1481,13 +1481,13 @@ $lang = array(
'_globCD' => "Общее время восстановления (GCD)",
'_gcdCategory' => "Категория ГКД",
'_value' => "Значение",
- '_radius' => "Радиус действия",
- '_interval' => "Интервал",
- '_inSlot' => "в слот",
+ '_radius' => "Радиус действия: ",
+ '_interval' => "Интервал: ",
+ '_inSlot' => "в слот: ",
'_collapseAll' => "Свернуть все",
'_expandAll' => "Развернуть все",
'_transfer' => 'Этот предмет превратится в %s, если вы перейдете за %s.',
- '_affected' => "Влияет на заклинания",
+ '_affected' => "Влияет на заклинания: ",
'_seeMore' => "[See more]",
'_rankRange' => "Ранг: %d - %d",
'_showXmore' => "Показать на %d больше",
@@ -1499,9 +1499,9 @@ $lang = array(
'currentArea' => '<current area>',
'discovered' => "Изучается путём освоения местности",
'ppm' => "(Срабатывает %s раз в минуту)",
- 'procChance' => "Шанс срабатывания",
+ 'procChance' => "Шанс срабатывания: ",
'starter' => "Начальное заклинание",
- 'trainingCost' => "Цена обучения",
+ 'trainingCost' => "Цена обучения: ",
'channeled' => "Направляемое",
'range' => "Радиус действия: %s м",
'meleeRange' => "Дистанция ближнего боя",
diff --git a/localization/locale_zhcn.php b/localization/locale_zhcn.php
index a6b92f10..bb35a340 100644
--- a/localization/locale_zhcn.php
+++ b/localization/locale_zhcn.php
@@ -334,15 +334,15 @@ $lang = array(
'duration' => "持续时间",
'eventShort' => "事件:%s",
'flags' => "标记",
- 'glyphType' => "雕文类型",
+ 'glyphType' => "雕文类型:",
'level' => "等级",
'mechanic' => "机制",
- 'mechAbbr' => "机制",
+ 'mechAbbr' => "机制:",
'meetingStone' => "集合石",
'requires' => "需要%s",
'requires2' => "需要",
'reqLevel' => "需要等级%s",
- 'reqSkillLevel' => "需要技能等级",
+ 'reqSkillLevel' => "需要技能等级:",
'school' => "类型",
'type' => "类型:",
'valueDelim' => "到",
@@ -359,7 +359,7 @@ $lang = array(
'_roles' => ["治疗者", "近距离伤害输出者", "远距离伤害输出者", "坦克"],
'phases' => "阶段",
- 'mode' => "模式",
+ 'mode' => "模式:",
'modes' => [-1 => "任何", "普通 / 普通 10人", "英雄 / 普通 25人", "英雄 10人", "英雄 25人"],
'expansions' => ["经典旧世", "燃烧的远征", "巫妖王之怒"],
'stats' => ["力量", "敏捷", "耐力", "智力", "精神"],
@@ -1480,13 +1480,13 @@ $lang = array(
'_globCD' => "公共冷却时间",
'_gcdCategory' => "GCD类别",
'_value' => "值",
- '_radius' => "半径",
- '_interval' => "间隔", //Interval
- '_inSlot' => "在插槽中",
+ '_radius' => "半径:",
+ '_interval' => "间隔:", //Interval
+ '_inSlot' => "在插槽中:",
'_collapseAll' => "折叠全部",
'_expandAll' => "展开全部",
'_transfer' => '这个法术将被转换到%s,如果你转移到%s。',
- '_affected' => "受影响法术",
+ '_affected' => "受影响法术:",
'_seeMore' => "[See more]",
'_rankRange' => "排名: %d - %d",
'_showXmore' => "[Show %d More]",
@@ -1498,9 +1498,9 @@ $lang = array(
'currentArea' => '<当前区域>',
'discovered' => "通过发现学习",
'ppm' => "%s每分钟触发几率",
- 'procChance' => "触发几率",
+ 'procChance' => "触发几率:",
'starter' => "初始法术",
- 'trainingCost' => "训练成本",
+ 'trainingCost' => "训练成本:",
'channeled' => "需引导",
'range' => "%s码范围",
'meleeRange' => "近战范围",
diff --git a/setup/tools/sqlgen/spell.ss.php b/setup/tools/sqlgen/spell.ss.php
index 69bf5ea1..ee874270 100644
--- a/setup/tools/sqlgen/spell.ss.php
+++ b/setup/tools/sqlgen/spell.ss.php
@@ -332,9 +332,9 @@ CLISetup::registerSetup("sql", new class extends SetupScript
default:
for ($i = -count(Game::$skillLineMask); $i < 0; $i++)
{
- foreach (Game::$skillLineMask[$i] as $k => $pair)
+ foreach (Game::$skillLineMask[$i] as $k => [, $skillLineId])
{
- if (in_array($pair[1], $lines))
+ if (in_array($skillLineId, $lines))
{
$update['skillLine1'] = $i;
$update['skillLine2OrMask'] |= 1 << $k;
diff --git a/template/pages/spell.tpl.php b/template/pages/spell.tpl.php
index 9f7b023c..6995c737 100644
--- a/template/pages/spell.tpl.php
+++ b/template/pages/spell.tpl.php
@@ -1,7 +1,12 @@
-
+brick('header'); ?>
+ use \Aowow\Lang;
+ $this->brick('header');
+
+ $iconOffset = 0;
+?>
@@ -18,7 +23,7 @@
brick('redButtons'); ?>
-
=$this->name; ?>
+
=$this->h1; ?>
brick('tooltip');
@@ -28,6 +33,7 @@ if ($this->tools):
endif;
if ($this->reagents[1]):
+ $iconOffset += count($this->reagents[1]);
$this->brick('reagentList', ['reagents' => $this->reagents[1], 'enhanced' => $this->reagents[0]]);
endif;
@@ -41,17 +47,15 @@ if ($this->tools):
=Lang::spell('tools'); ?>
tools as $i => $t):
- echo ' | '.$t['name']." |
\n";
+ foreach ($this->tools as $icon):
+ echo $icon->renderContainer(20, $iconOffset, true);
endforeach;
?>
@@ -63,10 +67,10 @@ endif;
?>
-brick('article'); ?>
-
transfer)):
+$this->brick('markup', ['markup' => $this->article]);
+
+if ($this->transfer):
echo "
\n ".$this->transfer."\n";
endif;
?>
@@ -111,7 +115,7 @@ endif;
| =Lang::spell('_cost');?> |
- =(!empty($this->powerCost) ? $this->powerCost : Lang::spell('_none'));?> |
+ =($this->powerCost ?: Lang::spell('_none'));?> |
| =Lang::spell('_range');?> |
@@ -139,7 +143,7 @@ if ($this->scaling):
scaling as $k => $v):
- echo ' '.Lang::spell('scaling', $k, [$v * 100])."
\n";
+ echo ' '.Lang::spell('scaling', $k, [$v * 100])."
\n";
endforeach;
?>
@@ -175,7 +179,7 @@ foreach ($this->effects as $i => $e):
echo ' '.$e['name'];
if ($e['footer']):
- echo "
".implode("
", $e['footer'])."\n";
+ echo "
".implode("
", $e['footer'])."\n";
endif;
if ($e['markup']):
@@ -185,63 +189,54 @@ $WH.aE(window,\'load\',function(){$WH.ge(\'spelleffectmarkup-'.$i.'\').innerHTML
endif;
if ($e['icon']):
- ['type' => $ty, 'typeId' => $ti, 'name' => $na, 'quality' => $qu, 'count' => $co] = $e['icon'];
?>
- |
-'.($na ? sprintf('%s', $ti, $na) : Util::ucFirst(Lang::game('item')).' #'.$ti)."\n";
- else:
- echo ' '.($na ? sprintf('%s', $ti, $na) : Util::ucFirst(Lang::game('spell')).' #'.$ti)." | \n";
- endif;
-?>
+ =$e['icon']->renderContainer(iconIdxOffset: $iconTabIdx); ?>
| |
$si, 'spellName' => $sn, 'itemId' => $ii, 'itemName' => $in, 'quality' => $qu, 'icon' => $ic, 'chance' => $ch] = $e['perfectItem'];
+ ['spellId' => $si, 'spellName' => $sn, 'item' => $it, 'icon' => $ic, 'chance' => $ch] = $e['perfectItem'];
?>
-
+
=$sn;?>=Lang::main('colon').' '.$ch.'%';?>
+ =$it->renderContainer(0, $iconTabIdx, true); ?>
-
=Lang::spell('_affected').Lang::main('colon');?>
+
=Lang::spell('_affected');?>
'.Lang::spell('_seeMore').'';
echo '
';
- foreach ($e['modifies'][$type] as $idx => [$id, $name, $minRank, $maxRank]):
+ foreach ($e['modifies'][$type] as $idx => [$icon, $ranks]):
if (!$idx || !($idx % 3))
echo "";
- $iconData[] = [++$iconTabIdx, $id];
- echo " | ".($type ? $name : "".$name."")."".($minRank != $maxRank ? " (".Lang::spell('_rankRange', [$minRank, $maxRank]).")" : '')." | \n";
+ $icon->renderContainer(iconIdxOffset: $iconTabIdx); // just to assign iconOffset
+ echo " | typeId."\">".($type ? $icon->text : "".$icon->text."")."".($ranks ? " (".Lang::spell('_rankRange', $ranks).")" : '')." | \n";
if ($idx == count($e['modifies'][$type]) - 1 || !(($idx + 1) % 3))
echo "
";
@@ -265,8 +260,8 @@ $WH.aE(window,\'load\',function(){$WH.ge(\'spelleffectmarkup-'.$i.'\').innerHTML
@@ -301,7 +296,7 @@ if ($this->attributes):
brick('lvTabs', ['relTabs' => true]);
+$this->brick('lvTabs');
$this->brick('contribute');
?>
diff --git a/template/pages/spells.tpl.php b/template/pages/spells.tpl.php
index 627e3deb..0579cdad 100644
--- a/template/pages/spells.tpl.php
+++ b/template/pages/spells.tpl.php
@@ -1,10 +1,11 @@
-
-
brick('header');
-$f = $this->filterObj->values // shorthand
-?>
+ namespace Aowow\Template;
+ use Aowow\Lang;
+
+$this->brick('header');
+$f = $this->filter->values; // shorthand
+?>
@@ -12,38 +13,33 @@ $f = $this->filterObj->values // shorthand
brick('announcement');
-$this->brick('pageTemplate', ['fiQuery' => $this->filterObj->query, 'fiMenuItem' => [1]]);
+$this->brick('pageTemplate', ['fiQuery' => $this->filter->query, 'fiMenuItem' => [1]]);
?>
-
-