diff --git a/includes/ajaxHandler/profile.class.php b/includes/ajaxHandler/profile.class.php
index 00aa72ce..d08d86d0 100644
--- a/includes/ajaxHandler/profile.class.php
+++ b/includes/ajaxHandler/profile.class.php
@@ -510,7 +510,7 @@ class AjaxProfile extends AjaxHandler
'level' => $pBase['level'],
'classs' => $pBase['class'],
'race' => $pBase['race'],
- 'faction' => Game::sideByRaceMask(1 << ($pBase['race'] - 1)) - 1,
+ 'faction' => ChrRace::tryFrom($pBase['race'])?->getSide() ?? SIDE_NONE,
'gender' => $pBase['gender'],
'skincolor' => $pBase['skincolor'],
'hairstyle' => $pBase['hairstyle'],
diff --git a/includes/components/Conditions/Conditions.class.php b/includes/components/Conditions/Conditions.class.php
index f28634b4..03331e7c 100644
--- a/includes/components/Conditions/Conditions.class.php
+++ b/includes/components/Conditions/Conditions.class.php
@@ -553,14 +553,14 @@ class Conditions
{
if ($cndId == self::CHR_CLASS)
{
- $cVal1 &= CLASS_MASK_ALL;
+ $cVal1 &= ChrClass::MASK_ALL;
foreach (Util::mask2bits($cVal1, 1) as $cId)
$this->jsGlobals[Type::CHR_CLASS][$cId] = $cId;
}
if ($cndId == self::CHR_RACE)
{
- $cVal1 &= RACE_MASK_ALL;
+ $cVal1 &= ChrRace::MASK_ALL;
foreach (Util::mask2bits($cVal1, 1) as $rId)
$this->jsGlobals[Type::CHR_RACE][$rId] = $rId;
}
diff --git a/includes/defines.php b/includes/defines.php
index c4c9e1c5..19f3d8e1 100644
--- a/includes/defines.php
+++ b/includes/defines.php
@@ -375,6 +375,7 @@ define('LOOT_SPELL', 'spell_loot_template');
define('LOOT_REFERENCE', 'reference_loot_template');
// Sides
+define('SIDE_NONE', 0);
define('SIDE_ALLIANCE', 1);
define('SIDE_HORDE', 2);
define('SIDE_BOTH', 3);
@@ -384,33 +385,152 @@ define('EXP_CLASSIC', 0);
define('EXP_BC', 1);
define('EXP_WOTLK', 2);
-// ClassMask
-define('CLASS_WARRIOR', 0x001);
-define('CLASS_PALADIN', 0x002);
-define('CLASS_HUNTER', 0x004);
-define('CLASS_ROGUE', 0x008);
-define('CLASS_PRIEST', 0x010);
-define('CLASS_DEATHKNIGHT', 0x020);
-define('CLASS_SHAMAN', 0x040);
-define('CLASS_MAGE', 0x080);
-define('CLASS_WARLOCK', 0x100);
-define('CLASS_DRUID', 0x400);
-define('CLASS_MASK_ALL', 0x5FF);
+enum ChrClass : int
+{
+ case WARRIOR = 1;
+ case PALADIN = 2;
+ case HUNTER = 3;
+ case ROGUE = 4;
+ case PRIEST = 5;
+ case DEATHKNIGHT = 6;
+ case SHAMAN = 7;
+ case MAGE = 8;
+ case WARLOCK = 9;
+ case DRUID = 11;
-// RaceMask
-define('RACE_HUMAN', 0x001);
-define('RACE_ORC', 0x002);
-define('RACE_DWARF', 0x004);
-define('RACE_NIGHTELF', 0x008);
-define('RACE_UNDEAD', 0x010);
-define('RACE_TAUREN', 0x020);
-define('RACE_GNOME', 0x040);
-define('RACE_TROLL', 0x080);
-define('RACE_BLOODELF', 0x200);
-define('RACE_DRAENEI', 0x400);
-define('RACE_MASK_ALLIANCE', 0x44D);
-define('RACE_MASK_HORDE', 0x2B2);
-define('RACE_MASK_ALL', 0x6FF);
+ public const MASK_ALL = 0x5FF;
+
+ public function matches(int $classMask) : bool
+ {
+ return !$classMask || $this->value & $classMask;
+ }
+
+ public function toMask() : int
+ {
+ return 1 << ($this->value - 1);
+ }
+
+ public static function fromMask(int $classMask = self::MASK_ALL) : array
+ {
+ $x = [];
+ foreach (self::cases() as $cl)
+ if ($cl->value & $classMask)
+ $x[] = $cl->value;
+
+ return $x;
+ }
+
+ public function json() : string
+ {
+ return match ($this)
+ {
+ self::WARRIOR => 'warrior',
+ self::PALADIN => 'paladin',
+ self::HUNTER => 'hunter',
+ self::ROGUE => 'rogue',
+ self::PRIEST => 'priest',
+ self::DEATHKNIGHT => 'deathknight',
+ self::SHAMAN => 'shaman',
+ self::MAGE => 'mage',
+ self::WARLOCK => 'warlock',
+ self::DRUID => 'druid'
+ };
+ }
+}
+
+enum ChrRace : int
+{
+ case HUMAN = 1;
+ case ORC = 2;
+ case DWARF = 3;
+ case NIGHTELF = 4;
+ case UNDEAD = 5;
+ case TAUREN = 6;
+ case GNOME = 7;
+ case TROLL = 8;
+ case BLOODELF = 10;
+ case DRAENEI = 11;
+
+ public const MASK_ALLIANCE = 0x44D;
+ public const MASK_HORDE = 0x2B2;
+ public const MASK_ALL = 0x6FF;
+
+ public function matches(int $raceMask) : bool
+ {
+ return !$raceMask || $this->value & $raceMask;
+ }
+
+ public function toMask() : int
+ {
+ return 1 << ($this->value - 1);
+ }
+
+ public function isAlliance() : bool
+ {
+ return $this->toMask() & self::MASK_ALLIANCE;
+ }
+
+ public function isHorde() : bool
+ {
+ return $this->toMask() & self::MASK_HORDE;
+ }
+
+ public function getSide() : int
+ {
+ if ($this->isHorde() && $this->isAlliance())
+ return SIDE_BOTH;
+ else if ($this->isHorde())
+ return SIDE_HORDE;
+ else if ($this->isAlliance())
+ return SIDE_ALLIANCE;
+ else
+ return SIDE_NONE;
+ }
+
+ public function json() : string
+ {
+ return match ($this)
+ {
+ self::HUMAN => 'human',
+ self::ORC => 'orc',
+ self::DWARF => 'dwarf',
+ self::NIGHTELF => 'nightelf',
+ self::UNDEAD => 'undead',
+ self::TAUREN => 'tauren',
+ self::GNOME => 'gnome',
+ self::TROLL => 'troll',
+ self::BLOODELF => 'bloodelf',
+ self::DRAENEI => 'draenei'
+ };
+ }
+
+ public static function fromMask(int $raceMask = self::MASK_ALL) : array
+ {
+ $x = [];
+ foreach (self::cases() as $cl)
+ if ($cl->value & $raceMask)
+ $x[] = $cl->value;
+
+ return $x;
+ }
+
+ public static function sideFromMask(int $raceMask) : int
+ {
+ // Any
+ if (!$raceMask || ($raceMask & self::MASK_ALL) == self::MASK_ALL)
+ return SIDE_BOTH;
+
+ // Horde
+ if ($raceMask & self::MASK_HORDE && !($raceMask & self::MASK_ALLIANCE))
+ return SIDE_HORDE;
+
+ // Alliance
+ if ($raceMask & self::MASK_ALLIANCE && !($raceMask & self::MASK_HORDE))
+ return SIDE_ALLIANCE;
+
+ return SIDE_BOTH;
+ }
+}
// SpellFamilyNames
define('SPELLFAMILY_GENERIC', 0);
diff --git a/includes/game.php b/includes/game.php
index b3e795e7..1418d67f 100644
--- a/includes/game.php
+++ b/includes/game.php
@@ -29,10 +29,6 @@ class Game
1 => ['ability_rogue_eviscerate', 'ability_warrior_innerrage', 'ability_warrior_defensivestance' ]
);
- public static $classFileStrings = array(
- null, 'warrior', 'paladin', 'hunter', 'rogue', 'priest', 'deathknight', 'shaman', 'mage', 'warlock', null, 'druid'
- );
-
public static $questClasses = array(
-2 => [ 0],
0 => [ 1, 3, 4, 8, 9, 10, 11, 12, 25, 28, 33, 36, 38, 40, 41, 44, 45, 46, 47, 51, 85, 130, 132, 139, 154, 267, 1497, 1519, 1537, 2257, 3430, 3431, 3433, 3487, 4080, 4298],
@@ -140,23 +136,6 @@ class Game
null, 4, 10, 9, 8, 6, 15, 11, 3, 5, null, 7
);
- public static function sideByRaceMask($race)
- {
- // Any
- if (!$race || ($race & RACE_MASK_ALL) == RACE_MASK_ALL)
- return SIDE_BOTH;
-
- // Horde
- if ($race & RACE_MASK_HORDE && !($race & RACE_MASK_ALLIANCE))
- return SIDE_HORDE;
-
- // Alliance
- if ($race & RACE_MASK_ALLIANCE && !($race & RACE_MASK_HORDE))
- return SIDE_ALLIANCE;
-
- return SIDE_BOTH;
- }
-
public static function getReputationLevelForPoints($pts)
{
if ($pts >= 41999)
diff --git a/includes/profiler.class.php b/includes/profiler.class.php
index 762dc0f6..69898145 100644
--- a/includes/profiler.class.php
+++ b/includes/profiler.class.php
@@ -247,17 +247,17 @@ class Profiler
private static function queueInsert($realmId, $guid, $type, $localId)
{
- if ($rData = DB::Aowow()->selectRow('SELECT requestTime AS time, status FROM ?_profiler_sync WHERE realm = ?d AND realmGUID = ?d AND `type` = ?d AND typeId = ?d AND status <> ?d', $realmId, $guid, $type, $localId, PR_QUEUE_STATUS_WORKING))
+ if ($rData = DB::Aowow()->selectRow('SELECT `requestTime` AS "time", `status` FROM ?_profiler_sync WHERE `realm` = ?d AND `realmGUID` = ?d AND `type` = ?d AND `typeId` = ?d AND `status` <> ?d', $realmId, $guid, $type, $localId, PR_QUEUE_STATUS_WORKING))
{
// not on already scheduled - recalc time and set status to PR_QUEUE_STATUS_WAITING
if ($rData['status'] != PR_QUEUE_STATUS_WAITING)
{
$newTime = Cfg::get('DEBUG') ? time() : max($rData['time'] + Cfg::get('PROFILER_RESYNC_DELAY'), time());
- DB::Aowow()->query('UPDATE ?_profiler_sync SET requestTime = ?d, status = ?d, errorCode = 0 WHERE realm = ?d AND realmGUID = ?d AND `type` = ?d AND typeId = ?d', $newTime, PR_QUEUE_STATUS_WAITING, $realmId, $guid, $type, $localId);
+ DB::Aowow()->query('UPDATE ?_profiler_sync SET `requestTime` = ?d, `status` = ?d, `errorCode` = 0 WHERE `realm` = ?d AND `realmGUID` = ?d AND `type` = ?d AND `typeId` = ?d', $newTime, PR_QUEUE_STATUS_WAITING, $realmId, $guid, $type, $localId);
}
}
else
- DB::Aowow()->query('REPLACE INTO ?_profiler_sync (realm, realmGUID, `type`, typeId, requestTime, status, errorCode) VALUES (?d, ?d, ?d, ?d, UNIX_TIMESTAMP(), ?d, 0)', $realmId, $guid, $type, $localId, PR_QUEUE_STATUS_WAITING);
+ DB::Aowow()->query('REPLACE INTO ?_profiler_sync (`realm`, `realmGUID`, `type`, `typeId`, `requestTime`, `status`, `errorCode`) VALUES (?d, ?d, ?d, ?d, UNIX_TIMESTAMP(), ?d, 0)', $realmId, $guid, $type, $localId, PR_QUEUE_STATUS_WAITING);
}
public static function scheduleResync($type, $realmId, $guid)
@@ -267,17 +267,17 @@ class Profiler
switch ($type)
{
case Type::PROFILE:
- if ($newId = DB::Aowow()->selectCell('SELECT id FROM ?_profiler_profiles WHERE realm = ?d AND realmGUID = ?d', $realmId, $guid))
+ if ($newId = DB::Aowow()->selectCell('SELECT `id` FROM ?_profiler_profiles WHERE `realm` = ?d AND `realmGUID` = ?d', $realmId, $guid))
self::queueInsert($realmId, $guid, Type::PROFILE, $newId);
break;
case Type::GUILD:
- if ($newId = DB::Aowow()->selectCell('SELECT id FROM ?_profiler_guild WHERE realm = ?d AND realmGUID = ?d', $realmId, $guid))
+ if ($newId = DB::Aowow()->selectCell('SELECT `id` FROM ?_profiler_guild WHERE `realm` = ?d AND `realmGUID` = ?d', $realmId, $guid))
self::queueInsert($realmId, $guid, Type::GUILD, $newId);
break;
case Type::ARENA_TEAM:
- if ($newId = DB::Aowow()->selectCell('SELECT id FROM ?_profiler_arena_team WHERE realm = ?d AND realmGUID = ?d', $realmId, $guid))
+ if ($newId = DB::Aowow()->selectCell('SELECT `id` FROM ?_profiler_arena_team WHERE `realm` = ?d AND `realmGUID` = ?d', $realmId, $guid))
self::queueInsert($realmId, $guid, Type::ARENA_TEAM, $newId);
break;
@@ -302,10 +302,10 @@ class Profiler
else
{
// error out all profiles with status WORKING, that are older than 60sec
- DB::Aowow()->query('UPDATE ?_profiler_sync SET status = ?d, errorCode = ?d WHERE status = ?d AND requestTime < ?d', PR_QUEUE_STATUS_ERROR, PR_QUEUE_ERROR_UNK, PR_QUEUE_STATUS_WORKING, time() - MINUTE);
+ DB::Aowow()->query('UPDATE ?_profiler_sync SET `status` = ?d, `errorCode` = ?d WHERE `status` = ?d AND `requestTime` < ?d', PR_QUEUE_STATUS_ERROR, PR_QUEUE_ERROR_UNK, PR_QUEUE_STATUS_WORKING, time() - MINUTE);
- $subjectStatus = DB::Aowow()->select('SELECT typeId AS ARRAY_KEY, status, realm, errorCode FROM ?_profiler_sync WHERE `type` = ?d AND typeId IN (?a)', $type, $subjectGUIDs);
- $queue = DB::Aowow()->selectCol('SELECT CONCAT(type, ":", typeId) FROM ?_profiler_sync WHERE status = ?d AND requestTime < UNIX_TIMESTAMP() ORDER BY requestTime ASC', PR_QUEUE_STATUS_WAITING);
+ $subjectStatus = DB::Aowow()->select('SELECT `typeId` AS ARRAY_KEY, `status`, `realm`, `errorCode` FROM ?_profiler_sync WHERE `type` = ?d AND `typeId` IN (?a)', $type, $subjectGUIDs);
+ $queue = DB::Aowow()->selectCol('SELECT CONCAT(`type`, ":", `typeId`) FROM ?_profiler_sync WHERE `status` = ?d AND `requestTime` < UNIX_TIMESTAMP() ORDER BY `requestTime` ASC', PR_QUEUE_STATUS_WAITING);
foreach ($subjectGUIDs as $guid)
{
if (empty($subjectStatus[$guid])) // whelp, thats some error..
@@ -328,7 +328,7 @@ class Profiler
public static function getCharFromRealm($realmId, $charGuid)
{
- $char = DB::Characters($realmId)->selectRow('SELECT c.* FROM characters c WHERE c.guid = ?d', $charGuid);
+ $char = DB::Characters($realmId)->selectRow('SELECT c.* FROM characters c WHERE c.`guid` = ?d', $charGuid);
if (!$char)
return false;
@@ -339,7 +339,7 @@ class Profiler
}
// reminder: this query should not fail: a placeholder entry is created as soon as a char listview is created or profile detail page is called
- $profile = DB::Aowow()->selectRow('SELECT id, lastupdated FROM ?_profiler_profiles WHERE realm = ?d AND realmGUID = ?d', $realmId, $char['guid']);
+ $profile = DB::Aowow()->selectRow('SELECT `id`, `lastupdated` FROM ?_profiler_profiles WHERE `realm` = ?d AND `realmGUID` = ?d', $realmId, $char['guid']);
if (!$profile)
return false; // well ... it failed
@@ -349,15 +349,15 @@ class Profiler
if (!$char['online'] && $char['logout_time'] <= $profile['lastupdated'])
{
- DB::Aowow()->query('UPDATE ?_profiler_profiles SET lastupdated = ?d WHERE id = ?d', time(), $profileId);
+ DB::Aowow()->query('UPDATE ?_profiler_profiles SET `lastupdated` = ?d WHERE `id` = ?d', time(), $profileId);
CLI::write('char did not log in since last update. skipping...');
return true;
}
CLI::write('writing...');
- $ra = (1 << ($char['race'] - 1));
- $cl = (1 << ($char['class'] - 1));
+ $ra = ChrRace::from($char['race']);
+ $cl = ChrClass::from($char['class']);
/*************/
/* equipment */
@@ -375,8 +375,8 @@ class Profiler
*/
- DB::Aowow()->query('DELETE FROM ?_profiler_items WHERE id = ?d', $profileId);
- $items = DB::Characters($realmId)->select('SELECT ci.slot AS ARRAY_KEY, ii.itemEntry, ii.enchantments, ii.randomPropertyId FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid WHERE ci.guid = ?d AND bag = 0 AND slot BETWEEN 0 AND 18', $char['guid']);
+ DB::Aowow()->query('DELETE FROM ?_profiler_items WHERE `id` = ?d', $profileId);
+ $items = DB::Characters($realmId)->select('SELECT ci.`slot` AS ARRAY_KEY, ii.`itemEntry`, ii.`enchantments`, ii.`randomPropertyId` FROM character_inventory ci JOIN item_instance ii ON ci.`item` = ii.`guid` WHERE ci.`guid` = ?d AND `bag` = 0 AND `slot` BETWEEN 0 AND 18', $char['guid']);
$gemItems = [];
$permEnch = [];
@@ -393,7 +393,7 @@ class Profiler
if ($gEnch)
{
- $gi = DB::Aowow()->selectCol('SELECT gemEnchantmentId AS ARRAY_KEY, id FROM ?_items WHERE class = 3 AND gemEnchantmentId IN (?a)', $gEnch);
+ $gi = DB::Aowow()->selectCol('SELECT `gemEnchantmentId` AS ARRAY_KEY, `id` FROM ?_items WHERE `class` = ?d AND `gemEnchantmentId` IN (?a)', ITEM_CLASS_GEM, $gEnch);
foreach ($gEnch as $eId)
{
if (isset($gemItems[$eId]))
@@ -449,7 +449,7 @@ class Profiler
'hairstyle' => $char['hairStyle'],
'haircolor' => $char['hairColor'],
'features' => $char['facialStyle'], // maybe facetype
- 'title' => $char['chosenTitle'] ? DB::Aowow()->selectCell('SELECT id FROM ?_titles WHERE bitIdx = ?d', $char['chosenTitle']) : 0,
+ 'title' => $char['chosenTitle'] ? DB::Aowow()->selectCell('SELECT `id` FROM ?_titles WHERE `bitIdx` = ?d', $char['chosenTitle']) : 0,
'playedtime' => $char['totaltime'],
'nomodelMask' => ($char['playerFlags'] & 0x400 ? (1 << SLOT_HEAD) : 0) | ($char['playerFlags'] & 0x800 ? (1 << SLOT_BACK) : 0),
'talenttree1' => 0,
@@ -469,7 +469,7 @@ class Profiler
// char is flagged for rename
if ($char['at_login'] & 0x1)
{
- $ri = DB::Aowow()->selectCell('SELECT MAX(renameItr) FROM ?_profiler_profiles WHERE realm = ?d AND realmGUID IS NOT NULL AND name = ?', $realmId, $char['name']);
+ $ri = DB::Aowow()->selectCell('SELECT MAX(`renameItr`) FROM ?_profiler_profiles WHERE `realm` = ?d AND `realmGUID` IS NOT NULL AND `name` = ?', $realmId, $char['name']);
$data['renameItr'] = $ri ? ++$ri : 1;
}
@@ -477,14 +477,14 @@ class Profiler
/* talents + glyphs */
/********************/
- $t = DB::Characters($realmId)->selectCol('SELECT talentGroup AS ARRAY_KEY, spell AS ARRAY_KEY2, spell FROM character_talent WHERE guid = ?d', $char['guid']);
- $g = DB::Characters($realmId)->select('SELECT talentGroup AS ARRAY_KEY, glyph1 AS g1, glyph2 AS g4, glyph3 AS g5, glyph4 AS g2, glyph5 AS g3, glyph6 AS g6 FROM character_glyphs WHERE guid = ?d', $char['guid']);
+ $t = DB::Characters($realmId)->selectCol('SELECT `talentGroup` AS ARRAY_KEY, `spell` AS ARRAY_KEY2, `spell` FROM character_talent WHERE `guid` = ?d', $char['guid']);
+ $g = DB::Characters($realmId)->select('SELECT `talentGroup` AS ARRAY_KEY, `glyph1` AS "g1", `glyph2` AS "g4", `glyph3` AS "g5", `glyph4` AS "g2", `glyph5` AS "g3", `glyph6` AS "g6" FROM character_glyphs WHERE `guid` = ?d', $char['guid']);
for ($i = 0; $i < 2; $i++)
{
// talents
for ($j = 0; $j < 3; $j++)
{
- $_ = DB::Aowow()->selectCol('SELECT spell AS ARRAY_KEY, MAX(IF(spell IN (?a), `rank`, 0)) FROM ?_talents WHERE class = ?d AND tab = ?d GROUP BY id ORDER BY `row`, `col` ASC', !empty($t[$i]) ? $t[$i] : [0], $char['class'], $j);
+ $_ = DB::Aowow()->selectCol('SELECT `spell` AS ARRAY_KEY, MAX(IF(`spell` IN (?a), `rank`, 0)) FROM ?_talents WHERE `class` = ?d AND `tab` = ?d GROUP BY `id` ORDER BY `row`, `col` ASC', $t[$i] ?? [0], $cl->value, $j);
$data['talentbuild'.($i + 1)] .= implode('', $_);
if ($data['activespec'] == $i)
$data['talenttree'.($j + 1)] = array_sum($_);
@@ -499,7 +499,7 @@ class Profiler
$gProps[$j] = $g[$i]['g'.$j];
if ($gProps)
- if ($gItems = DB::Aowow()->selectCol('SELECT i.id FROM ?_glyphproperties gp JOIN ?_spell s ON s.effect1MiscValue = gp.id AND s.effect1Id = 74 JOIN ?_items i ON i.class = 16 AND i.spellId1 = s.id WHERE gp.id IN (?a)', $gProps))
+ if ($gItems = DB::Aowow()->selectCol('SELECT i.`id` FROM ?_glyphproperties gp JOIN ?_spell s ON s.`effect1MiscValue` = gp.`id` AND s.`effect1Id` = ?d JOIN ?_items i ON i.`class` = ?d AND i.`spellId1` = s.`id` WHERE gp.`id` IN (?a)', SPELL_EFFECT_APPLY_GLYPH, ITEM_CLASS_GLYPH, $gProps))
$data['glyphs'.($i + 1)] = implode(':', $gItems);
}
}
@@ -532,7 +532,7 @@ class Profiler
// enchantId => multiple spells => multiple items with varying itemlevels, quality, whatevs
// cant reasonably get to the castItem from enchantId and slot
- $profSpec = DB::Aowow()->selectCol('SELECT id AS ARRAY_KEY, skillLevel AS "1", skillLine AS "0" FROM ?_itemenchantment WHERE id IN (?a)', $permEnch);
+ $profSpec = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `skillLevel` AS "1", `skillLine` AS "0" FROM ?_itemenchantment WHERE `id` IN (?a)', $permEnch);
foreach ($permEnch as $slot => $eId)
{
if (!isset($profSpec[$eId]))
@@ -557,7 +557,7 @@ class Profiler
/* hunter pets */
/***************/
- if ($cl == CLASS_HUNTER)
+ if ($cl == ChrClass::HUNTER)
{
DB::Aowow()->query('DELETE FROM ?_profiler_pets WHERE `owner` = ?d', $profileId);
$pets = DB::Characters($realmId)->select('SELECT `id` AS ARRAY_KEY, `entry`, `modelId`, `name` FROM character_pet WHERE `owner` = ?d', $charGuid);
@@ -568,9 +568,9 @@ class Profiler
'SELECT IFNULL(c3.`id`, IFNULL(c2.`id`, IFNULL(c1.`id`, c.`id`))) AS "entry", p.`type`, c.`family`
FROM ?_pet p
JOIN ?_creature c ON c.`family` = p.`id`
- LEFT JOIN ?_creature c1 ON c1.`difficultyEntry1` = c.id
- LEFT JOIN ?_creature c2 ON c2.`difficultyEntry2` = c.id
- LEFT JOIN ?_creature c3 ON c3.`difficultyEntry3` = c.id
+ LEFT JOIN ?_creature c1 ON c1.`difficultyEntry1` = c.`id`
+ LEFT JOIN ?_creature c2 ON c2.`difficultyEntry2` = c.`id`
+ LEFT JOIN ?_creature c3 ON c3.`difficultyEntry3` = c.`id`
WHERE c.`id` = ?d',
$petData['entry']
);
@@ -622,7 +622,7 @@ class Profiler
continue;
$r = $racials[$sk['skillId']];
- if ((!$r['reqRaceMask'] || $r['reqRaceMask'] & (1 << ($char['race'] - 1))) && (!$r['reqClassMask'] || $r['reqClassMask'] & (1 << ($char['class'] - 1))))
+ if ($ra->matches($r['reqRaceMask']) && $cl->matches($r['reqClassMask']))
{
$sk['value'] += $r['qty'];
$sk['max'] += $r['qty'];
@@ -648,7 +648,7 @@ class Profiler
SELECT `id` AS ARRAY_KEY, `baseRepValue2` FROM aowow_factions WHERE `baseRepValue2` AND (`baseRepRaceMask2` & ?d OR (`baseRepClassMask2` AND NOT `baseRepRaceMask2`)) AND ((`baseRepClassMask2` & ?d) OR NOT `baseRepClassMask2`) UNION
SELECT `id` AS ARRAY_KEY, `baseRepValue3` FROM aowow_factions WHERE `baseRepValue3` AND (`baseRepRaceMask3` & ?d OR (`baseRepClassMask3` AND NOT `baseRepRaceMask3`)) AND ((`baseRepClassMask3` & ?d) OR NOT `baseRepClassMask3`) UNION
SELECT `id` AS ARRAY_KEY, `baseRepValue4` FROM aowow_factions WHERE `baseRepValue4` AND (`baseRepRaceMask4` & ?d OR (`baseRepClassMask4` AND NOT `baseRepRaceMask4`)) AND ((`baseRepClassMask4` & ?d) OR NOT `baseRepClassMask4`)',
- $ra, $cl, $ra, $cl, $ra, $cl, $ra, $cl
+ $ra->toMask(), $cl->toMask(), $ra->toMask(), $cl->toMask(), $ra->toMask(), $cl->toMask(), $ra->toMask(), $cl->toMask()
);
if ($reputation = DB::Characters($realmId)->select('SELECT ?d AS `id`, `faction` AS `factionId`, `standing` FROM character_reputation WHERE `guid` = ?d AND (`flags` & 0x4) = 0', $profileId, $char['guid']))
@@ -744,8 +744,8 @@ class Profiler
(`reqClassMask` = 0 OR `reqClassMask` & ?d)',
$profileId,
array_column($skills, 'skillId'),
- 1 << ($char['race'] - 1),
- 1 << ($char['class'] - 1)
+ $ra->toMask(),
+ $cl->toMask()
);
CLI::write(' ..known spells (vanity pets & mounts)');
@@ -860,11 +860,11 @@ class Profiler
unset($guild['guildId']);
$guild['nameUrl'] = self::urlize($guild['name']);
- DB::Aowow()->query('UPDATE ?_profiler_guild SET ?a WHERE realm = ?d AND realmGUID = ?d', $guild, $realmId, $guildGuid);
+ DB::Aowow()->query('UPDATE ?_profiler_guild SET ?a WHERE `realm` = ?d AND `realmGUID` = ?d', $guild, $realmId, $guildGuid);
// ranks
DB::Aowow()->query('DELETE FROM ?_profiler_guild_rank WHERE `guildId` = ?d', $guildId);
- if ($ranks = DB::Characters($realmId)->select('SELECT ?d AS `guildId`, `rid` AS `rank`, `rname` AS `name` FROM guild_rank WHERE `guildid` = ?d', $guildId, $guildGuid))
+ if ($ranks = DB::Characters($realmId)->select('SELECT ?d AS `guildId`, `rid` AS "rank", `rname` AS "name" FROM guild_rank WHERE `guildid` = ?d', $guildId, $guildGuid))
foreach (Util::createSqlBatchInsert($ranks) as $r)
DB::Aowow()->query('INSERT INTO ?_profiler_guild_rank (?#) VALUES '.$r, array_keys(reset($ranks)));
@@ -914,7 +914,7 @@ class Profiler
}
// reminder: this query should not fail: a placeholder entry is created as soon as a team listview is created or team detail page is called
- $teamId = DB::Aowow()->selectCell('SELECT id FROM ?_profiler_arena_team WHERE realm = ?d AND realmGUID = ?d', $realmId, $team['arenaTeamId']);
+ $teamId = DB::Aowow()->selectCell('SELECT `id` FROM ?_profiler_arena_team WHERE `realm` = ?d AND `realmGUID` = ?d', $realmId, $team['arenaTeamId']);
CLI::write('fetching arena team #'.$teamGuid.' from realm #'.$realmId);
CLI::write('writing...');
diff --git a/includes/types/creature.class.php b/includes/types/creature.class.php
index 36753129..6ca1a35f 100644
--- a/includes/types/creature.class.php
+++ b/includes/types/creature.class.php
@@ -447,11 +447,11 @@ class CreatureListFilter extends Filter
case 1: // any
return ['AND', ['qse.method', $val, '&'], ['qse.questId', null, '!']];
case 2: // alliance
- return ['AND', ['qse.method', $val, '&'], ['qse.questId', null, '!'], [['qt.reqRaceMask', RACE_MASK_HORDE, '&'], 0], ['qt.reqRaceMask', RACE_MASK_ALLIANCE, '&']];
+ return ['AND', ['qse.method', $val, '&'], ['qse.questId', null, '!'], [['qt.reqRaceMask', ChrRace::MASK_HORDE, '&'], 0], ['qt.reqRaceMask', ChrRace::MASK_ALLIANCE, '&']];
case 3: // horde
- return ['AND', ['qse.method', $val, '&'], ['qse.questId', null, '!'], [['qt.reqRaceMask', RACE_MASK_ALLIANCE, '&'], 0], ['qt.reqRaceMask', RACE_MASK_HORDE, '&']];
+ return ['AND', ['qse.method', $val, '&'], ['qse.questId', null, '!'], [['qt.reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], 0], ['qt.reqRaceMask', ChrRace::MASK_HORDE, '&']];
case 4: // both
- return ['AND', ['qse.method', $val, '&'], ['qse.questId', null, '!'], ['OR', ['AND', ['qt.reqRaceMask', RACE_MASK_ALLIANCE, '&'], ['qt.reqRaceMask', RACE_MASK_HORDE, '&']], ['qt.reqRaceMask', 0]]];
+ return ['AND', ['qse.method', $val, '&'], ['qse.questId', null, '!'], ['OR', ['AND', ['qt.reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ['qt.reqRaceMask', ChrRace::MASK_HORDE, '&']], ['qt.reqRaceMask', 0]]];
case 5: // none
$this->extraOpts['ct']['h'][] = $field.' = 0';
return [1];
diff --git a/includes/types/gameobject.class.php b/includes/types/gameobject.class.php
index f3f34c5e..d1b38d6e 100644
--- a/includes/types/gameobject.class.php
+++ b/includes/types/gameobject.class.php
@@ -201,11 +201,11 @@ class GameObjectListFilter extends Filter
case 1: // any
return ['AND', ['qse.method', $value, '&'], ['qse.questId', null, '!']];
case 2: // alliance only
- return ['AND', ['qse.method', $value, '&'], ['qse.questId', null, '!'], [['qt.reqRaceMask', RACE_MASK_HORDE, '&'], 0], ['qt.reqRaceMask', RACE_MASK_ALLIANCE, '&']];
+ return ['AND', ['qse.method', $value, '&'], ['qse.questId', null, '!'], [['qt.reqRaceMask', ChrRace::MASK_HORDE, '&'], 0], ['qt.reqRaceMask', ChrRace::MASK_ALLIANCE, '&']];
case 3: // horde only
- return ['AND', ['qse.method', $value, '&'], ['qse.questId', null, '!'], [['qt.reqRaceMask', RACE_MASK_ALLIANCE, '&'], 0], ['qt.reqRaceMask', RACE_MASK_HORDE, '&']];
+ return ['AND', ['qse.method', $value, '&'], ['qse.questId', null, '!'], [['qt.reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], 0], ['qt.reqRaceMask', ChrRace::MASK_HORDE, '&']];
case 4: // both
- return ['AND', ['qse.method', $value, '&'], ['qse.questId', null, '!'], ['OR', ['AND', ['qt.reqRaceMask', RACE_MASK_ALLIANCE, '&'], ['qt.reqRaceMask', RACE_MASK_HORDE, '&']], ['qt.reqRaceMask', 0]]];
+ return ['AND', ['qse.method', $value, '&'], ['qse.questId', null, '!'], ['OR', ['AND', ['qt.reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ['qt.reqRaceMask', ChrRace::MASK_HORDE, '&']], ['qt.reqRaceMask', 0]]];
case 5: // none todo (low): broken, if entry starts and ends quests...
$this->extraOpts['o']['h'][] = $field.' = 0';
return [1];
diff --git a/includes/types/guide.class.php b/includes/types/guide.class.php
index d183670a..4316aa73 100644
--- a/includes/types/guide.class.php
+++ b/includes/types/guide.class.php
@@ -147,7 +147,7 @@ class GuideList extends BaseType
if ($c = $this->getField('classId'))
{
$n = Lang::game('cl', $c);
- $specStr .= ' – %s';
+ $specStr .= ' – %s';
if (($s = $this->getField('specId')) > -1)
{
diff --git a/includes/types/item.class.php b/includes/types/item.class.php
index 40aa516c..2cead090 100644
--- a/includes/types/item.class.php
+++ b/includes/types/item.class.php
@@ -65,14 +65,14 @@ class ItemList extends BaseType
// unify those pesky masks
$_ = &$_curTpl['requiredClass'];
- $_ &= CLASS_MASK_ALL;
- if ($_ < 0 || $_ == CLASS_MASK_ALL)
+ $_ &= ChrClass::MASK_ALL;
+ if ($_ < 0 || $_ == ChrClass::MASK_ALL)
$_ = 0;
unset($_);
$_ = &$_curTpl['requiredRace'];
- $_ &= RACE_MASK_ALL;
- if ($_ < 0 || $_ == RACE_MASK_ALL)
+ $_ &= ChrRace::MASK_ALL;
+ if ($_ < 0 || $_ == ChrRace::MASK_ALL)
$_ = 0;
unset($_);
@@ -433,7 +433,7 @@ class ItemList extends BaseType
$data[$this->id]['nslots'] = $x;
$_ = $this->curTpl['requiredRace'];
- if ($_ && $_ & RACE_MASK_ALLIANCE != RACE_MASK_ALLIANCE && $_ & RACE_MASK_HORDE != RACE_MASK_HORDE)
+ if ($_ && $_ & ChrRace::MASK_ALLIANCE != ChrRace::MASK_ALLIANCE && $_ & ChrRace::MASK_HORDE != ChrRace::MASK_HORDE)
$data[$this->id]['reqrace'] = $_;
if ($_ = $this->curTpl['requiredClass'])
@@ -1430,7 +1430,7 @@ class ItemList extends BaseType
return 0.0;
$subClasses = [ITEM_SUBCLASS_MISC_WEAPON];
- $weaponTypeMask = DB::Aowow()->selectCell('SELECT `weaponTypeMask` FROM ?_classes WHERE `id` = ?d', log(CLASS_DRUID, 2) + 1);
+ $weaponTypeMask = DB::Aowow()->selectCell('SELECT `weaponTypeMask` FROM ?_classes WHERE `id` = ?d', ChrClass::DRUID->value);
if ($weaponTypeMask)
for ($i = 0; $i < 21; $i++)
if ($weaponTypeMask & (1 << $i))
@@ -1688,7 +1688,7 @@ class ItemList extends BaseType
'subclass' => $subclass,
'subsubclass' => $this->curTpl['subSubClass'],
'heroic' => ($this->curTpl['flags'] & ITEM_FLAG_HEROIC) >> 3,
- 'side' => $this->curTpl['flagsExtra'] & 0x3 ? SIDE_BOTH - ($this->curTpl['flagsExtra'] & 0x3) : Game::sideByRaceMask($this->curTpl['requiredRace']),
+ 'side' => $this->curTpl['flagsExtra'] & 0x3 ? SIDE_BOTH - ($this->curTpl['flagsExtra'] & 0x3) : ChrRace::sideFromMask($this->curTpl['requiredRace']),
'slot' => $this->curTpl['slot'],
'slotbak' => $this->curTpl['slotBak'],
'level' => $this->curTpl['itemLevel'],
@@ -1836,162 +1836,162 @@ class ItemListFilter extends Filter
);
protected $genericFilter = array(
- 2 => [parent::CR_CALLBACK, 'cbFieldHasVal', 'bonding', 1 ], // bindonpickup [yn]
- 3 => [parent::CR_CALLBACK, 'cbFieldHasVal', 'bonding', 2 ], // bindonequip [yn]
- 4 => [parent::CR_CALLBACK, 'cbFieldHasVal', 'bonding', 3 ], // bindonuse [yn]
- 5 => [parent::CR_CALLBACK, 'cbFieldHasVal', 'bonding', [4, 5] ], // questitem [yn]
- 6 => [parent::CR_CALLBACK, 'cbQuestRelation', null, null ], // startsquest [side]
- 7 => [parent::CR_BOOLEAN, 'description_loc0', true ], // hasflavortext
- 8 => [parent::CR_BOOLEAN, 'requiredDisenchantSkill' ], // disenchantable
- 9 => [parent::CR_FLAG, 'flags', ITEM_FLAG_CONJURED ], // conjureditem
- 10 => [parent::CR_BOOLEAN, 'lockId' ], // locked
- 11 => [parent::CR_FLAG, 'flags', ITEM_FLAG_OPENABLE ], // openable
- 12 => [parent::CR_BOOLEAN, 'itemset' ], // partofset
- 13 => [parent::CR_BOOLEAN, 'randomEnchant' ], // randomlyenchanted
- 14 => [parent::CR_BOOLEAN, 'pageTextId' ], // readable
- 15 => [parent::CR_CALLBACK, 'cbFieldHasVal', 'maxCount', 1 ], // unique [yn]
- 16 => [parent::CR_CALLBACK, 'cbDropsInZone', null, null ], // dropsin [zone]
- 17 => [parent::CR_ENUM, 'requiredFaction', true, true ], // requiresrepwith
- 18 => [parent::CR_CALLBACK, 'cbFactionQuestReward', null, null ], // rewardedbyfactionquest [side]
- 20 => [parent::CR_NUMERIC, 'is.str', NUM_CAST_INT, true ], // str
- 21 => [parent::CR_NUMERIC, 'is.agi', NUM_CAST_INT, true ], // agi
- 22 => [parent::CR_NUMERIC, 'is.sta', NUM_CAST_INT, true ], // sta
- 23 => [parent::CR_NUMERIC, 'is.int', NUM_CAST_INT, true ], // int
- 24 => [parent::CR_NUMERIC, 'is.spi', NUM_CAST_INT, true ], // spi
- 25 => [parent::CR_NUMERIC, 'is.arcres', NUM_CAST_INT, true ], // arcres
- 26 => [parent::CR_NUMERIC, 'is.firres', NUM_CAST_INT, true ], // firres
- 27 => [parent::CR_NUMERIC, 'is.natres', NUM_CAST_INT, true ], // natres
- 28 => [parent::CR_NUMERIC, 'is.frores', NUM_CAST_INT, true ], // frores
- 29 => [parent::CR_NUMERIC, 'is.shares', NUM_CAST_INT, true ], // shares
- 30 => [parent::CR_NUMERIC, 'is.holres', NUM_CAST_INT, true ], // holres
- 32 => [parent::CR_NUMERIC, 'is.dps', NUM_CAST_FLOAT, true ], // dps
- 33 => [parent::CR_NUMERIC, 'is.dmgmin1', NUM_CAST_INT, true ], // dmgmin1
- 34 => [parent::CR_NUMERIC, 'is.dmgmax1', NUM_CAST_INT, true ], // dmgmax1
- 35 => [parent::CR_CALLBACK, 'cbDamageType', null, null ], // damagetype [enum]
- 36 => [parent::CR_NUMERIC, 'is.speed', NUM_CAST_FLOAT, true ], // speed
- 37 => [parent::CR_NUMERIC, 'is.mleatkpwr', NUM_CAST_INT, true ], // mleatkpwr
- 38 => [parent::CR_NUMERIC, 'is.rgdatkpwr', NUM_CAST_INT, true ], // rgdatkpwr
- 39 => [parent::CR_NUMERIC, 'is.rgdhitrtng', NUM_CAST_INT, true ], // rgdhitrtng
- 40 => [parent::CR_NUMERIC, 'is.rgdcritstrkrtng', NUM_CAST_INT, true ], // rgdcritstrkrtng
- 41 => [parent::CR_NUMERIC, 'is.armor', NUM_CAST_INT, true ], // armor
- 42 => [parent::CR_NUMERIC, 'is.defrtng', NUM_CAST_INT, true ], // defrtng
- 43 => [parent::CR_NUMERIC, 'is.block', NUM_CAST_INT, true ], // block
- 44 => [parent::CR_NUMERIC, 'is.blockrtng', NUM_CAST_INT, true ], // blockrtng
- 45 => [parent::CR_NUMERIC, 'is.dodgertng', NUM_CAST_INT, true ], // dodgertng
- 46 => [parent::CR_NUMERIC, 'is.parryrtng', NUM_CAST_INT, true ], // parryrtng
- 48 => [parent::CR_NUMERIC, 'is.splhitrtng', NUM_CAST_INT, true ], // splhitrtng
- 49 => [parent::CR_NUMERIC, 'is.splcritstrkrtng', NUM_CAST_INT, true ], // splcritstrkrtng
- 50 => [parent::CR_NUMERIC, 'is.splheal', NUM_CAST_INT, true ], // splheal
- 51 => [parent::CR_NUMERIC, 'is.spldmg', NUM_CAST_INT, true ], // spldmg
- 52 => [parent::CR_NUMERIC, 'is.arcsplpwr', NUM_CAST_INT, true ], // arcsplpwr
- 53 => [parent::CR_NUMERIC, 'is.firsplpwr', NUM_CAST_INT, true ], // firsplpwr
- 54 => [parent::CR_NUMERIC, 'is.frosplpwr', NUM_CAST_INT, true ], // frosplpwr
- 55 => [parent::CR_NUMERIC, 'is.holsplpwr', NUM_CAST_INT, true ], // holsplpwr
- 56 => [parent::CR_NUMERIC, 'is.natsplpwr', NUM_CAST_INT, true ], // natsplpwr
- 57 => [parent::CR_NUMERIC, 'is.shasplpwr', NUM_CAST_INT, true ], // shasplpwr
- 59 => [parent::CR_NUMERIC, 'durability', NUM_CAST_INT, true ], // dura
- 60 => [parent::CR_NUMERIC, 'is.healthrgn', NUM_CAST_INT, true ], // healthrgn
- 61 => [parent::CR_NUMERIC, 'is.manargn', NUM_CAST_INT, true ], // manargn
- 62 => [parent::CR_CALLBACK, 'cbCooldown', null, null ], // cooldown [op] [int]
- 63 => [parent::CR_NUMERIC, 'buyPrice', NUM_CAST_INT, true ], // buyprice
- 64 => [parent::CR_NUMERIC, 'sellPrice', NUM_CAST_INT, true ], // sellprice
- 65 => [parent::CR_CALLBACK, 'cbAvgMoneyContent', null, null ], // avgmoney [op] [int]
- 66 => [parent::CR_ENUM, 'requiredSpell' ], // requiresprofspec
- 68 => [parent::CR_CALLBACK, 'cbObtainedBy', 15, null ], // otdisenchanting [yn]
- 69 => [parent::CR_CALLBACK, 'cbObtainedBy', 16, null ], // otfishing [yn]
- 70 => [parent::CR_CALLBACK, 'cbObtainedBy', 17, null ], // otherbgathering [yn]
- 71 => [parent::CR_FLAG, 'cuFlags', ITEM_CU_OT_ITEMLOOT ], // otitemopening [yn]
- 72 => [parent::CR_CALLBACK, 'cbObtainedBy', 2, null ], // otlooting [yn]
- 73 => [parent::CR_CALLBACK, 'cbObtainedBy', 19, null ], // otmining [yn]
- 74 => [parent::CR_FLAG, 'cuFlags', ITEM_CU_OT_OBJECTLOOT ], // otobjectopening [yn]
- 75 => [parent::CR_CALLBACK, 'cbObtainedBy', 21, null ], // otpickpocketing [yn]
- 76 => [parent::CR_CALLBACK, 'cbObtainedBy', 23, null ], // otskinning [yn]
- 77 => [parent::CR_NUMERIC, 'is.atkpwr', NUM_CAST_INT, true ], // atkpwr
- 78 => [parent::CR_NUMERIC, 'is.mlehastertng', NUM_CAST_INT, true ], // mlehastertng
- 79 => [parent::CR_NUMERIC, 'is.resirtng', NUM_CAST_INT, true ], // resirtng
- 80 => [parent::CR_CALLBACK, 'cbHasSockets', null, null ], // has sockets [enum]
- 81 => [parent::CR_CALLBACK, 'cbFitsGemSlot', null, null ], // fits gem slot [enum]
- 83 => [parent::CR_FLAG, 'flags', ITEM_FLAG_UNIQUEEQUIPPED ], // uniqueequipped
- 84 => [parent::CR_NUMERIC, 'is.mlecritstrkrtng', NUM_CAST_INT, true ], // mlecritstrkrtng
- 85 => [parent::CR_CALLBACK, 'cbObjectiveOfQuest', null, null ], // objectivequest [side]
- 86 => [parent::CR_CALLBACK, 'cbCraftedByProf', null, null ], // craftedprof [enum]
- 87 => [parent::CR_CALLBACK, 'cbReagentForAbility', null, null ], // reagentforability [enum]
- 88 => [parent::CR_CALLBACK, 'cbObtainedBy', 20, null ], // otprospecting [yn]
- 89 => [parent::CR_FLAG, 'flags', ITEM_FLAG_PROSPECTABLE ], // prospectable
- 90 => [parent::CR_CALLBACK, 'cbAvgBuyout', null, null ], // avgbuyout [op] [int]
- 91 => [parent::CR_ENUM, 'totemCategory', false, true ], // tool
- 92 => [parent::CR_CALLBACK, 'cbObtainedBy', 5, null ], // soldbyvendor [yn]
- 93 => [parent::CR_CALLBACK, 'cbObtainedBy', 3, null ], // otpvp [pvp]
- 94 => [parent::CR_NUMERIC, 'is.splpen', NUM_CAST_INT, true ], // splpen
- 95 => [parent::CR_NUMERIC, 'is.mlehitrtng', NUM_CAST_INT, true ], // mlehitrtng
- 96 => [parent::CR_NUMERIC, 'is.critstrkrtng', NUM_CAST_INT, true ], // critstrkrtng
- 97 => [parent::CR_NUMERIC, 'is.feratkpwr', NUM_CAST_INT, true ], // feratkpwr
- 98 => [parent::CR_FLAG, 'flags', ITEM_FLAG_PARTYLOOT ], // partyloot
- 99 => [parent::CR_ENUM, 'requiredSkill' ], // requiresprof
- 100 => [parent::CR_NUMERIC, 'is.nsockets', NUM_CAST_INT ], // nsockets
- 101 => [parent::CR_NUMERIC, 'is.rgdhastertng', NUM_CAST_INT, true ], // rgdhastertng
- 102 => [parent::CR_NUMERIC, 'is.splhastertng', NUM_CAST_INT, true ], // splhastertng
- 103 => [parent::CR_NUMERIC, 'is.hastertng', NUM_CAST_INT, true ], // hastertng
- 104 => [parent::CR_STRING, 'description', STR_LOCALIZED ], // flavortext
- 105 => [parent::CR_CALLBACK, 'cbDropsInInstance', SRC_FLAG_DUNGEON_DROP, 1 ], // dropsinnormal [heroicdungeon-any]
- 106 => [parent::CR_CALLBACK, 'cbDropsInInstance', SRC_FLAG_DUNGEON_DROP, 2 ], // dropsinheroic [heroicdungeon-any]
- 107 => [parent::CR_NYI_PH, null, 1, ], // effecttext [str] not yet parsed ['effectsParsed_loc'.Lang::getLocale()->value, $cr[2]]
- 109 => [parent::CR_CALLBACK, 'cbArmorBonus', null, null ], // armorbonus [op] [int]
- 111 => [parent::CR_NUMERIC, 'requiredSkillRank', NUM_CAST_INT, true ], // reqskillrank
- 113 => [parent::CR_FLAG, 'cuFlags', CUSTOM_HAS_SCREENSHOT ], // hasscreenshots
- 114 => [parent::CR_NUMERIC, 'is.armorpenrtng', NUM_CAST_INT, true ], // armorpenrtng
- 115 => [parent::CR_NUMERIC, 'is.health', NUM_CAST_INT, true ], // health
- 116 => [parent::CR_NUMERIC, 'is.mana', NUM_CAST_INT, true ], // mana
- 117 => [parent::CR_NUMERIC, 'is.exprtng', NUM_CAST_INT, true ], // exprtng
- 118 => [parent::CR_CALLBACK, 'cbPurchasableWith', null, null ], // purchasablewithitem [enum]
- 119 => [parent::CR_NUMERIC, 'is.hitrtng', NUM_CAST_INT, true ], // hitrtng
- 123 => [parent::CR_NUMERIC, 'is.splpwr', NUM_CAST_INT, true ], // splpwr
- 124 => [parent::CR_CALLBACK, 'cbHasRandEnchant', null, null ], // randomenchants [str]
- 125 => [parent::CR_CALLBACK, 'cbReqArenaRating', null, null ], // reqarenartng [op] [int] todo (low): 'find out, why "IN (W, X, Y) AND IN (X, Y, Z)" doesn't result in "(X, Y)"
- 126 => [parent::CR_CALLBACK, 'cbQuestRewardIn', null, null ], // rewardedbyquestin [zone-any]
- 128 => [parent::CR_CALLBACK, 'cbSource', null, null ], // source [enum]
- 129 => [parent::CR_CALLBACK, 'cbSoldByNPC', null, null ], // soldbynpc [str-small]
- 130 => [parent::CR_FLAG, 'cuFlags', CUSTOM_HAS_COMMENT ], // hascomments
- 132 => [parent::CR_CALLBACK, 'cbGlyphType', null, null ], // glyphtype [enum]
- 133 => [parent::CR_FLAG, 'flags', ITEM_FLAG_ACCOUNTBOUND ], // accountbound
- 134 => [parent::CR_NUMERIC, 'is.mledps', NUM_CAST_FLOAT, true ], // mledps
- 135 => [parent::CR_NUMERIC, 'is.mledmgmin', NUM_CAST_INT, true ], // mledmgmin
- 136 => [parent::CR_NUMERIC, 'is.mledmgmax', NUM_CAST_INT, true ], // mledmgmax
- 137 => [parent::CR_NUMERIC, 'is.mlespeed', NUM_CAST_FLOAT, true ], // mlespeed
- 138 => [parent::CR_NUMERIC, 'is.rgddps', NUM_CAST_FLOAT, true ], // rgddps
- 139 => [parent::CR_NUMERIC, 'is.rgddmgmin', NUM_CAST_INT, true ], // rgddmgmin
- 140 => [parent::CR_NUMERIC, 'is.rgddmgmax', NUM_CAST_INT, true ], // rgddmgmax
- 141 => [parent::CR_NUMERIC, 'is.rgdspeed', NUM_CAST_FLOAT, true ], // rgdspeed
- 142 => [parent::CR_STRING, 'ic.name' ], // icon
- 143 => [parent::CR_CALLBACK, 'cbObtainedBy', 18, null ], // otmilling [yn]
- 144 => [parent::CR_CALLBACK, 'cbPvpPurchasable', 'reqHonorPoints', null ], // purchasablewithhonor [yn]
- 145 => [parent::CR_CALLBACK, 'cbPvpPurchasable', 'reqArenaPoints', null ], // purchasablewitharena [yn]
- 146 => [parent::CR_FLAG, 'flags', ITEM_FLAG_HEROIC ], // heroic
- 147 => [parent::CR_CALLBACK, 'cbDropsInInstance', SRC_FLAG_RAID_DROP, 1, ], // dropsinnormal10 [multimoderaid-any]
- 148 => [parent::CR_CALLBACK, 'cbDropsInInstance', SRC_FLAG_RAID_DROP, 2, ], // dropsinnormal25 [multimoderaid-any]
- 149 => [parent::CR_CALLBACK, 'cbDropsInInstance', SRC_FLAG_RAID_DROP, 4, ], // dropsinheroic10 [heroicraid-any]
- 150 => [parent::CR_CALLBACK, 'cbDropsInInstance', SRC_FLAG_RAID_DROP, 8, ], // dropsinheroic25 [heroicraid-any]
- 151 => [parent::CR_NUMERIC, 'id', NUM_CAST_INT, true ], // id
- 152 => [parent::CR_CALLBACK, 'cbClassRaceSpec', 'requiredClass', CLASS_MASK_ALL], // classspecific [enum]
- 153 => [parent::CR_CALLBACK, 'cbClassRaceSpec', 'requiredRace', RACE_MASK_ALL ], // racespecific [enum]
- 154 => [parent::CR_FLAG, 'flags', ITEM_FLAG_REFUNDABLE ], // refundable
- 155 => [parent::CR_FLAG, 'flags', ITEM_FLAG_USABLE_ARENA ], // usableinarenas
- 156 => [parent::CR_FLAG, 'flags', ITEM_FLAG_USABLE_SHAPED ], // usablewhenshapeshifted
- 157 => [parent::CR_FLAG, 'flags', ITEM_FLAG_SMARTLOOT ], // smartloot
- 158 => [parent::CR_CALLBACK, 'cbPurchasableWith', null, null ], // purchasablewithcurrency [enum]
- 159 => [parent::CR_FLAG, 'flags', ITEM_FLAG_MILLABLE ], // millable
- 160 => [parent::CR_NYI_PH, null, 1, ], // relatedevent [enum] like 169 .. crawl though npc_vendor and loot_templates of event-related spawns
- 161 => [parent::CR_CALLBACK, 'cbAvailable', null, null ], // availabletoplayers [yn]
- 162 => [parent::CR_FLAG, 'flags', ITEM_FLAG_DEPRECATED ], // deprecated
- 163 => [parent::CR_CALLBACK, 'cbDisenchantsInto', null, null ], // disenchantsinto [disenchanting]
- 165 => [parent::CR_NUMERIC, 'repairPrice', NUM_CAST_INT, true ], // repaircost
- 167 => [parent::CR_FLAG, 'cuFlags', CUSTOM_HAS_VIDEO ], // hasvideos
- 168 => [parent::CR_CALLBACK, 'cbFieldHasVal', 'spellId1', LEARN_SPELLS ], // teachesspell [yn]
- 169 => [parent::CR_ENUM, 'e.holidayId', true, true ], // requiresevent
- 171 => [parent::CR_CALLBACK, 'cbObtainedBy', 8, null ], // otredemption [yn]
- 172 => [parent::CR_CALLBACK, 'cbObtainedBy', 12, null ], // rewardedbyachievement [yn]
- 176 => [parent::CR_STAFFFLAG, 'flags' ], // flags
- 177 => [parent::CR_STAFFFLAG, 'flagsExtra' ], // flags2
+ 2 => [parent::CR_CALLBACK, 'cbFieldHasVal', 'bonding', 1 ], // bindonpickup [yn]
+ 3 => [parent::CR_CALLBACK, 'cbFieldHasVal', 'bonding', 2 ], // bindonequip [yn]
+ 4 => [parent::CR_CALLBACK, 'cbFieldHasVal', 'bonding', 3 ], // bindonuse [yn]
+ 5 => [parent::CR_CALLBACK, 'cbFieldHasVal', 'bonding', [4, 5] ], // questitem [yn]
+ 6 => [parent::CR_CALLBACK, 'cbQuestRelation', null, null ], // startsquest [side]
+ 7 => [parent::CR_BOOLEAN, 'description_loc0', true ], // hasflavortext
+ 8 => [parent::CR_BOOLEAN, 'requiredDisenchantSkill' ], // disenchantable
+ 9 => [parent::CR_FLAG, 'flags', ITEM_FLAG_CONJURED ], // conjureditem
+ 10 => [parent::CR_BOOLEAN, 'lockId' ], // locked
+ 11 => [parent::CR_FLAG, 'flags', ITEM_FLAG_OPENABLE ], // openable
+ 12 => [parent::CR_BOOLEAN, 'itemset' ], // partofset
+ 13 => [parent::CR_BOOLEAN, 'randomEnchant' ], // randomlyenchanted
+ 14 => [parent::CR_BOOLEAN, 'pageTextId' ], // readable
+ 15 => [parent::CR_CALLBACK, 'cbFieldHasVal', 'maxCount', 1 ], // unique [yn]
+ 16 => [parent::CR_CALLBACK, 'cbDropsInZone', null, null ], // dropsin [zone]
+ 17 => [parent::CR_ENUM, 'requiredFaction', true, true ], // requiresrepwith
+ 18 => [parent::CR_CALLBACK, 'cbFactionQuestReward', null, null ], // rewardedbyfactionquest [side]
+ 20 => [parent::CR_NUMERIC, 'is.str', NUM_CAST_INT, true ], // str
+ 21 => [parent::CR_NUMERIC, 'is.agi', NUM_CAST_INT, true ], // agi
+ 22 => [parent::CR_NUMERIC, 'is.sta', NUM_CAST_INT, true ], // sta
+ 23 => [parent::CR_NUMERIC, 'is.int', NUM_CAST_INT, true ], // int
+ 24 => [parent::CR_NUMERIC, 'is.spi', NUM_CAST_INT, true ], // spi
+ 25 => [parent::CR_NUMERIC, 'is.arcres', NUM_CAST_INT, true ], // arcres
+ 26 => [parent::CR_NUMERIC, 'is.firres', NUM_CAST_INT, true ], // firres
+ 27 => [parent::CR_NUMERIC, 'is.natres', NUM_CAST_INT, true ], // natres
+ 28 => [parent::CR_NUMERIC, 'is.frores', NUM_CAST_INT, true ], // frores
+ 29 => [parent::CR_NUMERIC, 'is.shares', NUM_CAST_INT, true ], // shares
+ 30 => [parent::CR_NUMERIC, 'is.holres', NUM_CAST_INT, true ], // holres
+ 32 => [parent::CR_NUMERIC, 'is.dps', NUM_CAST_FLOAT, true ], // dps
+ 33 => [parent::CR_NUMERIC, 'is.dmgmin1', NUM_CAST_INT, true ], // dmgmin1
+ 34 => [parent::CR_NUMERIC, 'is.dmgmax1', NUM_CAST_INT, true ], // dmgmax1
+ 35 => [parent::CR_CALLBACK, 'cbDamageType', null, null ], // damagetype [enum]
+ 36 => [parent::CR_NUMERIC, 'is.speed', NUM_CAST_FLOAT, true ], // speed
+ 37 => [parent::CR_NUMERIC, 'is.mleatkpwr', NUM_CAST_INT, true ], // mleatkpwr
+ 38 => [parent::CR_NUMERIC, 'is.rgdatkpwr', NUM_CAST_INT, true ], // rgdatkpwr
+ 39 => [parent::CR_NUMERIC, 'is.rgdhitrtng', NUM_CAST_INT, true ], // rgdhitrtng
+ 40 => [parent::CR_NUMERIC, 'is.rgdcritstrkrtng', NUM_CAST_INT, true ], // rgdcritstrkrtng
+ 41 => [parent::CR_NUMERIC, 'is.armor', NUM_CAST_INT, true ], // armor
+ 42 => [parent::CR_NUMERIC, 'is.defrtng', NUM_CAST_INT, true ], // defrtng
+ 43 => [parent::CR_NUMERIC, 'is.block', NUM_CAST_INT, true ], // block
+ 44 => [parent::CR_NUMERIC, 'is.blockrtng', NUM_CAST_INT, true ], // blockrtng
+ 45 => [parent::CR_NUMERIC, 'is.dodgertng', NUM_CAST_INT, true ], // dodgertng
+ 46 => [parent::CR_NUMERIC, 'is.parryrtng', NUM_CAST_INT, true ], // parryrtng
+ 48 => [parent::CR_NUMERIC, 'is.splhitrtng', NUM_CAST_INT, true ], // splhitrtng
+ 49 => [parent::CR_NUMERIC, 'is.splcritstrkrtng', NUM_CAST_INT, true ], // splcritstrkrtng
+ 50 => [parent::CR_NUMERIC, 'is.splheal', NUM_CAST_INT, true ], // splheal
+ 51 => [parent::CR_NUMERIC, 'is.spldmg', NUM_CAST_INT, true ], // spldmg
+ 52 => [parent::CR_NUMERIC, 'is.arcsplpwr', NUM_CAST_INT, true ], // arcsplpwr
+ 53 => [parent::CR_NUMERIC, 'is.firsplpwr', NUM_CAST_INT, true ], // firsplpwr
+ 54 => [parent::CR_NUMERIC, 'is.frosplpwr', NUM_CAST_INT, true ], // frosplpwr
+ 55 => [parent::CR_NUMERIC, 'is.holsplpwr', NUM_CAST_INT, true ], // holsplpwr
+ 56 => [parent::CR_NUMERIC, 'is.natsplpwr', NUM_CAST_INT, true ], // natsplpwr
+ 57 => [parent::CR_NUMERIC, 'is.shasplpwr', NUM_CAST_INT, true ], // shasplpwr
+ 59 => [parent::CR_NUMERIC, 'durability', NUM_CAST_INT, true ], // dura
+ 60 => [parent::CR_NUMERIC, 'is.healthrgn', NUM_CAST_INT, true ], // healthrgn
+ 61 => [parent::CR_NUMERIC, 'is.manargn', NUM_CAST_INT, true ], // manargn
+ 62 => [parent::CR_CALLBACK, 'cbCooldown', null, null ], // cooldown [op] [int]
+ 63 => [parent::CR_NUMERIC, 'buyPrice', NUM_CAST_INT, true ], // buyprice
+ 64 => [parent::CR_NUMERIC, 'sellPrice', NUM_CAST_INT, true ], // sellprice
+ 65 => [parent::CR_CALLBACK, 'cbAvgMoneyContent', null, null ], // avgmoney [op] [int]
+ 66 => [parent::CR_ENUM, 'requiredSpell' ], // requiresprofspec
+ 68 => [parent::CR_CALLBACK, 'cbObtainedBy', 15, null ], // otdisenchanting [yn]
+ 69 => [parent::CR_CALLBACK, 'cbObtainedBy', 16, null ], // otfishing [yn]
+ 70 => [parent::CR_CALLBACK, 'cbObtainedBy', 17, null ], // otherbgathering [yn]
+ 71 => [parent::CR_FLAG, 'cuFlags', ITEM_CU_OT_ITEMLOOT ], // otitemopening [yn]
+ 72 => [parent::CR_CALLBACK, 'cbObtainedBy', 2, null ], // otlooting [yn]
+ 73 => [parent::CR_CALLBACK, 'cbObtainedBy', 19, null ], // otmining [yn]
+ 74 => [parent::CR_FLAG, 'cuFlags', ITEM_CU_OT_OBJECTLOOT ], // otobjectopening [yn]
+ 75 => [parent::CR_CALLBACK, 'cbObtainedBy', 21, null ], // otpickpocketing [yn]
+ 76 => [parent::CR_CALLBACK, 'cbObtainedBy', 23, null ], // otskinning [yn]
+ 77 => [parent::CR_NUMERIC, 'is.atkpwr', NUM_CAST_INT, true ], // atkpwr
+ 78 => [parent::CR_NUMERIC, 'is.mlehastertng', NUM_CAST_INT, true ], // mlehastertng
+ 79 => [parent::CR_NUMERIC, 'is.resirtng', NUM_CAST_INT, true ], // resirtng
+ 80 => [parent::CR_CALLBACK, 'cbHasSockets', null, null ], // has sockets [enum]
+ 81 => [parent::CR_CALLBACK, 'cbFitsGemSlot', null, null ], // fits gem slot [enum]
+ 83 => [parent::CR_FLAG, 'flags', ITEM_FLAG_UNIQUEEQUIPPED ], // uniqueequipped
+ 84 => [parent::CR_NUMERIC, 'is.mlecritstrkrtng', NUM_CAST_INT, true ], // mlecritstrkrtng
+ 85 => [parent::CR_CALLBACK, 'cbObjectiveOfQuest', null, null ], // objectivequest [side]
+ 86 => [parent::CR_CALLBACK, 'cbCraftedByProf', null, null ], // craftedprof [enum]
+ 87 => [parent::CR_CALLBACK, 'cbReagentForAbility', null, null ], // reagentforability [enum]
+ 88 => [parent::CR_CALLBACK, 'cbObtainedBy', 20, null ], // otprospecting [yn]
+ 89 => [parent::CR_FLAG, 'flags', ITEM_FLAG_PROSPECTABLE ], // prospectable
+ 90 => [parent::CR_CALLBACK, 'cbAvgBuyout', null, null ], // avgbuyout [op] [int]
+ 91 => [parent::CR_ENUM, 'totemCategory', false, true ], // tool
+ 92 => [parent::CR_CALLBACK, 'cbObtainedBy', 5, null ], // soldbyvendor [yn]
+ 93 => [parent::CR_CALLBACK, 'cbObtainedBy', 3, null ], // otpvp [pvp]
+ 94 => [parent::CR_NUMERIC, 'is.splpen', NUM_CAST_INT, true ], // splpen
+ 95 => [parent::CR_NUMERIC, 'is.mlehitrtng', NUM_CAST_INT, true ], // mlehitrtng
+ 96 => [parent::CR_NUMERIC, 'is.critstrkrtng', NUM_CAST_INT, true ], // critstrkrtng
+ 97 => [parent::CR_NUMERIC, 'is.feratkpwr', NUM_CAST_INT, true ], // feratkpwr
+ 98 => [parent::CR_FLAG, 'flags', ITEM_FLAG_PARTYLOOT ], // partyloot
+ 99 => [parent::CR_ENUM, 'requiredSkill' ], // requiresprof
+ 100 => [parent::CR_NUMERIC, 'is.nsockets', NUM_CAST_INT ], // nsockets
+ 101 => [parent::CR_NUMERIC, 'is.rgdhastertng', NUM_CAST_INT, true ], // rgdhastertng
+ 102 => [parent::CR_NUMERIC, 'is.splhastertng', NUM_CAST_INT, true ], // splhastertng
+ 103 => [parent::CR_NUMERIC, 'is.hastertng', NUM_CAST_INT, true ], // hastertng
+ 104 => [parent::CR_STRING, 'description', STR_LOCALIZED ], // flavortext
+ 105 => [parent::CR_CALLBACK, 'cbDropsInInstance', SRC_FLAG_DUNGEON_DROP, 1 ], // dropsinnormal [heroicdungeon-any]
+ 106 => [parent::CR_CALLBACK, 'cbDropsInInstance', SRC_FLAG_DUNGEON_DROP, 2 ], // dropsinheroic [heroicdungeon-any]
+ 107 => [parent::CR_NYI_PH, null, 1, ], // effecttext [str] not yet parsed ['effectsParsed_loc'.Lang::getLocale()->value, $cr[2]]
+ 109 => [parent::CR_CALLBACK, 'cbArmorBonus', null, null ], // armorbonus [op] [int]
+ 111 => [parent::CR_NUMERIC, 'requiredSkillRank', NUM_CAST_INT, true ], // reqskillrank
+ 113 => [parent::CR_FLAG, 'cuFlags', CUSTOM_HAS_SCREENSHOT ], // hasscreenshots
+ 114 => [parent::CR_NUMERIC, 'is.armorpenrtng', NUM_CAST_INT, true ], // armorpenrtng
+ 115 => [parent::CR_NUMERIC, 'is.health', NUM_CAST_INT, true ], // health
+ 116 => [parent::CR_NUMERIC, 'is.mana', NUM_CAST_INT, true ], // mana
+ 117 => [parent::CR_NUMERIC, 'is.exprtng', NUM_CAST_INT, true ], // exprtng
+ 118 => [parent::CR_CALLBACK, 'cbPurchasableWith', null, null ], // purchasablewithitem [enum]
+ 119 => [parent::CR_NUMERIC, 'is.hitrtng', NUM_CAST_INT, true ], // hitrtng
+ 123 => [parent::CR_NUMERIC, 'is.splpwr', NUM_CAST_INT, true ], // splpwr
+ 124 => [parent::CR_CALLBACK, 'cbHasRandEnchant', null, null ], // randomenchants [str]
+ 125 => [parent::CR_CALLBACK, 'cbReqArenaRating', null, null ], // reqarenartng [op] [int] todo (low): 'find out, why "IN (W, X, Y) AND IN (X, Y, Z)" doesn't result in "(X, Y)"
+ 126 => [parent::CR_CALLBACK, 'cbQuestRewardIn', null, null ], // rewardedbyquestin [zone-any]
+ 128 => [parent::CR_CALLBACK, 'cbSource', null, null ], // source [enum]
+ 129 => [parent::CR_CALLBACK, 'cbSoldByNPC', null, null ], // soldbynpc [str-small]
+ 130 => [parent::CR_FLAG, 'cuFlags', CUSTOM_HAS_COMMENT ], // hascomments
+ 132 => [parent::CR_CALLBACK, 'cbGlyphType', null, null ], // glyphtype [enum]
+ 133 => [parent::CR_FLAG, 'flags', ITEM_FLAG_ACCOUNTBOUND ], // accountbound
+ 134 => [parent::CR_NUMERIC, 'is.mledps', NUM_CAST_FLOAT, true ], // mledps
+ 135 => [parent::CR_NUMERIC, 'is.mledmgmin', NUM_CAST_INT, true ], // mledmgmin
+ 136 => [parent::CR_NUMERIC, 'is.mledmgmax', NUM_CAST_INT, true ], // mledmgmax
+ 137 => [parent::CR_NUMERIC, 'is.mlespeed', NUM_CAST_FLOAT, true ], // mlespeed
+ 138 => [parent::CR_NUMERIC, 'is.rgddps', NUM_CAST_FLOAT, true ], // rgddps
+ 139 => [parent::CR_NUMERIC, 'is.rgddmgmin', NUM_CAST_INT, true ], // rgddmgmin
+ 140 => [parent::CR_NUMERIC, 'is.rgddmgmax', NUM_CAST_INT, true ], // rgddmgmax
+ 141 => [parent::CR_NUMERIC, 'is.rgdspeed', NUM_CAST_FLOAT, true ], // rgdspeed
+ 142 => [parent::CR_STRING, 'ic.name' ], // icon
+ 143 => [parent::CR_CALLBACK, 'cbObtainedBy', 18, null ], // otmilling [yn]
+ 144 => [parent::CR_CALLBACK, 'cbPvpPurchasable', 'reqHonorPoints', null ], // purchasablewithhonor [yn]
+ 145 => [parent::CR_CALLBACK, 'cbPvpPurchasable', 'reqArenaPoints', null ], // purchasablewitharena [yn]
+ 146 => [parent::CR_FLAG, 'flags', ITEM_FLAG_HEROIC ], // heroic
+ 147 => [parent::CR_CALLBACK, 'cbDropsInInstance', SRC_FLAG_RAID_DROP, 1, ], // dropsinnormal10 [multimoderaid-any]
+ 148 => [parent::CR_CALLBACK, 'cbDropsInInstance', SRC_FLAG_RAID_DROP, 2, ], // dropsinnormal25 [multimoderaid-any]
+ 149 => [parent::CR_CALLBACK, 'cbDropsInInstance', SRC_FLAG_RAID_DROP, 4, ], // dropsinheroic10 [heroicraid-any]
+ 150 => [parent::CR_CALLBACK, 'cbDropsInInstance', SRC_FLAG_RAID_DROP, 8, ], // dropsinheroic25 [heroicraid-any]
+ 151 => [parent::CR_NUMERIC, 'id', NUM_CAST_INT, true ], // id
+ 152 => [parent::CR_CALLBACK, 'cbClassRaceSpec', 'requiredClass', ChrClass::MASK_ALL], // classspecific [enum]
+ 153 => [parent::CR_CALLBACK, 'cbClassRaceSpec', 'requiredRace', ChrRace::MASK_ALL ], // racespecific [enum]
+ 154 => [parent::CR_FLAG, 'flags', ITEM_FLAG_REFUNDABLE ], // refundable
+ 155 => [parent::CR_FLAG, 'flags', ITEM_FLAG_USABLE_ARENA ], // usableinarenas
+ 156 => [parent::CR_FLAG, 'flags', ITEM_FLAG_USABLE_SHAPED ], // usablewhenshapeshifted
+ 157 => [parent::CR_FLAG, 'flags', ITEM_FLAG_SMARTLOOT ], // smartloot
+ 158 => [parent::CR_CALLBACK, 'cbPurchasableWith', null, null ], // purchasablewithcurrency [enum]
+ 159 => [parent::CR_FLAG, 'flags', ITEM_FLAG_MILLABLE ], // millable
+ 160 => [parent::CR_NYI_PH, null, 1, ], // relatedevent [enum] like 169 .. crawl though npc_vendor and loot_templates of event-related spawns
+ 161 => [parent::CR_CALLBACK, 'cbAvailable', null, null ], // availabletoplayers [yn]
+ 162 => [parent::CR_FLAG, 'flags', ITEM_FLAG_DEPRECATED ], // deprecated
+ 163 => [parent::CR_CALLBACK, 'cbDisenchantsInto', null, null ], // disenchantsinto [disenchanting]
+ 165 => [parent::CR_NUMERIC, 'repairPrice', NUM_CAST_INT, true ], // repaircost
+ 167 => [parent::CR_FLAG, 'cuFlags', CUSTOM_HAS_VIDEO ], // hasvideos
+ 168 => [parent::CR_CALLBACK, 'cbFieldHasVal', 'spellId1', LEARN_SPELLS ], // teachesspell [yn]
+ 169 => [parent::CR_ENUM, 'e.holidayId', true, true ], // requiresevent
+ 171 => [parent::CR_CALLBACK, 'cbObtainedBy', 8, null ], // otredemption [yn]
+ 172 => [parent::CR_CALLBACK, 'cbObtainedBy', 12, null ], // rewardedbyachievement [yn]
+ 176 => [parent::CR_STAFFFLAG, 'flags' ], // flags
+ 177 => [parent::CR_STAFFFLAG, 'flagsExtra' ], // flags2
);
protected $inputFields = array(
@@ -2155,25 +2155,25 @@ class ItemListFilter extends Filter
// side
if (isset($_v['si']))
{
- $ex = [['requiredRace', RACE_MASK_ALL, '&'], RACE_MASK_ALL, '!'];
- $notEx = ['OR', ['requiredRace', 0], [['requiredRace', RACE_MASK_ALL, '&'], RACE_MASK_ALL]];
+ $ex = [['requiredRace', ChrRace::MASK_ALL, '&'], ChrRace::MASK_ALL, '!'];
+ $notEx = ['OR', ['requiredRace', 0], [['requiredRace', ChrRace::MASK_ALL, '&'], ChrRace::MASK_ALL]];
switch ($_v['si'])
{
case 3:
- $parts[] = ['OR', [['flagsExtra', 0x3, '&'], [0, 3]], ['requiredRace', RACE_MASK_ALL], ['requiredRace', 0]];
+ $parts[] = ['OR', [['flagsExtra', 0x3, '&'], [0, 3]], ['requiredRace', ChrRace::MASK_ALL], ['requiredRace', 0]];
break;
case 2:
- $parts[] = ['AND', [['flagsExtra', 0x3, '&'], [0, 1]], ['OR', $notEx, ['requiredRace', RACE_MASK_HORDE, '&']]];
+ $parts[] = ['AND', [['flagsExtra', 0x3, '&'], [0, 1]], ['OR', $notEx, ['requiredRace', ChrRace::MASK_HORDE, '&']]];
break;
case -2:
- $parts[] = ['OR', [['flagsExtra', 0x3, '&'], 1], ['AND', $ex, ['requiredRace', RACE_MASK_HORDE, '&']]];
+ $parts[] = ['OR', [['flagsExtra', 0x3, '&'], 1], ['AND', $ex, ['requiredRace', ChrRace::MASK_HORDE, '&']]];
break;
case 1:
- $parts[] = ['AND', [['flagsExtra', 0x3, '&'], [0, 2]], ['OR', $notEx, ['requiredRace', RACE_MASK_ALLIANCE, '&']]];
+ $parts[] = ['AND', [['flagsExtra', 0x3, '&'], [0, 2]], ['OR', $notEx, ['requiredRace', ChrRace::MASK_ALLIANCE, '&']]];
break;
case -1:
- $parts[] = ['OR', [['flagsExtra', 0x3, '&'], 2], ['AND', $ex, ['requiredRace', RACE_MASK_ALLIANCE, '&']]];
+ $parts[] = ['OR', [['flagsExtra', 0x3, '&'], 2], ['AND', $ex, ['requiredRace', ChrRace::MASK_ALLIANCE, '&']]];
break;
}
}
@@ -2545,13 +2545,13 @@ class ItemListFilter extends Filter
$w = 1;
break;
case 2: // Alliance
- $w = '`reqRaceMask` & '.RACE_MASK_ALLIANCE.' AND (`reqRaceMask` & '.RACE_MASK_HORDE.') = 0';
+ $w = '`reqRaceMask` & '.ChrRace::MASK_ALLIANCE.' AND (`reqRaceMask` & '.ChrRace::MASK_HORDE.') = 0';
break;
case 3: // Horde
- $w = '`reqRaceMask` & '.RACE_MASK_HORDE.' AND (`reqRaceMask` & '.RACE_MASK_ALLIANCE.') = 0';
+ $w = '`reqRaceMask` & '.ChrRace::MASK_HORDE.' AND (`reqRaceMask` & '.ChrRace::MASK_ALLIANCE.') = 0';
break;
case 4: // Both
- $w = '(`reqRaceMask` & '.RACE_MASK_ALLIANCE.' AND `reqRaceMask` & '.RACE_MASK_HORDE.') OR `reqRaceMask` = 0';
+ $w = '(`reqRaceMask` & '.ChrRace::MASK_ALLIANCE.' AND `reqRaceMask` & '.ChrRace::MASK_HORDE.') OR `reqRaceMask` = 0';
break;
default:
return false;
diff --git a/includes/types/itemset.class.php b/includes/types/itemset.class.php
index 43ed3a3e..0a7cbbc6 100644
--- a/includes/types/itemset.class.php
+++ b/includes/types/itemset.class.php
@@ -29,17 +29,10 @@ class ItemsetList extends BaseType
// post processing
foreach ($this->iterate() as &$_curTpl)
{
- $_curTpl['classes'] = [];
- $_curTpl['pieces'] = [];
- for ($i = 1; $i < 12; $i++)
- {
- if ($_curTpl['classMask'] & (1 << ($i - 1)))
- {
- $this->classes[] = $i;
- $_curTpl['classes'][] = $i;
- }
- }
+ $_curTpl['classes'] = ChrClass::fromMask($_curTpl['classMask']);
+ $this->classes = array_merge($this->classes, $_curTpl['classes']);
+ $_curTpl['pieces'] = [];
for ($i = 1; $i < 10; $i++)
{
if ($piece = $_curTpl['item'.$i])
diff --git a/includes/types/profile.class.php b/includes/types/profile.class.php
index 075b4dd9..bf79e84d 100644
--- a/includes/types/profile.class.php
+++ b/includes/types/profile.class.php
@@ -31,7 +31,7 @@ class ProfileList extends BaseType
'classs' => $this->getField('class'),
'gender' => $this->getField('gender'),
'level' => $this->getField('level'),
- 'faction' => (1 << ($this->getField('race') - 1)) & RACE_MASK_ALLIANCE ? 0 : 1,
+ 'faction' => ChrRace::tryFrom($this->getField('race'))?->isAlliance() ? 0 : 1,
'talenttree1' => $this->getField('talenttree1'),
'talenttree2' => $this->getField('talenttree2'),
'talenttree3' => $this->getField('talenttree3'),
diff --git a/includes/types/quest.class.php b/includes/types/quest.class.php
index 3b839982..23f2bac0 100644
--- a/includes/types/quest.class.php
+++ b/includes/types/quest.class.php
@@ -175,7 +175,7 @@ class QuestList extends BaseType
foreach ($this->iterate() as $__)
{
- if (!(Game::sideByRaceMask($this->curTpl['reqRaceMask']) & $side))
+ if (!(ChrRace::sideFromMask($this->curTpl['reqRaceMask']) & $side))
continue;
[$series, $first] = DB::Aowow()->SelectRow(
@@ -212,7 +212,7 @@ class QuestList extends BaseType
'level' => $this->curTpl['level'],
'reqlevel' => $this->curTpl['minLevel'],
'name' => Lang::unescapeUISequences($this->getField('name', true), Lang::FMT_RAW),
- 'side' => Game::sideByRaceMask($this->curTpl['reqRaceMask']),
+ 'side' => ChrRace::sideFromMask($this->curTpl['reqRaceMask']),
'wflags' => 0x0,
'xp' => $this->curTpl['rewardXP']
);
@@ -238,8 +238,8 @@ class QuestList extends BaseType
if ($_ = $this->curTpl['reqClassMask'])
$data[$this->id]['reqclass'] = $_;
- if ($_ = ($this->curTpl['reqRaceMask'] & RACE_MASK_ALL))
- if ((($_ & RACE_MASK_ALLIANCE) != RACE_MASK_ALLIANCE) && (($_ & RACE_MASK_HORDE) != RACE_MASK_HORDE))
+ if ($_ = ($this->curTpl['reqRaceMask'] & ChrRace::MASK_ALL))
+ if ((($_ & ChrRace::MASK_ALLIANCE) != ChrRace::MASK_ALLIANCE) && (($_ & ChrRace::MASK_HORDE) != ChrRace::MASK_HORDE))
$data[$this->id]['reqrace'] = $_;
if ($_ = $this->curTpl['rewardOrReqMoney'])
@@ -525,8 +525,8 @@ class QuestListFilter extends Filter
// side
if (isset($_v['si']))
{
- $ex = [['reqRaceMask', RACE_MASK_ALL, '&'], RACE_MASK_ALL, '!'];
- $notEx = ['OR', ['reqRaceMask', 0], [['reqRaceMask', RACE_MASK_ALL, '&'], RACE_MASK_ALL]];
+ $ex = [['reqRaceMask', ChrRace::MASK_ALL, '&'], ChrRace::MASK_ALL, '!'];
+ $notEx = ['OR', ['reqRaceMask', 0], [['reqRaceMask', ChrRace::MASK_ALL, '&'], ChrRace::MASK_ALL]];
switch ($_v['si'])
{
@@ -534,16 +534,16 @@ class QuestListFilter extends Filter
$parts[] = $notEx;
break;
case SIDE_HORDE:
- $parts[] = ['OR', $notEx, ['reqRaceMask', RACE_MASK_HORDE, '&']];
+ $parts[] = ['OR', $notEx, ['reqRaceMask', ChrRace::MASK_HORDE, '&']];
break;
case -SIDE_HORDE:
- $parts[] = ['AND', $ex, ['reqRaceMask', RACE_MASK_HORDE, '&']];
+ $parts[] = ['AND', $ex, ['reqRaceMask', ChrRace::MASK_HORDE, '&']];
break;
case SIDE_ALLIANCE:
- $parts[] = ['OR', $notEx, ['reqRaceMask', RACE_MASK_ALLIANCE, '&']];
+ $parts[] = ['OR', $notEx, ['reqRaceMask', ChrRace::MASK_ALLIANCE, '&']];
break;
case -SIDE_ALLIANCE:
- $parts[] = ['AND', $ex, ['reqRaceMask', RACE_MASK_ALLIANCE, '&']];
+ $parts[] = ['AND', $ex, ['reqRaceMask', ChrRace::MASK_ALLIANCE, '&']];
break;
}
}
@@ -688,11 +688,11 @@ class QuestListFilter extends Filter
$_ = $this->enums[$cr[0]][$cr[1]];
if ($_ === true)
- return ['AND', ['reqClassMask', 0, '!'], [['reqClassMask', CLASS_MASK_ALL, '&'], CLASS_MASK_ALL, '!']];
+ return ['AND', ['reqClassMask', 0, '!'], [['reqClassMask', ChrClass::MASK_ALL, '&'], ChrClass::MASK_ALL, '!']];
else if ($_ === false)
- return ['OR', ['reqClassMask', 0], [['reqClassMask', CLASS_MASK_ALL, '&'], CLASS_MASK_ALL]];
+ return ['OR', ['reqClassMask', 0], [['reqClassMask', ChrClass::MASK_ALL, '&'], ChrClass::MASK_ALL]];
else if (is_int($_))
- return ['AND', ['reqClassMask', (1 << ($_ - 1)), '&'], [['reqClassMask', CLASS_MASK_ALL, '&'], CLASS_MASK_ALL, '!']];
+ return ['AND', ['reqClassMask', ChrClass::from($_)->toMask(), '&'], [['reqClassMask', ChrClass::MASK_ALL, '&'], ChrClass::MASK_ALL, '!']];
return false;
}
@@ -704,11 +704,11 @@ class QuestListFilter extends Filter
$_ = $this->enums[$cr[0]][$cr[1]];
if ($_ === true)
- return ['AND', ['reqRaceMask', 0, '!'], [['reqRaceMask', RACE_MASK_ALL, '&'], RACE_MASK_ALL, '!'], [['reqRaceMask', RACE_MASK_ALLIANCE, '&'], RACE_MASK_ALLIANCE, '!'], [['reqRaceMask', RACE_MASK_HORDE, '&'], RACE_MASK_HORDE, '!']];
+ return ['AND', ['reqRaceMask', 0, '!'], [['reqRaceMask', ChrRace::MASK_ALL, '&'], ChrRace::MASK_ALL, '!'], [['reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ChrRace::MASK_ALLIANCE, '!'], [['reqRaceMask', ChrRace::MASK_HORDE, '&'], ChrRace::MASK_HORDE, '!']];
else if ($_ === false)
- return ['OR', ['reqRaceMask', 0], ['reqRaceMask', RACE_MASK_ALL], ['reqRaceMask', RACE_MASK_ALLIANCE], ['reqRaceMask', RACE_MASK_HORDE]];
+ return ['OR', ['reqRaceMask', 0], ['reqRaceMask', ChrRace::MASK_ALL], ['reqRaceMask', ChrRace::MASK_ALLIANCE], ['reqRaceMask', ChrRace::MASK_HORDE]];
else if (is_int($_))
- return ['AND', ['reqRaceMask', (1 << ($_ - 1)), '&'], [['reqRaceMask', RACE_MASK_ALLIANCE, '&'], RACE_MASK_ALLIANCE, '!'], [['reqRaceMask', RACE_MASK_HORDE, '&'], RACE_MASK_HORDE, '!']];
+ return ['AND', ['reqRaceMask', ChrRace::from($_)->toMask(), '&'], [['reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ChrRace::MASK_ALLIANCE, '!'], [['reqRaceMask', ChrRace::MASK_HORDE, '&'], ChrRace::MASK_HORDE, '!']];
return false;
}
diff --git a/includes/types/spell.class.php b/includes/types/spell.class.php
index e8338bc7..a3a51599 100644
--- a/includes/types/spell.class.php
+++ b/includes/types/spell.class.php
@@ -145,12 +145,12 @@ class SpellList extends BaseType
}
// set full masks to 0
- $_curTpl['reqClassMask'] &= CLASS_MASK_ALL;
- if ($_curTpl['reqClassMask'] == CLASS_MASK_ALL)
+ $_curTpl['reqClassMask'] &= ChrClass::MASK_ALL;
+ if ($_curTpl['reqClassMask'] == ChrClass::MASK_ALL)
$_curTpl['reqClassMask'] = 0;
- $_curTpl['reqRaceMask'] &= RACE_MASK_ALL;
- if ($_curTpl['reqRaceMask'] == RACE_MASK_ALL)
+ $_curTpl['reqRaceMask'] &= ChrRace::MASK_ALL;
+ if ($_curTpl['reqRaceMask'] == ChrRace::MASK_ALL)
$_curTpl['reqRaceMask'] = 0;
// unpack skillLines
@@ -2124,15 +2124,11 @@ class SpellList extends BaseType
{
if ($addMask & GLOBALINFO_RELATED)
{
- if ($mask = $this->curTpl['reqClassMask'])
- for ($i = 0; $i < 11; $i++)
- if ($mask & (1 << $i))
- $data[Type::CHR_CLASS][$i + 1] = $i + 1;
+ foreach (ChrClass::fromMask($this->curTpl['reqClassMask']) as $id)
+ $data[Type::CHR_CLASS][$id] = $id;
- if ($mask = $this->curTpl['reqRaceMask'])
- for ($i = 0; $i < 11; $i++)
- if ($mask & (1 << $i))
- $data[Type::CHR_RACE][$i + 1] = $i + 1;
+ foreach (ChrRace::fromMask($this->curTpl['reqRaceMask']) as $id)
+ $data[Type::CHR_RACE][$id] = $id;
// play sound effect
for ($i = 1; $i < 4; $i++)
@@ -2477,7 +2473,7 @@ class SpellListFilter extends Filter
// race
if (isset($_v['ra']))
- $parts[] = ['AND', [['reqRaceMask', RACE_MASK_ALL, '&'], RACE_MASK_ALL, '!'], ['reqRaceMask', $this->list2Mask([$_v['ra']]), '&']];
+ $parts[] = ['AND', [['reqRaceMask', ChrRace::MASK_ALL, '&'], ChrRace::MASK_ALL, '!'], ['reqRaceMask', $this->list2Mask([$_v['ra']]), '&']];
// class [list]
if (isset($_v['cl']))
@@ -2618,11 +2614,11 @@ class SpellListFilter extends Filter
case 1: // yes
return ['reqRaceMask', 0, '!'];
case 2: // alliance
- return ['AND', [['reqRaceMask', RACE_MASK_HORDE, '&'], 0], ['reqRaceMask', RACE_MASK_ALLIANCE, '&']];
+ return ['AND', [['reqRaceMask', ChrRace::MASK_HORDE, '&'], 0], ['reqRaceMask', ChrRace::MASK_ALLIANCE, '&']];
case 3: // horde
- return ['AND', [['reqRaceMask', RACE_MASK_ALLIANCE, '&'], 0], ['reqRaceMask', RACE_MASK_HORDE, '&']];
+ return ['AND', [['reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], 0], ['reqRaceMask', ChrRace::MASK_HORDE, '&']];
case 4: // both
- return ['AND', ['reqRaceMask', RACE_MASK_ALLIANCE, '&'], ['reqRaceMask', RACE_MASK_HORDE, '&']];
+ return ['AND', ['reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ['reqRaceMask', ChrRace::MASK_HORDE, '&']];
case 5: // no
return ['reqRaceMask', 0];
default:
diff --git a/localization/lang.class.php b/localization/lang.class.php
index 30711951..9c76f6bf 100644
--- a/localization/lang.class.php
+++ b/localization/lang.class.php
@@ -425,13 +425,12 @@ class Lang
public static function getClassString(int $classMask, array &$ids = [], int $fmt = self::FMT_HTML) : string
{
- $classMask &= CLASS_MASK_ALL; // clamp to available classes..
+ $classMask &= ChrClass::MASK_ALL; // clamp to available classes..
- if ($classMask == CLASS_MASK_ALL) // available to all classes
+ if ($classMask == ChrClass::MASK_ALL) // available to all classes
return '';
$tmp = [];
- $i = 1;
switch ($fmt)
{
@@ -449,15 +448,8 @@ class Lang
$br = '';
}
- while ($classMask)
- {
- if ($classMask & (1 << ($i - 1)))
- {
- $tmp[$i] = (!fMod(count($tmp) + 1, 3) ? $br : null).sprintf($base, $i, self::game('cl', $i));
- $classMask &= ~(1 << ($i - 1));
- }
- $i++;
- }
+ foreach (ChrClass::fromMask($classMask) as $c)
+ $tmp[$c] = (!fMod(count($tmp) + 1, 3) ? $br : null).sprintf($base, $c, self::game('cl', $c));
$ids = array_keys($tmp);
@@ -466,16 +458,15 @@ class Lang
public static function getRaceString(int $raceMask, array &$ids = [], int $fmt = self::FMT_HTML) : string
{
- $raceMask &= RACE_MASK_ALL; // clamp to available races..
+ $raceMask &= ChrRace::MASK_ALL; // clamp to available races..
- if ($raceMask == RACE_MASK_ALL) // available to all races (we don't display 'both factions')
+ if ($raceMask == ChrRace::MASK_ALL) // available to all races (we don't display 'both factions')
return '';
if (!$raceMask)
return '';
$tmp = [];
- $i = 1;
switch ($fmt)
{
@@ -493,21 +484,14 @@ class Lang
$br = '';
}
- if ($raceMask == RACE_MASK_HORDE)
+ if ($raceMask == ChrRace::MASK_HORDE)
return self::game('ra', -2);
- if ($raceMask == RACE_MASK_ALLIANCE)
+ if ($raceMask == ChrRace::MASK_ALLIANCE)
return self::game('ra', -1);
- while ($raceMask)
- {
- if ($raceMask & (1 << ($i - 1)))
- {
- $tmp[$i] = (!fMod(count($tmp) + 1, 3) ? $br : null).sprintf($base, $i, self::game('ra', $i));
- $raceMask &= ~(1 << ($i - 1));
- }
- $i++;
- }
+ foreach (ChrRace::fromMask($raceMask) as $r)
+ $tmp[$r] = (!fMod(count($tmp) + 1, 3) ? $br : null).sprintf($base, $r, self::game('ra', $r));
$ids = array_keys($tmp);
diff --git a/localization/locale_zhcn.php b/localization/locale_zhcn.php
index 03316c43..9a300aba 100644
--- a/localization/locale_zhcn.php
+++ b/localization/locale_zhcn.php
@@ -1559,7 +1559,7 @@ $lang = array(
'dotSP' => "每个周期的法术强度 +%.2f%%", 'dotAP' => "每个周期的攻击强度 +%.2f%%"
),
'relItems' => array(
- 'base' => "显示与%s相关的 %s<",
+ 'base' => "显示与%s相关的 %s",
'link' => "或",
'recipes' => '制作物品',
'crafted' => '手工制作物品'
diff --git a/pages/class.php b/pages/class.php
index d92d6ada..88f21dcf 100644
--- a/pages/class.php
+++ b/pages/class.php
@@ -46,7 +46,7 @@ class ClassPage extends GenericPage
$this->addScript([SC_JS_FILE, '?data=zones']);
$infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags'));
- $_mask = 1 << ($this->typeId - 1);
+ $cl = ChrClass::from($this->typeId);
$tcClassId = [null, 8, 3, 1, 5, 4, 9, 6, 2, 7, null, 0]; // see TalentCalc.js
@@ -59,14 +59,14 @@ class ClassPage extends GenericPage
$infobox[] = '[tooltip=tooltip_heroclass]'.Lang::game('heroClass').'[/tooltip]';
// resource
- if ($this->typeId == 11) // special Druid case
+ if ($cl == ChrClass::DRUID) // special Druid case
$infobox[] = Lang::game('resources').Lang::main('colon').
'[tooltip name=powertype1]'.Lang::game('st', 0).', '.Lang::game('st', 31).', '.Lang::game('st', 2).'[/tooltip][span class=tip tooltip=powertype1]'.Util::ucFirst(Lang::spell('powerTypes', 0)).'[/span], '.
'[tooltip name=powertype2]'.Lang::game('st', 5).', '.Lang::game('st', 8).'[/tooltip][span class=tip tooltip=powertype2]'.Util::ucFirst(Lang::spell('powerTypes', 1)).'[/span], '.
'[tooltip name=powertype8]'.Lang::game('st', 1).'[/tooltip][span class=tip tooltip=powertype8]'.Util::ucFirst(Lang::spell('powerTypes', 3)).'[/span]';
- else if ($this->typeId == 6) // special DK case
+ else if ($cl == ChrClass::DEATHKNIGHT) // special DK case
$infobox[] = Lang::game('resources').Lang::main('colon').'[span]'.Util::ucFirst(Lang::spell('powerTypes', 5)).', '.Util::ucFirst(Lang::spell('powerTypes', $this->subject->getField('powerType'))).'[/span]';
- else // regular case
+ else // regular case
$infobox[] = Lang::game('resource').Lang::main('colon').'[span]'.Util::ucFirst(Lang::spell('powerTypes', $this->subject->getField('powerType'))).'[/span]';
// roles
@@ -118,11 +118,11 @@ class ClassPage extends GenericPage
[['s.cuFlags', (SPELL_CU_TRIGGERED | CUSTOM_EXCLUDE_FOR_LISTVIEW), '&'], 0],
[
'OR',
- ['s.reqClassMask', $_mask, '&'], // Glyphs, Proficiencies
+ ['s.reqClassMask', $cl->toMask(), '&'], // Glyphs, Proficiencies
['s.skillLine1', $this->subject->getField('skills')], // Abilities / Talents
['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->subject->getField('skills')]]
],
- [ // last rank or unranked
+ [ // last rank or unranked
'OR',
['s.cuFlags', SPELL_CU_LAST_RANK, '&'],
['s.rankNo', 0]
@@ -150,9 +150,9 @@ class ClassPage extends GenericPage
// Tab: Items (grouped)
$conditions = array(
['requiredClass', 0, '>'],
- ['requiredClass', $_mask, '&'],
- [['requiredClass', CLASS_MASK_ALL, '&'], CLASS_MASK_ALL, '!'],
- ['itemset', 0], // hmm, do or dont..?
+ ['requiredClass', $cl->toMask(), '&'],
+ [['requiredClass', ChrClass::MASK_ALL, '&'], ChrClass::MASK_ALL, '!'],
+ ['itemset', 0], // hmm, do or dont..?
Cfg::get('SQL_LIMIT_NONE')
);
@@ -180,8 +180,8 @@ class ClassPage extends GenericPage
// Tab: Quests
$conditions = array(
- ['reqClassMask', $_mask, '&'],
- [['reqClassMask', CLASS_MASK_ALL, '&'], CLASS_MASK_ALL, '!']
+ ['reqClassMask', $cl->toMask(), '&'],
+ [['reqClassMask', ChrClass::MASK_ALL, '&'], ChrClass::MASK_ALL, '!']
);
$quests = new QuestList($conditions);
@@ -196,7 +196,7 @@ class ClassPage extends GenericPage
}
// Tab: Itemsets
- $sets = new ItemsetList(array(['classMask', $_mask, '&']));
+ $sets = new ItemsetList(array(['classMask', $cl->toMask(), '&']));
if (!$sets->error)
{
$this->extendGlobalData($sets->getJSGlobals(GLOBALINFO_SELF));
@@ -211,8 +211,8 @@ class ClassPage extends GenericPage
// Tab: Trainer
$conditions = array(
- ['npcflag', 0x30, '&'], // is trainer
- ['trainerType', 0], // trains class spells
+ ['npcflag', 0x30, '&'], // is trainer
+ ['trainerType', 0], // trains class spells
['trainerRequirement', $this->typeId]
);
@@ -227,7 +227,7 @@ class ClassPage extends GenericPage
}
// Tab: Races
- $races = new CharRaceList(array(['classMask', $_mask, '&']));
+ $races = new CharRaceList(array(['classMask', $cl->toMask(), '&']));
if (!$races->error)
$this->lvTabs[] = [CharRaceList::$brickFile, ['data' => array_values($races->getListviewData())]];
diff --git a/pages/emote.php b/pages/emote.php
index 6d330d68..8d634b78 100644
--- a/pages/emote.php
+++ b/pages/emote.php
@@ -89,7 +89,7 @@ class EmotePage extends GenericPage
if ($this->subject->getField('cuFlags') & EMOTE_CU_MISSING_CMD)
$text .= Lang::emote('noCommand').'[br][br]';
- else if ($aliasses = DB::Aowow()->selectCol('SELECT command FROM ?_emotes_aliasses WHERE id = ?d AND locales & ?d', $this->typeId, 1 << Lang::getLocale()->value))
+ else if ($aliasses = DB::Aowow()->selectCol('SELECT `command` FROM ?_emotes_aliasses WHERE `id` = ?d AND `locales` & ?d', $this->typeId, 1 << Lang::getLocale()->value))
{
$text .= '[h3]'.Lang::emote('aliases').'[/h3][ul]';
foreach ($aliasses as $a)
@@ -161,7 +161,7 @@ class EmotePage extends GenericPage
}
// tab: sound
- if ($em = DB::Aowow()->select('SELECT soundId AS ARRAY_KEY, BIT_OR(1 << (raceId - 1)) AS raceMask, BIT_OR(1 << (gender - 1)) AS gender FROM ?_emotes_sounds WHERE -emoteId = ?d GROUP BY soundId', $this->typeId > 0 ? $this->subject->getField('parentEmote') : $this->typeId))
+ if ($em = DB::Aowow()->select('SELECT `soundId` AS ARRAY_KEY, BIT_OR(1 << (`raceId` - 1)) AS "raceMask", BIT_OR(1 << (`gender` - 1)) AS "gender" FROM ?_emotes_sounds WHERE -`emoteId` = ?d GROUP BY `soundId`', $this->typeId > 0 ? $this->subject->getField('parentEmote') : $this->typeId))
{
$sounds = new SoundList(array(['id', array_keys($em)]));
if (!$sounds->error)
diff --git a/pages/guide.php b/pages/guide.php
index 74f28d8e..c0bf3a34 100644
--- a/pages/guide.php
+++ b/pages/guide.php
@@ -485,7 +485,7 @@ class GuidePage extends GenericPage
// sanitize: spec / class
if ($this->_post['category'] == 1) // Classes
{
- if ($this->_post['classId'] && !((1 << $this->_post['classId']) & CLASS_MASK_ALL))
+ if ($this->_post['classId'] && !ChrClass::tryFrom($this->_post['classId']))
$this->_post['classId'] = 0;
if (!in_array($this->_post['specId'], [-1, 0, 1, 2]))
diff --git a/pages/quest.php b/pages/quest.php
index 14c2355d..7dce4fef 100644
--- a/pages/quest.php
+++ b/pages/quest.php
@@ -81,7 +81,7 @@ class QuestPage extends GenericPage
$_minLevel = $this->subject->getField('minLevel');
$_flags = $this->subject->getField('flags');
$_specialFlags = $this->subject->getField('specialFlags');
- $_side = Game::sideByRaceMask($this->subject->getField('reqRaceMask'));
+ $_side = ChrRace::sideFromMask($this->subject->getField('reqRaceMask'));
/***********/
/* Infobox */
@@ -300,7 +300,7 @@ class QuestPage extends GenericPage
$n = Util::localizedString($_, 'name');
array_unshift($chain, array(
array(
- 'side' => Game::sideByRaceMask($_['reqRaceMask']),
+ 'side' => ChrRace::sideFromMask($_['reqRaceMask']),
'typeStr' => Type::getFileString(Type::QUEST),
'typeId' => $_['typeId'],
'name' => Util::htmlEscape(Lang::trimTextClean($n, 40)),
@@ -320,7 +320,7 @@ class QuestPage extends GenericPage
$n = Util::localizedString($_, 'name');
array_push($chain, array(
array(
- 'side' => Game::sideByRaceMask($_['reqRaceMask']),
+ 'side' => ChrRace::sideFromMask($_['reqRaceMask']),
'typeStr' => Type::getFileString(Type::QUEST),
'typeId' => $_['typeId'],
'name' => Util::htmlEscape(Lang::trimTextClean($n, 40)),
@@ -346,7 +346,7 @@ class QuestPage extends GenericPage
{
$n = $list->getField('name', true);
$chain[] = array(array(
- 'side' => Game::sideByRaceMask($list->getField('reqRaceMask')),
+ 'side' => ChrRace::sideFromMask($list->getField('reqRaceMask')),
'typeStr' => Type::getFileString(Type::QUEST),
'typeId' => $id,
'name' => Util::htmlEscape(Lang::trimTextClean($n, 40))
diff --git a/pages/race.php b/pages/race.php
index b8b6b334..0b2f64ef 100644
--- a/pages/race.php
+++ b/pages/race.php
@@ -44,7 +44,7 @@ class RacePage extends GenericPage
protected function generateContent()
{
$infobox = [];
- $_mask = 1 << ($this->typeId - 1);
+ $ra = ChrRace::from($this->typeId);
$mountVendors = array( // race => [starter, argent tournament]
null, [384, 33307], [3362, 33553], [1261, 33310],
[4730, 33653], [4731, 33555], [3685, 33556], [7955, 33650],
@@ -59,7 +59,7 @@ class RacePage extends GenericPage
// side
if ($_ = $this->subject->getField('side'))
- $infobox[] = Lang::main('side').Lang::main('colon').'[span class=icon-'.($_ == 2 ? 'horde' : 'alliance').']'.Lang::game('si', $_).'[/span]';
+ $infobox[] = Lang::main('side').Lang::main('colon').'[span class=icon-'.($_ == SIDE_HORDE ? 'horde' : 'alliance').']'.Lang::game('si', $_).'[/span]';
// faction
if ($_ = $this->subject->getField('factionId'))
@@ -90,10 +90,7 @@ class RacePage extends GenericPage
$this->infobox = '[ul][li]'.implode('[/li][li]', $infobox).'[/li][/ul]';
$this->expansion = Util::$expansionString[$this->subject->getField('expansion')];
- $this->headIcons = array(
- 'race_'.strtolower($this->subject->getField('fileString')).'_male',
- 'race_'.strtolower($this->subject->getField('fileString')).'_female'
- );
+ $this->headIcons = ['race_'.$ra->json().'_male', 'race_'.$ra->json().'_female'];
$this->redButtons = array(
BUTTON_WOWHEAD => true,
BUTTON_LINKS => ['type' => $this->type, 'typeId' => $this->typeId]
@@ -105,7 +102,7 @@ class RacePage extends GenericPage
/**************/
// Classes
- $classes = new CharClassList(array(['racemask', $_mask, '&']));
+ $classes = new CharClassList(array(['racemask', $ra->toMask(), '&']));
if (!$classes->error)
{
$this->extendGlobalData($classes->getJSGlobals());
@@ -115,7 +112,7 @@ class RacePage extends GenericPage
// Tongues
$conditions = array(
['typeCat', -11], // proficiencies
- ['reqRaceMask', $_mask, '&'] // only languages are race-restricted
+ ['reqRaceMask', $ra->toMask(), '&'] // only languages are race-restricted
);
$tongues = new SpellList($conditions);
@@ -133,7 +130,7 @@ class RacePage extends GenericPage
// Racials
$conditions = array(
['typeCat', -4], // racial traits
- ['reqRaceMask', $_mask, '&']
+ ['reqRaceMask', $ra->toMask(), '&']
);
$racials = new SpellList($conditions);
@@ -150,9 +147,9 @@ class RacePage extends GenericPage
// Quests
$conditions = array(
- ['reqRaceMask', $_mask, '&'],
- [['reqRaceMask', RACE_MASK_HORDE, '&'], RACE_MASK_HORDE, '!'],
- [['reqRaceMask', RACE_MASK_ALLIANCE, '&'], RACE_MASK_ALLIANCE, '!']
+ ['reqRaceMask', $ra->toMask(), '&'],
+ [['reqRaceMask', ChrRace::MASK_HORDE, '&'], ChrRace::MASK_HORDE, '!'],
+ [['reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ChrRace::MASK_ALLIANCE, '!']
);
$quests = new QuestList($conditions);
@@ -164,7 +161,7 @@ class RacePage extends GenericPage
// Mounts
// ok, this sucks, but i rather hardcode the trainer, than fetch items by namepart
- $items = isset($mountVendors[$this->typeId]) ? DB::World()->selectCol('SELECT item FROM npc_vendor WHERE entry IN (?a)', $mountVendors[$this->typeId]) : 0;
+ $items = isset($mountVendors[$this->typeId]) ? DB::World()->selectCol('SELECT `item` FROM npc_vendor WHERE `entry` IN (?a)', $mountVendors[$this->typeId]) : 0;
$conditions = array(
['i.id', $items],
@@ -185,7 +182,7 @@ class RacePage extends GenericPage
}
// Sounds
- if ($vo = DB::Aowow()->selectCol('SELECT soundId AS ARRAY_KEY, gender FROM ?_races_sounds WHERE raceId = ?d', $this->typeId))
+ if ($vo = DB::Aowow()->selectCol('SELECT `soundId` AS ARRAY_KEY, `gender` FROM ?_races_sounds WHERE `raceId` = ?d', $this->typeId))
{
$sounds = new SoundList(array(['id', array_keys($vo)]));
if (!$sounds->error)
@@ -213,5 +210,4 @@ class RacePage extends GenericPage
}
}
-
?>
diff --git a/pages/search.php b/pages/search.php
index e036782b..a8891f1d 100644
--- a/pages/search.php
+++ b/pages/search.php
@@ -637,23 +637,11 @@ class SearchPage extends GenericPage
if ($this->searchMask & SEARCH_TYPE_REGULAR)
$this->extendGlobalData($abilities->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED));
- $multiClass = 0;
- foreach ($data as $d)
- {
- $multiClass = 0;
- for ($i = 1; $i <= 10; $i++)
- if (isset($d['reqclass']) && ($d['reqclass'] & (1 << ($i - 1))))
- $multiClass++;
-
- if ($multiClass > 1)
- break;
- }
-
$vis = ['level', 'schools'];
if ($abilities->hasSetFields('reagent1', 'reagent2', 'reagent3', 'reagent4', 'reagent5', 'reagent6', 'reagent7', 'reagent8'))
$vis[] = 'reagents';
- $vis[] = $multiClass > 1 ? 'classes' : 'singleclass';
+ $vis[] = count(ChrClass::fromMask($d['reqclass'] ?? 0)) > 1 ? 'classes' : 'singleclass';
$osInfo = [Type::SPELL, ' (Ability)', $abilities->getMatches(), [], []];
$result = array(
diff --git a/pages/skill.php b/pages/skill.php
index b80a8de4..6902d9c1 100644
--- a/pages/skill.php
+++ b/pages/skill.php
@@ -312,12 +312,7 @@ class SkillPage extends GenericPage
}
// tab: related classes (apply classes from [spells])
- $class = [];
- for ($i = 0; $i < 11; $i++)
- if ($reqClass & (1 << $i))
- $class[] = $i + 1;
-
- if ($class)
+ if ($class = ChrClass::fromMask($reqClass))
{
$classes = new CharClassList(array(['id', $class]));
if (!$classes->error)
@@ -325,12 +320,7 @@ class SkillPage extends GenericPage
}
// tab: related races (apply races from [spells])
- $race = [];
- for ($i = 0; $i < 12; $i++)
- if ($reqRace & (1 << $i))
- $race[] = $i + 1;
-
- if ($race)
+ if ($race = ChrRace::fromMask($reqRace))
{
$races = new CharRaceList(array(['id', $race]));
if (!$races->error)
diff --git a/pages/sound.php b/pages/sound.php
index adabc4f2..b44782bb 100644
--- a/pages/sound.php
+++ b/pages/sound.php
@@ -91,7 +91,7 @@ class SoundPage extends GenericPage
}
// get full path ingame for sound (workaround for missing PlaySoundKit())
- $fullpath = DB::Aowow()->selectCell('SELECT IF(sf.`path` <> "", CONCAT(sf.`path`, "\\\\", sf.`file`), sf.`file`) FROM ?_sounds_files sf JOIN ?_sounds s ON s.soundFile1 = sf.id WHERE s.id = ?d', $this->typeId);
+ $fullpath = DB::Aowow()->selectCell('SELECT IF(sf.`path` <> "", CONCAT(sf.`path`, "\\\\", sf.`file`), sf.`file`) FROM ?_sounds_files sf JOIN ?_sounds s ON s.`soundFile1` = sf.`id` WHERE s.`id` = ?d', $this->typeId);
$this->map = $map;
$this->headIcons = [$this->subject->getField('iconString')];
@@ -114,31 +114,21 @@ class SoundPage extends GenericPage
// tab: Spells
// skipping (always empty): ready, castertargeting, casterstate, targetstate
- $displayIds = DB::Aowow()->selectCol('
- SELECT id FROM ?_spell_sounds WHERE
- animation = ?d OR
- precast = ?d OR
- cast = ?d OR
- impact = ?d OR
- state = ?d OR
- statedone = ?d OR
- channel = ?d OR
- casterimpact = ?d OR
- targetimpact = ?d OR
- missiletargeting = ?d OR
- instantarea = ?d OR
- persistentarea = ?d OR
- missile = ?d OR
- impactarea = ?d
- ', $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId);
+ $displayIds = DB::Aowow()->selectCol(
+ 'SELECT `id`
+ FROM ?_spell_sounds
+ WHERE `animation` = ?d OR `precast` = ?d OR `cast` = ?d OR `impact` = ?d OR `state` = ?d OR
+ `statedone` = ?d OR `channel` = ?d OR `casterimpact` = ?d OR `targetimpact` = ?d OR `missiletargeting` = ?d OR
+ `instantarea` = ?d OR `persistentarea` = ?d OR `missile` = ?d OR `impactarea` = ?d',
+ $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId
+ );
- $seMiscValues = DB::Aowow()->selectCol('
- SELECT `id` FROM ?_screeneffect_sounds WHERE
- `ambienceDay` = ?d OR
- `ambienceNight` = ?d OR
- `musicDay` = ?d OR
- `musicNight` = ?d
- ', $this->typeId, $this->typeId, $this->typeId, $this->typeId);
+ $seMiscValues = DB::Aowow()->selectCol(
+ 'SELECT `id`
+ FROM ?_screeneffect_sounds
+ WHERE `ambienceDay` = ?d OR `ambienceNight` = ?d OR `musicDay` = ?d OR `musicNight` = ?d',
+ $this->typeId, $this->typeId, $this->typeId, $this->typeId
+ );
$cnd = array(
'OR',
@@ -168,27 +158,19 @@ class SoundPage extends GenericPage
// tab: Items
$subClasses = [];
- if ($subClassMask = DB::Aowow()->selectCell('SELECT subClassMask FROM ?_items_sounds WHERE soundId = ?d', $this->typeId))
+ if ($subClassMask = DB::Aowow()->selectCell('SELECT `subClassMask` FROM ?_items_sounds WHERE `soundId` = ?d', $this->typeId))
for ($i = 0; $i <= 20; $i++)
if ($subClassMask & (1 << $i))
$subClasses[] = $i;
- $itemIds = DB::Aowow()->selectCol('
- SELECT
- id
- FROM
- ?_items
- WHERE
- {spellVisualId IN (?a) OR }
- pickUpSoundId = ?d OR
- dropDownSoundId = ?d OR
- sheatheSoundId = ?d OR
- unsheatheSoundId = ?d {OR
- (
- IF (soundOverrideSubclass > 0, soundOverrideSubclass, subclass) IN (?a) AND
- class = ?d
- )}
- ', $displayIds ?: DBSIMPLE_SKIP, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $subClasses ?: DBSIMPLE_SKIP, ITEM_CLASS_WEAPON);
+ $itemIds = DB::Aowow()->selectCol(
+ 'SELECT id
+ FROM ?_items
+ WHERE `pickUpSoundId` = ?d OR `dropDownSoundId` = ?d OR `sheatheSoundId` = ?d OR `unsheatheSoundId` = ?d
+ { OR `spellVisualId` IN (?a) }
+ { OR (IF (`soundOverrideSubclass` > 0, `soundOverrideSubclass`, `subclass`) IN (?a) AND `class` = ?d) }',
+ $this->typeId, $this->typeId, $this->typeId, $this->typeId, $displayIds ?: DBSIMPLE_SKIP, $subClasses ?: DBSIMPLE_SKIP, ITEM_CLASS_WEAPON
+ );
if ($itemIds)
{
$items = new ItemList(array(['id', $itemIds]));
@@ -201,7 +183,7 @@ class SoundPage extends GenericPage
// tab: Zones
- if ($zoneIds = DB::Aowow()->select('SELECT id, worldStateId, worldStateValue FROM ?_zones_sounds WHERE ambienceDay = ?d OR ambienceNight = ?d OR musicDay = ?d OR musicNight = ?d OR intro = ?d', $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId))
+ if ($zoneIds = DB::Aowow()->select('SELECT `id`, `worldStateId`, `worldStateValue` FROM ?_zones_sounds WHERE `ambienceDay` = ?d OR `ambienceNight` = ?d OR `musicDay` = ?d OR `musicNight` = ?d OR `intro` = ?d', $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId))
{
$zones = new ZoneList(array(['id', array_column($zoneIds, 'id')]));
if (!$zones->error)
@@ -265,7 +247,7 @@ class SoundPage extends GenericPage
// tab: Races (VocalUISounds (containing error voice overs))
- if ($vo = DB::Aowow()->selectCol('SELECT raceId FROM ?_races_sounds WHERE soundId = ?d GROUP BY raceId', $this->typeId))
+ if ($vo = DB::Aowow()->selectCol('SELECT `raceId` FROM ?_races_sounds WHERE `soundId` = ?d GROUP BY `raceId`', $this->typeId))
{
$races = new CharRaceList(array(['id', $vo]));
if (!$races->error)
@@ -277,7 +259,7 @@ class SoundPage extends GenericPage
// tab: Emotes (EmotesTextSound (containing emote audio))
- if ($em = DB::Aowow()->selectCol('SELECT emoteId FROM ?_emotes_sounds WHERE soundId = ?d GROUP BY emoteId UNION SELECT id FROM ?_emotes WHERE soundId = ?d', $this->typeId, $this->typeId))
+ if ($em = DB::Aowow()->selectCol('SELECT `emoteId` FROM ?_emotes_sounds WHERE `soundId` = ?d GROUP BY `emoteId` UNION SELECT `id` FROM ?_emotes WHERE `soundId` = ?d', $this->typeId, $this->typeId))
{
$races = new EmoteList(array(['id', $em]));
if (!$races->error)
@@ -290,7 +272,7 @@ class SoundPage extends GenericPage
}
}
- $creatureIds = DB::World()->selectCol('SELECT ct.CreatureID FROM creature_text ct LEFT JOIN broadcast_text bct ON bct.ID = ct.BroadCastTextId WHERE bct.SoundEntriesID = ?d OR ct.Sound = ?d', $this->typeId, $this->typeId);
+ $creatureIds = DB::World()->selectCol('SELECT ct.`CreatureID` FROM creature_text ct LEFT JOIN broadcast_text bct ON bct.`ID` = ct.`BroadCastTextId` WHERE bct.`SoundEntriesID` = ?d OR ct.`Sound` = ?d', $this->typeId, $this->typeId);
// can objects or areatrigger play sound...?
if ($goosp = SmartAI::getOwnerOfSoundPlayed($this->typeId, Type::NPC))
@@ -298,35 +280,20 @@ class SoundPage extends GenericPage
// tab: NPC (dialogues...?, generic creature sound)
// skipping (always empty): transforms, footsteps
- $displayIds = DB::Aowow()->selectCol('
- SELECT id FROM ?_creature_sounds WHERE
- greeting = ?d OR
- farewell = ?d OR
- angry = ?d OR
- exertion = ?d OR
- exertioncritical = ?d OR
- injury = ?d OR
- injurycritical = ?d OR
- death = ?d OR
- stun = ?d OR
- stand = ?d OR
- aggro = ?d OR
- wingflap = ?d OR
- wingglide = ?d OR
- alert = ?d OR
- fidget = ?d OR
- customattack = ?d OR
- `loop` = ?d OR
- jumpstart = ?d OR
- jumpend = ?d OR
- petattack = ?d OR
- petorder = ?d OR
- petdismiss = ?d OR
- birth = ?d OR
- spellcast = ?d OR
- submerge = ?d OR
- submerged = ?d
- ', $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId);
+ $displayIds = DB::Aowow()->selectCol(
+ 'SELECT `id`
+ FROM ?_creature_sounds
+ WHERE `greeting` = ?d OR `farewell` = ?d OR `angry` = ?d OR `exertion` = ?d OR `exertioncritical` = ?d OR
+ `injury` = ?d OR `injurycritical` = ?d OR `death` = ?d OR `stun` = ?d OR `stand` = ?d OR
+ `aggro` = ?d OR `wingflap` = ?d OR `wingglide` = ?d OR `alert` = ?d OR `fidget` = ?d OR
+ `customattack` = ?d OR `loop` = ?d OR `jumpstart` = ?d OR `jumpend` = ?d OR `petattack` = ?d OR
+ `petorder` = ?d OR `petdismiss` = ?d OR `birth` = ?d OR `spellcast` = ?d OR `submerge` = ?d OR `submerged` = ?d',
+ $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId,
+ $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId,
+ $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId,
+ $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId,
+ $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId
+ );
// broadcast_text <-> creature_text
if ($creatureIds || $displayIds)
diff --git a/setup/tools/filegen/itemscaling.ss.php b/setup/tools/filegen/itemscaling.ss.php
index 37a2adec..2e13d833 100644
--- a/setup/tools/filegen/itemscaling.ss.php
+++ b/setup/tools/filegen/itemscaling.ss.php
@@ -84,7 +84,7 @@ CLISetup::registerSetup("build", new class extends SetupScript
*/
$offsets = array_map(function ($v) { // LookupEntry((getClass()-1)*GT_MAX_RATING+cr+1)
- return (CLASS_WARRIOR - 1) * 32 + $v + 1; // should this be dynamic per pinned character? ITEM_MOD HASTE has a worse scaler for a subset of classes (see table)
+ return (ChrClass::WARRIOR->value - 1) * 32 + $v + 1; // should this be dynamic per pinned character? ITEM_MOD HASTE has a worse scaler for a subset of classes (see table)
}, $ratings);
$mods = DB::Aowow()->selectCol('SELECT idx - 1 AS ARRAY_KEY, ratio FROM dbc_gtoctclasscombatratingscalar WHERE idx IN (?a)', $offsets);
diff --git a/setup/tools/filegen/itemsets.ss.php b/setup/tools/filegen/itemsets.ss.php
index b00eb619..4bd0f485 100644
--- a/setup/tools/filegen/itemsets.ss.php
+++ b/setup/tools/filegen/itemsets.ss.php
@@ -68,11 +68,7 @@ CLISetup::registerSetup("build", new class extends SetupScript
if ($set['classMask'])
{
$setOut['reqclass'] = $set['classMask'];
- $setOut['classes'] = [];
-
- for ($i = 0; $i < 12; $i++)
- if ($set['classMask'] & (1 << $i))
- $setOut['classes'][] = $i + 1;
+ $setOut['classes'] = ChrClass::fromMask($set['classMask']);
}
if ($set['contentGroup'])
diff --git a/setup/tools/filegen/profiler.ss.php b/setup/tools/filegen/profiler.ss.php
index fab85d9d..73cf1f20 100644
--- a/setup/tools/filegen/profiler.ss.php
+++ b/setup/tools/filegen/profiler.ss.php
@@ -188,9 +188,9 @@ CLISetup::registerSetup("build", new class extends SetupScript
{
// two cases where the spell is unrestricted but the castitem has class restriction (too lazy to formulate ruleset)
if ($id == 66906) // Argent Charger
- $data['reqclass'] = CLASS_PALADIN;
+ $data['reqclass'] = ChrClass::PALADIN->toMask();
else if ($id == 54729) // Winged Steed of the Ebon Blade
- $data['reqclass'] = CLASS_DEATHKNIGHT;
+ $data['reqclass'] = ChrClass::DEATHKNIGHT->toMask();
rsort($data['skill']); // riding (777) expected at pos 0
@@ -420,20 +420,20 @@ CLISetup::registerSetup("build", new class extends SetupScript
private function sumTotal(array &$sumArr, int $raceMask = -1, int $classMask= -1) : void
{
- for ($i = 0; $i < RACE_MASK_ALL; $i++)
+ foreach (ChrRace::cases() as $ra)
{
- if (!((1 << $i) & $raceMask) || !((1 << $i) & RACE_MASK_ALL))
+ if (!$ra->matches($raceMask))
continue;
- for ($j = 0; $j < CLASS_MASK_ALL; $j++)
+ foreach (ChrClass::cases() as $cl)
{
- if (!((1 << $j) & $classMask) || !((1 << $j) & CLASS_MASK_ALL))
+ if (!$cl->matches($classMask))
continue;
- if (!isset($sumArr[$i+1][$j+1]))
- $sumArr[$i+1][$j+1] = 1;
+ if (!isset($sumArr[$ra->value][$cl->value]))
+ $sumArr[$ra->value][$cl->value] = 1;
else
- $sumArr[$i+1][$j+1]++;
+ $sumArr[$ra->value][$cl->value]++;
}
}
}
diff --git a/setup/tools/filegen/talentcalc.ss.php b/setup/tools/filegen/talentcalc.ss.php
index 671a3555..2d9429b1 100644
--- a/setup/tools/filegen/talentcalc.ss.php
+++ b/setup/tools/filegen/talentcalc.ss.php
@@ -59,15 +59,12 @@ CLISetup::registerSetup("build", new class extends SetupScript
Lang::load($loc);
// TalentCalc
- for ($i = 1; (1 << ($i - 1)) < CLASS_MASK_ALL; $i++ )
+ foreach (ChrClass::cases() as $class)
{
- if (!((1 << ($i - 1)) & CLASS_MASK_ALL))
- continue;
-
set_time_limit(20);
- $file = 'datasets/'.$loc->json().'/talents-'.$i;
- $toFile = '$WowheadTalentCalculator.registerClass('.$i.', '.Util::toJSON($this->buildTree(1 << ($i - 1))).')';
+ $file = 'datasets/'.$loc->json().'/talents-'.$class->value;
+ $toFile = '$WowheadTalentCalculator.registerClass('.$class->value.', '.Util::toJSON($this->buildTree($class->toMask())).')';
if (!CLISetup::writeFile($file, $toFile))
$this->success = false;
diff --git a/setup/tools/filegen/talenticons.ss.php b/setup/tools/filegen/talenticons.ss.php
index 718660d8..6011aa90 100644
--- a/setup/tools/filegen/talenticons.ss.php
+++ b/setup/tools/filegen/talenticons.ss.php
@@ -19,89 +19,115 @@ CLISetup::registerSetup("build", new class extends SetupScript
private const ICON_SIZE = 36; // px
- private $filenames = ['icons', 'warrior', 'paladin', 'hunter', 'rogue', 'priest', 'deathknight', 'shaman', 'mage', 'warlock', null, 'druid'];
-
public function generate() : bool
{
- foreach ($this->filenames as $k => $v)
- {
- if (!$v)
- continue;
+ /***************/
+ /* Hunter Pets */
+ /***************/
+ for ($tabIdx = 0; $tabIdx < 3; $tabIdx++)
+ {
+ $outFile = 'static/images/wow/hunterpettalents/icons_'.($tabIdx + 1).'.jpg';
+
+ if ($tex = $this->compileTexture('creatureFamilyMask', 1 << $tabIdx, 0))
+ {
+ if (!imagejpeg($tex, $outFile))
+ {
+ CLI::write('[talenticons] - '.CLI::bold($outFile.'.jpg').' could not be written', CLI::LOG_ERROR);
+ $this->success = false;
+ }
+ else
+ CLI::write('[talenticons] created file '.CLI::bold($outFile), CLI::LOG_OK, true, true);
+ }
+ else
+ $this->success = false;
+ }
+
+
+ /***********/
+ /* Players */
+ /***********/
+
+ foreach (ChrClass::cases() as $class)
+ {
set_time_limit(10);
- for ($tree = 0; $tree < 3; $tree++)
+ for ($tabIdx = 0; $tabIdx < 3; $tabIdx++)
{
- $what = $k ? 'classMask' : 'creatureFamilyMask';
- $set = $k ? 1 << ($k - 1) : 1 << $tree;
- $subset = $k ? $tree : 0;
- $path = $k ? 'talents/icons' : 'hunterpettalents';
- $outFile = 'static/images/wow/'.$path.'/'.$v.'_'.($tree + 1).'.jpg';
- $icons = DB::Aowow()->SelectCol(
- 'SELECT ic.name AS iconString
- FROM ?_icons ic
- JOIN ?_spell s ON s.iconId = ic.id
- JOIN dbc_talent t ON t.rank1 = s.id
- JOIN dbc_talenttab tt ON tt.id = t.tabId
- WHERE tt.?# = ?d AND tt.tabNumber = ?d
- ORDER BY t.row, t.column ASC, s.id DESC',
- $what, $set, $subset);
+ $outFile = 'static/images/wow/talents/icons/'.$class->json().'_'.($tabIdx + 1).'.jpg';
- if (empty($icons))
+ if ($tex = $this->compileTexture('classMask', $class->toMask(), $tabIdx))
{
- CLI::write('[talenticons] - query for '.$v.' tree: '.$k.' returned empty', CLI::LOG_ERROR);
- $this->success = false;
- continue;
- }
-
- $res = imageCreateTrueColor(count($icons) * self::ICON_SIZE, 2 * self::ICON_SIZE);
- if (!$res)
- {
- $this->success = false;
- CLI::write('[talenticons] - image resource not created', CLI::LOG_ERROR);
- continue;
- }
-
- for ($i = 0; $i < count($icons); $i++)
- {
- $imgFile = 'static/images/wow/icons/medium/'.strtolower($icons[$i]).'.jpg';
- if (!file_exists($imgFile))
+ if (!imagejpeg($tex, $outFile))
{
- CLI::write('[talenticons] - raw image '.CLI::bold($imgFile). ' not found', CLI::LOG_ERROR);
+ CLI::write('[talenticons] - '.CLI::bold($outFile.'.jpg').' could not be written', CLI::LOG_ERROR);
$this->success = false;
- break;
}
-
- $im = imagecreatefromjpeg($imgFile);
-
- // colored
- imagecopymerge($res, $im, $i * self::ICON_SIZE, 0, 0, 0, imageSX($im), imageSY($im), 100);
-
- // grayscale
- if (imageistruecolor($im))
- imagetruecolortopalette($im, false, 256);
-
- for ($j = 0; $j < imagecolorstotal($im); $j++)
- {
- $color = imagecolorsforindex($im, $j);
- $gray = round(0.299 * $color['red'] + 0.587 * $color['green'] + 0.114 * $color['blue']);
- imagecolorset($im, $j, $gray, $gray, $gray);
- }
- imagecopymerge($res, $im, $i * self::ICON_SIZE, self::ICON_SIZE, 0, 0, imageSX($im), imageSY($im), 100);
+ else
+ CLI::write('[talenticons] created file '.CLI::bold($outFile), CLI::LOG_OK, true, true);
}
-
- if (@imagejpeg($res, $outFile))
- CLI::write('[talenticons] created file '.CLI::bold($outFile), CLI::LOG_OK, true, true);
else
- {
$this->success = false;
- CLI::write('[talenticons] - '.CLI::bold($outFile.'.jpg').' could not be written', CLI::LOG_ERROR);
- }
}
}
return $this->success;
}
+
+ private function compileTexture(string $ttField, int $searchMask, int $tabIdx) : ?GDImage
+ {
+ $icons = DB::Aowow()->SelectCol(
+ 'SELECT ic.`name` AS "iconString"
+ FROM ?_icons ic
+ JOIN ?_spell s ON s.`iconId` = ic.`id`
+ JOIN dbc_talent t ON t.`rank1` = s.`id`
+ JOIN dbc_talenttab tt ON tt.`id` = t.`tabId`
+ WHERE tt.?# = ?d AND tt.`tabNumber` = ?d
+ ORDER BY t.`row`, t.`column` ASC, s.`id` DESC',
+ $ttField, $searchMask, $tabIdx);
+
+ if (empty($icons))
+ {
+ CLI::write('[talenticons] - query for '.$ttField.': '.$searchMask.' on idx: '.$tabIdx.' returned empty', CLI::LOG_ERROR);
+ return null;
+ }
+
+ $res = imageCreateTrueColor(count($icons) * self::ICON_SIZE, 2 * self::ICON_SIZE);
+ if (!$res)
+ {
+ CLI::write('[talenticons] - image resource not created', CLI::LOG_ERROR);
+ return null;
+ }
+
+ for ($i = 0; $i < count($icons); $i++)
+ {
+ $imgFile = 'static/images/wow/icons/medium/'.strtolower($icons[$i]).'.jpg';
+ if (!file_exists($imgFile))
+ {
+ CLI::write('[talenticons] - raw image '.CLI::bold($imgFile). ' not found', CLI::LOG_ERROR);
+ return null;
+ }
+
+ $im = imagecreatefromjpeg($imgFile);
+
+ // colored
+ imagecopymerge($res, $im, $i * self::ICON_SIZE, 0, 0, 0, imageSX($im), imageSY($im), 100);
+
+ // grayscale
+ if (imageistruecolor($im))
+ imagetruecolortopalette($im, false, 256);
+
+ for ($j = 0; $j < imagecolorstotal($im); $j++)
+ {
+ $color = imagecolorsforindex($im, $j);
+ $gray = round(0.299 * $color['red'] + 0.587 * $color['green'] + 0.114 * $color['blue']);
+ imagecolorset($im, $j, $gray, $gray, $gray);
+ }
+ imagecopymerge($res, $im, $i * self::ICON_SIZE, self::ICON_SIZE, 0, 0, imageSX($im), imageSY($im), 100);
+ }
+
+ return $res;
+ }
});
?>
diff --git a/setup/tools/sqlgen/classes.ss.php b/setup/tools/sqlgen/classes.ss.php
index 7c6dd6ca..19129f82 100644
--- a/setup/tools/sqlgen/classes.ss.php
+++ b/setup/tools/sqlgen/classes.ss.php
@@ -21,22 +21,37 @@ CLISetup::registerSetup("sql", new class extends SetupScript
{
DB::Aowow()->query('TRUNCATE ?_classes');
- $classes = DB::Aowow()->select('SELECT *, id AS ARRAY_KEY FROM dbc_chrclasses');
+ $classes = DB::Aowow()->select('SELECT *, `id` AS ARRAY_KEY FROM dbc_chrclasses');
// add raceMask
- $races = DB::Aowow()->select('SELECT classId AS ARRAY_KEY, BIT_OR(1 << (raceId - 1)) AS raceMask FROM dbc_charbaseinfo GROUP BY classId');
+ $races = DB::Aowow()->select('SELECT `classId` AS ARRAY_KEY, BIT_OR(1 << (`raceId` - 1)) AS "raceMask" FROM dbc_charbaseinfo GROUP BY `classId`');
Util::arraySumByKey($classes, $races);
// add skills
- if ($skills = DB::Aowow()->selectCol('SELECT LOG(2, classMask) + 1 AS ARRAY_KEY, GROUP_CONCAT(skillLine SEPARATOR \' \') FROM dbc_skillraceclassinfo WHERE flags = ?d GROUP BY classMask HAVING ARRAY_KEY = CAST(LOG(2, classMask) + 1 AS SIGNED)', 0x410))
+ if ($skills = DB::Aowow()->selectCol('SELECT LOG(2, `classMask`) + 1 AS ARRAY_KEY, GROUP_CONCAT(`skillLine` SEPARATOR \' \') FROM dbc_skillraceclassinfo WHERE `flags` = ?d GROUP BY `classMask` HAVING ARRAY_KEY = CAST(LOG(2, `classMask`) + 1 AS SIGNED)', 0x410))
foreach ($skills as $classId => $skillStr)
$classes[$classId]['skills'] = $skillStr;
// add weaponTypeMask & armorTypeMask
foreach ($classes as $id => &$data)
{
- $data['weaponTypeMask'] = DB::Aowow()->selectCell('SELECT BIT_OR(equippedItemSubClassMask) FROM dbc_spell s JOIN dbc_skilllineability sla ON sla.spellId = s.id JOIN dbc_skillraceclassinfo srci ON srci.skillLine = sla.skillLineId AND srci.classMask & ?d WHERE sla.skilllineid <> 183 AND (sla.reqClassMask & ?d OR sla.reqClassMask = 0) AND equippedItemClass = ?d AND (effect1Id = 60 OR effect2Id = 60)', 1 << ($id - 1), 1 << ($id - 1), ITEM_CLASS_WEAPON);
- $data['armorTypeMask'] = DB::Aowow()->selectCell('SELECT BIT_OR(equippedItemSubClassMask) FROM dbc_spell s JOIN dbc_skilllineability sla ON sla.spellId = s.id JOIN dbc_skillraceclassinfo srci ON srci.skillLine = sla.skillLineId AND srci.classMask & ?d WHERE sla.reqClassMask & ?d AND equippedItemClass = ?d AND (effect1Id = 60 OR effect2Id = 60)', 1 << ($id - 1), 1 << ($id - 1), ITEM_CLASS_ARMOR);
+ $mask = 1 << ($id - 1);
+ $data['weaponTypeMask'] = DB::Aowow()->selectCell(
+ 'SELECT BIT_OR(`equippedItemSubClassMask`)
+ FROM dbc_spell s
+ JOIN dbc_skilllineability sla ON sla.`spellId` = s.`id`
+ JOIN dbc_skillraceclassinfo srci ON srci.`skillLine` = sla.`skillLineId` AND srci.`classMask` & ?d
+ WHERE sla.`skilllineid` <> 183 AND (sla.`reqClassMask` & ?d OR sla.`reqClassMask` = 0) AND `equippedItemClass` = ?d AND (`effect1Id` = ?d OR `effect2Id` = ?d)',
+ $mask, $mask, ITEM_CLASS_WEAPON, SPELL_EFFECT_PROFICIENCY, SPELL_EFFECT_PROFICIENCY
+ );
+ $data['armorTypeMask'] = DB::Aowow()->selectCell(
+ 'SELECT BIT_OR(`equippedItemSubClassMask`)
+ FROM dbc_spell s
+ JOIN dbc_skilllineability sla ON sla.`spellId` = s.`id`
+ JOIN dbc_skillraceclassinfo srci ON srci.`skillLine` = sla.`skillLineId` AND srci.`classMask` & ?d
+ WHERE sla.`reqClassMask` & ?d AND `equippedItemClass` = ?d AND (`effect1Id` = ?d OR `effect2Id` = ?d)',
+ $mask, $mask, ITEM_CLASS_ARMOR, SPELL_EFFECT_PROFICIENCY, SPELL_EFFECT_PROFICIENCY
+ );
}
foreach ($classes as $cl)
diff --git a/setup/tools/sqlgen/itemset.ss.php b/setup/tools/sqlgen/itemset.ss.php
index 99eb8a42..b89d5839 100644
--- a/setup/tools/sqlgen/itemset.ss.php
+++ b/setup/tools/sqlgen/itemset.ss.php
@@ -151,7 +151,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript
return $tag;
// try arena set
- if ($item['AllowableClass'] && ($item['AllowableClass'] & CLASS_MASK_ALL) != CLASS_MASK_ALL)
+ if ($item['AllowableClass'] && ($item['AllowableClass'] & ChrClass::MASK_ALL) != ChrClass::MASK_ALL)
return $this->tagsByItemlevel[$item['ItemLevel']] ?? 0;
return 0;
@@ -163,11 +163,11 @@ CLISetup::registerSetup("sql", new class extends SetupScript
foreach ($items as $item)
$data['item'.$i++] = $item['entry'];
- $mask = CLASS_MASK_ALL;
+ $mask = ChrClass::MASK_ALL;
foreach ($items as $item)
$mask &= $item['AllowableClass'];
- if ($mask != CLASS_MASK_ALL)
+ if ($mask != ChrClass::MASK_ALL)
$data['classMask'] = $mask;
$iLvl = array_column($items, 'ItemLevel');
diff --git a/setup/tools/sqlgen/races.ss.php b/setup/tools/sqlgen/races.ss.php
index fe5d3dbc..0e35772b 100644
--- a/setup/tools/sqlgen/races.ss.php
+++ b/setup/tools/sqlgen/races.ss.php
@@ -22,15 +22,15 @@ CLISetup::registerSetup("sql", new class extends SetupScript
DB::Aowow()->query('TRUNCATE ?_races');
DB::Aowow()->query(
'INSERT INTO ?_races
- SELECT id, 0, flags, 0, factionId, 0, 0, baseLanguage, IF(side = 2, 0, side + 1), fileString, name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8, expansion
+ SELECT `id`, 0, `flags`, 0, `factionId`, 0, 0, `baseLanguage`, IF(`side` = 2, 0, `side` + 1), `fileString`, `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8`, `expansion`
FROM dbc_chrraces'
);
// add classMask
- DB::Aowow()->query('UPDATE ?_races r JOIN (SELECT BIT_OR(1 << (classId - 1)) as classMask, raceId FROM dbc_charbaseinfo GROUP BY raceId) cbi ON cbi.raceId = r.id SET r.classMask = cbi.classMask');
+ DB::Aowow()->query('UPDATE ?_races r JOIN (SELECT BIT_OR(1 << (`classId` - 1)) AS "classMask", `raceId` FROM dbc_charbaseinfo GROUP BY `raceId`) cbi ON cbi.`raceId` = r.id SET r.`classMask` = cbi.`classMask`');
// add cuFlags
- DB::Aowow()->query('UPDATE ?_races SET cuFlags = ?d WHERE flags & ?d', CUSTOM_EXCLUDE_FOR_LISTVIEW, 0x1);
+ DB::Aowow()->query('UPDATE ?_races SET `cuFlags` = ?d WHERE `flags` & ?d', CUSTOM_EXCLUDE_FOR_LISTVIEW, 0x1);
$this->reapplyCCFlags('races', Type::CHR_RACE);
diff --git a/setup/tools/sqlgen/source.ss.php b/setup/tools/sqlgen/source.ss.php
index 7e166633..0191ec64 100644
--- a/setup/tools/sqlgen/source.ss.php
+++ b/setup/tools/sqlgen/source.ss.php
@@ -447,17 +447,17 @@ CLISetup::registerSetup("sql", new class extends SetupScript
SELECT `StartItem` AS `item`, `ID`, COUNT(1) AS `qty`, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS `side`, IF(COUNT(DISTINCT `QuestSortID`) > 1, 0, GREATEST(`QuestSortID`, 0)) AS `zone` FROM quest_template WHERE `StartItem` > 0 GROUP BY `item`) n
JOIN item_template it ON it.`entry` = n.`item`
GROUP BY `item`',
- RACE_MASK_HORDE, RACE_MASK_ALLIANCE, SIDE_HORDE, RACE_MASK_ALLIANCE, RACE_MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
- RACE_MASK_HORDE, RACE_MASK_ALLIANCE, SIDE_HORDE, RACE_MASK_ALLIANCE, RACE_MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
- RACE_MASK_HORDE, RACE_MASK_ALLIANCE, SIDE_HORDE, RACE_MASK_ALLIANCE, RACE_MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
- RACE_MASK_HORDE, RACE_MASK_ALLIANCE, SIDE_HORDE, RACE_MASK_ALLIANCE, RACE_MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
- RACE_MASK_HORDE, RACE_MASK_ALLIANCE, SIDE_HORDE, RACE_MASK_ALLIANCE, RACE_MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
- RACE_MASK_HORDE, RACE_MASK_ALLIANCE, SIDE_HORDE, RACE_MASK_ALLIANCE, RACE_MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
- RACE_MASK_HORDE, RACE_MASK_ALLIANCE, SIDE_HORDE, RACE_MASK_ALLIANCE, RACE_MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
- RACE_MASK_HORDE, RACE_MASK_ALLIANCE, SIDE_HORDE, RACE_MASK_ALLIANCE, RACE_MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
- RACE_MASK_HORDE, RACE_MASK_ALLIANCE, SIDE_HORDE, RACE_MASK_ALLIANCE, RACE_MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
- RACE_MASK_HORDE, RACE_MASK_ALLIANCE, SIDE_HORDE, RACE_MASK_ALLIANCE, RACE_MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
- RACE_MASK_HORDE, RACE_MASK_ALLIANCE, SIDE_HORDE, RACE_MASK_ALLIANCE, RACE_MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH
+ ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
+ ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
+ ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
+ ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
+ ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
+ ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
+ ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
+ ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
+ ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
+ ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
+ ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH
);
$areaParent = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `parentArea` FROM ?_zones WHERE `id` IN (?a) AND `parentArea` > 0', array_filter(array_column($quests, 'zone')));
@@ -480,7 +480,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript
LEFT JOIN item_template it ON it.`entry` = mlt.`Item` AND mlt.`Reference` <= 0
WHERE qta.`RewardMailTemplateId` > 0
GROUP BY ARRAY_KEY',
- RACE_MASK_HORDE, RACE_MASK_ALLIANCE, SIDE_HORDE, RACE_MASK_ALLIANCE, RACE_MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH
+ ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH
);
$areaParent = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `parentArea` FROM ?_zones WHERE `id` IN (?a) AND `parentArea` > 0', array_filter(array_column($mailLoot, 'zone')));
@@ -1012,8 +1012,8 @@ CLISetup::registerSetup("sql", new class extends SetupScript
FROM (SELECT IF(`RewardSpell` = 0, `RewardDisplaySpell`, `RewardSpell`) AS `spell`, `Id`, COUNT(1) AS `qty`, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS `side`, GREATEST(`QuestSortID`, 0) AS `zone` FROM quest_template WHERE IF(`RewardSpell` = 0, `RewardDisplaySpell`, `RewardSpell`) > 0 GROUP BY `spell` UNION
SELECT qta.`SourceSpellId` AS `spell`, qt.`Id`, COUNT(1) AS `qty`, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS `side`, GREATEST(`QuestSortID`, 0) AS `zone` FROM quest_template qt JOIN quest_template_addon qta ON qta.ID = qt.ID WHERE qta.`SourceSpellId` > 0 GROUP BY `spell`) t
GROUP BY `spell`',
- RACE_MASK_HORDE, RACE_MASK_ALLIANCE, SIDE_HORDE, RACE_MASK_ALLIANCE, RACE_MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
- RACE_MASK_HORDE, RACE_MASK_ALLIANCE, SIDE_HORDE, RACE_MASK_ALLIANCE, RACE_MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH
+ ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH,
+ ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH
);
if (!$quests)
@@ -1142,7 +1142,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript
'SELECT `RewardTitle` AS ARRAY_KEY, `ID` AS `id`, SUM(`qty`) AS `qty`, BIT_OR(`side`) AS `side`, IF(COUNT(DISTINCT `zone`) > 1, 0, `zone`) AS `zone`
FROM (SELECT `RewardTitle`, `ID`, 1 AS `qty`, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS `side`, GREATEST(`QuestSortID`, 0) AS `zone` FROM quest_template WHERE `RewardTitle` > 0) q
GROUP BY `RewardTitle`',
- RACE_MASK_HORDE, RACE_MASK_ALLIANCE, SIDE_HORDE, RACE_MASK_ALLIANCE, RACE_MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH
+ ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH
);
if (!$quests)
diff --git a/setup/tools/sqlgen/spell.ss.php b/setup/tools/sqlgen/spell.ss.php
index 5dc9667b..fc458d57 100644
--- a/setup/tools/sqlgen/spell.ss.php
+++ b/setup/tools/sqlgen/spell.ss.php
@@ -453,9 +453,9 @@ CLISetup::registerSetup("sql", new class extends SetupScript
CLI::write('[spell] - misc fixups & icons');
// FU [FixUps]
- DB::Aowow()->query('UPDATE ?_spell SET `reqRaceMask` = ?d WHERE `skillLine1` = ?d', RACE_DRAENEI, 760); // Draenai Racials
- DB::Aowow()->query('UPDATE ?_spell SET `reqRaceMask` = ?d WHERE `skillLine1` = ?d', RACE_BLOODELF, 756); // Bloodelf Racials
- DB::Aowow()->query('UPDATE ?_spell SET `reqClassMask` = ?d WHERE `id` = ?d', CLASS_MAGE, 30449); // Mage - Spellsteal
+ DB::Aowow()->query('UPDATE ?_spell SET `reqRaceMask` = ?d WHERE `skillLine1` = ?d', ChrRace::DRAENEI->value, 760); // Draenei Racials
+ DB::Aowow()->query('UPDATE ?_spell SET `reqRaceMask` = ?d WHERE `skillLine1` = ?d', ChrRace::BLOODELF->value, 756); // Bloodelf Racials
+ DB::Aowow()->query('UPDATE ?_spell SET `reqClassMask` = ?d WHERE `id` = ?d', ChrClass::MAGE->value, 30449); // Mage - Spellsteal
// triggered by spell
DB::Aowow()->query(
@@ -580,14 +580,14 @@ CLISetup::registerSetup("sql", new class extends SetupScript
(s.attributes0 = 0x20000000 AND s.attributes3 = 0x10000000) -- Master Demonologist (FamilyId = 0)
)', CUSTOM_EXCLUDE_FOR_LISTVIEW);
- for ($i = 0; (1 << $i) < CLASS_MASK_ALL; $i++)
- if ((1 << $i) & CLASS_MASK_ALL)
- DB::Aowow()->query(
- 'UPDATE ?_spell s, dbc_skillline sl, dbc_skillraceclassinfo srci
- SET s.reqClassMask = srci.classMask
- WHERE s.typeCat IN (-2, 7) AND (s.attributes0 & 0x80) = 0 AND s.skillLine1 = srci.skillLine AND sl.categoryId = 7 AND
- srci.skillline <> 769 AND srci.skillline = sl.id AND srci.flags & 0x90 AND srci.classMask & ?d',
- 1 << $i);
+ foreach (ChrClass::cases() as $cl)
+ DB::Aowow()->query(
+ 'UPDATE ?_spell s, dbc_skillline sl, dbc_skillraceclassinfo srci
+ SET s.`reqClassMask` = srci.`classMask`
+ WHERE s.`typeCat` IN (-2, 7) AND (s.`attributes0` & 0x80) = 0 AND s.`skillLine1` = srci.`skillLine` AND sl.`categoryId` = 7 AND
+ srci.`skillline` <> 769 AND srci.`skillline` = sl.`id` AND srci.`flags` & 0x90 AND srci.`classMask` & ?d',
+ $cl->toMask()
+ );
// secondary Skills (9)
DB::Aowow()->query('UPDATE ?_spell s SET s.typeCat = 9 WHERE s.typeCat = 0 AND (s.skillLine1 IN (?a) OR (s.skillLine1 > 0 AND s.skillLine2OrMask IN (?a)))', SKILLS_TRADE_SECONDARY, SKILLS_TRADE_SECONDARY);
diff --git a/setup/tools/sqlgen/titles.ss.php b/setup/tools/sqlgen/titles.ss.php
index eed458a7..094af7d1 100644
--- a/setup/tools/sqlgen/titles.ss.php
+++ b/setup/tools/sqlgen/titles.ss.php
@@ -74,7 +74,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript
if ($data['eventEntry'])
DB::Aowow()->query('UPDATE ?_titles SET `eventId` = ?d WHERE `id` = ?d', $data['eventEntry'], $tId);
- $side = Game::sideByRaceMask($data['AllowableRaces']);
+ $side = ChrRace::sideFromMask($data['AllowableRaces']);
if ($side == SIDE_BOTH)
continue;