Util/Enums

* create helper enum classes ChrClass & ChrRace
 * replace various iterators and checks with said enums
This commit is contained in:
Sarjuuk
2022-04-05 16:51:59 +02:00
parent a5bd6ddc8a
commit 1f59e6fe2d
34 changed files with 642 additions and 595 deletions

View File

@@ -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'],

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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)

View File

@@ -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...');

View File

@@ -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];

View File

@@ -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];

View File

@@ -147,7 +147,7 @@ class GuideList extends BaseType
if ($c = $this->getField('classId'))
{
$n = Lang::game('cl', $c);
$specStr .= '&nbsp;&nbsp;&nbsp;&nbsp;<span class="icontiny c'.$c.'" style="background-image: url('.Cfg::get('STATIC_URL').'/images/wow/icons/tiny/class_'.Game::$classFileStrings[$c].'.gif)">%s</span>';
$specStr .= '&nbsp;&nbsp;&nbsp;&nbsp;<span class="icontiny c'.$c.'" style="background-image: url('.Cfg::get('STATIC_URL').'/images/wow/icons/tiny/class_'.ChrClass::tryFrom($c)->json().'.gif)">%s</span>';
if (($s = $this->getField('specId')) > -1)
{

View File

@@ -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;

View File

@@ -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])

View File

@@ -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'),

View File

@@ -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;
}

View File

@@ -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:

View File

@@ -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);

View File

@@ -1559,7 +1559,7 @@ $lang = array(
'dotSP' => "每个周期的法术强度 +%.2f%%", 'dotAP' => "每个周期的攻击强度 +%.2f%%"
),
'relItems' => array(
'base' => "<small>显示与<b>%s</b>相关的 %s<</small>",
'base' => "<small>显示与<b>%s</b>相关的 %s</small>",
'link' => "",
'recipes' => '<a href="?items=9.%s">制作物品</a>',
'crafted' => '<a href="?items&filter=cr=86;crs=%s;crv=0">手工制作物品</a>'

View File

@@ -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())]];

View File

@@ -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)

View File

@@ -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]))

View File

@@ -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))

View File

@@ -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
}
}
?>

View File

@@ -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(

View File

@@ -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)

View File

@@ -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)

View File

@@ -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);

View File

@@ -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'])

View File

@@ -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]++;
}
}
}

View File

@@ -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;

View File

@@ -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;
}
});
?>

View File

@@ -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)

View File

@@ -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');

View File

@@ -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);

View File

@@ -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)

View File

@@ -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);

View File

@@ -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;