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'], 'level' => $pBase['level'],
'classs' => $pBase['class'], 'classs' => $pBase['class'],
'race' => $pBase['race'], 'race' => $pBase['race'],
'faction' => Game::sideByRaceMask(1 << ($pBase['race'] - 1)) - 1, 'faction' => ChrRace::tryFrom($pBase['race'])?->getSide() ?? SIDE_NONE,
'gender' => $pBase['gender'], 'gender' => $pBase['gender'],
'skincolor' => $pBase['skincolor'], 'skincolor' => $pBase['skincolor'],
'hairstyle' => $pBase['hairstyle'], 'hairstyle' => $pBase['hairstyle'],

View File

@@ -553,14 +553,14 @@ class Conditions
{ {
if ($cndId == self::CHR_CLASS) if ($cndId == self::CHR_CLASS)
{ {
$cVal1 &= CLASS_MASK_ALL; $cVal1 &= ChrClass::MASK_ALL;
foreach (Util::mask2bits($cVal1, 1) as $cId) foreach (Util::mask2bits($cVal1, 1) as $cId)
$this->jsGlobals[Type::CHR_CLASS][$cId] = $cId; $this->jsGlobals[Type::CHR_CLASS][$cId] = $cId;
} }
if ($cndId == self::CHR_RACE) if ($cndId == self::CHR_RACE)
{ {
$cVal1 &= RACE_MASK_ALL; $cVal1 &= ChrRace::MASK_ALL;
foreach (Util::mask2bits($cVal1, 1) as $rId) foreach (Util::mask2bits($cVal1, 1) as $rId)
$this->jsGlobals[Type::CHR_RACE][$rId] = $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'); define('LOOT_REFERENCE', 'reference_loot_template');
// Sides // Sides
define('SIDE_NONE', 0);
define('SIDE_ALLIANCE', 1); define('SIDE_ALLIANCE', 1);
define('SIDE_HORDE', 2); define('SIDE_HORDE', 2);
define('SIDE_BOTH', 3); define('SIDE_BOTH', 3);
@@ -384,33 +385,152 @@ define('EXP_CLASSIC', 0);
define('EXP_BC', 1); define('EXP_BC', 1);
define('EXP_WOTLK', 2); define('EXP_WOTLK', 2);
// ClassMask enum ChrClass : int
define('CLASS_WARRIOR', 0x001); {
define('CLASS_PALADIN', 0x002); case WARRIOR = 1;
define('CLASS_HUNTER', 0x004); case PALADIN = 2;
define('CLASS_ROGUE', 0x008); case HUNTER = 3;
define('CLASS_PRIEST', 0x010); case ROGUE = 4;
define('CLASS_DEATHKNIGHT', 0x020); case PRIEST = 5;
define('CLASS_SHAMAN', 0x040); case DEATHKNIGHT = 6;
define('CLASS_MAGE', 0x080); case SHAMAN = 7;
define('CLASS_WARLOCK', 0x100); case MAGE = 8;
define('CLASS_DRUID', 0x400); case WARLOCK = 9;
define('CLASS_MASK_ALL', 0x5FF); case DRUID = 11;
// RaceMask public const MASK_ALL = 0x5FF;
define('RACE_HUMAN', 0x001);
define('RACE_ORC', 0x002); public function matches(int $classMask) : bool
define('RACE_DWARF', 0x004); {
define('RACE_NIGHTELF', 0x008); return !$classMask || $this->value & $classMask;
define('RACE_UNDEAD', 0x010); }
define('RACE_TAUREN', 0x020);
define('RACE_GNOME', 0x040); public function toMask() : int
define('RACE_TROLL', 0x080); {
define('RACE_BLOODELF', 0x200); return 1 << ($this->value - 1);
define('RACE_DRAENEI', 0x400); }
define('RACE_MASK_ALLIANCE', 0x44D);
define('RACE_MASK_HORDE', 0x2B2); public static function fromMask(int $classMask = self::MASK_ALL) : array
define('RACE_MASK_ALL', 0x6FF); {
$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 // SpellFamilyNames
define('SPELLFAMILY_GENERIC', 0); define('SPELLFAMILY_GENERIC', 0);

View File

@@ -29,10 +29,6 @@ class Game
1 => ['ability_rogue_eviscerate', 'ability_warrior_innerrage', 'ability_warrior_defensivestance' ] 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( public static $questClasses = array(
-2 => [ 0], -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], 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 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) public static function getReputationLevelForPoints($pts)
{ {
if ($pts >= 41999) if ($pts >= 41999)

View File

@@ -247,17 +247,17 @@ class Profiler
private static function queueInsert($realmId, $guid, $type, $localId) 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 // not on already scheduled - recalc time and set status to PR_QUEUE_STATUS_WAITING
if ($rData['status'] != 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()); $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 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) public static function scheduleResync($type, $realmId, $guid)
@@ -267,17 +267,17 @@ class Profiler
switch ($type) switch ($type)
{ {
case Type::PROFILE: 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); self::queueInsert($realmId, $guid, Type::PROFILE, $newId);
break; break;
case Type::GUILD: 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); self::queueInsert($realmId, $guid, Type::GUILD, $newId);
break; break;
case Type::ARENA_TEAM: 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); self::queueInsert($realmId, $guid, Type::ARENA_TEAM, $newId);
break; break;
@@ -302,10 +302,10 @@ class Profiler
else else
{ {
// error out all profiles with status WORKING, that are older than 60sec // 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); $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); $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) foreach ($subjectGUIDs as $guid)
{ {
if (empty($subjectStatus[$guid])) // whelp, thats some error.. if (empty($subjectStatus[$guid])) // whelp, thats some error..
@@ -328,7 +328,7 @@ class Profiler
public static function getCharFromRealm($realmId, $charGuid) 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) if (!$char)
return false; 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 // 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) if (!$profile)
return false; // well ... it failed return false; // well ... it failed
@@ -349,15 +349,15 @@ class Profiler
if (!$char['online'] && $char['logout_time'] <= $profile['lastupdated']) 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...'); CLI::write('char did not log in since last update. skipping...');
return true; return true;
} }
CLI::write('writing...'); CLI::write('writing...');
$ra = (1 << ($char['race'] - 1)); $ra = ChrRace::from($char['race']);
$cl = (1 << ($char['class'] - 1)); $cl = ChrClass::from($char['class']);
/*************/ /*************/
/* equipment */ /* equipment */
@@ -375,8 +375,8 @@ class Profiler
*/ */
DB::Aowow()->query('DELETE FROM ?_profiler_items WHERE id = ?d', $profileId); 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']); $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 = []; $gemItems = [];
$permEnch = []; $permEnch = [];
@@ -393,7 +393,7 @@ class Profiler
if ($gEnch) 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) foreach ($gEnch as $eId)
{ {
if (isset($gemItems[$eId])) if (isset($gemItems[$eId]))
@@ -449,7 +449,7 @@ class Profiler
'hairstyle' => $char['hairStyle'], 'hairstyle' => $char['hairStyle'],
'haircolor' => $char['hairColor'], 'haircolor' => $char['hairColor'],
'features' => $char['facialStyle'], // maybe facetype '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'], 'playedtime' => $char['totaltime'],
'nomodelMask' => ($char['playerFlags'] & 0x400 ? (1 << SLOT_HEAD) : 0) | ($char['playerFlags'] & 0x800 ? (1 << SLOT_BACK) : 0), 'nomodelMask' => ($char['playerFlags'] & 0x400 ? (1 << SLOT_HEAD) : 0) | ($char['playerFlags'] & 0x800 ? (1 << SLOT_BACK) : 0),
'talenttree1' => 0, 'talenttree1' => 0,
@@ -469,7 +469,7 @@ class Profiler
// char is flagged for rename // char is flagged for rename
if ($char['at_login'] & 0x1) 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; $data['renameItr'] = $ri ? ++$ri : 1;
} }
@@ -477,14 +477,14 @@ class Profiler
/* talents + glyphs */ /* 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']); $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']); $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++) for ($i = 0; $i < 2; $i++)
{ {
// talents // talents
for ($j = 0; $j < 3; $j++) 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('', $_); $data['talentbuild'.($i + 1)] .= implode('', $_);
if ($data['activespec'] == $i) if ($data['activespec'] == $i)
$data['talenttree'.($j + 1)] = array_sum($_); $data['talenttree'.($j + 1)] = array_sum($_);
@@ -499,7 +499,7 @@ class Profiler
$gProps[$j] = $g[$i]['g'.$j]; $gProps[$j] = $g[$i]['g'.$j];
if ($gProps) 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); $data['glyphs'.($i + 1)] = implode(':', $gItems);
} }
} }
@@ -532,7 +532,7 @@ class Profiler
// enchantId => multiple spells => multiple items with varying itemlevels, quality, whatevs // enchantId => multiple spells => multiple items with varying itemlevels, quality, whatevs
// cant reasonably get to the castItem from enchantId and slot // 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) foreach ($permEnch as $slot => $eId)
{ {
if (!isset($profSpec[$eId])) if (!isset($profSpec[$eId]))
@@ -557,7 +557,7 @@ class Profiler
/* hunter pets */ /* hunter pets */
/***************/ /***************/
if ($cl == CLASS_HUNTER) if ($cl == ChrClass::HUNTER)
{ {
DB::Aowow()->query('DELETE FROM ?_profiler_pets WHERE `owner` = ?d', $profileId); 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); $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` 'SELECT IFNULL(c3.`id`, IFNULL(c2.`id`, IFNULL(c1.`id`, c.`id`))) AS "entry", p.`type`, c.`family`
FROM ?_pet p FROM ?_pet p
JOIN ?_creature c ON c.`family` = p.`id` JOIN ?_creature c ON c.`family` = p.`id`
LEFT JOIN ?_creature c1 ON c1.`difficultyEntry1` = c.id LEFT JOIN ?_creature c1 ON c1.`difficultyEntry1` = c.`id`
LEFT JOIN ?_creature c2 ON c2.`difficultyEntry2` = c.id LEFT JOIN ?_creature c2 ON c2.`difficultyEntry2` = c.`id`
LEFT JOIN ?_creature c3 ON c3.`difficultyEntry3` = c.id LEFT JOIN ?_creature c3 ON c3.`difficultyEntry3` = c.`id`
WHERE c.`id` = ?d', WHERE c.`id` = ?d',
$petData['entry'] $petData['entry']
); );
@@ -622,7 +622,7 @@ class Profiler
continue; continue;
$r = $racials[$sk['skillId']]; $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['value'] += $r['qty'];
$sk['max'] += $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, `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, `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`)', 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'])) 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)', (`reqClassMask` = 0 OR `reqClassMask` & ?d)',
$profileId, $profileId,
array_column($skills, 'skillId'), array_column($skills, 'skillId'),
1 << ($char['race'] - 1), $ra->toMask(),
1 << ($char['class'] - 1) $cl->toMask()
); );
CLI::write(' ..known spells (vanity pets & mounts)'); CLI::write(' ..known spells (vanity pets & mounts)');
@@ -860,11 +860,11 @@ class Profiler
unset($guild['guildId']); unset($guild['guildId']);
$guild['nameUrl'] = self::urlize($guild['name']); $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 // ranks
DB::Aowow()->query('DELETE FROM ?_profiler_guild_rank WHERE `guildId` = ?d', $guildId); 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) foreach (Util::createSqlBatchInsert($ranks) as $r)
DB::Aowow()->query('INSERT INTO ?_profiler_guild_rank (?#) VALUES '.$r, array_keys(reset($ranks))); 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 // 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('fetching arena team #'.$teamGuid.' from realm #'.$realmId);
CLI::write('writing...'); CLI::write('writing...');

View File

@@ -447,11 +447,11 @@ class CreatureListFilter extends Filter
case 1: // any case 1: // any
return ['AND', ['qse.method', $val, '&'], ['qse.questId', null, '!']]; return ['AND', ['qse.method', $val, '&'], ['qse.questId', null, '!']];
case 2: // alliance 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 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 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 case 5: // none
$this->extraOpts['ct']['h'][] = $field.' = 0'; $this->extraOpts['ct']['h'][] = $field.' = 0';
return [1]; return [1];

View File

@@ -201,11 +201,11 @@ class GameObjectListFilter extends Filter
case 1: // any case 1: // any
return ['AND', ['qse.method', $value, '&'], ['qse.questId', null, '!']]; return ['AND', ['qse.method', $value, '&'], ['qse.questId', null, '!']];
case 2: // alliance only 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 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 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... case 5: // none todo (low): broken, if entry starts and ends quests...
$this->extraOpts['o']['h'][] = $field.' = 0'; $this->extraOpts['o']['h'][] = $field.' = 0';
return [1]; return [1];

View File

@@ -147,7 +147,7 @@ class GuideList extends BaseType
if ($c = $this->getField('classId')) if ($c = $this->getField('classId'))
{ {
$n = Lang::game('cl', $c); $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) if (($s = $this->getField('specId')) > -1)
{ {

View File

@@ -65,14 +65,14 @@ class ItemList extends BaseType
// unify those pesky masks // unify those pesky masks
$_ = &$_curTpl['requiredClass']; $_ = &$_curTpl['requiredClass'];
$_ &= CLASS_MASK_ALL; $_ &= ChrClass::MASK_ALL;
if ($_ < 0 || $_ == CLASS_MASK_ALL) if ($_ < 0 || $_ == ChrClass::MASK_ALL)
$_ = 0; $_ = 0;
unset($_); unset($_);
$_ = &$_curTpl['requiredRace']; $_ = &$_curTpl['requiredRace'];
$_ &= RACE_MASK_ALL; $_ &= ChrRace::MASK_ALL;
if ($_ < 0 || $_ == RACE_MASK_ALL) if ($_ < 0 || $_ == ChrRace::MASK_ALL)
$_ = 0; $_ = 0;
unset($_); unset($_);
@@ -433,7 +433,7 @@ class ItemList extends BaseType
$data[$this->id]['nslots'] = $x; $data[$this->id]['nslots'] = $x;
$_ = $this->curTpl['requiredRace']; $_ = $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'] = $_; $data[$this->id]['reqrace'] = $_;
if ($_ = $this->curTpl['requiredClass']) if ($_ = $this->curTpl['requiredClass'])
@@ -1430,7 +1430,7 @@ class ItemList extends BaseType
return 0.0; return 0.0;
$subClasses = [ITEM_SUBCLASS_MISC_WEAPON]; $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) if ($weaponTypeMask)
for ($i = 0; $i < 21; $i++) for ($i = 0; $i < 21; $i++)
if ($weaponTypeMask & (1 << $i)) if ($weaponTypeMask & (1 << $i))
@@ -1688,7 +1688,7 @@ class ItemList extends BaseType
'subclass' => $subclass, 'subclass' => $subclass,
'subsubclass' => $this->curTpl['subSubClass'], 'subsubclass' => $this->curTpl['subSubClass'],
'heroic' => ($this->curTpl['flags'] & ITEM_FLAG_HEROIC) >> 3, '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'], 'slot' => $this->curTpl['slot'],
'slotbak' => $this->curTpl['slotBak'], 'slotbak' => $this->curTpl['slotBak'],
'level' => $this->curTpl['itemLevel'], 'level' => $this->curTpl['itemLevel'],
@@ -1972,8 +1972,8 @@ class ItemListFilter extends Filter
149 => [parent::CR_CALLBACK, 'cbDropsInInstance', SRC_FLAG_RAID_DROP, 4, ], // dropsinheroic10 [heroicraid-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] 150 => [parent::CR_CALLBACK, 'cbDropsInInstance', SRC_FLAG_RAID_DROP, 8, ], // dropsinheroic25 [heroicraid-any]
151 => [parent::CR_NUMERIC, 'id', NUM_CAST_INT, true ], // id 151 => [parent::CR_NUMERIC, 'id', NUM_CAST_INT, true ], // id
152 => [parent::CR_CALLBACK, 'cbClassRaceSpec', 'requiredClass', CLASS_MASK_ALL], // classspecific [enum] 152 => [parent::CR_CALLBACK, 'cbClassRaceSpec', 'requiredClass', ChrClass::MASK_ALL], // classspecific [enum]
153 => [parent::CR_CALLBACK, 'cbClassRaceSpec', 'requiredRace', RACE_MASK_ALL ], // racespecific [enum] 153 => [parent::CR_CALLBACK, 'cbClassRaceSpec', 'requiredRace', ChrRace::MASK_ALL ], // racespecific [enum]
154 => [parent::CR_FLAG, 'flags', ITEM_FLAG_REFUNDABLE ], // refundable 154 => [parent::CR_FLAG, 'flags', ITEM_FLAG_REFUNDABLE ], // refundable
155 => [parent::CR_FLAG, 'flags', ITEM_FLAG_USABLE_ARENA ], // usableinarenas 155 => [parent::CR_FLAG, 'flags', ITEM_FLAG_USABLE_ARENA ], // usableinarenas
156 => [parent::CR_FLAG, 'flags', ITEM_FLAG_USABLE_SHAPED ], // usablewhenshapeshifted 156 => [parent::CR_FLAG, 'flags', ITEM_FLAG_USABLE_SHAPED ], // usablewhenshapeshifted
@@ -2155,25 +2155,25 @@ class ItemListFilter extends Filter
// side // side
if (isset($_v['si'])) if (isset($_v['si']))
{ {
$ex = [['requiredRace', RACE_MASK_ALL, '&'], RACE_MASK_ALL, '!']; $ex = [['requiredRace', ChrRace::MASK_ALL, '&'], ChrRace::MASK_ALL, '!'];
$notEx = ['OR', ['requiredRace', 0], [['requiredRace', RACE_MASK_ALL, '&'], RACE_MASK_ALL]]; $notEx = ['OR', ['requiredRace', 0], [['requiredRace', ChrRace::MASK_ALL, '&'], ChrRace::MASK_ALL]];
switch ($_v['si']) switch ($_v['si'])
{ {
case 3: 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; break;
case 2: 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; break;
case -2: 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; break;
case 1: 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; break;
case -1: 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; break;
} }
} }
@@ -2545,13 +2545,13 @@ class ItemListFilter extends Filter
$w = 1; $w = 1;
break; break;
case 2: // Alliance 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; break;
case 3: // Horde 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; break;
case 4: // Both 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; break;
default: default:
return false; return false;

View File

@@ -29,17 +29,10 @@ class ItemsetList extends BaseType
// post processing // post processing
foreach ($this->iterate() as &$_curTpl) foreach ($this->iterate() as &$_curTpl)
{ {
$_curTpl['classes'] = []; $_curTpl['classes'] = ChrClass::fromMask($_curTpl['classMask']);
$_curTpl['pieces'] = []; $this->classes = array_merge($this->classes, $_curTpl['classes']);
for ($i = 1; $i < 12; $i++)
{
if ($_curTpl['classMask'] & (1 << ($i - 1)))
{
$this->classes[] = $i;
$_curTpl['classes'][] = $i;
}
}
$_curTpl['pieces'] = [];
for ($i = 1; $i < 10; $i++) for ($i = 1; $i < 10; $i++)
{ {
if ($piece = $_curTpl['item'.$i]) if ($piece = $_curTpl['item'.$i])

View File

@@ -31,7 +31,7 @@ class ProfileList extends BaseType
'classs' => $this->getField('class'), 'classs' => $this->getField('class'),
'gender' => $this->getField('gender'), 'gender' => $this->getField('gender'),
'level' => $this->getField('level'), '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'), 'talenttree1' => $this->getField('talenttree1'),
'talenttree2' => $this->getField('talenttree2'), 'talenttree2' => $this->getField('talenttree2'),
'talenttree3' => $this->getField('talenttree3'), 'talenttree3' => $this->getField('talenttree3'),

View File

@@ -175,7 +175,7 @@ class QuestList extends BaseType
foreach ($this->iterate() as $__) foreach ($this->iterate() as $__)
{ {
if (!(Game::sideByRaceMask($this->curTpl['reqRaceMask']) & $side)) if (!(ChrRace::sideFromMask($this->curTpl['reqRaceMask']) & $side))
continue; continue;
[$series, $first] = DB::Aowow()->SelectRow( [$series, $first] = DB::Aowow()->SelectRow(
@@ -212,7 +212,7 @@ class QuestList extends BaseType
'level' => $this->curTpl['level'], 'level' => $this->curTpl['level'],
'reqlevel' => $this->curTpl['minLevel'], 'reqlevel' => $this->curTpl['minLevel'],
'name' => Lang::unescapeUISequences($this->getField('name', true), Lang::FMT_RAW), 'name' => Lang::unescapeUISequences($this->getField('name', true), Lang::FMT_RAW),
'side' => Game::sideByRaceMask($this->curTpl['reqRaceMask']), 'side' => ChrRace::sideFromMask($this->curTpl['reqRaceMask']),
'wflags' => 0x0, 'wflags' => 0x0,
'xp' => $this->curTpl['rewardXP'] 'xp' => $this->curTpl['rewardXP']
); );
@@ -238,8 +238,8 @@ class QuestList extends BaseType
if ($_ = $this->curTpl['reqClassMask']) if ($_ = $this->curTpl['reqClassMask'])
$data[$this->id]['reqclass'] = $_; $data[$this->id]['reqclass'] = $_;
if ($_ = ($this->curTpl['reqRaceMask'] & RACE_MASK_ALL)) if ($_ = ($this->curTpl['reqRaceMask'] & ChrRace::MASK_ALL))
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'] = $_; $data[$this->id]['reqrace'] = $_;
if ($_ = $this->curTpl['rewardOrReqMoney']) if ($_ = $this->curTpl['rewardOrReqMoney'])
@@ -525,8 +525,8 @@ class QuestListFilter extends Filter
// side // side
if (isset($_v['si'])) if (isset($_v['si']))
{ {
$ex = [['reqRaceMask', RACE_MASK_ALL, '&'], RACE_MASK_ALL, '!']; $ex = [['reqRaceMask', ChrRace::MASK_ALL, '&'], ChrRace::MASK_ALL, '!'];
$notEx = ['OR', ['reqRaceMask', 0], [['reqRaceMask', RACE_MASK_ALL, '&'], RACE_MASK_ALL]]; $notEx = ['OR', ['reqRaceMask', 0], [['reqRaceMask', ChrRace::MASK_ALL, '&'], ChrRace::MASK_ALL]];
switch ($_v['si']) switch ($_v['si'])
{ {
@@ -534,16 +534,16 @@ class QuestListFilter extends Filter
$parts[] = $notEx; $parts[] = $notEx;
break; break;
case SIDE_HORDE: case SIDE_HORDE:
$parts[] = ['OR', $notEx, ['reqRaceMask', RACE_MASK_HORDE, '&']]; $parts[] = ['OR', $notEx, ['reqRaceMask', ChrRace::MASK_HORDE, '&']];
break; break;
case -SIDE_HORDE: case -SIDE_HORDE:
$parts[] = ['AND', $ex, ['reqRaceMask', RACE_MASK_HORDE, '&']]; $parts[] = ['AND', $ex, ['reqRaceMask', ChrRace::MASK_HORDE, '&']];
break; break;
case SIDE_ALLIANCE: case SIDE_ALLIANCE:
$parts[] = ['OR', $notEx, ['reqRaceMask', RACE_MASK_ALLIANCE, '&']]; $parts[] = ['OR', $notEx, ['reqRaceMask', ChrRace::MASK_ALLIANCE, '&']];
break; break;
case -SIDE_ALLIANCE: case -SIDE_ALLIANCE:
$parts[] = ['AND', $ex, ['reqRaceMask', RACE_MASK_ALLIANCE, '&']]; $parts[] = ['AND', $ex, ['reqRaceMask', ChrRace::MASK_ALLIANCE, '&']];
break; break;
} }
} }
@@ -688,11 +688,11 @@ class QuestListFilter extends Filter
$_ = $this->enums[$cr[0]][$cr[1]]; $_ = $this->enums[$cr[0]][$cr[1]];
if ($_ === true) 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) 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($_)) 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; return false;
} }
@@ -704,11 +704,11 @@ class QuestListFilter extends Filter
$_ = $this->enums[$cr[0]][$cr[1]]; $_ = $this->enums[$cr[0]][$cr[1]];
if ($_ === true) 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) 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($_)) 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; return false;
} }

View File

@@ -145,12 +145,12 @@ class SpellList extends BaseType
} }
// set full masks to 0 // set full masks to 0
$_curTpl['reqClassMask'] &= CLASS_MASK_ALL; $_curTpl['reqClassMask'] &= ChrClass::MASK_ALL;
if ($_curTpl['reqClassMask'] == CLASS_MASK_ALL) if ($_curTpl['reqClassMask'] == ChrClass::MASK_ALL)
$_curTpl['reqClassMask'] = 0; $_curTpl['reqClassMask'] = 0;
$_curTpl['reqRaceMask'] &= RACE_MASK_ALL; $_curTpl['reqRaceMask'] &= ChrRace::MASK_ALL;
if ($_curTpl['reqRaceMask'] == RACE_MASK_ALL) if ($_curTpl['reqRaceMask'] == ChrRace::MASK_ALL)
$_curTpl['reqRaceMask'] = 0; $_curTpl['reqRaceMask'] = 0;
// unpack skillLines // unpack skillLines
@@ -2124,15 +2124,11 @@ class SpellList extends BaseType
{ {
if ($addMask & GLOBALINFO_RELATED) if ($addMask & GLOBALINFO_RELATED)
{ {
if ($mask = $this->curTpl['reqClassMask']) foreach (ChrClass::fromMask($this->curTpl['reqClassMask']) as $id)
for ($i = 0; $i < 11; $i++) $data[Type::CHR_CLASS][$id] = $id;
if ($mask & (1 << $i))
$data[Type::CHR_CLASS][$i + 1] = $i + 1;
if ($mask = $this->curTpl['reqRaceMask']) foreach (ChrRace::fromMask($this->curTpl['reqRaceMask']) as $id)
for ($i = 0; $i < 11; $i++) $data[Type::CHR_RACE][$id] = $id;
if ($mask & (1 << $i))
$data[Type::CHR_RACE][$i + 1] = $i + 1;
// play sound effect // play sound effect
for ($i = 1; $i < 4; $i++) for ($i = 1; $i < 4; $i++)
@@ -2477,7 +2473,7 @@ class SpellListFilter extends Filter
// race // race
if (isset($_v['ra'])) 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] // class [list]
if (isset($_v['cl'])) if (isset($_v['cl']))
@@ -2618,11 +2614,11 @@ class SpellListFilter extends Filter
case 1: // yes case 1: // yes
return ['reqRaceMask', 0, '!']; return ['reqRaceMask', 0, '!'];
case 2: // alliance 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 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 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 case 5: // no
return ['reqRaceMask', 0]; return ['reqRaceMask', 0];
default: default:

View File

@@ -425,13 +425,12 @@ class Lang
public static function getClassString(int $classMask, array &$ids = [], int $fmt = self::FMT_HTML) : string 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 ''; return '';
$tmp = []; $tmp = [];
$i = 1;
switch ($fmt) switch ($fmt)
{ {
@@ -449,15 +448,8 @@ class Lang
$br = ''; $br = '';
} }
while ($classMask) foreach (ChrClass::fromMask($classMask) as $c)
{ $tmp[$c] = (!fMod(count($tmp) + 1, 3) ? $br : null).sprintf($base, $c, self::game('cl', $c));
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++;
}
$ids = array_keys($tmp); $ids = array_keys($tmp);
@@ -466,16 +458,15 @@ class Lang
public static function getRaceString(int $raceMask, array &$ids = [], int $fmt = self::FMT_HTML) : string 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 ''; return '';
if (!$raceMask) if (!$raceMask)
return ''; return '';
$tmp = []; $tmp = [];
$i = 1;
switch ($fmt) switch ($fmt)
{ {
@@ -493,21 +484,14 @@ class Lang
$br = ''; $br = '';
} }
if ($raceMask == RACE_MASK_HORDE) if ($raceMask == ChrRace::MASK_HORDE)
return self::game('ra', -2); return self::game('ra', -2);
if ($raceMask == RACE_MASK_ALLIANCE) if ($raceMask == ChrRace::MASK_ALLIANCE)
return self::game('ra', -1); return self::game('ra', -1);
while ($raceMask) foreach (ChrRace::fromMask($raceMask) as $r)
{ $tmp[$r] = (!fMod(count($tmp) + 1, 3) ? $br : null).sprintf($base, $r, self::game('ra', $r));
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++;
}
$ids = array_keys($tmp); $ids = array_keys($tmp);

View File

@@ -1559,7 +1559,7 @@ $lang = array(
'dotSP' => "每个周期的法术强度 +%.2f%%", 'dotAP' => "每个周期的攻击强度 +%.2f%%" 'dotSP' => "每个周期的法术强度 +%.2f%%", 'dotAP' => "每个周期的攻击强度 +%.2f%%"
), ),
'relItems' => array( 'relItems' => array(
'base' => "<small>显示与<b>%s</b>相关的 %s<</small>", 'base' => "<small>显示与<b>%s</b>相关的 %s</small>",
'link' => "", 'link' => "",
'recipes' => '<a href="?items=9.%s">制作物品</a>', 'recipes' => '<a href="?items=9.%s">制作物品</a>',
'crafted' => '<a href="?items&filter=cr=86;crs=%s;crv=0">手工制作物品</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']); $this->addScript([SC_JS_FILE, '?data=zones']);
$infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); $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 $tcClassId = [null, 8, 3, 1, 5, 4, 9, 6, 2, 7, null, 0]; // see TalentCalc.js
@@ -59,12 +59,12 @@ class ClassPage extends GenericPage
$infobox[] = '[tooltip=tooltip_heroclass]'.Lang::game('heroClass').'[/tooltip]'; $infobox[] = '[tooltip=tooltip_heroclass]'.Lang::game('heroClass').'[/tooltip]';
// resource // resource
if ($this->typeId == 11) // special Druid case if ($cl == ChrClass::DRUID) // special Druid case
$infobox[] = Lang::game('resources').Lang::main('colon'). $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=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=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]'; '[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]'; $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]'; $infobox[] = Lang::game('resource').Lang::main('colon').'[span]'.Util::ucFirst(Lang::spell('powerTypes', $this->subject->getField('powerType'))).'[/span]';
@@ -118,7 +118,7 @@ class ClassPage extends GenericPage
[['s.cuFlags', (SPELL_CU_TRIGGERED | CUSTOM_EXCLUDE_FOR_LISTVIEW), '&'], 0], [['s.cuFlags', (SPELL_CU_TRIGGERED | CUSTOM_EXCLUDE_FOR_LISTVIEW), '&'], 0],
[ [
'OR', 'OR',
['s.reqClassMask', $_mask, '&'], // Glyphs, Proficiencies ['s.reqClassMask', $cl->toMask(), '&'], // Glyphs, Proficiencies
['s.skillLine1', $this->subject->getField('skills')], // Abilities / Talents ['s.skillLine1', $this->subject->getField('skills')], // Abilities / Talents
['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->subject->getField('skills')]] ['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->subject->getField('skills')]]
], ],
@@ -150,8 +150,8 @@ class ClassPage extends GenericPage
// Tab: Items (grouped) // Tab: Items (grouped)
$conditions = array( $conditions = array(
['requiredClass', 0, '>'], ['requiredClass', 0, '>'],
['requiredClass', $_mask, '&'], ['requiredClass', $cl->toMask(), '&'],
[['requiredClass', CLASS_MASK_ALL, '&'], CLASS_MASK_ALL, '!'], [['requiredClass', ChrClass::MASK_ALL, '&'], ChrClass::MASK_ALL, '!'],
['itemset', 0], // hmm, do or dont..? ['itemset', 0], // hmm, do or dont..?
Cfg::get('SQL_LIMIT_NONE') Cfg::get('SQL_LIMIT_NONE')
); );
@@ -180,8 +180,8 @@ class ClassPage extends GenericPage
// Tab: Quests // Tab: Quests
$conditions = array( $conditions = array(
['reqClassMask', $_mask, '&'], ['reqClassMask', $cl->toMask(), '&'],
[['reqClassMask', CLASS_MASK_ALL, '&'], CLASS_MASK_ALL, '!'] [['reqClassMask', ChrClass::MASK_ALL, '&'], ChrClass::MASK_ALL, '!']
); );
$quests = new QuestList($conditions); $quests = new QuestList($conditions);
@@ -196,7 +196,7 @@ class ClassPage extends GenericPage
} }
// Tab: Itemsets // Tab: Itemsets
$sets = new ItemsetList(array(['classMask', $_mask, '&'])); $sets = new ItemsetList(array(['classMask', $cl->toMask(), '&']));
if (!$sets->error) if (!$sets->error)
{ {
$this->extendGlobalData($sets->getJSGlobals(GLOBALINFO_SELF)); $this->extendGlobalData($sets->getJSGlobals(GLOBALINFO_SELF));
@@ -227,7 +227,7 @@ class ClassPage extends GenericPage
} }
// Tab: Races // Tab: Races
$races = new CharRaceList(array(['classMask', $_mask, '&'])); $races = new CharRaceList(array(['classMask', $cl->toMask(), '&']));
if (!$races->error) if (!$races->error)
$this->lvTabs[] = [CharRaceList::$brickFile, ['data' => array_values($races->getListviewData())]]; $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) if ($this->subject->getField('cuFlags') & EMOTE_CU_MISSING_CMD)
$text .= Lang::emote('noCommand').'[br][br]'; $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]'; $text .= '[h3]'.Lang::emote('aliases').'[/h3][ul]';
foreach ($aliasses as $a) foreach ($aliasses as $a)
@@ -161,7 +161,7 @@ class EmotePage extends GenericPage
} }
// tab: sound // 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)])); $sounds = new SoundList(array(['id', array_keys($em)]));
if (!$sounds->error) if (!$sounds->error)

View File

@@ -485,7 +485,7 @@ class GuidePage extends GenericPage
// sanitize: spec / class // sanitize: spec / class
if ($this->_post['category'] == 1) // Classes 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; $this->_post['classId'] = 0;
if (!in_array($this->_post['specId'], [-1, 0, 1, 2])) 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'); $_minLevel = $this->subject->getField('minLevel');
$_flags = $this->subject->getField('flags'); $_flags = $this->subject->getField('flags');
$_specialFlags = $this->subject->getField('specialFlags'); $_specialFlags = $this->subject->getField('specialFlags');
$_side = Game::sideByRaceMask($this->subject->getField('reqRaceMask')); $_side = ChrRace::sideFromMask($this->subject->getField('reqRaceMask'));
/***********/ /***********/
/* Infobox */ /* Infobox */
@@ -300,7 +300,7 @@ class QuestPage extends GenericPage
$n = Util::localizedString($_, 'name'); $n = Util::localizedString($_, 'name');
array_unshift($chain, array( array_unshift($chain, array(
array( array(
'side' => Game::sideByRaceMask($_['reqRaceMask']), 'side' => ChrRace::sideFromMask($_['reqRaceMask']),
'typeStr' => Type::getFileString(Type::QUEST), 'typeStr' => Type::getFileString(Type::QUEST),
'typeId' => $_['typeId'], 'typeId' => $_['typeId'],
'name' => Util::htmlEscape(Lang::trimTextClean($n, 40)), 'name' => Util::htmlEscape(Lang::trimTextClean($n, 40)),
@@ -320,7 +320,7 @@ class QuestPage extends GenericPage
$n = Util::localizedString($_, 'name'); $n = Util::localizedString($_, 'name');
array_push($chain, array( array_push($chain, array(
array( array(
'side' => Game::sideByRaceMask($_['reqRaceMask']), 'side' => ChrRace::sideFromMask($_['reqRaceMask']),
'typeStr' => Type::getFileString(Type::QUEST), 'typeStr' => Type::getFileString(Type::QUEST),
'typeId' => $_['typeId'], 'typeId' => $_['typeId'],
'name' => Util::htmlEscape(Lang::trimTextClean($n, 40)), 'name' => Util::htmlEscape(Lang::trimTextClean($n, 40)),
@@ -346,7 +346,7 @@ class QuestPage extends GenericPage
{ {
$n = $list->getField('name', true); $n = $list->getField('name', true);
$chain[] = array(array( $chain[] = array(array(
'side' => Game::sideByRaceMask($list->getField('reqRaceMask')), 'side' => ChrRace::sideFromMask($list->getField('reqRaceMask')),
'typeStr' => Type::getFileString(Type::QUEST), 'typeStr' => Type::getFileString(Type::QUEST),
'typeId' => $id, 'typeId' => $id,
'name' => Util::htmlEscape(Lang::trimTextClean($n, 40)) 'name' => Util::htmlEscape(Lang::trimTextClean($n, 40))

View File

@@ -44,7 +44,7 @@ class RacePage extends GenericPage
protected function generateContent() protected function generateContent()
{ {
$infobox = []; $infobox = [];
$_mask = 1 << ($this->typeId - 1); $ra = ChrRace::from($this->typeId);
$mountVendors = array( // race => [starter, argent tournament] $mountVendors = array( // race => [starter, argent tournament]
null, [384, 33307], [3362, 33553], [1261, 33310], null, [384, 33307], [3362, 33553], [1261, 33310],
[4730, 33653], [4731, 33555], [3685, 33556], [7955, 33650], [4730, 33653], [4731, 33555], [3685, 33556], [7955, 33650],
@@ -59,7 +59,7 @@ class RacePage extends GenericPage
// side // side
if ($_ = $this->subject->getField('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 // faction
if ($_ = $this->subject->getField('factionId')) if ($_ = $this->subject->getField('factionId'))
@@ -90,10 +90,7 @@ class RacePage extends GenericPage
$this->infobox = '[ul][li]'.implode('[/li][li]', $infobox).'[/li][/ul]'; $this->infobox = '[ul][li]'.implode('[/li][li]', $infobox).'[/li][/ul]';
$this->expansion = Util::$expansionString[$this->subject->getField('expansion')]; $this->expansion = Util::$expansionString[$this->subject->getField('expansion')];
$this->headIcons = array( $this->headIcons = ['race_'.$ra->json().'_male', 'race_'.$ra->json().'_female'];
'race_'.strtolower($this->subject->getField('fileString')).'_male',
'race_'.strtolower($this->subject->getField('fileString')).'_female'
);
$this->redButtons = array( $this->redButtons = array(
BUTTON_WOWHEAD => true, BUTTON_WOWHEAD => true,
BUTTON_LINKS => ['type' => $this->type, 'typeId' => $this->typeId] BUTTON_LINKS => ['type' => $this->type, 'typeId' => $this->typeId]
@@ -105,7 +102,7 @@ class RacePage extends GenericPage
/**************/ /**************/
// Classes // Classes
$classes = new CharClassList(array(['racemask', $_mask, '&'])); $classes = new CharClassList(array(['racemask', $ra->toMask(), '&']));
if (!$classes->error) if (!$classes->error)
{ {
$this->extendGlobalData($classes->getJSGlobals()); $this->extendGlobalData($classes->getJSGlobals());
@@ -115,7 +112,7 @@ class RacePage extends GenericPage
// Tongues // Tongues
$conditions = array( $conditions = array(
['typeCat', -11], // proficiencies ['typeCat', -11], // proficiencies
['reqRaceMask', $_mask, '&'] // only languages are race-restricted ['reqRaceMask', $ra->toMask(), '&'] // only languages are race-restricted
); );
$tongues = new SpellList($conditions); $tongues = new SpellList($conditions);
@@ -133,7 +130,7 @@ class RacePage extends GenericPage
// Racials // Racials
$conditions = array( $conditions = array(
['typeCat', -4], // racial traits ['typeCat', -4], // racial traits
['reqRaceMask', $_mask, '&'] ['reqRaceMask', $ra->toMask(), '&']
); );
$racials = new SpellList($conditions); $racials = new SpellList($conditions);
@@ -150,9 +147,9 @@ class RacePage extends GenericPage
// Quests // Quests
$conditions = array( $conditions = array(
['reqRaceMask', $_mask, '&'], ['reqRaceMask', $ra->toMask(), '&'],
[['reqRaceMask', RACE_MASK_HORDE, '&'], RACE_MASK_HORDE, '!'], [['reqRaceMask', ChrRace::MASK_HORDE, '&'], ChrRace::MASK_HORDE, '!'],
[['reqRaceMask', RACE_MASK_ALLIANCE, '&'], RACE_MASK_ALLIANCE, '!'] [['reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ChrRace::MASK_ALLIANCE, '!']
); );
$quests = new QuestList($conditions); $quests = new QuestList($conditions);
@@ -164,7 +161,7 @@ class RacePage extends GenericPage
// Mounts // Mounts
// ok, this sucks, but i rather hardcode the trainer, than fetch items by namepart // 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( $conditions = array(
['i.id', $items], ['i.id', $items],
@@ -185,7 +182,7 @@ class RacePage extends GenericPage
} }
// Sounds // 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)])); $sounds = new SoundList(array(['id', array_keys($vo)]));
if (!$sounds->error) 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) if ($this->searchMask & SEARCH_TYPE_REGULAR)
$this->extendGlobalData($abilities->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); $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']; $vis = ['level', 'schools'];
if ($abilities->hasSetFields('reagent1', 'reagent2', 'reagent3', 'reagent4', 'reagent5', 'reagent6', 'reagent7', 'reagent8')) if ($abilities->hasSetFields('reagent1', 'reagent2', 'reagent3', 'reagent4', 'reagent5', 'reagent6', 'reagent7', 'reagent8'))
$vis[] = 'reagents'; $vis[] = 'reagents';
$vis[] = $multiClass > 1 ? 'classes' : 'singleclass'; $vis[] = count(ChrClass::fromMask($d['reqclass'] ?? 0)) > 1 ? 'classes' : 'singleclass';
$osInfo = [Type::SPELL, ' (Ability)', $abilities->getMatches(), [], []]; $osInfo = [Type::SPELL, ' (Ability)', $abilities->getMatches(), [], []];
$result = array( $result = array(

View File

@@ -312,12 +312,7 @@ class SkillPage extends GenericPage
} }
// tab: related classes (apply classes from [spells]) // tab: related classes (apply classes from [spells])
$class = []; if ($class = ChrClass::fromMask($reqClass))
for ($i = 0; $i < 11; $i++)
if ($reqClass & (1 << $i))
$class[] = $i + 1;
if ($class)
{ {
$classes = new CharClassList(array(['id', $class])); $classes = new CharClassList(array(['id', $class]));
if (!$classes->error) if (!$classes->error)
@@ -325,12 +320,7 @@ class SkillPage extends GenericPage
} }
// tab: related races (apply races from [spells]) // tab: related races (apply races from [spells])
$race = []; if ($race = ChrRace::fromMask($reqRace))
for ($i = 0; $i < 12; $i++)
if ($reqRace & (1 << $i))
$race[] = $i + 1;
if ($race)
{ {
$races = new CharRaceList(array(['id', $race])); $races = new CharRaceList(array(['id', $race]));
if (!$races->error) if (!$races->error)

View File

@@ -91,7 +91,7 @@ class SoundPage extends GenericPage
} }
// get full path ingame for sound (workaround for missing PlaySoundKit()) // 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->map = $map;
$this->headIcons = [$this->subject->getField('iconString')]; $this->headIcons = [$this->subject->getField('iconString')];
@@ -114,31 +114,21 @@ class SoundPage extends GenericPage
// tab: Spells // tab: Spells
// skipping (always empty): ready, castertargeting, casterstate, targetstate // skipping (always empty): ready, castertargeting, casterstate, targetstate
$displayIds = DB::Aowow()->selectCol(' $displayIds = DB::Aowow()->selectCol(
SELECT id FROM ?_spell_sounds WHERE 'SELECT `id`
animation = ?d OR FROM ?_spell_sounds
precast = ?d OR WHERE `animation` = ?d OR `precast` = ?d OR `cast` = ?d OR `impact` = ?d OR `state` = ?d OR
cast = ?d OR `statedone` = ?d OR `channel` = ?d OR `casterimpact` = ?d OR `targetimpact` = ?d OR `missiletargeting` = ?d OR
impact = ?d OR `instantarea` = ?d OR `persistentarea` = ?d OR `missile` = ?d OR `impactarea` = ?d',
state = ?d OR $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
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(' $seMiscValues = DB::Aowow()->selectCol(
SELECT `id` FROM ?_screeneffect_sounds WHERE 'SELECT `id`
`ambienceDay` = ?d OR FROM ?_screeneffect_sounds
`ambienceNight` = ?d OR WHERE `ambienceDay` = ?d OR `ambienceNight` = ?d OR `musicDay` = ?d OR `musicNight` = ?d',
`musicDay` = ?d OR $this->typeId, $this->typeId, $this->typeId, $this->typeId
`musicNight` = ?d );
', $this->typeId, $this->typeId, $this->typeId, $this->typeId);
$cnd = array( $cnd = array(
'OR', 'OR',
@@ -168,27 +158,19 @@ class SoundPage extends GenericPage
// tab: Items // tab: Items
$subClasses = []; $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++) for ($i = 0; $i <= 20; $i++)
if ($subClassMask & (1 << $i)) if ($subClassMask & (1 << $i))
$subClasses[] = $i; $subClasses[] = $i;
$itemIds = DB::Aowow()->selectCol(' $itemIds = DB::Aowow()->selectCol(
SELECT 'SELECT id
id FROM ?_items
FROM WHERE `pickUpSoundId` = ?d OR `dropDownSoundId` = ?d OR `sheatheSoundId` = ?d OR `unsheatheSoundId` = ?d
?_items { OR `spellVisualId` IN (?a) }
WHERE { OR (IF (`soundOverrideSubclass` > 0, `soundOverrideSubclass`, `subclass`) IN (?a) AND `class` = ?d) }',
{spellVisualId IN (?a) OR } $this->typeId, $this->typeId, $this->typeId, $this->typeId, $displayIds ?: DBSIMPLE_SKIP, $subClasses ?: DBSIMPLE_SKIP, ITEM_CLASS_WEAPON
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);
if ($itemIds) if ($itemIds)
{ {
$items = new ItemList(array(['id', $itemIds])); $items = new ItemList(array(['id', $itemIds]));
@@ -201,7 +183,7 @@ class SoundPage extends GenericPage
// tab: Zones // 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')])); $zones = new ZoneList(array(['id', array_column($zoneIds, 'id')]));
if (!$zones->error) if (!$zones->error)
@@ -265,7 +247,7 @@ class SoundPage extends GenericPage
// tab: Races (VocalUISounds (containing error voice overs)) // 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])); $races = new CharRaceList(array(['id', $vo]));
if (!$races->error) if (!$races->error)
@@ -277,7 +259,7 @@ class SoundPage extends GenericPage
// tab: Emotes (EmotesTextSound (containing emote audio)) // 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])); $races = new EmoteList(array(['id', $em]));
if (!$races->error) 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...? // can objects or areatrigger play sound...?
if ($goosp = SmartAI::getOwnerOfSoundPlayed($this->typeId, Type::NPC)) if ($goosp = SmartAI::getOwnerOfSoundPlayed($this->typeId, Type::NPC))
@@ -298,35 +280,20 @@ class SoundPage extends GenericPage
// tab: NPC (dialogues...?, generic creature sound) // tab: NPC (dialogues...?, generic creature sound)
// skipping (always empty): transforms, footsteps // skipping (always empty): transforms, footsteps
$displayIds = DB::Aowow()->selectCol(' $displayIds = DB::Aowow()->selectCol(
SELECT id FROM ?_creature_sounds WHERE 'SELECT `id`
greeting = ?d OR FROM ?_creature_sounds
farewell = ?d OR WHERE `greeting` = ?d OR `farewell` = ?d OR `angry` = ?d OR `exertion` = ?d OR `exertioncritical` = ?d OR
angry = ?d OR `injury` = ?d OR `injurycritical` = ?d OR `death` = ?d OR `stun` = ?d OR `stand` = ?d OR
exertion = ?d OR `aggro` = ?d OR `wingflap` = ?d OR `wingglide` = ?d OR `alert` = ?d OR `fidget` = ?d OR
exertioncritical = ?d OR `customattack` = ?d OR `loop` = ?d OR `jumpstart` = ?d OR `jumpend` = ?d OR `petattack` = ?d OR
injury = ?d OR `petorder` = ?d OR `petdismiss` = ?d OR `birth` = ?d OR `spellcast` = ?d OR `submerge` = ?d OR `submerged` = ?d',
injurycritical = ?d OR $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId,
death = ?d OR $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId,
stun = ?d OR $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId,
stand = ?d OR $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId,
aggro = ?d OR $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId
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 // broadcast_text <-> creature_text
if ($creatureIds || $displayIds) 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) $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); }, $ratings);
$mods = DB::Aowow()->selectCol('SELECT idx - 1 AS ARRAY_KEY, ratio FROM dbc_gtoctclasscombatratingscalar WHERE idx IN (?a)', $offsets); $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']) if ($set['classMask'])
{ {
$setOut['reqclass'] = $set['classMask']; $setOut['reqclass'] = $set['classMask'];
$setOut['classes'] = []; $setOut['classes'] = ChrClass::fromMask($set['classMask']);
for ($i = 0; $i < 12; $i++)
if ($set['classMask'] & (1 << $i))
$setOut['classes'][] = $i + 1;
} }
if ($set['contentGroup']) 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) // two cases where the spell is unrestricted but the castitem has class restriction (too lazy to formulate ruleset)
if ($id == 66906) // Argent Charger if ($id == 66906) // Argent Charger
$data['reqclass'] = CLASS_PALADIN; $data['reqclass'] = ChrClass::PALADIN->toMask();
else if ($id == 54729) // Winged Steed of the Ebon Blade 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 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 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; 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; continue;
if (!isset($sumArr[$i+1][$j+1])) if (!isset($sumArr[$ra->value][$cl->value]))
$sumArr[$i+1][$j+1] = 1; $sumArr[$ra->value][$cl->value] = 1;
else 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); Lang::load($loc);
// TalentCalc // 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); set_time_limit(20);
$file = 'datasets/'.$loc->json().'/talents-'.$i; $file = 'datasets/'.$loc->json().'/talents-'.$class->value;
$toFile = '$WowheadTalentCalculator.registerClass('.$i.', '.Util::toJSON($this->buildTree(1 << ($i - 1))).')'; $toFile = '$WowheadTalentCalculator.registerClass('.$class->value.', '.Util::toJSON($this->buildTree($class->toMask())).')';
if (!CLISetup::writeFile($file, $toFile)) if (!CLISetup::writeFile($file, $toFile))
$this->success = false; $this->success = false;

View File

@@ -19,47 +19,84 @@ CLISetup::registerSetup("build", new class extends SetupScript
private const ICON_SIZE = 36; // px private const ICON_SIZE = 36; // px
private $filenames = ['icons', 'warrior', 'paladin', 'hunter', 'rogue', 'priest', 'deathknight', 'shaman', 'mage', 'warlock', null, 'druid'];
public function generate() : bool public function generate() : bool
{ {
foreach ($this->filenames as $k => $v) /***************/
{ /* Hunter Pets */
if (!$v) /***************/
continue;
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); set_time_limit(10);
for ($tree = 0; $tree < 3; $tree++) for ($tabIdx = 0; $tabIdx < 3; $tabIdx++)
{
$outFile = 'static/images/wow/talents/icons/'.$class->json().'_'.($tabIdx + 1).'.jpg';
if ($tex = $this->compileTexture('classMask', $class->toMask(), $tabIdx))
{
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;
}
}
return $this->success;
}
private function compileTexture(string $ttField, int $searchMask, int $tabIdx) : ?GDImage
{ {
$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( $icons = DB::Aowow()->SelectCol(
'SELECT ic.name AS iconString 'SELECT ic.`name` AS "iconString"
FROM ?_icons ic FROM ?_icons ic
JOIN ?_spell s ON s.iconId = ic.id JOIN ?_spell s ON s.`iconId` = ic.`id`
JOIN dbc_talent t ON t.rank1 = s.id JOIN dbc_talent t ON t.`rank1` = s.`id`
JOIN dbc_talenttab tt ON tt.id = t.tabId JOIN dbc_talenttab tt ON tt.`id` = t.`tabId`
WHERE tt.?# = ?d AND tt.tabNumber = ?d WHERE tt.?# = ?d AND tt.`tabNumber` = ?d
ORDER BY t.row, t.column ASC, s.id DESC', ORDER BY t.`row`, t.`column` ASC, s.`id` DESC',
$what, $set, $subset); $ttField, $searchMask, $tabIdx);
if (empty($icons)) if (empty($icons))
{ {
CLI::write('[talenticons] - query for '.$v.' tree: '.$k.' returned empty', CLI::LOG_ERROR); CLI::write('[talenticons] - query for '.$ttField.': '.$searchMask.' on idx: '.$tabIdx.' returned empty', CLI::LOG_ERROR);
$this->success = false; return null;
continue;
} }
$res = imageCreateTrueColor(count($icons) * self::ICON_SIZE, 2 * self::ICON_SIZE); $res = imageCreateTrueColor(count($icons) * self::ICON_SIZE, 2 * self::ICON_SIZE);
if (!$res) if (!$res)
{ {
$this->success = false;
CLI::write('[talenticons] - image resource not created', CLI::LOG_ERROR); CLI::write('[talenticons] - image resource not created', CLI::LOG_ERROR);
continue; return null;
} }
for ($i = 0; $i < count($icons); $i++) for ($i = 0; $i < count($icons); $i++)
@@ -68,8 +105,7 @@ CLISetup::registerSetup("build", new class extends SetupScript
if (!file_exists($imgFile)) if (!file_exists($imgFile))
{ {
CLI::write('[talenticons] - raw image '.CLI::bold($imgFile). ' not found', CLI::LOG_ERROR); CLI::write('[talenticons] - raw image '.CLI::bold($imgFile). ' not found', CLI::LOG_ERROR);
$this->success = false; return null;
break;
} }
$im = imagecreatefromjpeg($imgFile); $im = imagecreatefromjpeg($imgFile);
@@ -90,17 +126,7 @@ CLISetup::registerSetup("build", new class extends SetupScript
imagecopymerge($res, $im, $i * self::ICON_SIZE, self::ICON_SIZE, 0, 0, imageSX($im), imageSY($im), 100); imagecopymerge($res, $im, $i * self::ICON_SIZE, self::ICON_SIZE, 0, 0, imageSX($im), imageSY($im), 100);
} }
if (@imagejpeg($res, $outFile)) return $res;
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;
} }
}); });

View File

@@ -21,22 +21,37 @@ CLISetup::registerSetup("sql", new class extends SetupScript
{ {
DB::Aowow()->query('TRUNCATE ?_classes'); 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 // 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); Util::arraySumByKey($classes, $races);
// add skills // 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) foreach ($skills as $classId => $skillStr)
$classes[$classId]['skills'] = $skillStr; $classes[$classId]['skills'] = $skillStr;
// add weaponTypeMask & armorTypeMask // add weaponTypeMask & armorTypeMask
foreach ($classes as $id => &$data) 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); $mask = 1 << ($id - 1);
$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); $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) foreach ($classes as $cl)

View File

@@ -151,7 +151,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript
return $tag; return $tag;
// try arena set // 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 $this->tagsByItemlevel[$item['ItemLevel']] ?? 0;
return 0; return 0;
@@ -163,11 +163,11 @@ CLISetup::registerSetup("sql", new class extends SetupScript
foreach ($items as $item) foreach ($items as $item)
$data['item'.$i++] = $item['entry']; $data['item'.$i++] = $item['entry'];
$mask = CLASS_MASK_ALL; $mask = ChrClass::MASK_ALL;
foreach ($items as $item) foreach ($items as $item)
$mask &= $item['AllowableClass']; $mask &= $item['AllowableClass'];
if ($mask != CLASS_MASK_ALL) if ($mask != ChrClass::MASK_ALL)
$data['classMask'] = $mask; $data['classMask'] = $mask;
$iLvl = array_column($items, 'ItemLevel'); $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('TRUNCATE ?_races');
DB::Aowow()->query( DB::Aowow()->query(
'INSERT INTO ?_races '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' FROM dbc_chrraces'
); );
// add classMask // 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 // 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); $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 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` JOIN item_template it ON it.`entry` = n.`item`
GROUP BY `item`', GROUP BY `item`',
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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($quests, 'zone'))); $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 LEFT JOIN item_template it ON it.`entry` = mlt.`Item` AND mlt.`Reference` <= 0
WHERE qta.`RewardMailTemplateId` > 0 WHERE qta.`RewardMailTemplateId` > 0
GROUP BY ARRAY_KEY', 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'))); $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 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 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`', GROUP BY `spell`',
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,
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) 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` '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 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`', 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) if (!$quests)

View File

@@ -453,9 +453,9 @@ CLISetup::registerSetup("sql", new class extends SetupScript
CLI::write('[spell] - misc fixups & icons'); CLI::write('[spell] - misc fixups & icons');
// FU [FixUps] // 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', ChrRace::DRAENEI->value, 760); // Draenei Racials
DB::Aowow()->query('UPDATE ?_spell SET `reqRaceMask` = ?d WHERE `skillLine1` = ?d', RACE_BLOODELF, 756); // Bloodelf 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', CLASS_MAGE, 30449); // Mage - Spellsteal DB::Aowow()->query('UPDATE ?_spell SET `reqClassMask` = ?d WHERE `id` = ?d', ChrClass::MAGE->value, 30449); // Mage - Spellsteal
// triggered by spell // triggered by spell
DB::Aowow()->query( 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) (s.attributes0 = 0x20000000 AND s.attributes3 = 0x10000000) -- Master Demonologist (FamilyId = 0)
)', CUSTOM_EXCLUDE_FOR_LISTVIEW); )', CUSTOM_EXCLUDE_FOR_LISTVIEW);
for ($i = 0; (1 << $i) < CLASS_MASK_ALL; $i++) foreach (ChrClass::cases() as $cl)
if ((1 << $i) & CLASS_MASK_ALL)
DB::Aowow()->query( DB::Aowow()->query(
'UPDATE ?_spell s, dbc_skillline sl, dbc_skillraceclassinfo srci 'UPDATE ?_spell s, dbc_skillline sl, dbc_skillraceclassinfo srci
SET s.reqClassMask = srci.classMask 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 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', srci.`skillline` <> 769 AND srci.`skillline` = sl.`id` AND srci.`flags` & 0x90 AND srci.`classMask` & ?d',
1 << $i); $cl->toMask()
);
// secondary Skills (9) // 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); 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']) if ($data['eventEntry'])
DB::Aowow()->query('UPDATE ?_titles SET `eventId` = ?d WHERE `id` = ?d', $data['eventEntry'], $tId); 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) if ($side == SIDE_BOTH)
continue; continue;