Setup/Scripts

* restructure setup to allow for self contained setup steps to self register (just the sql for now)
 * should ease adding new scripts in future
This commit is contained in:
Sarjuuk
2019-07-31 23:25:44 +02:00
parent 163e3d82b0
commit ccef11323b
51 changed files with 5345 additions and 4964 deletions

View File

@@ -7,22 +7,21 @@ if (!CLI)
die('not in cli mode');
/* deps:
* dbc_achievement
* disables
*/
// Higher Learning - item rewarded through gossip
$customData = array(
1956 => ['itemExtra' => 44738]
);
$reqDBC = ['achievement_category', 'achievement', 'spellicon'];
function achievement(array $ids = [])
SqlGen::register(new class extends SetupScript
{
if ($ids)
DB::Aowow()->query('DELETE FROM ?_achievement WHERE id IN (?a)', $ids);
else
use TrCustomData;
protected $command = 'achievement';
protected $tblDependancyAowow = ['icons'];
protected $tblDependancyTC = ['dbc_achievement', 'disables'];
protected $dbcSourceFiles = ['achievement_category', 'achievement', 'spellicon'];
private $customData = array(
1956 => ['itemExtra' => 44738] // Higher Learning - item rewarded through gossip
);
public function generate(array $ids = []) : bool
{
DB::Aowow()->query('
REPLACE INTO
@@ -55,50 +54,51 @@ function achievement(array $ids = [])
dbc_spellicon si ON si.id = a.iconId
LEFT JOIN
?_icons i ON LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1)) = i.name
');
}
{ WHERE a.id IN (?a) }
', $ids ?: DBSIMPLE_SKIP);
// serverside achievements
$serverAchievements = DB::World()->select('SELECT ID, IF(requiredFaction = -1, 3, IF(requiredFaction = 0, 2, 1)) AS "faction", mapID, points, flags, count, refAchievement FROM achievement_dbc{ WHERE id IN (?a)}',
$ids ?: DBSIMPLE_SKIP
);
foreach ($serverAchievements as $sa)
DB::Aowow()->query('REPLACE INTO ?_achievement (id, faction, map, points, flags, reqCriteriaCount, refAchievement, cuFlags, name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8) VALUES (?d, ?d, ?d, ?d, ?d, ?d, ?d, ?d, ?, ?, ?, ?, ?, ?)',
$sa['ID'], $sa['faction'], $sa['mapID'], $sa['points'], $sa['flags'], $sa['count'], $sa['refAchievement'], CUSTOM_SERVERSIDE,
'Serverside - #'.$sa['ID'], 'Serverside - #'.$sa['ID'], 'Serverside - #'.$sa['ID'], 'Serverside - #'.$sa['ID'], 'Serverside - #'.$sa['ID'], 'Serverside - #'.$sa['ID']
// serverside achievements
$serverAchievements = DB::World()->select('SELECT ID, IF(requiredFaction = -1, 3, IF(requiredFaction = 0, 2, 1)) AS "faction", mapID, points, flags, count, refAchievement FROM achievement_dbc{ WHERE id IN (?a)}',
$ids ?: DBSIMPLE_SKIP
);
if ($ids)
return true;
// create chain of achievements
$chainIdx = 0;
$parents = DB::Aowow()->selectCol('SELECT a.id FROM dbc_achievement a JOIN dbc_achievement b ON b.previous = a.id WHERE a.previous = 0');
foreach ($parents as $chainId => $next)
{
$tree = [null, $next];
while ($next = DB::Aowow()->selectCell('SELECT id FROM dbc_achievement WHERE previous = ?d', $next))
$tree[] = $next;
foreach ($tree as $idx => $aId)
{
if (!$aId)
continue;
DB::Aowow()->query('UPDATE ?_achievement SET cuFlags = cuFlags | ?d, chainId = ?d, chainPos = ?d WHERE id = ?d',
$idx == 1 ? ACHIEVEMENT_CU_FIRST_SERIES : (count($tree) == $idx + 1 ? ACHIEVEMENT_CU_LAST_SERIES : 0),
$chainId + 1,
$idx,
$aId
foreach ($serverAchievements as $sa)
DB::Aowow()->query('REPLACE INTO ?_achievement (id, faction, map, points, flags, reqCriteriaCount, refAchievement, cuFlags, name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8) VALUES (?d, ?d, ?d, ?d, ?d, ?d, ?d, ?d, ?, ?, ?, ?, ?, ?)',
$sa['ID'], $sa['faction'], $sa['mapID'], $sa['points'], $sa['flags'], $sa['count'], $sa['refAchievement'], CUSTOM_SERVERSIDE,
'Serverside - #'.$sa['ID'], 'Serverside - #'.$sa['ID'], 'Serverside - #'.$sa['ID'], 'Serverside - #'.$sa['ID'], 'Serverside - #'.$sa['ID'], 'Serverside - #'.$sa['ID']
);
if ($ids)
return true;
// create chain of achievements
$chainIdx = 0;
$parents = DB::Aowow()->selectCol('SELECT a.id FROM dbc_achievement a JOIN dbc_achievement b ON b.previous = a.id WHERE a.previous = 0');
foreach ($parents as $chainId => $next)
{
$tree = [null, $next];
while ($next = DB::Aowow()->selectCell('SELECT id FROM dbc_achievement WHERE previous = ?d', $next))
$tree[] = $next;
foreach ($tree as $idx => $aId)
{
if (!$aId)
continue;
DB::Aowow()->query('UPDATE ?_achievement SET cuFlags = cuFlags | ?d, chainId = ?d, chainPos = ?d WHERE id = ?d',
$idx == 1 ? ACHIEVEMENT_CU_FIRST_SERIES : (count($tree) == $idx + 1 ? ACHIEVEMENT_CU_LAST_SERIES : 0),
$chainId + 1,
$idx,
$aId
);
}
}
// apply disables
if ($criteria = DB::World()->selectCol('SELECT entry FROM disables WHERE sourceType = 4'))
DB::Aowow()->query('UPDATE aowow_achievement a JOIN aowow_achievementcriteria ac ON a.id = ac.refAchievementId SET a.cuFlags = ?d WHERE ac.id IN (?a)', CUSTOM_DISABLED, $criteria);
return true;
}
// apply disables
if ($criteria = DB::World()->selectCol('SELECT entry FROM disables WHERE sourceType = 4'))
DB::Aowow()->query('UPDATE aowow_achievement a JOIN aowow_achievementcriteria ac ON a.id = ac.refAchievementId SET a.cuFlags = ?d WHERE ac.id IN (?a)', CUSTOM_DISABLED, $criteria);
return true;
}
});
?>

View File

@@ -0,0 +1,18 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
if (!CLI)
die('not in cli mode');
SqlGen::register(new class extends SetupScript
{
use TrDBCcopy;
protected $command = 'achievementcategory';
protected $dbcSourceFiles = ['achievement_category'];
});
?>

View File

@@ -0,0 +1,18 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
if (!CLI)
die('not in cli mode');
SqlGen::register(new class extends SetupScript
{
use TrDBCcopy;
protected $command = 'achievementcriteria';
protected $dbcSourceFiles = ['achievement_criteria'];
});
?>

View File

@@ -7,101 +7,96 @@ if (!CLI)
die('not in cli mode');
/* deps:
* areatrigger_tavern
* areatrigger_scripts
* areatrigger_involvedrelation
* quest_template
* quest_template_addon
* areatrigger_teleport
*/
$customData = array(
);
$reqDBC = ['areatrigger'];
function areatrigger(/*array $ids = [] */)
SqlGen::register(new class extends SetupScript
{
DB::Aowow()->query('TRUNCATE ?_areatrigger');
DB::Aowow()->query('INSERT INTO ?_areatrigger SELECT id, 0, 0, NULL, orientation, NULL, NULL, NULL, NULL, NULL, NULL FROM dbc_areatrigger');
protected $command = 'areatrigger';
/* notes:
* while areatrigger DO have dimensions, displaying them on a map is almost always futile,
* as they are either too small to be noticable or larger than the map itself (looking at you, oculus dungeon exit)
*/
protected $tblDependancyTC = ['areatrigger_involvedrelation', 'areatrigger_scripts', 'areatrigger_tavern', 'areatrigger_teleport', 'quest_template', 'quest_template_addon'];
protected $dbcSourceFiles = ['areatrigger'];
// 1: Taverns
CLI::write(' - fetching taverns');
$addData = DB::World()->select('SELECT id AS ARRAY_KEY, name, ?d AS `type` FROM areatrigger_tavern', AT_TYPE_TAVERN);
foreach ($addData as $id => $ad)
DB::Aowow()->query('UPDATE ?_areatrigger SET ?a WHERE id = ?d', $ad, $id);
// 2: Teleporter + teleporting 4: Smart Trigger
CLI::write(' - calculation teleporter coordinates');
$addData = DB::World()->select('
SELECT ID AS ARRAY_KEY, Name AS `name`, target_map AS `map`, target_position_x AS `posY`, target_position_y AS `posX`, target_orientation AS `orientation` FROM areatrigger_teleport UNION
SELECT entryorguid AS ARRAY_KEY, "TBD" AS `name`, action_param1 AS `map`, target_x AS `posY`, target_y AS `posX`, target_o AS `orientation` FROM smart_scripts WHERE source_type = 2 AND action_type = 62
');
foreach ($addData as $id => $ad)
public function generate(array $ids = []) : bool
{
// todo (low): unify with spawns function
$queryPost = 'SELECT dm.id, wma.areaId, IFNULL(dm.floor, 0) AS floor, ' .
'100 - ROUND(IF(dm.id IS NOT NULL, (?f - dm.minY) * 100 / (dm.maxY - dm.minY), (?f - wma.right) * 100 / (wma.left - wma.right)), 1) AS `posX`, ' .
'100 - ROUND(IF(dm.id IS NOT NULL, (?f - dm.minX) * 100 / (dm.maxX - dm.minX), (?f - wma.bottom) * 100 / (wma.top - wma.bottom)), 1) AS `posY`, ' .
'((abs(IF(dm.id IS NOT NULL, (?f - dm.minY) * 100 / (dm.maxY - dm.minY), (?f - wma.right) * 100 / (wma.left - wma.right)) - 50) / 50) * ' .
' (abs(IF(dm.id IS NOT NULL, (?f - dm.minX) * 100 / (dm.maxX - dm.minX), (?f - wma.bottom) * 100 / (wma.top - wma.bottom)) - 50) / 50)) AS quality ' .
'FROM dbc_worldmaparea wma ' .
'LEFT JOIN dbc_dungeonmap dm ON dm.mapId = IF(?d AND (wma.mapId NOT IN (0, 1, 530, 571) OR wma.areaId = 4395), wma.mapId, -1) ' .
'WHERE wma.mapId = ?d AND wma.areaId <> 0 ' .
'HAVING (`posX` BETWEEN 0.1 AND 99.9 AND `posY` BETWEEN 0.1 AND 99.9) ' .
'ORDER BY quality ASC';
DB::Aowow()->query('TRUNCATE ?_areatrigger');
DB::Aowow()->query('INSERT INTO ?_areatrigger SELECT id, 0, 0, NULL, orientation, NULL, NULL, NULL, NULL, NULL, NULL FROM dbc_areatrigger');
$points = DB::Aowow()->select($queryPost, $ad['posX'], $ad['posX'], $ad['posY'], $ad['posY'], $ad['posX'], $ad['posX'], $ad['posY'], $ad['posY'], 1, $ad['map']);
if (!$points)
$points = DB::Aowow()->select($queryPost, $ad['posX'], $ad['posX'], $ad['posY'], $ad['posY'], $ad['posX'], $ad['posX'], $ad['posY'], $ad['posY'], 0, $ad['map']);
/* notes:
* while areatrigger DO have dimensions, displaying them on a map is almost always futile,
* as they are either too small to be noticable or larger than the map itself (looking at you, oculus dungeon exit)
*/
if (!$points)
// 1: Taverns
CLI::write(' - fetching taverns');
$addData = DB::World()->select('SELECT id AS ARRAY_KEY, name, ?d AS `type` FROM areatrigger_tavern', AT_TYPE_TAVERN);
foreach ($addData as $id => $ad)
DB::Aowow()->query('UPDATE ?_areatrigger SET ?a WHERE id = ?d', $ad, $id);
// 2: Teleporter + teleporting 4: Smart Trigger
CLI::write(' - calculation teleporter coordinates');
$addData = DB::World()->select('
SELECT ID AS ARRAY_KEY, Name AS `name`, target_map AS `map`, target_position_x AS `posY`, target_position_y AS `posX`, target_orientation AS `orientation` FROM areatrigger_teleport UNION
SELECT entryorguid AS ARRAY_KEY, "TBD" AS `name`, action_param1 AS `map`, target_x AS `posY`, target_y AS `posX`, target_o AS `orientation` FROM smart_scripts WHERE source_type = 2 AND action_type = 62
');
foreach ($addData as $id => $ad)
{
CLI::write(' * AT '.$id.' teleporter endpoint '.CLI::bold($ad['name']).' could not be matched to displayable area [M:'.$ad['map'].'; X:'.$ad['posY'].'; Y:'.$ad['posX'].']', CLI::LOG_WARN);
DB::Aowow()->query('UPDATE ?_areatrigger SET `name` = ?, `type` = ?d WHERE id = ?d', $ad['name'], AT_TYPE_TELEPORT, $id);
continue;
// todo (low): unify with spawns function
$queryPost = 'SELECT dm.id, wma.areaId, IFNULL(dm.floor, 0) AS floor, ' .
'100 - ROUND(IF(dm.id IS NOT NULL, (?f - dm.minY) * 100 / (dm.maxY - dm.minY), (?f - wma.right) * 100 / (wma.left - wma.right)), 1) AS `posX`, ' .
'100 - ROUND(IF(dm.id IS NOT NULL, (?f - dm.minX) * 100 / (dm.maxX - dm.minX), (?f - wma.bottom) * 100 / (wma.top - wma.bottom)), 1) AS `posY`, ' .
'((abs(IF(dm.id IS NOT NULL, (?f - dm.minY) * 100 / (dm.maxY - dm.minY), (?f - wma.right) * 100 / (wma.left - wma.right)) - 50) / 50) * ' .
' (abs(IF(dm.id IS NOT NULL, (?f - dm.minX) * 100 / (dm.maxX - dm.minX), (?f - wma.bottom) * 100 / (wma.top - wma.bottom)) - 50) / 50)) AS quality ' .
'FROM dbc_worldmaparea wma ' .
'LEFT JOIN dbc_dungeonmap dm ON dm.mapId = IF(?d AND (wma.mapId NOT IN (0, 1, 530, 571) OR wma.areaId = 4395), wma.mapId, -1) ' .
'WHERE wma.mapId = ?d AND wma.areaId <> 0 ' .
'HAVING (`posX` BETWEEN 0.1 AND 99.9 AND `posY` BETWEEN 0.1 AND 99.9) ' .
'ORDER BY quality ASC';
$points = DB::Aowow()->select($queryPost, $ad['posX'], $ad['posX'], $ad['posY'], $ad['posY'], $ad['posX'], $ad['posX'], $ad['posY'], $ad['posY'], 1, $ad['map']);
if (!$points)
$points = DB::Aowow()->select($queryPost, $ad['posX'], $ad['posX'], $ad['posY'], $ad['posY'], $ad['posX'], $ad['posX'], $ad['posY'], $ad['posY'], 0, $ad['map']);
if (!$points)
{
CLI::write(' * AT '.$id.' teleporter endpoint '.CLI::bold($ad['name']).' could not be matched to displayable area [M:'.$ad['map'].'; X:'.$ad['posY'].'; Y:'.$ad['posX'].']', CLI::LOG_WARN);
DB::Aowow()->query('UPDATE ?_areatrigger SET `name` = ?, `type` = ?d WHERE id = ?d', $ad['name'], AT_TYPE_TELEPORT, $id);
continue;
}
$update = array(
'name' => $ad['name'],
'type' => AT_TYPE_TELEPORT,
'teleportA' => $points[0]['areaId'],
'teleportX' => $points[0]['posX'],
'teleportY' => $points[0]['posY'],
'teleportO' => $ad['orientation'],
'teleportF' => $points[0]['floor']
);
DB::Aowow()->query('UPDATE ?_areatrigger SET ?a WHERE id = ?d', $update, $id);
}
$update = array(
'name' => $ad['name'],
'type' => AT_TYPE_TELEPORT,
'teleportA' => $points[0]['areaId'],
'teleportX' => $points[0]['posX'],
'teleportY' => $points[0]['posY'],
'teleportO' => $ad['orientation'],
'teleportF' => $points[0]['floor']
);
// 3: Quest Objectives
CLI::write(' - satisfying quest objectives');
DB::Aowow()->query('UPDATE ?_areatrigger SET ?a WHERE id = ?d', $update, $id);
$addData = DB::World()->select('SELECT atir.id AS ARRAY_KEY, qt.ID AS quest, NULLIF(qt.AreaDescription, "") AS `name`, qta.SpecialFlags FROM quest_template qt LEFT JOIN quest_template_addon qta ON qta.ID = qt.ID JOIN areatrigger_involvedrelation atir ON atir.quest = qt.ID');
foreach ($addData as $id => $ad)
{
if (!($ad['SpecialFlags'] & QUEST_FLAG_SPECIAL_EXT_COMPLETE))
CLI::write(' * Areatrigger '.CLI::bold($id).' is involved in Quest '.CLI::bold($ad['quest']).', but Quest is not flagged for external completion (SpecialFlags & '.Util::asHex(QUEST_FLAG_SPECIAL_EXT_COMPLETE).')', CLI::LOG_WARN);
DB::Aowow()->query('UPDATE ?_areatrigger SET name = ?, type = ?d, quest = ?d WHERE id = ?d', $ad['name'], AT_TYPE_OBJECTIVE, $ad['quest'], $id);
}
// 4/5 Scripted
CLI::write(' - assigning scripts');
$addData = DB::World()->select('SELECT entry AS ARRAY_KEY, IF(ScriptName = "SmartTrigger", NULL, ScriptName) AS `name`, IF(ScriptName = "SmartTrigger", 4, 5) AS `type` FROM areatrigger_scripts');
foreach ($addData as $id => $ad)
DB::Aowow()->query('UPDATE ?_areatrigger SET ?a WHERE id = ?d', $ad, $id);
return true;
}
// 3: Quest Objectives
CLI::write(' - satisfying quest objectives');
$addData = DB::World()->select('SELECT atir.id AS ARRAY_KEY, qt.ID AS quest, NULLIF(qt.AreaDescription, "") AS `name`, qta.SpecialFlags FROM quest_template qt LEFT JOIN quest_template_addon qta ON qta.ID = qt.ID JOIN areatrigger_involvedrelation atir ON atir.quest = qt.ID');
foreach ($addData as $id => $ad)
{
if (!($ad['SpecialFlags'] & QUEST_FLAG_SPECIAL_EXT_COMPLETE))
CLI::write(' * Areatrigger '.CLI::bold($id).' is involved in Quest '.CLI::bold($ad['quest']).', but Quest is not flagged for external completion (SpecialFlags & '.Util::asHex(QUEST_FLAG_SPECIAL_EXT_COMPLETE).')', CLI::LOG_WARN);
DB::Aowow()->query('UPDATE ?_areatrigger SET name = ?, type = ?d, quest = ?d WHERE id = ?d', $ad['name'], AT_TYPE_OBJECTIVE, $ad['quest'], $id);
}
// 4/5 Scripted
CLI::write(' - assigning scripts');
$addData = DB::World()->select('SELECT entry AS ARRAY_KEY, IF(ScriptName = "SmartTrigger", NULL, ScriptName) AS `name`, IF(ScriptName = "SmartTrigger", 4, 5) AS `type` FROM areatrigger_scripts');
foreach ($addData as $id => $ad)
DB::Aowow()->query('UPDATE ?_areatrigger SET ?a WHERE id = ?d', $ad, $id);
return true;
}
});
?>

View File

@@ -7,44 +7,52 @@ if (!CLI)
die('not in cli mode');
// roles (1:heal; 2:mleDPS; 4:rngDPS; 8:tank)
$customData = array(
1 => ['roles' => 0xA],
2 => ['roles' => 0xB],
3 => ['roles' => 0x4],
4 => ['roles' => 0x2],
5 => ['roles' => 0x5],
6 => ['roles' => 0xA],
7 => ['roles' => 0x7],
8 => ['roles' => 0x4],
9 => ['roles' => 0x4],
11 => ['roles' => 0xF],
);
$reqDBC = ['spell', 'charbaseinfo', 'skillraceclassinfo', 'skilllineability', 'chrclasses'];
function classes()
SqlGen::register(new class extends SetupScript
{
$classes = DB::Aowow()->select('SELECT *, id AS ARRAY_KEY FROM dbc_chrclasses');
use TrCustomData;
// add raceMask
$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);
protected $command = 'classes';
// add skills
$skills = DB::Aowow()->select('SELECT LOG(2, classMask) + 1 AS ARRAY_KEY, GROUP_CONCAT(skillLine SEPARATOR \' \') AS skills FROM dbc_skillraceclassinfo WHERE flags = 1040 GROUP BY classMask HAVING ARRAY_KEY = CAST(LOG(2, classMask) + 1 AS SIGNED)');
Util::arraySumByKey($classes, $skills);
protected $dbcSourceFiles = ['spell', 'charbaseinfo', 'skillraceclassinfo', 'skilllineability', 'chrclasses'];
// add weaponTypeMask & armorTypeMask
foreach ($classes as $id => &$data)
// roles (1:heal; 2:mleDPS; 4:rngDPS; 8:tank)
private $customData = array(
1 => ['roles' => 0xA],
2 => ['roles' => 0xB],
3 => ['roles' => 0x4],
4 => ['roles' => 0x2],
5 => ['roles' => 0x5],
6 => ['roles' => 0xA],
7 => ['roles' => 0x7],
8 => ['roles' => 0x4],
9 => ['roles' => 0x4],
11 => ['roles' => 0xF],
);
public function generate(array $ids = []) : bool
{
$data['weaponTypeMask'] = DB::Aowow()->selectCell('SELECT BIT_OR(equippedItemSubClassMask) FROM dbc_spell s JOIN dbc_skilllineability sla ON sla.spellId = s.id JOIN dbc_skillraceclassinfo srci ON srci.skillLine = sla.skillLineId AND srci.classMask & ?d WHERE sla.skilllineid <> 183 AND (sla.reqClassMask & ?d OR sla.reqClassMask = 0) AND equippedItemClass = ?d AND (effect1Id = 60 OR effect2Id = 60)', 1 << ($id - 1), 1 << ($id - 1), ITEM_CLASS_WEAPON);
$data['armorTypeMask'] = DB::Aowow()->selectCell('SELECT BIT_OR(equippedItemSubClassMask) FROM dbc_spell s JOIN dbc_skilllineability sla ON sla.spellId = s.id JOIN dbc_skillraceclassinfo srci ON srci.skillLine = sla.skillLineId AND srci.classMask & ?d WHERE sla.reqClassMask & ?d AND equippedItemClass = ?d AND (effect1Id = 60 OR effect2Id = 60)', 1 << ($id - 1), 1 << ($id - 1), ITEM_CLASS_ARMOR);
$classes = DB::Aowow()->select('SELECT *, id AS ARRAY_KEY FROM dbc_chrclasses');
// add raceMask
$races = DB::Aowow()->select('SELECT classId AS ARRAY_KEY, BIT_OR(1 << (raceId - 1)) AS raceMask FROM dbc_charbaseinfo GROUP BY classId');
Util::arraySumByKey($classes, $races);
// add skills
$skills = DB::Aowow()->select('SELECT LOG(2, classMask) + 1 AS ARRAY_KEY, GROUP_CONCAT(skillLine SEPARATOR \' \') AS skills FROM dbc_skillraceclassinfo WHERE flags = 1040 GROUP BY classMask HAVING ARRAY_KEY = CAST(LOG(2, classMask) + 1 AS SIGNED)');
Util::arraySumByKey($classes, $skills);
// add weaponTypeMask & armorTypeMask
foreach ($classes as $id => &$data)
{
$data['weaponTypeMask'] = DB::Aowow()->selectCell('SELECT BIT_OR(equippedItemSubClassMask) FROM dbc_spell s JOIN dbc_skilllineability sla ON sla.spellId = s.id JOIN dbc_skillraceclassinfo srci ON srci.skillLine = sla.skillLineId AND srci.classMask & ?d WHERE sla.skilllineid <> 183 AND (sla.reqClassMask & ?d OR sla.reqClassMask = 0) AND equippedItemClass = ?d AND (effect1Id = 60 OR effect2Id = 60)', 1 << ($id - 1), 1 << ($id - 1), ITEM_CLASS_WEAPON);
$data['armorTypeMask'] = DB::Aowow()->selectCell('SELECT BIT_OR(equippedItemSubClassMask) FROM dbc_spell s JOIN dbc_skilllineability sla ON sla.spellId = s.id JOIN dbc_skillraceclassinfo srci ON srci.skillLine = sla.skillLineId AND srci.classMask & ?d WHERE sla.reqClassMask & ?d AND equippedItemClass = ?d AND (effect1Id = 60 OR effect2Id = 60)', 1 << ($id - 1), 1 << ($id - 1), ITEM_CLASS_ARMOR);
}
foreach ($classes as $cl)
DB::Aowow()->query('REPLACE INTO ?_classes (?#) VALUES (?a)', array_keys($cl), array_values($cl));
return true;
}
foreach ($classes as $cl)
DB::Aowow()->query('REPLACE INTO ?_classes (?#) VALUES (?a)', array_keys($cl), array_values($cl));
return true;
}
});
?>

View File

@@ -7,156 +7,152 @@ if (!CLI)
die('not in cli mode');
/* deps:
* creature_template
* creature_template_locale
* creature_classlevelstats
* instance_encounters
*/
$customData = array(
);
$reqDBC = ['creaturedisplayinfo', 'creaturedisplayinfoextra'];
function creature(array $ids = [])
SqlGen::register(new class extends SetupScript
{
$baseQuery = '
SELECT
ct.entry,
IF(ie.entry IS NULL, 0, ?d) AS cuFlags, -- cuFlags
difficulty_entry_1, difficulty_entry_2, difficulty_entry_3,
KillCredit1, KillCredit2,
modelid1, modelid2, modelid3, modelid4,
"" AS textureString, -- textureString
0 AS modelId, -- modelId
0 AS humanoid, -- uses creaturedisplayinfoextra
"" AS iconString, -- iconString
ct.name, IFNULL(ctl2.`Name`, "") AS n2, IFNULL(ctl3.`Name`, "") AS n3, IFNULL(ctl4.`Name`, "") AS n4, IFNULL(ctl6.`Name`, "") AS n6, IFNULL(ctl8.`Name`, "") AS n8,
subname, IFNULL(ctl2.`Title`, "") AS t2, IFNULL(ctl3.`Title`, "") AS t3, IFNULL(ctl4.`Title`, "") AS t4, IFNULL(ctl6.`Title`, "") AS t6, IFNULL(ctl8.`Title`, "") AS t8,
minLevel, maxLevel,
exp,
faction,
npcflag,
IF(rank > 4, 0, rank),
dmgSchool,
DamageModifier,
BaseAttackTime,
RangeAttackTime,
BaseVariance,
RangeVariance,
unit_class,
unit_flags, unit_flags2, dynamicflags,
family,
trainer_type,
trainer_spell,
trainer_class,
trainer_race,
(CASE ct.exp WHEN 0 THEN min.damage_base WHEN 1 THEN min.damage_exp1 ELSE min.damage_exp2 END) AS dmgMin,
(CASE ct.exp WHEN 0 THEN max.damage_base WHEN 1 THEN max.damage_exp1 ELSE max.damage_exp2 END) AS dmgMax,
min.attackpower AS mleAtkPwrMin,
max.attackpower AS mleAtkPwrMax,
min.rangedattackpower AS rmgAtkPwrMin,
max.rangedattackpower AS rmgAtkPwrMax,
type,
type_flags,
lootid, pickpocketloot, skinloot,
spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8,
PetSpellDataId,
VehicleId,
mingold, maxgold,
AIName,
(CASE ct.exp WHEN 0 THEN min.basehp0 WHEN 1 THEN min.basehp1 ELSE min.basehp2 END) * ct.HealthModifier AS healthMin,
(CASE ct.exp WHEN 0 THEN max.basehp0 WHEN 1 THEN max.basehp1 ELSE max.basehp2 END) * ct.HealthModifier AS healthMax,
min.basemana * ct.ManaModifier AS manaMin,
max.basemana * ct.ManaModifier AS manaMax,
min.basearmor * ct.ArmorModifier AS armorMin,
max.basearmor * ct.ArmorModifier AS armorMax,
RacialLeader,
mechanic_immune_mask,
flags_extra,
ScriptName
FROM
creature_template ct
JOIN
creature_classlevelstats min ON ct.unit_class = min.class AND ct.minlevel = min.level
JOIN
creature_classlevelstats max ON ct.unit_class = max.class AND ct.maxlevel = max.level
LEFT JOIN
creature_template_locale ctl2 ON ct.entry = ctl2.entry AND ctl2.`locale` = "frFR"
LEFT JOIN
creature_template_locale ctl3 ON ct.entry = ctl3.entry AND ctl3.`locale` = "deDE"
LEFT JOIN
creature_template_locale ctl4 ON ct.entry = ctl4.entry AND ctl4.`locale` = "zhCN"
LEFT JOIN
creature_template_locale ctl6 ON ct.entry = ctl6.entry AND ctl6.`locale` = "esES"
LEFT JOIN
creature_template_locale ctl8 ON ct.entry = ctl8.entry AND ctl8.`locale` = "ruRU"
LEFT JOIN
instance_encounters ie ON ie.creditEntry = ct.entry AND ie.creditType = 0
WHERE
ct.entry > ?d
{
AND ct.entry IN (?a)
}
ORDER BY
ct.entry ASC
LIMIT
?d';
protected $command = 'creature';
$dummyQuery = '
UPDATE
?_creature a
JOIN
(
SELECT b.difficultyEntry1 AS dummy FROM ?_creature b UNION
SELECT c.difficultyEntry2 AS dummy FROM ?_creature c UNION
SELECT d.difficultyEntry3 AS dummy FROM ?_creature d
) j
SET
a.cuFlags = a.cuFlags | ?d
WHERE
a.id = j.dummy';
protected $tblDependancyTC = ['creature_template', 'creature_template_locale', 'creature_classlevelstats', 'instance_encounters'];
protected $dbcSourceFiles = ['creaturedisplayinfo', 'creaturedisplayinfoextra'];
$displayInfoQuery = '
UPDATE
?_creature c
JOIN
dbc_creaturedisplayinfo cdi ON c.displayId1 = cdi.id
LEFT JOIN
dbc_creaturedisplayinfoextra cdie ON cdi.extraInfoId = cdie.id
SET
c.textureString = IFNULL(cdie.textureString, cdi.skin1),
c.modelId = cdi.modelId,
c.iconString = cdi.iconString,
c.humanoid = IF(cdie.id IS NULL, 0, 1)';
$lastMax = 0;
while ($npcs = DB::World()->select($baseQuery, NPC_CU_INSTANCE_BOSS, $lastMax, $ids ?: DBSIMPLE_SKIP, SqlGen::$stepSize))
public function generate(array $ids = []) : bool
{
$newMax = max(array_column($npcs, 'entry'));
$baseQuery = '
SELECT
ct.entry,
IF(ie.entry IS NULL, 0, ?d) AS cuFlags, -- cuFlags
difficulty_entry_1, difficulty_entry_2, difficulty_entry_3,
KillCredit1, KillCredit2,
modelid1, modelid2, modelid3, modelid4,
"" AS textureString, -- textureString
0 AS modelId, -- modelId
0 AS humanoid, -- uses creaturedisplayinfoextra
"" AS iconString, -- iconString
ct.name, IFNULL(ctl2.`Name`, "") AS n2, IFNULL(ctl3.`Name`, "") AS n3, IFNULL(ctl4.`Name`, "") AS n4, IFNULL(ctl6.`Name`, "") AS n6, IFNULL(ctl8.`Name`, "") AS n8,
subname, IFNULL(ctl2.`Title`, "") AS t2, IFNULL(ctl3.`Title`, "") AS t3, IFNULL(ctl4.`Title`, "") AS t4, IFNULL(ctl6.`Title`, "") AS t6, IFNULL(ctl8.`Title`, "") AS t8,
minLevel, maxLevel,
exp,
faction,
npcflag,
IF(rank > 4, 0, rank),
dmgSchool,
DamageModifier,
BaseAttackTime,
RangeAttackTime,
BaseVariance,
RangeVariance,
unit_class,
unit_flags, unit_flags2, dynamicflags,
family,
trainer_type,
trainer_spell,
trainer_class,
trainer_race,
(CASE ct.exp WHEN 0 THEN min.damage_base WHEN 1 THEN min.damage_exp1 ELSE min.damage_exp2 END) AS dmgMin,
(CASE ct.exp WHEN 0 THEN max.damage_base WHEN 1 THEN max.damage_exp1 ELSE max.damage_exp2 END) AS dmgMax,
min.attackpower AS mleAtkPwrMin,
max.attackpower AS mleAtkPwrMax,
min.rangedattackpower AS rmgAtkPwrMin,
max.rangedattackpower AS rmgAtkPwrMax,
type,
type_flags,
lootid, pickpocketloot, skinloot,
spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8,
PetSpellDataId,
VehicleId,
mingold, maxgold,
AIName,
(CASE ct.exp WHEN 0 THEN min.basehp0 WHEN 1 THEN min.basehp1 ELSE min.basehp2 END) * ct.HealthModifier AS healthMin,
(CASE ct.exp WHEN 0 THEN max.basehp0 WHEN 1 THEN max.basehp1 ELSE max.basehp2 END) * ct.HealthModifier AS healthMax,
min.basemana * ct.ManaModifier AS manaMin,
max.basemana * ct.ManaModifier AS manaMax,
min.basearmor * ct.ArmorModifier AS armorMin,
max.basearmor * ct.ArmorModifier AS armorMax,
RacialLeader,
mechanic_immune_mask,
flags_extra,
ScriptName
FROM
creature_template ct
JOIN
creature_classlevelstats min ON ct.unit_class = min.class AND ct.minlevel = min.level
JOIN
creature_classlevelstats max ON ct.unit_class = max.class AND ct.maxlevel = max.level
LEFT JOIN
creature_template_locale ctl2 ON ct.entry = ctl2.entry AND ctl2.`locale` = "frFR"
LEFT JOIN
creature_template_locale ctl3 ON ct.entry = ctl3.entry AND ctl3.`locale` = "deDE"
LEFT JOIN
creature_template_locale ctl4 ON ct.entry = ctl4.entry AND ctl4.`locale` = "zhCN"
LEFT JOIN
creature_template_locale ctl6 ON ct.entry = ctl6.entry AND ctl6.`locale` = "esES"
LEFT JOIN
creature_template_locale ctl8 ON ct.entry = ctl8.entry AND ctl8.`locale` = "ruRU"
LEFT JOIN
instance_encounters ie ON ie.creditEntry = ct.entry AND ie.creditType = 0
WHERE
ct.entry > ?d
{
AND ct.entry IN (?a)
}
ORDER BY
ct.entry ASC
LIMIT
?d';
CLI::write(' * sets '.($lastMax + 1).' - '.$newMax);
$dummyQuery = '
UPDATE
?_creature a
JOIN
(
SELECT b.difficultyEntry1 AS dummy FROM ?_creature b UNION
SELECT c.difficultyEntry2 AS dummy FROM ?_creature c UNION
SELECT d.difficultyEntry3 AS dummy FROM ?_creature d
) j
SET
a.cuFlags = a.cuFlags | ?d
WHERE
a.id = j.dummy';
$lastMax = $newMax;
$displayInfoQuery = '
UPDATE
?_creature c
JOIN
dbc_creaturedisplayinfo cdi ON c.displayId1 = cdi.id
LEFT JOIN
dbc_creaturedisplayinfoextra cdie ON cdi.extraInfoId = cdie.id
SET
c.textureString = IFNULL(cdie.textureString, cdi.skin1),
c.modelId = cdi.modelId,
c.iconString = cdi.iconString,
c.humanoid = IF(cdie.id IS NULL, 0, 1)';
foreach ($npcs as $npc)
DB::Aowow()->query('REPLACE INTO ?_creature VALUES (?a)', array_values($npc));
$lastMax = 0;
while ($npcs = DB::World()->select($baseQuery, NPC_CU_INSTANCE_BOSS, $lastMax, $ids ?: DBSIMPLE_SKIP, SqlGen::$sqlBatchSize))
{
$newMax = max(array_column($npcs, 'entry'));
CLI::write(' * sets '.($lastMax + 1).' - '.$newMax);
$lastMax = $newMax;
foreach ($npcs as $npc)
DB::Aowow()->query('REPLACE INTO ?_creature VALUES (?a)', array_values($npc));
}
// apply "textureString", "modelId" and "iconSring"
DB::Aowow()->query($displayInfoQuery);
// apply cuFlag: difficultyDummy
DB::Aowow()->query($dummyQuery, NPC_CU_DIFFICULTY_DUMMY | CUSTOM_EXCLUDE_FOR_LISTVIEW);
// apply cuFlag: excludeFromListview [for trigger-creatures]
DB::Aowow()->query('UPDATE ?_creature SET cuFlags = cuFlags | ?d WHERE flagsExtra & ?d', CUSTOM_EXCLUDE_FOR_LISTVIEW, 0x80);
// apply cuFlag: exCludeFromListview [for nameparts indicating internal usage]
DB::Aowow()->query('UPDATE ?_creature SET cuFlags = cuFlags | ?d WHERE name_loc0 LIKE "%[%" OR name_loc0 LIKE "%(%" OR name_loc0 LIKE "%visual%" OR name_loc0 LIKE "%trigger%" OR name_loc0 LIKE "%credit%" OR name_loc0 LIKE "%marker%"', CUSTOM_EXCLUDE_FOR_LISTVIEW);
return true;
}
// apply "textureString", "modelId" and "iconSring"
DB::Aowow()->query($displayInfoQuery);
// apply cuFlag: difficultyDummy
DB::Aowow()->query($dummyQuery, NPC_CU_DIFFICULTY_DUMMY | CUSTOM_EXCLUDE_FOR_LISTVIEW);
// apply cuFlag: excludeFromListview [for trigger-creatures]
DB::Aowow()->query('UPDATE ?_creature SET cuFlags = cuFlags | ?d WHERE flagsExtra & ?d', CUSTOM_EXCLUDE_FOR_LISTVIEW, 0x80);
// apply cuFlag: exCludeFromListview [for nameparts indicating internal usage]
DB::Aowow()->query('UPDATE ?_creature SET cuFlags = cuFlags | ?d WHERE name_loc0 LIKE "%[%" OR name_loc0 LIKE "%(%" OR name_loc0 LIKE "%visual%" OR name_loc0 LIKE "%trigger%" OR name_loc0 LIKE "%credit%" OR name_loc0 LIKE "%marker%"', CUSTOM_EXCLUDE_FOR_LISTVIEW);
return true;
}
});
?>

View File

@@ -7,82 +7,87 @@ if (!CLI)
die('not in cli mode');
/* deps:
* item_template
* item_template_locale
*/
// hide test tokens and move them to unused
$customData = array(
1 => ['cuFlags' => CUSTOM_EXCLUDE_FOR_LISTVIEW, 'category' => 3],
2 => ['cuFlags' => CUSTOM_EXCLUDE_FOR_LISTVIEW, 'category' => 3],
4 => ['cuFlags' => CUSTOM_EXCLUDE_FOR_LISTVIEW, 'category' => 3],
22 => ['cuFlags' => CUSTOM_EXCLUDE_FOR_LISTVIEW, 'category' => 3],
141 => ['cuFlags' => CUSTOM_EXCLUDE_FOR_LISTVIEW, 'category' => 3],
103 => ['cap' => 10000], // Arena Points
104 => ['cap' => 75000] // Honor Points
);
$reqDBC = ['itemdisplayinfo', 'currencytypes'];
function currencies(array $ids = [])
SqlGen::register(new class extends SetupScript
{
if (!$ids)
DB::Aowow()->query('REPLACE INTO ?_currencies (id, category, itemId) SELECT id, category, itemId FROM dbc_currencytypes');
use TrCustomData;
$moneyItems = DB::Aowow()->selectCol('SELECT id AS ARRAY_KEY, itemId FROM dbc_currencytypes{ WHERE id IN (?a)}', $ids ?: DBSIMPLE_SKIP);
protected $command = 'currencies';
// apply names & cap
$moneyNames = DB::World()->select('
SELECT
it.entry AS ARRAY_KEY,
it.name AS name_loc0, IFNULL(itl2.Name, "") AS name_loc2, IFNULL(itl3.Name, "") AS name_loc3, IFNULL(itl4.Name, "") AS name_loc4, IFNULL(itl6.Name, "") AS name_loc6, IFNULL(itl8.Name, "") AS name_loc8,
it.maxCount AS cap
FROM
item_template it
LEFT JOIN
item_template_locale itl2 ON it.entry = itl2.ID AND itl2.locale = "frFR"
LEFT JOIN
item_template_locale itl3 ON it.entry = itl3.ID AND itl3.locale = "deDE"
LEFT JOIN
item_template_locale itl4 ON it.entry = itl4.ID AND itl4.locale = "zhCN"
LEFT JOIN
item_template_locale itl6 ON it.entry = itl6.ID AND itl6.locale = "esES"
LEFT JOIN
item_template_locale itl8 ON it.entry = itl8.ID AND itl8.locale = "ruRU"
WHERE
it.entry IN (?a)',
$moneyItems);
protected $tblDependancyAowow = ['icons'];
protected $tblDependancyTC = ['item_template', 'item_template_locale'];
protected $dbcSourceFiles = ['itemdisplayinfo', 'currencytypes'];
foreach ($moneyItems as $cId => $itemId)
// hide test tokens and move them to unused
private $customData = array(
1 => ['cuFlags' => CUSTOM_EXCLUDE_FOR_LISTVIEW, 'category' => 3],
2 => ['cuFlags' => CUSTOM_EXCLUDE_FOR_LISTVIEW, 'category' => 3],
4 => ['cuFlags' => CUSTOM_EXCLUDE_FOR_LISTVIEW, 'category' => 3],
22 => ['cuFlags' => CUSTOM_EXCLUDE_FOR_LISTVIEW, 'category' => 3],
141 => ['cuFlags' => CUSTOM_EXCLUDE_FOR_LISTVIEW, 'category' => 3],
103 => ['cap' => 10000], // Arena Points
104 => ['cap' => 75000] // Honor Points
);
public function generate(array $ids = []) : bool
{
if (!empty($moneyNames[$itemId]))
$strings = $moneyNames[$itemId];
else
if (!$ids)
DB::Aowow()->query('REPLACE INTO ?_currencies (id, category, itemId) SELECT id, category, itemId FROM dbc_currencytypes');
$moneyItems = DB::Aowow()->selectCol('SELECT id AS ARRAY_KEY, itemId FROM dbc_currencytypes{ WHERE id IN (?a)}', $ids ?: DBSIMPLE_SKIP);
// apply names & cap
$moneyNames = DB::World()->select('
SELECT
it.entry AS ARRAY_KEY,
it.name AS name_loc0, IFNULL(itl2.Name, "") AS name_loc2, IFNULL(itl3.Name, "") AS name_loc3, IFNULL(itl4.Name, "") AS name_loc4, IFNULL(itl6.Name, "") AS name_loc6, IFNULL(itl8.Name, "") AS name_loc8,
it.maxCount AS cap
FROM
item_template it
LEFT JOIN
item_template_locale itl2 ON it.entry = itl2.ID AND itl2.locale = "frFR"
LEFT JOIN
item_template_locale itl3 ON it.entry = itl3.ID AND itl3.locale = "deDE"
LEFT JOIN
item_template_locale itl4 ON it.entry = itl4.ID AND itl4.locale = "zhCN"
LEFT JOIN
item_template_locale itl6 ON it.entry = itl6.ID AND itl6.locale = "esES"
LEFT JOIN
item_template_locale itl8 ON it.entry = itl8.ID AND itl8.locale = "ruRU"
WHERE
it.entry IN (?a)',
$moneyItems);
foreach ($moneyItems as $cId => $itemId)
{
CLI::write('item #'.$itemId.' required by currency #'.$cId.' not in item_template', CLI::LOG_WARN);
$strings = ['name_loc0' => 'Item #'.$itemId.' not in DB', 'iconId' => 0, 'cuFlags' => CUSTOM_EXCLUDE_FOR_LISTVIEW, 'category' => 3];
if (!empty($moneyNames[$itemId]))
$strings = $moneyNames[$itemId];
else
{
CLI::write('item #'.$itemId.' required by currency #'.$cId.' not in item_template', CLI::LOG_WARN);
$strings = ['name_loc0' => 'Item #'.$itemId.' not in DB', 'iconId' => 0, 'cuFlags' => CUSTOM_EXCLUDE_FOR_LISTVIEW, 'category' => 3];
}
DB::Aowow()->query('UPDATE ?_currencies SET ?a WHERE itemId = ?d', $strings, $itemId);
}
DB::Aowow()->query('UPDATE ?_currencies SET ?a WHERE itemId = ?d', $strings, $itemId);
// apply icons
$displayIds = DB::World()->selectCol('SELECT entry AS ARRAY_KEY, displayid FROM item_template WHERE entry IN (?a)', $moneyItems);
foreach ($displayIds as $itemId => $iconId)
DB::Aowow()->query('
UPDATE
?_currencies c,
?_icons i,
dbc_itemdisplayinfo idi
SET
c.iconId = i.id
WHERE
i.name = LOWER(idi.inventoryIcon1) AND
idi.id = ?d AND
c.itemId = ?d
', $iconId, $itemId);
return true;
}
// apply icons
$displayIds = DB::World()->selectCol('SELECT entry AS ARRAY_KEY, displayid FROM item_template WHERE entry IN (?a)', $moneyItems);
foreach ($displayIds as $itemId => $iconId)
DB::Aowow()->query('
UPDATE
?_currencies c,
?_icons i,
dbc_itemdisplayinfo idi
SET
c.iconId = i.id
WHERE
i.name = LOWER(idi.inventoryIcon1) AND
idi.id = ?d AND
c.itemId = ?d
', $iconId, $itemId);
return true;
}
});
?>

View File

@@ -7,93 +7,96 @@ if (!CLI)
die('not in cli mode');
$customData = array(
);
$reqDBC = ['emotes', 'emotestext', 'emotestextdata'];
function emotes(/*array $ids = [] */)
SqlGen::register(new class extends SetupScript
{
/**********/
/* Basics */
/**********/
protected $command = 'emotes';
$globStrPath = CLISetup::$srcDir.'%sInterface/FrameXML/GlobalStrings.lua';
$allOK = true;
$locPath = [];
protected $dbcSourceFiles = ['emotes', 'emotestext', 'emotestextdata'];
DB::Aowow()->query('TRUNCATE ?_emotes_aliasses');
foreach (CLISetup::$localeIds as $lId)
public function generate(array $ids = []) : bool
{
foreach (CLISetup::$expectedPaths as $xp => $locId)
/**********/
/* Basics */
/**********/
$globStrPath = CLISetup::$srcDir.'%sInterface/FrameXML/GlobalStrings.lua';
$allOK = true;
$locPath = [];
DB::Aowow()->query('TRUNCATE ?_emotes_aliasses');
foreach (CLISetup::$localeIds as $lId)
{
if ($lId != $locId)
continue;
if ($xp) // if in subDir add trailing slash
$xp .= '/';
$path = sprintf($globStrPath, $xp);
if (CLISetup::fileExists($path))
foreach (CLISetup::$expectedPaths as $xp => $locId)
{
$locPath[$lId] = $path;
continue 2;
if ($lId != $locId)
continue;
if ($xp) // if in subDir add trailing slash
$xp .= '/';
$path = sprintf($globStrPath, $xp);
if (CLISetup::fileExists($path))
{
$locPath[$lId] = $path;
continue 2;
}
}
CLI::write('GlobalStrings.lua not found for selected locale '.CLI::bold(Util::$localeStrings[$lId]), CLI::LOG_WARN);
$allOK = false;
}
$_= DB::Aowow()->query('REPLACE INTO ?_emotes SELECT
et.id,
LOWER(et.command),
IF(e.animationId, 1, 0),
0, -- cuFlags
etdT.text_loc0, etdT.text_loc2, etdT.text_loc3, etdT.text_loc4, etdT.text_loc6, etdT.text_loc8,
etdNT.text_loc0, etdNT.text_loc2, etdNT.text_loc3, etdNT.text_loc4, etdNT.text_loc6, etdNT.text_loc8,
etdS.text_loc0, etdS.text_loc2, etdS.text_loc3, etdS.text_loc4, etdS.text_loc6, etdS.text_loc8
FROM
dbc_emotestext et
LEFT JOIN
dbc_emotes e ON e.id = et.emoteId
LEFT JOIN
dbc_emotestextdata etdT ON etdT.id = et.targetId
LEFT JOIN
dbc_emotestextdata etdNT ON etdNT.id = et.noTargetId
LEFT JOIN
dbc_emotestextdata etdS ON etdS.id = et.selfId'
);
if (!$_)
$allOK = false;
// i have no idea, how the indexing in this file works.
// sometimes the \d+ after EMOTE is the emoteTextId, but not nearly often enough
$aliasses = [];
foreach ($locPath as $lId => $path)
foreach (file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line)
if (preg_match('/^EMOTE(\d+)_CMD\d+\s=\s\"\/([^"]+)\";$/', $line, $m))
$aliasses[$m[1]][] = [$lId, $m[2]];
$emotes = DB::Aowow()->selectCol('SELECT id AS ARRAY_KEY, cmd FROM ?_emotes');
foreach($emotes as $eId => $cmd)
{
foreach ($aliasses as $gsId => $data)
{
if (in_array($cmd, array_column($data, 1)))
{
foreach ($data as $d)
DB::Aowow()->query('INSERT IGNORE INTO ?_emotes_aliasses VALUES (?d, ?d, ?) ON DUPLICATE KEY UPDATE locales = locales | ?d', $eId, (1 << $d[0]), strtolower($d[1]), (1 << $d[0]));
break;
}
}
}
CLI::write('GlobalStrings.lua not found for selected locale '.CLI::bold(Util::$localeStrings[$lId]), CLI::LOG_WARN);
$allOK = false;
return $allOK;
}
$_= DB::Aowow()->query('REPLACE INTO ?_emotes SELECT
et.id,
LOWER(et.command),
IF(e.animationId, 1, 0),
0, -- cuFlags
etdT.text_loc0, etdT.text_loc2, etdT.text_loc3, etdT.text_loc4, etdT.text_loc6, etdT.text_loc8,
etdNT.text_loc0, etdNT.text_loc2, etdNT.text_loc3, etdNT.text_loc4, etdNT.text_loc6, etdNT.text_loc8,
etdS.text_loc0, etdS.text_loc2, etdS.text_loc3, etdS.text_loc4, etdS.text_loc6, etdS.text_loc8
FROM
dbc_emotestext et
LEFT JOIN
dbc_emotes e ON e.id = et.emoteId
LEFT JOIN
dbc_emotestextdata etdT ON etdT.id = et.targetId
LEFT JOIN
dbc_emotestextdata etdNT ON etdNT.id = et.noTargetId
LEFT JOIN
dbc_emotestextdata etdS ON etdS.id = et.selfId'
);
if (!$_)
$allOK = false;
// i have no idea, how the indexing in this file works.
// sometimes the \d+ after EMOTE is the emoteTextId, but not nearly often enough
$aliasses = [];
foreach ($locPath as $lId => $path)
foreach (file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line)
if (preg_match('/^EMOTE(\d+)_CMD\d+\s=\s\"\/([^"]+)\";$/', $line, $m))
$aliasses[$m[1]][] = [$lId, $m[2]];
$emotes = DB::Aowow()->selectCol('SELECT id AS ARRAY_KEY, cmd FROM ?_emotes');
foreach($emotes as $eId => $cmd)
{
foreach ($aliasses as $gsId => $data)
{
if (in_array($cmd, array_column($data, 1)))
{
foreach ($data as $d)
DB::Aowow()->query('INSERT IGNORE INTO ?_emotes_aliasses VALUES (?d, ?d, ?) ON DUPLICATE KEY UPDATE locales = locales | ?d', $eId, (1 << $d[0]), strtolower($d[1]), (1 << $d[0]));
break;
}
}
}
return $allOK;
}
});
?>

View File

@@ -7,46 +7,43 @@ if (!CLI)
die('not in cli mode');
/* deps:
* game_event
* game_event_prerequisite
*/
$customData = array(
);
$reqDBC = array(
);
function events(array $ids = [])
SqlGen::register(new class extends SetupScript
{
$eventQuery = '
SELECT
ge.eventEntry,
holiday,
0, -- cuFlags
IFNULL(UNIX_TIMESTAMP(start_time), 0),
IFNULL(UNIX_TIMESTAMP(end_time), 0),
occurence * 60,
length * 60,
IF (gep.eventEntry IS NOT NULL, GROUP_CONCAT(prerequisite_event SEPARATOR " "), NULL),
description
FROM
game_event ge
LEFT JOIN
game_event_prerequisite gep ON gep.eventEntry = ge.eventEntry
{
WHERE
ge.eventEntry IN (?a)
}
GROUP BY
ge.eventEntry';
protected $command = 'events';
$events = DB::World()->select($eventQuery, $ids ?: DBSIMPLE_SKIP);
protected $tblDependancyTC = ['game_event', 'game_event_prerequisite'];
foreach ($events as $e)
DB::Aowow()->query('REPLACE INTO ?_events VALUES (?a)', array_values($e));
public function generate(array $ids = []) : bool
{
$eventQuery = '
SELECT
ge.eventEntry,
holiday,
0, -- cuFlags
IFNULL(UNIX_TIMESTAMP(start_time), 0),
IFNULL(UNIX_TIMESTAMP(end_time), 0),
occurence * 60,
length * 60,
IF (gep.eventEntry IS NOT NULL, GROUP_CONCAT(prerequisite_event SEPARATOR " "), NULL),
description
FROM
game_event ge
LEFT JOIN
game_event_prerequisite gep ON gep.eventEntry = ge.eventEntry
{
WHERE
ge.eventEntry IN (?a)
}
GROUP BY
ge.eventEntry';
return true;
}
$events = DB::World()->select($eventQuery, $ids ?: DBSIMPLE_SKIP);
foreach ($events as $e)
DB::Aowow()->query('REPLACE INTO ?_events VALUES (?a)', array_values($e));
return true;
}
});
?>

View File

@@ -7,126 +7,134 @@ if (!CLI)
die('not in cli mode');
$customData = array(
47 => ['qmNpcIds' => '33310'],
68 => ['qmNpcIds' => '33555'],
69 => ['qmNpcIds' => '33653'],
72 => ['qmNpcIds' => '33307'],
76 => ['qmNpcIds' => '33553'],
81 => ['qmNpcIds' => '33556'],
922 => ['qmNpcIds' => '16528'],
930 => ['qmNpcIds' => '33657'],
932 => ['qmNpcIds' => '19321'],
933 => ['qmNpcIds' => '20242 23007'],
935 => ['qmNpcIds' => '21432'],
941 => ['qmNpcIds' => '20241'],
942 => ['qmNpcIds' => '17904'],
946 => ['qmNpcIds' => '17657'],
947 => ['qmNpcIds' => '17585'],
970 => ['qmNpcIds' => '18382'],
978 => ['qmNpcIds' => '20240'],
989 => ['qmNpcIds' => '21643'],
1011 => ['qmNpcIds' => '21655'],
1012 => ['qmNpcIds' => '23159'],
1037 => ['qmNpcIds' => '32773 32564'],
1038 => ['qmNpcIds' => '23428'],
1052 => ['qmNpcIds' => '32774 32565'],
1073 => ['qmNpcIds' => '31916 32763'],
1090 => ['qmNpcIds' => '32287'],
1091 => ['qmNpcIds' => '32533'],
1094 => ['qmNpcIds' => '34881'],
1105 => ['qmNpcIds' => '31910'],
1106 => ['qmNpcIds' => '30431'],
1119 => ['qmNpcIds' => '32540'],
1124 => ['qmNpcIds' => '34772'],
1156 => ['qmNpcIds' => '37687'],
1082 => ['cuFlags' => CUSTOM_EXCLUDE_FOR_LISTVIEW],
952 => ['cuFlags' => CUSTOM_EXCLUDE_FOR_LISTVIEW],
);
$reqDBC = ['faction', 'factiontemplate'];
function factions()
SqlGen::register(new class extends SetupScript
{
$factionQuery = '
REPLACE INTO
?_factions
SELECT
f.id,
f.repIdx,
baseRepRaceMask1, baseRepRaceMask2, baseRepRaceMask3, baseRepRaceMask4,
baseRepClassMask1, baseRepClassMask2, baseRepClassMask3, baseRepClassMask4,
baseRepValue1, baseRepValue2, baseRepValue3, baseRepValue4,
IF(SUM(ft.ourMask & 0x6) / COUNT(1) = 0x4, 2, IF(SUM(ft.ourMask & 0x6) / COUNT(1) = 0x2, 1, 0)) as side,
0, -- expansion
"", -- quartermasterNpcIds
"", -- factionTemplateIds
0, -- cuFlags
parentFaction,
spilloverRateIn, spilloverRateOut, spilloverMaxRank,
name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8
FROM
dbc_faction f
LEFT JOIN
dbc_factiontemplate ft ON ft.factionid = f.id
GROUP BY
f.id';
use TrCustomData;
$templateQuery = '
UPDATE
?_factions f
JOIN
(SELECT ft.factionId, GROUP_CONCAT(ft.id SEPARATOR " ") AS tplIds FROM dbc_factiontemplate ft GROUP BY ft.factionId) temp ON f.id = temp.factionId
SET
f.templateIds = temp.tplIds';
protected $command = 'factions';
$recursiveUpdateQuery = '
UPDATE
?_factions top
JOIN
(SELECT id, parentFactionId FROM ?_factions) mid ON mid.parentFactionId IN (?a)
LEFT JOIN
(SELECT id, parentFactionId FROM ?_factions) low ON low.parentFactionId = mid.id
SET
?a
WHERE
repIdx > 0 AND (
top.id IN (?a) OR
top.id = mid.id OR
top.id = low.id
)';
protected $dbcSourceFiles = ['faction', 'factiontemplate'];
$excludeQuery = '
UPDATE
?_factions x
JOIN
dbc_faction f ON f.id = x.id
LEFT JOIN
dbc_factiontemplate ft ON f.id = ft.factionId
SET
cuFlags = cuFlags | ?d
WHERE
f.repIdx < 0 OR
(
f.repIdx > 0 AND
(f.repFlags1 & 0x8 OR ft.id IS NULL) AND
(f.repFlags1 & 0x80) = 0
)';
$pairs = array(
[[980], ['expansion' => 1]],
[[1097], ['expansion' => 2]],
[[469, 891, 1037], ['side' => 1]],
[[ 67, 892, 1052], ['side' => 2]],
private $customData = array(
47 => ['qmNpcIds' => '33310'],
68 => ['qmNpcIds' => '33555'],
69 => ['qmNpcIds' => '33653'],
72 => ['qmNpcIds' => '33307'],
76 => ['qmNpcIds' => '33553'],
81 => ['qmNpcIds' => '33556'],
922 => ['qmNpcIds' => '16528'],
930 => ['qmNpcIds' => '33657'],
932 => ['qmNpcIds' => '19321'],
933 => ['qmNpcIds' => '20242 23007'],
935 => ['qmNpcIds' => '21432'],
941 => ['qmNpcIds' => '20241'],
942 => ['qmNpcIds' => '17904'],
946 => ['qmNpcIds' => '17657'],
947 => ['qmNpcIds' => '17585'],
970 => ['qmNpcIds' => '18382'],
978 => ['qmNpcIds' => '20240'],
989 => ['qmNpcIds' => '21643'],
1011 => ['qmNpcIds' => '21655'],
1012 => ['qmNpcIds' => '23159'],
1037 => ['qmNpcIds' => '32773 32564'],
1038 => ['qmNpcIds' => '23428'],
1052 => ['qmNpcIds' => '32774 32565'],
1073 => ['qmNpcIds' => '31916 32763'],
1090 => ['qmNpcIds' => '32287'],
1091 => ['qmNpcIds' => '32533'],
1094 => ['qmNpcIds' => '34881'],
1105 => ['qmNpcIds' => '31910'],
1106 => ['qmNpcIds' => '30431'],
1119 => ['qmNpcIds' => '32540'],
1124 => ['qmNpcIds' => '34772'],
1156 => ['qmNpcIds' => '37687'],
1082 => ['cuFlags' => CUSTOM_EXCLUDE_FOR_LISTVIEW],
952 => ['cuFlags' => CUSTOM_EXCLUDE_FOR_LISTVIEW],
);
DB::Aowow()->query($factionQuery);
DB::Aowow()->query($templateQuery);
DB::Aowow()->query($excludeQuery, CUSTOM_EXCLUDE_FOR_LISTVIEW);
public function generate(array $ids = []) : bool
{
$factionQuery = '
REPLACE INTO
?_factions
SELECT
f.id,
f.repIdx,
baseRepRaceMask1, baseRepRaceMask2, baseRepRaceMask3, baseRepRaceMask4,
baseRepClassMask1, baseRepClassMask2, baseRepClassMask3, baseRepClassMask4,
baseRepValue1, baseRepValue2, baseRepValue3, baseRepValue4,
IF(SUM(ft.ourMask & 0x6) / COUNT(1) = 0x4, 2, IF(SUM(ft.ourMask & 0x6) / COUNT(1) = 0x2, 1, 0)) as side,
0, -- expansion
"", -- quartermasterNpcIds
"", -- factionTemplateIds
0, -- cuFlags
parentFaction,
spilloverRateIn, spilloverRateOut, spilloverMaxRank,
name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8
FROM
dbc_faction f
LEFT JOIN
dbc_factiontemplate ft ON ft.factionid = f.id
GROUP BY
f.id';
foreach ($pairs as $p)
DB::Aowow()->query($recursiveUpdateQuery, $p[0], $p[1], $p[0]);
$templateQuery = '
UPDATE
?_factions f
JOIN
(SELECT ft.factionId, GROUP_CONCAT(ft.id SEPARATOR " ") AS tplIds FROM dbc_factiontemplate ft GROUP BY ft.factionId) temp ON f.id = temp.factionId
SET
f.templateIds = temp.tplIds';
return true;
}
$recursiveUpdateQuery = '
UPDATE
?_factions top
JOIN
(SELECT id, parentFactionId FROM ?_factions) mid ON mid.parentFactionId IN (?a)
LEFT JOIN
(SELECT id, parentFactionId FROM ?_factions) low ON low.parentFactionId = mid.id
SET
?a
WHERE
repIdx > 0 AND (
top.id IN (?a) OR
top.id = mid.id OR
top.id = low.id
)';
$excludeQuery = '
UPDATE
?_factions x
JOIN
dbc_faction f ON f.id = x.id
LEFT JOIN
dbc_factiontemplate ft ON f.id = ft.factionId
SET
cuFlags = cuFlags | ?d
WHERE
f.repIdx < 0 OR
(
f.repIdx > 0 AND
(f.repFlags1 & 0x8 OR ft.id IS NULL) AND
(f.repFlags1 & 0x80) = 0
)';
$pairs = array(
[[980], ['expansion' => 1]],
[[1097], ['expansion' => 2]],
[[469, 891, 1037], ['side' => 1]],
[[ 67, 892, 1052], ['side' => 2]],
);
DB::Aowow()->query($factionQuery);
DB::Aowow()->query($templateQuery);
DB::Aowow()->query($excludeQuery, CUSTOM_EXCLUDE_FOR_LISTVIEW);
foreach ($pairs as $p)
DB::Aowow()->query($recursiveUpdateQuery, $p[0], $p[1], $p[0]);
return true;
}
});
?>

View File

@@ -7,32 +7,35 @@ if (!CLI)
die('not in cli mode');
$customData = array(
);
$reqDBC = ['factiontemplate'];
function factiontemplate()
SqlGen::register(new class extends SetupScript
{
$query = '
REPLACE INTO
?_factiontemplate
SELECT
id,
factionId,
IF(friendFactionId1 = 1 OR friendFactionId2 = 1 OR friendFactionId3 = 1 OR friendFactionId4 = 1 OR friendlyMask & 0x3,
1,
IF(enemyFactionId1 = 1 OR enemyFactionId2 = 1 OR enemyFactionId3 = 1 OR enemyFactionId4 = 1 OR hostileMask & 0x3, -1, 0)
),
IF(friendFactionId1 = 2 OR friendFactionId2 = 2 OR friendFactionId3 = 2 OR friendFactionId4 = 2 OR friendlyMask & 0x5,
1,
IF(enemyFactionId1 = 2 OR enemyFactionId2 = 2 OR enemyFactionId3 = 2 OR enemyFactionId4 = 2 OR hostileMask & 0x5, -1, 0)
)
FROM
dbc_factiontemplate';
protected $command = 'factiontemplate';
DB::Aowow()->query($query);
protected $dbcSourceFiles = ['factiontemplate'];
return true;
}
public function generate(array $ids = []) : bool
{
$query = '
REPLACE INTO
?_factiontemplate
SELECT
id,
factionId,
IF(friendFactionId1 = 1 OR friendFactionId2 = 1 OR friendFactionId3 = 1 OR friendFactionId4 = 1 OR friendlyMask & 0x3,
1,
IF(enemyFactionId1 = 1 OR enemyFactionId2 = 1 OR enemyFactionId3 = 1 OR enemyFactionId4 = 1 OR hostileMask & 0x3, -1, 0)
),
IF(friendFactionId1 = 2 OR friendFactionId2 = 2 OR friendFactionId3 = 2 OR friendFactionId4 = 2 OR friendlyMask & 0x5,
1,
IF(enemyFactionId1 = 2 OR enemyFactionId2 = 2 OR enemyFactionId3 = 2 OR enemyFactionId4 = 2 OR hostileMask & 0x5, -1, 0)
)
FROM
dbc_factiontemplate';
DB::Aowow()->query($query);
return true;
}
});
?>

View File

@@ -6,15 +6,22 @@ if (!defined('AOWOW_REVISION'))
if (!CLI)
die('not in cli mode');
$reqDBC = ['glyphproperties', 'spellicon'];
function glyphproperties()
SqlGen::register(new class extends SetupScript
{
DB::Aowow()->query('REPLACE INTO ?_glyphproperties SELECT id, spellId, typeFlags, 0, iconId FROM dbc_glyphproperties');
protected $command = 'glyphproperties';
DB::Aowow()->query('UPDATE ?_glyphproperties gp, ?_icons ic, dbc_spellicon si SET gp.iconId = ic.id WHERE gp.iconIdBak = si.id AND ic.name = LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1))');
protected $tblDependancyAowow = ['icons'];
protected $dbcSourceFiles = ['glyphproperties', 'spellicon'];
return true;
}
public function generate(array $ids = []) : bool
{
DB::Aowow()->query('REPLACE INTO ?_glyphproperties SELECT id, spellId, typeFlags, 0, iconId FROM dbc_glyphproperties');
DB::Aowow()->query('UPDATE ?_glyphproperties gp, ?_icons ic, dbc_spellicon si SET gp.iconId = ic.id WHERE gp.iconIdBak = si.id AND ic.name = LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1))');
return true;
}
});
?>

View File

@@ -7,53 +7,62 @@ if (!CLI)
die('not in cli mode');
$customData = array(
62 => ['iconString' => 'inv_misc_missilelarge_red' ],
141 => ['iconString' => 'calendar_winterveilstart', 'achievementCatOrId' => 156 ],
181 => ['iconString' => 'calendar_noblegardenstart', 'achievementCatOrId' => 159 ],
201 => ['iconString' => 'calendar_childrensweekstart', 'achievementCatOrId' => 163 ],
283 => ['iconString' => 'inv_jewelry_necklace_21' ],
284 => ['iconString' => 'inv_misc_rune_07' ],
285 => ['iconString' => 'inv_jewelry_amulet_07' ],
301 => ['iconString' => 'calendar_fishingextravaganzastart' ],
321 => ['iconString' => 'calendar_harvestfestivalstart' ],
324 => ['iconString' => 'calendar_hallowsendstart', 'bossCreature' => 23682, 'achievementCatOrId' => 158 ],
327 => ['iconString' => 'calendar_lunarfestivalstart', 'bossCreature' => 15467, 'achievementCatOrId' => 160 ],
335 => ['iconString' => 'calendar_loveintheairstart' ],
341 => ['iconString' => 'calendar_midsummerstart', 'bossCreature' => 25740, 'achievementCatOrId' => 161 ],
353 => ['iconString' => 'spell_nature_eyeofthestorm' ],
372 => ['iconString' => 'calendar_brewfeststart', 'bossCreature' => 23872, 'achievementCatOrId' => 162 ],
374 => ['iconString' => 'calendar_darkmoonfaireelwynnstart' ],
375 => ['iconString' => 'calendar_darkmoonfairemulgorestart' ],
376 => ['iconString' => 'calendar_darkmoonfaireterokkarstart' ],
398 => ['iconString' => 'calendar_piratesdaystart', 'achievementCatOrId' => -3457],
400 => ['iconString' => 'achievement_bg_winsoa' ],
404 => ['iconString' => 'calendar_harvestfestivalstart', 'achievementCatOrId' => 14981],
406 => ['iconString' => 'achievement_boss_lichking' ],
409 => ['iconString' => 'calendar_dayofthedeadstart', 'achievementCatOrId' => -3456],
420 => ['iconString' => 'achievement_bg_winwsg' ],
423 => ['iconString' => 'calendar_loveintheairstart', 'bossCreature' => 36296, 'achievementCatOrId' => 187 ],
424 => ['iconString' => 'calendar_fishingextravaganzastart' ],
);
$reqDBC = ['holidays', 'holidaydescriptions', 'holidaynames'];
function holidays()
SqlGen::register(new class extends SetupScript
{
$query = '
REPLACE INTO
?_holidays (id, name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8, description_loc0, description_loc2, description_loc3, description_loc4, description_loc6, description_loc8, looping, scheduleType, textureString)
SELECT
h.id, n.name_loc0, n.name_loc2, n.name_loc3, n.name_loc4, n.name_loc6, n.name_loc8, d.description_loc0, d.description_loc2, d.description_loc3, d.description_loc4, d.description_loc6, d.description_loc8, h.looping, h.scheduleType, h.textureString
FROM
dbc_holidays h
LEFT JOIN
dbc_holidaynames n ON n.id = h.nameId
LEFT JOIN
dbc_holidaydescriptions d ON d.id = h.descriptionId';
use TrCustomData;
DB::Aowow()->query($query);
protected $command = 'holidays';
return true;
}
protected $dbcSourceFiles = ['holidays', 'holidaydescriptions', 'holidaynames'];
private $customData = array(
62 => ['iconString' => 'inv_misc_missilelarge_red' ],
141 => ['iconString' => 'calendar_winterveilstart', 'achievementCatOrId' => 156 ],
181 => ['iconString' => 'calendar_noblegardenstart', 'achievementCatOrId' => 159 ],
201 => ['iconString' => 'calendar_childrensweekstart', 'achievementCatOrId' => 163 ],
283 => ['iconString' => 'inv_jewelry_necklace_21' ],
284 => ['iconString' => 'inv_misc_rune_07' ],
285 => ['iconString' => 'inv_jewelry_amulet_07' ],
301 => ['iconString' => 'calendar_fishingextravaganzastart' ],
321 => ['iconString' => 'calendar_harvestfestivalstart' ],
324 => ['iconString' => 'calendar_hallowsendstart', 'bossCreature' => 23682, 'achievementCatOrId' => 158 ],
327 => ['iconString' => 'calendar_lunarfestivalstart', 'bossCreature' => 15467, 'achievementCatOrId' => 160 ],
335 => ['iconString' => 'calendar_loveintheairstart' ],
341 => ['iconString' => 'calendar_midsummerstart', 'bossCreature' => 25740, 'achievementCatOrId' => 161 ],
353 => ['iconString' => 'spell_nature_eyeofthestorm' ],
372 => ['iconString' => 'calendar_brewfeststart', 'bossCreature' => 23872, 'achievementCatOrId' => 162 ],
374 => ['iconString' => 'calendar_darkmoonfaireelwynnstart' ],
375 => ['iconString' => 'calendar_darkmoonfairemulgorestart' ],
376 => ['iconString' => 'calendar_darkmoonfaireterokkarstart' ],
398 => ['iconString' => 'calendar_piratesdaystart', 'achievementCatOrId' => -3457],
400 => ['iconString' => 'achievement_bg_winsoa' ],
404 => ['iconString' => 'calendar_harvestfestivalstart', 'achievementCatOrId' => 14981],
406 => ['iconString' => 'achievement_boss_lichking' ],
409 => ['iconString' => 'calendar_dayofthedeadstart', 'achievementCatOrId' => -3456],
420 => ['iconString' => 'achievement_bg_winwsg' ],
423 => ['iconString' => 'calendar_loveintheairstart', 'bossCreature' => 36296, 'achievementCatOrId' => 187 ],
424 => ['iconString' => 'calendar_fishingextravaganzastart' ],
);
public function generate(array $ids = []) : bool
{
$query = '
REPLACE INTO
?_holidays (id, name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8, description_loc0, description_loc2, description_loc3, description_loc4, description_loc6, description_loc8, looping, scheduleType, textureString)
SELECT
h.id, n.name_loc0, n.name_loc2, n.name_loc3, n.name_loc4, n.name_loc6, n.name_loc8, d.description_loc0, d.description_loc2, d.description_loc3, d.description_loc4, d.description_loc6, d.description_loc8, h.looping, h.scheduleType, h.textureString
FROM
dbc_holidays h
LEFT JOIN
dbc_holidaynames n ON n.id = h.nameId
LEFT JOIN
dbc_holidaydescriptions d ON d.id = h.descriptionId';
DB::Aowow()->query($query);
return true;
}
});
?>

View File

@@ -7,32 +7,35 @@ if (!CLI)
die('not in cli mode');
$customData = array(
);
$reqDBC = ['spellicon', 'itemdisplayinfo', 'creaturefamily'];
function icons()
SqlGen::register(new class extends SetupScript
{
DB::Aowow()->query('TRUNCATE ?_icons');
DB::Aowow()->query('ALTER TABLE ?_icons AUTO_INCREMENT = 1');
protected $command = 'icons';
$baseQuery = '
INSERT INTO ?_icons (`name`) SELECT x FROM
(
(SELECT LOWER(SUBSTRING_INDEX(iconPath, "\\\\", -1)) AS x FROM dbc_spellicon WHERE iconPath LIKE "%icons%")
UNION
(SELECT LOWER(inventoryIcon1) AS x FROM dbc_itemdisplayinfo WHERE inventoryIcon1 <> "")
UNION
(SELECT LOWER(SUBSTRING_INDEX(iconString, "\\\\", -1)) AS x FROM dbc_creaturefamily WHERE iconString LIKE "%icons%")
) y
GROUP BY
x
ORDER BY
x ASC';
protected $dbcSourceFiles = ['spellicon', 'itemdisplayinfo', 'creaturefamily'];
DB::Aowow()->query($baseQuery);
public function generate(array $ids = []) : bool
{
DB::Aowow()->query('TRUNCATE ?_icons');
DB::Aowow()->query('ALTER TABLE ?_icons AUTO_INCREMENT = 1');
return true;
}
$baseQuery = '
INSERT INTO ?_icons (`name`) SELECT x FROM
(
(SELECT LOWER(SUBSTRING_INDEX(iconPath, "\\\\", -1)) AS x FROM dbc_spellicon WHERE iconPath LIKE "%icons%")
UNION
(SELECT LOWER(inventoryIcon1) AS x FROM dbc_itemdisplayinfo WHERE inventoryIcon1 <> "")
UNION
(SELECT LOWER(SUBSTRING_INDEX(iconString, "\\\\", -1)) AS x FROM dbc_creaturefamily WHERE iconString LIKE "%icons%")
) y
GROUP BY
x
ORDER BY
x ASC';
DB::Aowow()->query($baseQuery);
return true;
}
});
?>

View File

@@ -7,16 +7,6 @@ if (!CLI)
die('not in cli mode');
/* deps:
* ?_items finalized
* ?_spell finalized
* dbc_spellitemenchantment
*/
$customData = array(
);
$reqDBC = ['spellitemenchantment'];
class ItemStatSetup extends ItemList
{
private $statCols = [];
@@ -138,140 +128,148 @@ class ItemStatSetup extends ItemList
}
}
function item_stats(array $ids = [])
SqlGen::register(new class extends SetupScript
{
$offset = 0;
protected $command = 'item_stats'; // and enchantment stats
CLI::write(' - applying stats for enchantments');
$enchStats = enchantment_stats();
CLI::write(' '.count($enchStats).' enchantments parsed');
CLI::write(' - applying stats for items');
protected $tblDependancyAowow = ['items', 'spell'];
protected $dbcSourceFiles = ['spellitemenchantment'];
while (true)
private function enchantment_stats() : array
{
$items = new ItemStatSetup($offset, SqlGen::$stepSize, $ids, $enchStats);
if ($items->error)
break;
$statCols = DB::Aowow()->selectCol('SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_NAME` LIKE "%item_stats"');
$enchants = DB::Aowow()->select('SELECT *, id AS ARRAY_KEY FROM dbc_spellitemenchantment');
$spells = [];
$spellStats = [];
$max = max($items->getFoundIDs());
$num = count($items->getFoundIDs());
CLI::write(' * sets '.($offset + 1).' - '.($max));
$offset = $max;
$items->writeStatsTable();
}
return true;
}
function enchantment_stats()
{
$statCols = DB::Aowow()->selectCol('SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_NAME` LIKE "%item_stats"');
$enchants = DB::Aowow()->select('SELECT *, id AS ARRAY_KEY FROM dbc_spellitemenchantment');
$spells = [];
$spellStats = [];
foreach ($enchants as $eId => $e)
{
for ($i = 1; $i <=3; $i++)
foreach ($enchants as $eId => $e)
{
// trigger: onEquip + valid SpellId
if ($e['object'.$i] > 0 && $e['type'.$i] == 3)
$spells[] = $e['object'.$i];
}
}
if ($spells)
$spellStats = (new SpellList(array(['id', $spells], CFG_SQL_LIMIT_NONE)))->getStatGain();
$result = [];
foreach ($enchants as $eId => $e)
{
// parse stats
$result[$eId] = [];
for ($h = 1; $h <= 3; $h++)
{
$obj = (int)$e['object'.$h];
$val = (int)$e['amount'.$h];
switch ($e['type'.$h])
for ($i = 1; $i <=3; $i++)
{
case 6: // TYPE_TOTEM +AmountX as DPS (Rockbiter)
$result[$eId]['dps'] = $val; // we do not use dps as itemMod, so apply it directly
$obj = null;
break;
case 2: // TYPE_DAMAGE +AmountX damage
$obj = ITEM_MOD_WEAPON_DMG;
break;
// case 1: // TYPE_COMBAT_SPELL proc spell from ObjectX (amountX == procChance)
// case 7: // TYPE_USE_SPELL Engineering gadgets
case 3: // TYPE_EQUIP_SPELL Spells from ObjectX (use of amountX?)
if (!empty($spellStats[$obj]))
foreach ($spellStats[$obj] as $mod => $val)
if ($str = Game::$itemMods[$mod])
Util::arraySumByKey($result[$eId], [$str => $val]);
// trigger: onEquip + valid SpellId
if ($e['object'.$i] > 0 && $e['type'.$i] == 3)
$spells[] = $e['object'.$i];
}
}
$obj = null;
break;
case 4: // TYPE_RESISTANCE +AmountX resistance for ObjectX School
switch ($obj)
{
case 0: // Physical
$obj = ITEM_MOD_ARMOR;
break;
case 1: // Holy
$obj = ITEM_MOD_HOLY_RESISTANCE;
break;
case 2: // Fire
$obj = ITEM_MOD_FIRE_RESISTANCE;
break;
case 3: // Nature
$obj = ITEM_MOD_NATURE_RESISTANCE;
break;
case 4: // Frost
$obj = ITEM_MOD_FROST_RESISTANCE;
break;
case 5: // Shadow
$obj = ITEM_MOD_SHADOW_RESISTANCE;
break;
case 6: // Arcane
$obj = ITEM_MOD_ARCANE_RESISTANCE;
break;
default:
$obj = null;
}
break;
case 5: // TYPE_STAT +AmountX for Statistic by type of ObjectX
if ($obj < 2) // [mana, health] are on [0, 1] respectively and are expected on [1, 2] ..
$obj++; // 0 is weaponDmg .. ehh .. i messed up somewhere
if ($spells)
$spellStats = (new SpellList(array(['id', $spells], CFG_SQL_LIMIT_NONE)))->getStatGain();
break; // stats are directly assigned below
case 8: // TYPE_PRISMATIC_SOCKET Extra Sockets AmountX as socketCount (ignore)
$result[$eId]['nsockets'] = $val; // there is no itemmod for sockets, so apply it directly
default: // TYPE_NONE dnd stuff; skip assignment below
$obj = null;
$result = [];
foreach ($enchants as $eId => $e)
{
// parse stats
$result[$eId] = [];
for ($h = 1; $h <= 3; $h++)
{
$obj = (int)$e['object'.$h];
$val = (int)$e['amount'.$h];
switch ($e['type'.$h])
{
case 6: // TYPE_TOTEM +AmountX as DPS (Rockbiter)
$result[$eId]['dps'] = $val; // we do not use dps as itemMod, so apply it directly
$obj = null;
break;
case 2: // TYPE_DAMAGE +AmountX damage
$obj = ITEM_MOD_WEAPON_DMG;
break;
// case 1: // TYPE_COMBAT_SPELL proc spell from ObjectX (amountX == procChance)
// case 7: // TYPE_USE_SPELL Engineering gadgets
case 3: // TYPE_EQUIP_SPELL Spells from ObjectX (use of amountX?)
if (!empty($spellStats[$obj]))
foreach ($spellStats[$obj] as $mod => $val)
if ($str = Game::$itemMods[$mod])
Util::arraySumByKey($result[$eId], [$str => $val]);
$obj = null;
break;
case 4: // TYPE_RESISTANCE +AmountX resistance for ObjectX School
switch ($obj)
{
case 0: // Physical
$obj = ITEM_MOD_ARMOR;
break;
case 1: // Holy
$obj = ITEM_MOD_HOLY_RESISTANCE;
break;
case 2: // Fire
$obj = ITEM_MOD_FIRE_RESISTANCE;
break;
case 3: // Nature
$obj = ITEM_MOD_NATURE_RESISTANCE;
break;
case 4: // Frost
$obj = ITEM_MOD_FROST_RESISTANCE;
break;
case 5: // Shadow
$obj = ITEM_MOD_SHADOW_RESISTANCE;
break;
case 6: // Arcane
$obj = ITEM_MOD_ARCANE_RESISTANCE;
break;
default:
$obj = null;
}
break;
case 5: // TYPE_STAT +AmountX for Statistic by type of ObjectX
if ($obj < 2) // [mana, health] are on [0, 1] respectively and are expected on [1, 2] ..
$obj++; // 0 is weaponDmg .. ehh .. i messed up somewhere
break; // stats are directly assigned below
case 8: // TYPE_PRISMATIC_SOCKET Extra Sockets AmountX as socketCount (ignore)
$result[$eId]['nsockets'] = $val; // there is no itemmod for sockets, so apply it directly
default: // TYPE_NONE dnd stuff; skip assignment below
$obj = null;
}
if ($obj !== null)
if ($str = Game::$itemMods[$obj]) // check if we use these mods
Util::arraySumByKey($result[$eId], [$str => $val]);
}
if ($obj !== null)
if ($str = Game::$itemMods[$obj]) // check if we use these mods
Util::arraySumByKey($result[$eId], [$str => $val]);
$updateCols = ['type' => TYPE_ENCHANTMENT, 'typeId' => $eId];
foreach ($result[$eId] as $k => $v)
{
if (!in_array($k, $statCols) || !$v || $k == 'id')
continue;
$updateCols[$k] = number_format($v, 2, '.', '');
}
DB::Aowow()->query('REPLACE INTO ?_item_stats (?#) VALUES (?a)', array_keys($updateCols), array_values($updateCols));
}
$updateCols = ['type' => TYPE_ENCHANTMENT, 'typeId' => $eId];
foreach ($result[$eId] as $k => $v)
{
if (!in_array($k, $statCols) || !$v || $k == 'id')
continue;
$updateCols[$k] = number_format($v, 2, '.', '');
}
DB::Aowow()->query('REPLACE INTO ?_item_stats (?#) VALUES (?a)', array_keys($updateCols), array_values($updateCols));
return $result;
}
return $result;
}
public function generate(array $ids = []) : bool
{
$offset = 0;
CLI::write(' - applying stats for enchantments');
$enchStats = enchantment_stats();
CLI::write(' '.count($enchStats).' enchantments parsed');
CLI::write(' - applying stats for items');
while (true)
{
$items = new ItemStatSetup($offset, SqlGen::$sqlBatchSize, $ids, $enchStats);
if ($items->error)
break;
$max = max($items->getFoundIDs());
$num = count($items->getFoundIDs());
CLI::write(' * sets '.($offset + 1).' - '.($max));
$offset = $max;
$items->writeStatsTable();
}
return true;
}
});
?>

View File

@@ -7,31 +7,35 @@ if (!CLI)
die('not in cli mode');
$customData = array(
);
$reqDBC = ['spellitemenchantment'];
function itemenchantment()
SqlGen::register(new class extends SetupScript
{
$baseQuery = '
REPLACE INTO
?_itemenchantment
SELECT
Id, charges, 0, 0, 0, type1, type2, type3, amount1, amount2, amount3, object1, object2, object3, name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8, conditionId, skillLine, skillLevel, requiredLevel
FROM
dbc_spellitemenchantment';
protected $command = 'itemenchantment';
DB::Aowow()->query($baseQuery);
protected $tblDependancyTC = ['spell_enchant_proc_data'];
protected $dbcSourceFiles = ['spellitemenchantment'];
$cuProcs = DB::World()->select('SELECT EnchantID AS ARRAY_KEY, Chance AS procChance, ProcsPerMinute AS ppmRate FROM spell_enchant_proc_data');
foreach ($cuProcs as $id => $vals)
DB::Aowow()->query('UPDATE ?_itemenchantment SET ?a WHERE id = ?d', $vals, $id);
public function generate(array $ids = []) : bool
{
$baseQuery = '
REPLACE INTO
?_itemenchantment
SELECT
Id, charges, 0, 0, 0, type1, type2, type3, amount1, amount2, amount3, object1, object2, object3, name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8, conditionId, skillLine, skillLevel, requiredLevel
FROM
dbc_spellitemenchantment';
// hide strange stuff
DB::Aowow()->query('UPDATE ?_itemenchantment SET cuFlags = ?d WHERE type1 = 0 AND type2 = 0 AND type3 = 0', CUSTOM_EXCLUDE_FOR_LISTVIEW);
DB::Aowow()->query('UPDATE ?_itemenchantment SET cuFlags = ?d WHERE name_loc0 LIKE "%test%"', CUSTOM_EXCLUDE_FOR_LISTVIEW);
DB::Aowow()->query($baseQuery);
return true;
}
$cuProcs = DB::World()->select('SELECT EnchantID AS ARRAY_KEY, Chance AS procChance, ProcsPerMinute AS ppmRate FROM spell_enchant_proc_data');
foreach ($cuProcs as $id => $vals)
DB::Aowow()->query('UPDATE ?_itemenchantment SET ?a WHERE id = ?d', $vals, $id);
// hide strange stuff
DB::Aowow()->query('UPDATE ?_itemenchantment SET cuFlags = ?d WHERE type1 = 0 AND type2 = 0 AND type3 = 0', CUSTOM_EXCLUDE_FOR_LISTVIEW);
DB::Aowow()->query('UPDATE ?_itemenchantment SET cuFlags = ?d WHERE name_loc0 LIKE "%test%"', CUSTOM_EXCLUDE_FOR_LISTVIEW);
return true;
}
});
?>

View File

@@ -0,0 +1,18 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
if (!CLI)
die('not in cli mode');
SqlGen::register(new class extends SetupScript
{
use TrDBCcopy;
protected $command = 'itemenchantmentcondition';
protected $dbcSourceFiles = ['spellitemenchantmentcondition'];
});
?>

View File

@@ -0,0 +1,18 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
if (!CLI)
die('not in cli mode');
SqlGen::register(new class extends SetupScript
{
use TrDBCcopy;
protected $command = 'itemextendedcost';
protected $dbcSourceFiles = ['itemextendedcost'];
});
?>

View File

@@ -0,0 +1,18 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
if (!CLI)
die('not in cli mode');
SqlGen::register(new class extends SetupScript
{
use TrDBCcopy;
protected $command = 'itemlimitcategory';
protected $dbcSourceFiles = ['itemlimitcategory'];
});
?>

View File

@@ -7,21 +7,24 @@ if (!CLI)
die('not in cli mode');
$customData = array(
);
$reqDBC = ['itemrandomsuffix', 'itemrandomproperties'];
function itemrandomenchant()
SqlGen::register(new class extends SetupScript
{
$query = '
REPLACE INTO ?_itemrandomenchant
SELECT -id, name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8, nameINT, enchantId1, enchantId2, enchantId3, enchantId4, enchantId5, allocationPct1, allocationPct2, allocationPct3, allocationPct4, allocationPct5 FROM dbc_itemrandomsuffix
UNION
SELECT id, name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8, nameINT, enchantId1, enchantId2, enchantId3, enchantId4, enchantId5, 0, 0, 0, 0, 0 FROM dbc_itemrandomproperties';
protected $command = 'itemrandomenchant';
DB::Aowow()->query($query);
protected $dbcSourceFiles = ['itemrandomsuffix', 'itemrandomproperties'];
return true;
}
public function generate(array $ids = []) : bool
{
$query = '
REPLACE INTO ?_itemrandomenchant
SELECT -id, name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8, nameINT, enchantId1, enchantId2, enchantId3, enchantId4, enchantId5, allocationPct1, allocationPct2, allocationPct3, allocationPct4, allocationPct5 FROM dbc_itemrandomsuffix
UNION
SELECT id, name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8, nameINT, enchantId1, enchantId2, enchantId3, enchantId4, enchantId5, 0, 0, 0, 0, 0 FROM dbc_itemrandomproperties';
DB::Aowow()->query($query);
return true;
}
});
?>

View File

@@ -0,0 +1,18 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
if (!CLI)
die('not in cli mode');
SqlGen::register(new class extends SetupScript
{
use TrDBCcopy;
protected $command = 'itemrandomproppoints';
protected $dbcSourceFiles = ['itemrandomproperties'];
});
?>

View File

@@ -7,252 +7,254 @@ if (!CLI)
die('not in cli mode');
/* deps:
* item_template
* item_template_locale
* spell_group
* game_event
*/
$customData = array(
33147 => ['class' => 9, 'subClass' => 8], // one stray enchanting recipe .. with a strange icon
7948 => ['itemset' => 221], // v unsure if this should be fixed v
7949 => ['itemset' => 221],
7950 => ['itemset' => 221],
7951 => ['itemset' => 221],
7952 => ['itemset' => 221],
7953 => ['itemset' => 221]
);
$reqDBC = ['gemproperties', 'itemdisplayinfo', 'spell', 'glyphproperties', 'durabilityquality', 'durabilitycosts'];
function items(array $ids = [])
SqlGen::register(new class extends SetupScript
{
$baseQuery = '
SELECT
it.entry,
class, class as classBak,
subclass, subclass AS subClassBak,
SoundOverrideSubclass,
IFNULL(sg.id, 0) AS subSubClass,
it.name, IFNULL(itl2.Name, ""), IFNULL(itl3.Name, ""), IFNULL(itl4.Name, ""), IFNULL(itl6.Name, ""), IFNULL(itl8.Name, ""),
0 AS iconId,
displayid,
0 AS spellVisualId,
Quality,
Flags, FlagsExtra,
BuyCount, BuyPrice, SellPrice,
0 AS repairPrice,
InventoryType AS slot, InventoryType AS slotBak,
AllowableClass, AllowableRace,
ItemLevel,
RequiredLevel,
RequiredSkill, RequiredSkillRank,
requiredspell,
requiredhonorrank,
RequiredCityRank,
RequiredReputationFaction,
RequiredReputationRank,
maxcount,
0 AS cuFlags,
0 AS model,
stackable,
ContainerSlots,
stat_type1, stat_value1,
stat_type2, stat_value2,
stat_type3, stat_value3,
stat_type4, stat_value4,
stat_type5, stat_value5,
stat_type6, stat_value6,
stat_type7, stat_value7,
stat_type8, stat_value8,
stat_type9, stat_value9,
stat_type10, stat_value10,
ScalingStatDistribution,
ScalingStatValue,
dmg_min1, dmg_max1, dmg_type1,
dmg_min2, dmg_max2, dmg_type2,
delay,
armor, ArmorDamageModifier,
block,
holy_res, fire_res, nature_res, frost_res, shadow_res, arcane_res,
ammo_type,
RangedModRange,
spellid_1, spelltrigger_1, spellcharges_1, spellppmRate_1, spellcooldown_1, spellcategory_1, spellcategorycooldown_1,
spellid_2, spelltrigger_2, spellcharges_2, spellppmRate_2, spellcooldown_2, spellcategory_2, spellcategorycooldown_2,
spellid_3, spelltrigger_3, spellcharges_3, spellppmRate_3, spellcooldown_3, spellcategory_3, spellcategorycooldown_3,
spellid_4, spelltrigger_4, spellcharges_4, spellppmRate_4, spellcooldown_4, spellcategory_4, spellcategorycooldown_4,
spellid_5, spelltrigger_5, spellcharges_5, spellppmRate_5, spellcooldown_5, spellcategory_5, spellcategorycooldown_5,
bonding,
it.description, IFNULL(itl2.Description, ""), IFNULL(itl3.Description, ""), IFNULL(itl4.Description, ""), IFNULL(itl6.Description, ""), IFNULL(itl8.Description, ""),
PageText,
LanguageID,
startquest,
lockid,
Material,
IF(RandomProperty > 0, RandomProperty, -RandomSuffix) AS randomEnchant,
itemset,
MaxDurability,
area,
Map,
BagFamily,
TotemCategory,
socketColor_1, socketContent_1,
socketColor_2, socketContent_2,
socketColor_3, socketContent_3,
socketBonus,
GemProperties,
RequiredDisenchantSkill,
DisenchantID,
duration,
ItemLimitCategory,
IFNULL(ge.eventEntry, 0),
ScriptName,
FoodType,
0 AS gemEnchantmentId,
minMoneyLoot, maxMoneyLoot,
0 AS pickUpSoundId,
0 AS dropDownSoundId,
0 AS sheatheSoundId,
0 AS unsheatheSoundId,
flagsCustom
FROM
item_template it
LEFT JOIN
item_template_locale itl2 ON it.entry = itl2.ID AND itl2.locale = "frFR"
LEFT JOIN
item_template_locale itl3 ON it.entry = itl3.ID AND itl3.locale = "deDE"
LEFT JOIN
item_template_locale itl4 ON it.entry = itl4.ID AND itl4.locale = "zhCN"
LEFT JOIN
item_template_locale itl6 ON it.entry = itl6.ID AND itl6.locale = "esES"
LEFT JOIN
item_template_locale itl8 ON it.entry = itl8.ID AND itl8.locale = "ruRU"
LEFT JOIN
spell_group sg ON sg.spell_id = it.spellid_1 AND it.class = 0 AND it.subclass = 2 AND sg.id IN (1, 2)
LEFT JOIN
game_event ge ON ge.holiday = it.HolidayId AND it.HolidayId > 0
WHERE
it.entry > ?d
{
AND it.entry IN (?a)
}
ORDER BY
it.entry ASC
LIMIT
?d';
use TrCustomData;
$lastMax = 0;
while ($items = DB::World()->select($baseQuery, $lastMax, $ids ?: DBSIMPLE_SKIP, SqlGen::$stepSize))
{
$newMax = max(array_column($items, 'entry'));
protected $command = 'items';
CLI::write(' * sets '.($lastMax + 1).' - '.$newMax);
protected $tblDependancyAowow = ['icons'];
protected $tblDependancyTC = ['item_template', 'item_template_locale', 'spell_group', 'game_event'];
protected $dbcSourceFiles = ['gemproperties', 'itemdisplayinfo', 'spell', 'glyphproperties', 'durabilityquality', 'durabilitycosts'];
$lastMax = $newMax;
private $customData = array(
33147 => ['class' => 9, 'subClass' => 8], // one stray enchanting recipe .. with a strange icon
7948 => ['itemset' => 221], // v unsure if this should be fixed v
7949 => ['itemset' => 221],
7950 => ['itemset' => 221],
7951 => ['itemset' => 221],
7952 => ['itemset' => 221],
7953 => ['itemset' => 221]
);
foreach ($items as $item)
DB::Aowow()->query('REPLACE INTO ?_items VALUES (?a)', array_values($item));
}
// merge with gemProperties
DB::Aowow()->query('UPDATE ?_items i, dbc_gemproperties gp SET i.gemEnchantmentId = gp.enchantmentId, i.gemColorMask = gp.colorMask WHERE i.gemColorMask = gp.id');
// get modelString
DB::Aowow()->query('UPDATE ?_items i, dbc_itemdisplayinfo idi SET i.model = IF(idi.leftModelName = "", idi.rightModelName, idi.leftModelName) WHERE i.displayId = idi.id');
// get iconId
DB::Aowow()->query('UPDATE ?_items i, dbc_itemdisplayinfo idi, ?_icons ic SET i.iconId = ic.id WHERE i.displayId = idi.id AND LOWER(idi.inventoryIcon1) = ic.name');
// unify slots: Robes => Chest; Ranged (right) => Ranged
DB::Aowow()->query('UPDATE ?_items SET slot = 15 WHERE slotbak = 26');
DB::Aowow()->query('UPDATE ?_items SET slot = 5 WHERE slotbak = 20');
// custom sub-classes
DB::Aowow()->query('
UPDATE ?_items SET subclass = IF(
slotbak = 4, -8, IF( -- shirt
slotbak = 19, -7, IF( -- tabard
slotbak = 16, -6, IF( -- cloak
slotbak = 23, -5, IF( -- held in offhand
slotbak = 12, -4, IF( -- trinket
slotbak = 2, -3, IF( -- amulet
slotbak = 11, -2, subClassBak -- ring
))))))) WHERE class = 4');
// move alchemist stones to trinkets (Armor)
DB::Aowow()->query('UPDATE ?_items SET class = 4, subClass = -4 WHERE classBak = 7 AND subClassBak = 11 AND slotBak = 12');
// mark keys as key (if not quest items)
DB::Aowow()->query('UPDATE ?_items SET class = 13, subClass = 0 WHERE classBak IN (0, 15) AND bagFamily & 0x100');
// set subSubClass for Glyphs (major/minor)
DB::Aowow()->query('UPDATE ?_items i, dbc_spell s, dbc_glyphproperties gp SET i.subSubClass = IF(gp.typeFlags & 0x1, 2, 1) WHERE i.spellId1 = s.id AND s.effect1MiscValue = gp.id AND i.classBak = 16');
// filter misc(class:15) junk(subclass:0) to appropriate categories
// assign pets and mounts to category
DB::Aowow()->query('UPDATE ?_items i, dbc_spell s SET subClass = IF(effect1AuraId <> 78, 2, IF(effect2AuraId = 207 OR effect3AuraId = 207 OR (s.id <> 65917 AND effect2AuraId = 4 AND effect3Id = 77), -7, 5)) WHERE s.id = spellId2 AND class = 15 AND spellId1 IN (483, 55884)');
// more corner cases (mounts that are not actualy learned)
DB::Aowow()->query('UPDATE ?_items i, dbc_spell s SET i.subClass = -7 WHERE (effect1Id = 64 OR (effect1AuraId = 78 AND effect2AuraId = 4 AND effect3Id = 77) OR effect1AuraId = 207 OR effect2AuraId = 207 OR effect3AuraId = 207) AND s.id = i.spellId1 AND i.class = 15 AND i.subClass = 5');
DB::Aowow()->query('UPDATE ?_items i, dbc_spell s SET i.subClass = 5 WHERE s.effect1AuraId = 78 AND s.id = i.spellId1 AND i.class = 15 AND i.subClass = 0');
// move some permanent enchantments to own category
DB::Aowow()->query('UPDATE ?_items i, dbc_spell s SET i.class = 0, i.subClass = 6 WHERE s.effect1Id = 53 AND s.id = i.spellId1 AND i.class = 15');
// move temporary enchantments to own category
DB::Aowow()->query('UPDATE ?_items i, dbc_spell s SET i.subClass = -3 WHERE s.effect1Id = 54 AND s.id = i.spellId1 AND i.class = 0 AND i.subClassBak = 8');
// move armor tokens to own category
DB::Aowow()->query('UPDATE ?_items SET subClass = -2 WHERE quality = 4 AND class = 15 AND subClassBak = 0 AND requiredClass AND (requiredClass & 0x5FF) <> 0x5FF');
// move some junk to holiday if it requires one
DB::Aowow()->query('UPDATE ?_items SET subClass = 3 WHERE classBak = 15 AND subClassBak = 0 AND eventId <> 0');
// move misc items that start quests to class: quest (except Sayges scrolls for consistency)
DB::Aowow()->query('UPDATE ?_items SET class = 12 WHERE classBak = 15 AND startQuest <> 0 AND name_loc0 NOT LIKE "sayge\'s fortune%"');
// move perm. enchantments into appropriate cat/subcat
DB::Aowow()->query('UPDATE ?_items i, dbc_spell s SET i.class = 0, i.subClass = 6 WHERE s.id = i.spellId1 AND s.effect1Id = 53 AND i.classBak = 12');
// move some generic recipes into appropriate sub-categories
$skillz = array(
private $skill2cat = array(
773 => 11, // inscription
356 => 9, // fishing
186 => 12, // mining
185 => 5, // cooking
171 => 6 // alchemy
);
foreach ($skillz as $skill => $cat)
DB::Aowow()->query('UPDATE ?_items SET subClass = ?d WHERE classBak = 9 AND subClassBak = 0 AND requiredSkill = ?d', $cat, $skill);
// calculate durabilityCosts
DB::Aowow()->query('
UPDATE
?_items i
JOIN
dbc_durabilityquality dq ON dq.id = ((i.quality + 1) * 2)
JOIN
dbc_durabilitycosts dc ON dc.id = i.itemLevel
SET
i.repairPrice = (durability* dq.mod * IF(i.classBak = 2,
CASE i.subClassBak
WHEN 0 THEN w0 WHEN 1 THEN w1 WHEN 2 THEN w2 WHEN 3 THEN w3 WHEN 4 THEN w4
WHEN 5 THEN w5 WHEN 6 THEN w6 WHEN 7 THEN w7 WHEN 8 THEN w8 WHEN 10 THEN w10
WHEN 11 THEN w11 WHEN 12 THEN w12 WHEN 13 THEN w13 WHEN 14 THEN w14 WHEN 15 THEN w15
WHEN 16 THEN w16 WHEN 17 THEN w17 WHEN 18 THEN w18 WHEN 19 THEN w19 WHEN 20 THEN w20
END,
CASE i.subClassBak
WHEN 1 THEN a1 WHEN 2 THEN a2 WHEN 3 THEN a3 WHEN 4 THEN a4 WHEN 6 THEN a6
END
))
WHERE
durability > 0 AND ((classBak = 4 AND subClassBak IN (1, 2, 3, 4, 6)) OR (classBak = 2 AND subClassBak <> 9))');
public function generate(array $ids = []) : bool
{
$baseQuery = '
SELECT
it.entry,
class, class as classBak,
subclass, subclass AS subClassBak,
SoundOverrideSubclass,
IFNULL(sg.id, 0) AS subSubClass,
it.name, IFNULL(itl2.Name, ""), IFNULL(itl3.Name, ""), IFNULL(itl4.Name, ""), IFNULL(itl6.Name, ""), IFNULL(itl8.Name, ""),
0 AS iconId,
displayid,
0 AS spellVisualId,
Quality,
Flags, FlagsExtra,
BuyCount, BuyPrice, SellPrice,
0 AS repairPrice,
InventoryType AS slot, InventoryType AS slotBak,
AllowableClass, AllowableRace,
ItemLevel,
RequiredLevel,
RequiredSkill, RequiredSkillRank,
requiredspell,
requiredhonorrank,
RequiredCityRank,
RequiredReputationFaction,
RequiredReputationRank,
maxcount,
0 AS cuFlags,
0 AS model,
stackable,
ContainerSlots,
stat_type1, stat_value1,
stat_type2, stat_value2,
stat_type3, stat_value3,
stat_type4, stat_value4,
stat_type5, stat_value5,
stat_type6, stat_value6,
stat_type7, stat_value7,
stat_type8, stat_value8,
stat_type9, stat_value9,
stat_type10, stat_value10,
ScalingStatDistribution,
ScalingStatValue,
dmg_min1, dmg_max1, dmg_type1,
dmg_min2, dmg_max2, dmg_type2,
delay,
armor, ArmorDamageModifier,
block,
holy_res, fire_res, nature_res, frost_res, shadow_res, arcane_res,
ammo_type,
RangedModRange,
spellid_1, spelltrigger_1, spellcharges_1, spellppmRate_1, spellcooldown_1, spellcategory_1, spellcategorycooldown_1,
spellid_2, spelltrigger_2, spellcharges_2, spellppmRate_2, spellcooldown_2, spellcategory_2, spellcategorycooldown_2,
spellid_3, spelltrigger_3, spellcharges_3, spellppmRate_3, spellcooldown_3, spellcategory_3, spellcategorycooldown_3,
spellid_4, spelltrigger_4, spellcharges_4, spellppmRate_4, spellcooldown_4, spellcategory_4, spellcategorycooldown_4,
spellid_5, spelltrigger_5, spellcharges_5, spellppmRate_5, spellcooldown_5, spellcategory_5, spellcategorycooldown_5,
bonding,
it.description, IFNULL(itl2.Description, ""), IFNULL(itl3.Description, ""), IFNULL(itl4.Description, ""), IFNULL(itl6.Description, ""), IFNULL(itl8.Description, ""),
PageText,
LanguageID,
startquest,
lockid,
Material,
IF(RandomProperty > 0, RandomProperty, -RandomSuffix) AS randomEnchant,
itemset,
MaxDurability,
area,
Map,
BagFamily,
TotemCategory,
socketColor_1, socketContent_1,
socketColor_2, socketContent_2,
socketColor_3, socketContent_3,
socketBonus,
GemProperties,
RequiredDisenchantSkill,
DisenchantID,
duration,
ItemLimitCategory,
IFNULL(ge.eventEntry, 0),
ScriptName,
FoodType,
0 AS gemEnchantmentId,
minMoneyLoot, maxMoneyLoot,
0 AS pickUpSoundId,
0 AS dropDownSoundId,
0 AS sheatheSoundId,
0 AS unsheatheSoundId,
flagsCustom
FROM
item_template it
LEFT JOIN
item_template_locale itl2 ON it.entry = itl2.ID AND itl2.locale = "frFR"
LEFT JOIN
item_template_locale itl3 ON it.entry = itl3.ID AND itl3.locale = "deDE"
LEFT JOIN
item_template_locale itl4 ON it.entry = itl4.ID AND itl4.locale = "zhCN"
LEFT JOIN
item_template_locale itl6 ON it.entry = itl6.ID AND itl6.locale = "esES"
LEFT JOIN
item_template_locale itl8 ON it.entry = itl8.ID AND itl8.locale = "ruRU"
LEFT JOIN
spell_group sg ON sg.spell_id = it.spellid_1 AND it.class = 0 AND it.subclass = 2 AND sg.id IN (1, 2)
LEFT JOIN
game_event ge ON ge.holiday = it.HolidayId AND it.HolidayId > 0
WHERE
it.entry > ?d
{
AND it.entry IN (?a)
}
ORDER BY
it.entry ASC
LIMIT
?d';
return true;
}
$lastMax = 0;
while ($items = DB::World()->select($baseQuery, $lastMax, $ids ?: DBSIMPLE_SKIP, SqlGen::$sqlBatchSize))
{
$newMax = max(array_column($items, 'entry'));
CLI::write(' * sets '.($lastMax + 1).' - '.$newMax);
$lastMax = $newMax;
foreach ($items as $item)
DB::Aowow()->query('REPLACE INTO ?_items VALUES (?a)', array_values($item));
}
// merge with gemProperties
DB::Aowow()->query('UPDATE ?_items i, dbc_gemproperties gp SET i.gemEnchantmentId = gp.enchantmentId, i.gemColorMask = gp.colorMask WHERE i.gemColorMask = gp.id');
// get modelString
DB::Aowow()->query('UPDATE ?_items i, dbc_itemdisplayinfo idi SET i.model = IF(idi.leftModelName = "", idi.rightModelName, idi.leftModelName) WHERE i.displayId = idi.id');
// get iconId
DB::Aowow()->query('UPDATE ?_items i, dbc_itemdisplayinfo idi, ?_icons ic SET i.iconId = ic.id WHERE i.displayId = idi.id AND LOWER(idi.inventoryIcon1) = ic.name');
// unify slots: Robes => Chest; Ranged (right) => Ranged
DB::Aowow()->query('UPDATE ?_items SET slot = 15 WHERE slotbak = 26');
DB::Aowow()->query('UPDATE ?_items SET slot = 5 WHERE slotbak = 20');
// custom sub-classes
DB::Aowow()->query('
UPDATE ?_items SET subclass = IF(
slotbak = 4, -8, IF( -- shirt
slotbak = 19, -7, IF( -- tabard
slotbak = 16, -6, IF( -- cloak
slotbak = 23, -5, IF( -- held in offhand
slotbak = 12, -4, IF( -- trinket
slotbak = 2, -3, IF( -- amulet
slotbak = 11, -2, subClassBak -- ring
))))))) WHERE class = 4');
// move alchemist stones to trinkets (Armor)
DB::Aowow()->query('UPDATE ?_items SET class = 4, subClass = -4 WHERE classBak = 7 AND subClassBak = 11 AND slotBak = 12');
// mark keys as key (if not quest items)
DB::Aowow()->query('UPDATE ?_items SET class = 13, subClass = 0 WHERE classBak IN (0, 15) AND bagFamily & 0x100');
// set subSubClass for Glyphs (major/minor)
DB::Aowow()->query('UPDATE ?_items i, dbc_spell s, dbc_glyphproperties gp SET i.subSubClass = IF(gp.typeFlags & 0x1, 2, 1) WHERE i.spellId1 = s.id AND s.effect1MiscValue = gp.id AND i.classBak = 16');
// filter misc(class:15) junk(subclass:0) to appropriate categories
// assign pets and mounts to category
DB::Aowow()->query('UPDATE ?_items i, dbc_spell s SET subClass = IF(effect1AuraId <> 78, 2, IF(effect2AuraId = 207 OR effect3AuraId = 207 OR (s.id <> 65917 AND effect2AuraId = 4 AND effect3Id = 77), -7, 5)) WHERE s.id = spellId2 AND class = 15 AND spellId1 IN (483, 55884)');
// more corner cases (mounts that are not actualy learned)
DB::Aowow()->query('UPDATE ?_items i, dbc_spell s SET i.subClass = -7 WHERE (effect1Id = 64 OR (effect1AuraId = 78 AND effect2AuraId = 4 AND effect3Id = 77) OR effect1AuraId = 207 OR effect2AuraId = 207 OR effect3AuraId = 207) AND s.id = i.spellId1 AND i.class = 15 AND i.subClass = 5');
DB::Aowow()->query('UPDATE ?_items i, dbc_spell s SET i.subClass = 5 WHERE s.effect1AuraId = 78 AND s.id = i.spellId1 AND i.class = 15 AND i.subClass = 0');
// move some permanent enchantments to own category
DB::Aowow()->query('UPDATE ?_items i, dbc_spell s SET i.class = 0, i.subClass = 6 WHERE s.effect1Id = 53 AND s.id = i.spellId1 AND i.class = 15');
// move temporary enchantments to own category
DB::Aowow()->query('UPDATE ?_items i, dbc_spell s SET i.subClass = -3 WHERE s.effect1Id = 54 AND s.id = i.spellId1 AND i.class = 0 AND i.subClassBak = 8');
// move armor tokens to own category
DB::Aowow()->query('UPDATE ?_items SET subClass = -2 WHERE quality = 4 AND class = 15 AND subClassBak = 0 AND requiredClass AND (requiredClass & 0x5FF) <> 0x5FF');
// move some junk to holiday if it requires one
DB::Aowow()->query('UPDATE ?_items SET subClass = 3 WHERE classBak = 15 AND subClassBak = 0 AND eventId <> 0');
// move misc items that start quests to class: quest (except Sayges scrolls for consistency)
DB::Aowow()->query('UPDATE ?_items SET class = 12 WHERE classBak = 15 AND startQuest <> 0 AND name_loc0 NOT LIKE "sayge\'s fortune%"');
// move perm. enchantments into appropriate cat/subcat
DB::Aowow()->query('UPDATE ?_items i, dbc_spell s SET i.class = 0, i.subClass = 6 WHERE s.id = i.spellId1 AND s.effect1Id = 53 AND i.classBak = 12');
// move some generic recipes into appropriate sub-categories
foreach ($this->skill2cat as $skill => $cat)
DB::Aowow()->query('UPDATE ?_items SET subClass = ?d WHERE classBak = 9 AND subClassBak = 0 AND requiredSkill = ?d', $cat, $skill);
// calculate durabilityCosts
DB::Aowow()->query('
UPDATE
?_items i
JOIN
dbc_durabilityquality dq ON dq.id = ((i.quality + 1) * 2)
JOIN
dbc_durabilitycosts dc ON dc.id = i.itemLevel
SET
i.repairPrice = (durability* dq.mod * IF(i.classBak = 2,
CASE i.subClassBak
WHEN 0 THEN w0 WHEN 1 THEN w1 WHEN 2 THEN w2 WHEN 3 THEN w3 WHEN 4 THEN w4
WHEN 5 THEN w5 WHEN 6 THEN w6 WHEN 7 THEN w7 WHEN 8 THEN w8 WHEN 10 THEN w10
WHEN 11 THEN w11 WHEN 12 THEN w12 WHEN 13 THEN w13 WHEN 14 THEN w14 WHEN 15 THEN w15
WHEN 16 THEN w16 WHEN 17 THEN w17 WHEN 18 THEN w18 WHEN 19 THEN w19 WHEN 20 THEN w20
END,
CASE i.subClassBak
WHEN 1 THEN a1 WHEN 2 THEN a2 WHEN 3 THEN a3 WHEN 4 THEN a4 WHEN 6 THEN a6
END
))
WHERE
durability > 0 AND ((classBak = 4 AND subClassBak IN (1, 2, 3, 4, 6)) OR (classBak = 2 AND subClassBak <> 9))');
return true;
}
});
?>

View File

@@ -8,39 +8,35 @@ if (!CLI)
/*
note: the virtual set-ids wont match the ones of wowhead
since there are some unused itemsets and and items flying around in a default database this script will create about 20 sets more than you'd expect.
since there are some unused itemsets and items flying around in a default database this script will create about 20 sets more than you'd expect.
and i have no idea how to merge the prefixes/suffixes for wotlk-raidsets and arena-sets in gereral onto the name.. at least not for all locales and i'll be damned if i have to skip one
*/
/* deps:
* item_template
* game_event
*/
$customData = array(
221 => ['item1' => 7948, 'item2' => 7949, 'item3' => 7950, 'item4' => 7951, 'item5' => 7952, 'item6' => 7953]
);
$reqDBC = ['itemset'];
function itemset()
SqlGen::register(new class extends SetupScript
{
$setToHoliday = array (
761 => 141, // Winterveil
762 => 372, // Brewfest
785 => 341, // Midsummer
812 => 181, // Noblegarden
use TrCustomData;
protected $command = 'itemset';
protected $tblDependancyAowow = ['spell'];
protected $tblDependancyTC = ['item_template', 'game_event'];
protected $dbcSourceFiles = ['itemset'];
private $customData = array(
221 => ['item1' => 7948, 'item2' => 7949, 'item3' => 7950, 'item4' => 7951, 'item5' => 7952, 'item6' => 7953]
);
// find events associated with holidayIds
if ($pairs = DB::World()->selectCol('SELECT holiday AS ARRAY_KEY, eventEntry FROM game_event WHERE holiday IN (?a)', array_values($setToHoliday)))
foreach ($setToHoliday as &$hId)
$hId = !empty($pairs[$hId]) ? $pairs[$hId] : 0;
private $setToHoliday = array (
761 => 141, // Winterveil
762 => 372, // Brewfest
785 => 341, // Midsummer
812 => 181, // Noblegarden
);
// tags where refId == virtualId
// in pve sets are not recycled beyond the contentGroup
$tagsById = array(
private $tagsById = array(
// "Dungeon Set 1"
1 => [181, 182, 183, 184, 185, 186, 187, 188, 189],
// "Dungeon Set 2"
@@ -88,7 +84,7 @@ function itemset()
);
// well .. fuck
$tagsByNamePart = array(
private $tagsByNamePart = array(
17 => ['gladiator'], // "Arena Season 1 Set",
19 => ['merciless'], // "Arena Season 2 Set",
20 => ['vengeful'], // "Arena Season 3 Set",
@@ -99,272 +95,279 @@ function itemset()
30 => ['wrathful'] // "Arena Season 8 Set",
);
DB::Aowow()->query('TRUNCATE TABLE ?_itemset');
$vIdx = 0;
$virtualId = 0;
$sets = DB::Aowow()->select('SELECT *, id AS ARRAY_KEY FROM dbc_itemset');
foreach ($sets as $setId => $setData)
public function generate(array $ids = []) : bool
{
$spells = $items = $mods = $descText = $name = $gains = [];
$max = $reqLvl = $min = $quality = $heroic = $nPieces = [];
$classMask = $type = 0;
$hasRing = false;
// find events associated with holidayIds
if ($pairs = DB::World()->selectCol('SELECT holiday AS ARRAY_KEY, eventEntry FROM game_event WHERE holiday IN (?a)', array_values($this->setToHoliday)))
foreach ($this->setToHoliday as &$hId)
$hId = !empty($pairs[$hId]) ? $pairs[$hId] : 0;
$holiday = isset($setToHoliday[$setId]) ? $setToHoliday[$setId] : 0;
$canReuse = !$holiday; // can't reuse holiday-sets
$slotList = [];
$pieces = DB::World()->select('SELECT *, IF(InventoryType = 15, 26, IF(InventoryType = 5, 20, InventoryType)) AS slot, entry AS ARRAY_KEY FROM item_template WHERE itemset = ?d AND (class <> 4 OR subclass NOT IN (1, 2, 3, 4) OR armor > 0 OR Quality = 1) ORDER BY itemLevel, subclass, slot ASC', $setId);
DB::Aowow()->query('TRUNCATE TABLE ?_itemset');
/****************************************/
/* determine type and reuse from pieces */
/****************************************/
// make the first vId always same as setId
$firstPiece = reset($pieces);
$tmp = [$firstPiece['Quality'].$firstPiece['ItemLevel'] => $setId];
// walk through all items associated with the set
foreach ($pieces as $itemId => $piece)
$vIdx = 0;
$virtualId = 0;
$sets = DB::Aowow()->select('SELECT *, id AS ARRAY_KEY FROM dbc_itemset');
foreach ($sets as $setId => $setData)
{
$classMask |= ($piece['AllowableClass'] & CLASS_MASK_ALL);
$key = $piece['Quality'].str_pad($piece['ItemLevel'], 3, 0, STR_PAD_LEFT);
$spells = $items = $mods = $descText = $name = $gains = [];
$max = $reqLvl = $min = $quality = $heroic = $nPieces = [];
$classMask = $type = 0;
$hasRing = false;
if (!isset($tmp[$key]))
$tmp[$key] = --$vIdx;
$holiday = $this->setToHoliday[$setId] ?? 0;
$canReuse = !$holiday; // can't reuse holiday-sets
$slotList = [];
$pieces = DB::World()->select('SELECT *, IF(InventoryType = 15, 26, IF(InventoryType = 5, 20, InventoryType)) AS slot, entry AS ARRAY_KEY FROM item_template WHERE itemset = ?d AND (class <> 4 OR subclass NOT IN (1, 2, 3, 4) OR armor > 0 OR Quality = 1) ORDER BY itemLevel, subclass, slot ASC', $setId);
$vId = $tmp[$key];
/****************************************/
/* determine type and reuse from pieces */
/****************************************/
// check only actual armor in rare quality or higher (or inherits holiday)
if ($piece['class'] != ITEM_CLASS_ARMOR || $piece['subclass'] == 0)
$canReuse = false;
// make the first vId always same as setId
$firstPiece = reset($pieces);
$tmp = [$firstPiece['Quality'].$firstPiece['ItemLevel'] => $setId];
/* gather relevant stats for use */
if (!isset($quality[$vId]) || $piece['Quality'] > $quality[$vId])
$quality[$vId] = $piece['Quality'];
if ($piece['Flags'] & ITEM_FLAG_HEROIC)
$heroic[$vId] = true;
if (!isset($reqLvl[$vId]) || $piece['RequiredLevel'] > $reqLvl[$vId])
$reqLvl[$vId] = $piece['RequiredLevel'];
if (!isset($min[$vId]) || $piece['ItemLevel'] < $min[$vId])
$min[$vId] = $piece['ItemLevel'];
if (!isset($max[$vId]) || $piece['ItemLevel'] > $max[$vId])
$max[$vId] = $piece['ItemLevel'];
if (!isset($items[$vId][$piece['slot']]) || !$canReuse)
// walk through all items associated with the set
foreach ($pieces as $itemId => $piece)
{
if (!isset($nPieces[$vId]))
$nPieces[$vId] = 1;
else
$nPieces[$vId]++;
}
$classMask |= ($piece['AllowableClass'] & CLASS_MASK_ALL);
$key = $piece['Quality'].str_pad($piece['ItemLevel'], 3, 0, STR_PAD_LEFT);
if (isset($items[$vId][$piece['slot']]))
{
// not reusable -> insert anyway on unique keys
if (!$canReuse)
$items[$vId][$piece['slot'].$itemId] = $itemId;
else
if (!isset($tmp[$key]))
$tmp[$key] = --$vIdx;
$vId = $tmp[$key];
// check only actual armor in rare quality or higher (or inherits holiday)
if ($piece['class'] != ITEM_CLASS_ARMOR || $piece['subclass'] == 0)
$canReuse = false;
/* gather relevant stats for use */
if (!isset($quality[$vId]) || $piece['Quality'] > $quality[$vId])
$quality[$vId] = $piece['Quality'];
if ($piece['Flags'] & ITEM_FLAG_HEROIC)
$heroic[$vId] = true;
if (!isset($reqLvl[$vId]) || $piece['RequiredLevel'] > $reqLvl[$vId])
$reqLvl[$vId] = $piece['RequiredLevel'];
if (!isset($min[$vId]) || $piece['ItemLevel'] < $min[$vId])
$min[$vId] = $piece['ItemLevel'];
if (!isset($max[$vId]) || $piece['ItemLevel'] > $max[$vId])
$max[$vId] = $piece['ItemLevel'];
if (!isset($items[$vId][$piece['slot']]) || !$canReuse)
{
CLI::write("set: ".$setId." ilvl: ".$piece['ItemLevel']." - conflict between item: ".$items[$vId][$piece['slot']]." and item: ".$itemId." choosing lower itemId", CLI::LOG_WARN);
if ($items[$vId][$piece['slot']] > $itemId)
$items[$vId][$piece['slot']] = $itemId;
}
}
else
$items[$vId][$piece['slot']] = $itemId;
/* check for type */
// skip cloaks, they mess with armor classes
if ($piece['slot'] == 16)
continue;
// skip event-sets
if ($piece['Quality'] == 1)
continue;
if ($piece['class'] == 2 && $piece['subclass'] == 0)
$type = 8; // 1H-Axe
else if ($piece['class'] == 2 && $piece['subclass'] == 4)
$type = 9; // 1H-Mace
else if ($piece['class'] == 2 && $piece['subclass'] == 7)
$type = 10; // 1H-Sword
else if ($piece['class'] == 2 && $piece['subclass'] == 13)
$type = 7; // Fist Weapon
else if ($piece['class'] == 2 && $piece['subclass'] == 15)
$type = 5; // Dagger
if (!$type)
{
if ($piece['class'] == 4 && $piece['slot'] == 12)
$type = 11; // trinket
else if ($piece['class'] == 4 && $piece['slot'] == 2)
$type = 12; // amulet
else if ($piece['class'] == 4 && $piece['subclass'] != 0)
$type = $piece['subclass']; // 'armor' set
if ($piece['class'] == 4 && $piece['slot'] == 11)
$hasRing = true; // contains ring
}
}
if ($hasRing && !$type)
$type = 6; // pure ring-set
$isMultiSet = false;
$oldSlotMask = 0x0;
foreach ($items as $subset)
{
$curSlotMask = 0x0;
foreach ($subset as $slot => $item)
$curSlotMask |= (1 << $slot);
if ($oldSlotMask && $oldSlotMask == $curSlotMask)
{
$isMultiSet = true;
break;
}
$oldSlotMask = $curSlotMask;
}
if (!$isMultiSet || !$canReuse || $setId == 555)
{
$temp = [];
foreach ($items as $subset)
{
foreach ($subset as $slot => $item)
{
if (isset($temp[$slot]) && $temp[$slot] < $item)
CLI::write("set: ".$setId." - conflict between item: ".$item." and item: ".$temp[$slot]." choosing lower itemId", CLI::LOG_WARN);
else if ($slot == 13 || $slot = 11) // special case
$temp[] = $item;
if (!isset($nPieces[$vId]))
$nPieces[$vId] = 1;
else
$temp[$slot] = $item;
$nPieces[$vId]++;
}
}
$items = [$temp];
$heroic = [reset($heroic)];
$nPieces = [count($temp)];
$quality = [reset($quality)];
$reqLvl = [reset($reqLvl)];
$max = $max ? [max($max)] : [0];
$min = $min ? [min($min)] : [0];
}
if (isset($items[$vId][$piece['slot']]))
{
// not reusable -> insert anyway on unique keys
if (!$canReuse)
$items[$vId][$piece['slot'].$itemId] = $itemId;
else
{
CLI::write("set: ".$setId." ilvl: ".$piece['ItemLevel']." - conflict between item: ".$items[$vId][$piece['slot']]." and item: ".$itemId." choosing lower itemId", CLI::LOG_WARN);
foreach ($items as &$subsets)
$subsets = array_pad($subsets, 10, 0);
if ($items[$vId][$piece['slot']] > $itemId)
$items[$vId][$piece['slot']] = $itemId;
}
}
else
$items[$vId][$piece['slot']] = $itemId;
/********************/
/* calc statbonuses */
/********************/
/* check for type */
for ($i = 1; $i < 9; $i++)
if ($setData['spellId'.$i] > 0 && $setData['itemCount'.$i] > 0)
$spells[] = [$setData['spellId'.$i], $setData['itemCount'.$i]];
$bonusSpells = new SpellList(array(['s.id', array_column($spells, 0)]));
$mods = $bonusSpells->getStatGain();
$spells = array_pad($spells, 8, [0, 0]);
for ($i = 1; $i < 9; $i++)
if ($setData['itemCount'.$i] > 0 && !empty($mods[$setData['spellId'.$i]]))
$gains[$setData['itemCount'.$i]] = $mods[$setData['spellId'.$i]];
/**************************/
/* get name & description */
/**************************/
foreach (array_keys(array_filter(Util::$localeStrings)) as $loc)
{
User::useLocale($loc);
$name[$loc] = Util::localizedString($setData, 'name');
foreach ($bonusSpells->iterate() as $__)
{
if (!isset($descText[$loc]))
$descText[$loc] = '';
$descText[$loc] .= $bonusSpells->parseText()[0]."\n";
}
// strip rating blocks - e.g. <!--rtg19-->14&nbsp;<small>(<!--rtg%19-->0.30%&nbsp;@&nbsp;L<!--lvl-->80)</small>
$descText[$loc] = preg_replace('/<!--rtg\d+-->(\d+)&nbsp.*?<\/small>/i', '\1', $descText[$loc]);
}
/****************************/
/* finalaize data and write */
/****************************/
foreach ($items as $vId => $vSet)
{
$note = 0;
foreach ($tagsById as $tag => $sets)
{
if (!in_array($setId, $sets))
// skip cloaks, they mess with armor classes
if ($piece['slot'] == 16)
continue;
$note = $tag;
// skip event-sets
if ($piece['Quality'] == 1)
continue;
if ($piece['class'] == 2 && $piece['subclass'] == 0)
$type = 8; // 1H-Axe
else if ($piece['class'] == 2 && $piece['subclass'] == 4)
$type = 9; // 1H-Mace
else if ($piece['class'] == 2 && $piece['subclass'] == 7)
$type = 10; // 1H-Sword
else if ($piece['class'] == 2 && $piece['subclass'] == 13)
$type = 7; // Fist Weapon
else if ($piece['class'] == 2 && $piece['subclass'] == 15)
$type = 5; // Dagger
if (!$type)
{
if ($piece['class'] == 4 && $piece['slot'] == 12)
$type = 11; // trinket
else if ($piece['class'] == 4 && $piece['slot'] == 2)
$type = 12; // amulet
else if ($piece['class'] == 4 && $piece['subclass'] != 0)
$type = $piece['subclass']; // 'armor' set
if ($piece['class'] == 4 && $piece['slot'] == 11)
$hasRing = true; // contains ring
}
}
if (!$note && $min > 120 && $classMask && $classMask != CLASS_MASK_ALL)
if ($hasRing && !$type)
$type = 6; // pure ring-set
$isMultiSet = false;
$oldSlotMask = 0x0;
foreach ($items as $subset)
{
foreach ($tagsByNamePart as $tag => $strings)
$curSlotMask = 0x0;
foreach ($subset as $slot => $item)
$curSlotMask |= (1 << $slot);
if ($oldSlotMask && $oldSlotMask == $curSlotMask)
{
foreach ($strings as $str)
$isMultiSet = true;
break;
}
$oldSlotMask = $curSlotMask;
}
if (!$isMultiSet || !$canReuse || $setId == 555)
{
$temp = [];
foreach ($items as $subset)
{
foreach ($subset as $slot => $item)
{
if (isset($pieces[reset($vSet)]) && stripos($pieces[reset($vSet)]['name'], $str) === 0)
if (isset($temp[$slot]) && $temp[$slot] < $item)
CLI::write("set: ".$setId." - conflict between item: ".$item." and item: ".$temp[$slot]." choosing lower itemId", CLI::LOG_WARN);
else if ($slot == 13 || $slot = 11) // special case
$temp[] = $item;
else
$temp[$slot] = $item;
}
}
$items = [$temp];
$heroic = [reset($heroic)];
$nPieces = [count($temp)];
$quality = [reset($quality)];
$reqLvl = [reset($reqLvl)];
$max = $max ? [max($max)] : [0];
$min = $min ? [min($min)] : [0];
}
foreach ($items as &$subsets)
$subsets = array_pad($subsets, 10, 0);
/********************/
/* calc statbonuses */
/********************/
for ($i = 1; $i < 9; $i++)
if ($setData['spellId'.$i] > 0 && $setData['itemCount'.$i] > 0)
$spells[] = [$setData['spellId'.$i], $setData['itemCount'.$i]];
$bonusSpells = new SpellList(array(['s.id', array_column($spells, 0)]));
$mods = $bonusSpells->getStatGain();
$spells = array_pad($spells, 8, [0, 0]);
for ($i = 1; $i < 9; $i++)
if ($setData['itemCount'.$i] > 0 && !empty($mods[$setData['spellId'.$i]]))
$gains[$setData['itemCount'.$i]] = $mods[$setData['spellId'.$i]];
/**************************/
/* get name & description */
/**************************/
foreach (array_keys(array_filter(Util::$localeStrings)) as $loc)
{
User::useLocale($loc);
$name[$loc] = Util::localizedString($setData, 'name');
foreach ($bonusSpells->iterate() as $__)
{
if (!isset($descText[$loc]))
$descText[$loc] = '';
$descText[$loc] .= $bonusSpells->parseText()[0]."\n";
}
// strip rating blocks - e.g. <!--rtg19-->14&nbsp;<small>(<!--rtg%19-->0.30%&nbsp;@&nbsp;L<!--lvl-->80)</small>
$descText[$loc] = preg_replace('/<!--rtg\d+-->(\d+)&nbsp.*?<\/small>/i', '\1', $descText[$loc]);
}
/****************************/
/* finalaize data and write */
/****************************/
foreach ($items as $vId => $vSet)
{
$note = 0;
foreach ($this->tagsById as $tag => $sets)
{
if (!in_array($setId, $sets))
continue;
$note = $tag;
}
if (!$note && $min > 120 && $classMask && $classMask != CLASS_MASK_ALL)
{
foreach ($this->tagsByNamePart as $tag => $strings)
{
foreach ($strings as $str)
{
$note = $tag;
break 2;
if (isset($pieces[reset($vSet)]) && stripos($pieces[reset($vSet)]['name'], $str) === 0)
{
$note = $tag;
break 2;
}
}
}
}
$row = [];
$row[] = $vId < 0 ? --$virtualId : $setId;
$row[] = $setId; // refSetId
$row[] = 0; // cuFlags
$row = array_merge($row, $name, $vSet);
foreach (array_column($spells, 0) as $spellId)
$row[] = $spellId;
foreach (array_column($spells, 1) as $nItems)
$row[] = $nItems;
$row = array_merge($row, $descText);
$row[] = serialize($gains);
$row[] = $nPieces[$vId];
$row[] = $min[$vId];
$row[] = $max[$vId];
$row[] = $reqLvl[$vId];
$row[] = $classMask == CLASS_MASK_ALL ? 0 : $classMask;
$row[] = !empty($heroic[$vId]) ? 1 : 0;
$row[] = $quality[$vId];
$row[] = $type;
$row[] = $note; // contentGroup
$row[] = $holiday;
$row[] = $setData['reqSkillId'];
$row[] = $setData['reqSkillLevel'];
DB::Aowow()->query('REPLACE INTO ?_itemset VALUES (?a)', array_values($row));
}
$row = [];
$row[] = $vId < 0 ? --$virtualId : $setId;
$row[] = $setId; // refSetId
$row[] = 0; // cuFlags
$row = array_merge($row, $name, $vSet);
foreach (array_column($spells, 0) as $spellId)
$row[] = $spellId;
foreach (array_column($spells, 1) as $nItems)
$row[] = $nItems;
$row = array_merge($row, $descText);
$row[] = serialize($gains);
$row[] = $nPieces[$vId];
$row[] = $min[$vId];
$row[] = $max[$vId];
$row[] = $reqLvl[$vId];
$row[] = $classMask == CLASS_MASK_ALL ? 0 : $classMask;
$row[] = !empty($heroic[$vId]) ? 1 : 0;
$row[] = $quality[$vId];
$row[] = $type;
$row[] = $note; // contentGroup
$row[] = $holiday;
$row[] = $setData['reqSkillId'];
$row[] = $setData['reqSkillLevel'];
DB::Aowow()->query('REPLACE INTO ?_itemset VALUES (?a)', array_values($row));
}
// hide empty sets
DB::Aowow()->query('UPDATE ?_itemset SET cuFlags = cuFlags | ?d WHERE item1 = 0', CUSTOM_EXCLUDE_FOR_LISTVIEW);
return true;
}
// hide empty sets
DB::Aowow()->query('UPDATE ?_itemset SET cuFlags = cuFlags | ?d WHERE item1 = 0', CUSTOM_EXCLUDE_FOR_LISTVIEW);
return true;
}
});
?>

View File

@@ -0,0 +1,18 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
if (!CLI)
die('not in cli mode');
SqlGen::register(new class extends SetupScript
{
use TrDBCcopy;
protected $command = 'lock';
protected $dbcSourceFiles = ['lock'];
});
?>

View File

@@ -0,0 +1,18 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
if (!CLI)
die('not in cli mode');
SqlGen::register(new class extends SetupScript
{
use TrDBCcopy;
protected $command = 'mailtemplate';
protected $dbcSourceFiles = ['mailtemplate'];
});
?>

View File

@@ -7,124 +7,121 @@ if (!CLI)
die('not in cli mode');
/* deps:
* gameobject_template
* gameobject_template_locale
* gameobject_questitem
*/
$customData = array(
);
$reqDBC = ['lock'];
function objects(array $ids = [])
SqlGen::register(new class extends SetupScript
{
$baseQuery = '
SELECT
go.entry,
`type`,
IF(`type` = 2, -2, -- quests 1
IF(`type` = 8 AND Data0 IN (1, 2, 3, 4, 1552), -6, -- tools
IF(`type` = 3 AND IFNULL(gqi.ItemId, 0) <> 0, -2, -- quests 2
IF(`type` IN (3, 9, 25), `type`, 0)))), -- regular chests, books, pools
0 AS event, -- linked worldevent
displayId,
go.name,
IFNULL(gtl2.`name`, "") AS name_loc2,
IFNULL(gtl3.`name`, "") AS name_loc3,
IFNULL(gtl4.`name`, "") AS name_loc4,
IFNULL(gtl6.`name`, "") AS name_loc6,
IFNULL(gtl8.`name`, "") AS name_loc8,
IFNULL(goa.faction, 0),
IFNULL(goa.flags, 0),
0 AS cuFlags, -- custom Flags
IF(`type` IN (3, 25), Data1, 0), -- lootId
IF(`type` IN (2, 3, 6, 10, 13, 24, 26), Data0, IF(`type` IN (0, 1), Data1, 0)), -- lockId
0 AS reqSkill, -- reqSkill
IF(`type` = 9, Data0, IF(`type` = 10, Data7, 0)), -- pageTextId
IF(`type` = 1, Data3, -- linkedTrapIds
IF(`type` = 3, Data7,
IF(`type` = 10, Data12,
IF(`type` = 8, Data2, 0)))),
IF(`type` = 5, Data5, -- reqQuest
IF(`type` = 3, Data8,
IF(`type` = 10, Data1,
IF(`type` = 8, Data4, 0)))),
IF(`type` = 8, Data0, 0), -- spellFocusId
IF(`type` = 10, Data10, -- onUseSpell
IF(`type` IN (18, 24), Data1,
IF(`type` = 26, Data2,
IF(`type` = 22, Data0, 0)))),
IF(`type` = 18, Data4, 0), -- onSuccessSpell
IF(`type` = 18, Data2, IF(`type` = 24, Data3, 0)), -- auraSpell
IF(`type` = 30, Data2, IF(`type` = 24, Data4, IF(`type` = 6, Data3, 0))), -- triggeredSpell
IF(`type` = 29, CONCAT_WS(" ", Data14, Data15, Data16, Data17, Data0), -- miscInfo: capturePoint
IF(`type` = 3, CONCAT_WS(" ", Data4, Data5, Data2), -- miscInfo: loot v
IF(`type` = 25, CONCAT_WS(" ", Data2, Data3, 0),
IF(`type` = 23, CONCAT_WS(" ", Data0, Data1, Data2), "")))), -- miscInfo: meetingStone
IF(ScriptName <> "", ScriptName, AIName)
FROM
gameobject_template go
LEFT JOIN
gameobject_template_addon goa ON go.entry = goa.entry
LEFT JOIN
gameobject_template_locale gtl2 ON go.entry = gtl2.entry AND gtl2.`locale` = "frFR"
LEFT JOIN
gameobject_template_locale gtl3 ON go.entry = gtl3.entry AND gtl3.`locale` = "deDE"
LEFT JOIN
gameobject_template_locale gtl4 ON go.entry = gtl4.entry AND gtl4.`locale` = "zhCN"
LEFT JOIN
gameobject_template_locale gtl6 ON go.entry = gtl6.entry AND gtl6.`locale` = "esES"
LEFT JOIN
gameobject_template_locale gtl8 ON go.entry = gtl8.entry AND gtl8.`locale` = "ruRU"
LEFT JOIN
gameobject_questitem gqi ON gqi.GameObjectEntry = go.entry
WHERE
go.entry > ?d
{
AND go.entry IN (?a)
}
GROUP BY
go.entry
ORDER BY
go.entry ASC
LIMIT
?d';
protected $command = 'objects';
$updateQuery = '
UPDATE
?_objects o
LEFT JOIN
dbc_lock l ON l.id = IF(o.`type` = 3, lockId, null)
SET
typeCat = IF(`type` = 3 AND (l.properties1 = 1 OR l.properties2 = 1), -5, -- footlocker
IF(`type` = 3 AND (l.properties1 = 2), -3, -- herb
IF(`type` = 3 AND (l.properties1 = 3), -4, typeCat))), -- ore
reqSkill = IF(`type` = 3 AND l.properties1 IN (1, 2, 3), IF(l.reqSkill1 > 1, l.reqSkill1, 1),
IF(`type` = 3 AND l.properties2 = 1, IF(l.reqSkill2 > 1, l.reqSkill2, 1), 0))
{
WHERE
o.id IN (?a)
}';
protected $tblDependancyTC = ['gameobject_template', 'gameobject_template_locale', 'gameobject_questitem'];
protected $dbcSourceFiles = ['lock'];
$lastMax = 0;
while ($objects = DB::World()->select($baseQuery, $lastMax, $ids ?: DBSIMPLE_SKIP, SqlGen::$stepSize))
public function generate(array $ids = []) : bool
{
$newMax = max(array_column($objects, 'entry'));
$baseQuery = '
SELECT
go.entry,
`type`,
IF(`type` = 2, -2, -- quests 1
IF(`type` = 8 AND Data0 IN (1, 2, 3, 4, 1552), -6, -- tools
IF(`type` = 3 AND IFNULL(gqi.ItemId, 0) <> 0, -2, -- quests 2
IF(`type` IN (3, 9, 25), `type`, 0)))), -- regular chests, books, pools
0 AS event, -- linked worldevent
displayId,
go.name,
IFNULL(gtl2.`name`, "") AS name_loc2,
IFNULL(gtl3.`name`, "") AS name_loc3,
IFNULL(gtl4.`name`, "") AS name_loc4,
IFNULL(gtl6.`name`, "") AS name_loc6,
IFNULL(gtl8.`name`, "") AS name_loc8,
IFNULL(goa.faction, 0),
IFNULL(goa.flags, 0),
0 AS cuFlags, -- custom Flags
IF(`type` IN (3, 25), Data1, 0), -- lootId
IF(`type` IN (2, 3, 6, 10, 13, 24, 26), Data0, IF(`type` IN (0, 1), Data1, 0)), -- lockId
0 AS reqSkill, -- reqSkill
IF(`type` = 9, Data0, IF(`type` = 10, Data7, 0)), -- pageTextId
IF(`type` = 1, Data3, -- linkedTrapIds
IF(`type` = 3, Data7,
IF(`type` = 10, Data12,
IF(`type` = 8, Data2, 0)))),
IF(`type` = 5, Data5, -- reqQuest
IF(`type` = 3, Data8,
IF(`type` = 10, Data1,
IF(`type` = 8, Data4, 0)))),
IF(`type` = 8, Data0, 0), -- spellFocusId
IF(`type` = 10, Data10, -- onUseSpell
IF(`type` IN (18, 24), Data1,
IF(`type` = 26, Data2,
IF(`type` = 22, Data0, 0)))),
IF(`type` = 18, Data4, 0), -- onSuccessSpell
IF(`type` = 18, Data2, IF(`type` = 24, Data3, 0)), -- auraSpell
IF(`type` = 30, Data2, IF(`type` = 24, Data4, IF(`type` = 6, Data3, 0))), -- triggeredSpell
IF(`type` = 29, CONCAT_WS(" ", Data14, Data15, Data16, Data17, Data0), -- miscInfo: capturePoint
IF(`type` = 3, CONCAT_WS(" ", Data4, Data5, Data2), -- miscInfo: loot v
IF(`type` = 25, CONCAT_WS(" ", Data2, Data3, 0),
IF(`type` = 23, CONCAT_WS(" ", Data0, Data1, Data2), "")))), -- miscInfo: meetingStone
IF(ScriptName <> "", ScriptName, AIName)
FROM
gameobject_template go
LEFT JOIN
gameobject_template_addon goa ON go.entry = goa.entry
LEFT JOIN
gameobject_template_locale gtl2 ON go.entry = gtl2.entry AND gtl2.`locale` = "frFR"
LEFT JOIN
gameobject_template_locale gtl3 ON go.entry = gtl3.entry AND gtl3.`locale` = "deDE"
LEFT JOIN
gameobject_template_locale gtl4 ON go.entry = gtl4.entry AND gtl4.`locale` = "zhCN"
LEFT JOIN
gameobject_template_locale gtl6 ON go.entry = gtl6.entry AND gtl6.`locale` = "esES"
LEFT JOIN
gameobject_template_locale gtl8 ON go.entry = gtl8.entry AND gtl8.`locale` = "ruRU"
LEFT JOIN
gameobject_questitem gqi ON gqi.GameObjectEntry = go.entry
WHERE
go.entry > ?d
{
AND go.entry IN (?a)
}
GROUP BY
go.entry
ORDER BY
go.entry ASC
LIMIT
?d';
CLI::write(' * sets '.($lastMax + 1).' - '.$newMax);
$updateQuery = '
UPDATE
?_objects o
LEFT JOIN
dbc_lock l ON l.id = IF(o.`type` = 3, lockId, null)
SET
typeCat = IF(`type` = 3 AND (l.properties1 = 1 OR l.properties2 = 1), -5, -- footlocker
IF(`type` = 3 AND (l.properties1 = 2), -3, -- herb
IF(`type` = 3 AND (l.properties1 = 3), -4, typeCat))), -- ore
reqSkill = IF(`type` = 3 AND l.properties1 IN (1, 2, 3), IF(l.reqSkill1 > 1, l.reqSkill1, 1),
IF(`type` = 3 AND l.properties2 = 1, IF(l.reqSkill2 > 1, l.reqSkill2, 1), 0))
{
WHERE
o.id IN (?a)
}';
$lastMax = $newMax;
$lastMax = 0;
while ($objects = DB::World()->select($baseQuery, $lastMax, $ids ?: DBSIMPLE_SKIP, SqlGen::$sqlBatchSize))
{
$newMax = max(array_column($objects, 'entry'));
foreach ($objects as $o)
DB::Aowow()->query('REPLACE INTO ?_objects VALUES (?a)', array_values($o));
CLI::write(' * sets '.($lastMax + 1).' - '.$newMax);
$lastMax = $newMax;
foreach ($objects as $o)
DB::Aowow()->query('REPLACE INTO ?_objects VALUES (?a)', array_values($o));
}
// apply typeCat and reqSkill depending on locks
DB::Aowow()->query($updateQuery, $ids ?: DBSIMPLE_SKIP);
return true;
}
// apply typeCat and reqSkill depending on locks
DB::Aowow()->query($updateQuery, $ids ?: DBSIMPLE_SKIP);
return true;
}
});
?>

View File

@@ -7,121 +7,120 @@ if (!CLI)
die('not in cli mode');
/* deps:
* creature_template
* creature
*/
$customData = array(
);
$reqDBC = ['talent', 'spell', 'skilllineability', 'creaturefamily'];
function pet(array $ids = [])
SqlGen::register(new class extends SetupScript
{
$baseQuery = '
REPLACE INTO
?_pet
SELECT
f.id,
categoryEnumId,
0, -- cuFlags
0, -- minLevel
0, -- maxLevel
petFoodMask,
petTalentType,
0, -- exotic
0, -- expansion
name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8,
ic.id,
skillLine1,
0, 0, 0, 0, -- spell[1-4]
0, 0, 0 -- armor, damage, health
FROM
dbc_creaturefamily f
LEFT JOIN
?_icons ic ON ic.name = LOWER(SUBSTRING_INDEX(f.iconString, "\\\\", -1))
WHERE
petTalentType <> -1';
protected $command = 'pet';
$spawnQuery = '
SELECT
ct.family AS ARRAY_KEY,
MIN(ct.minlevel) AS minLevel,
MAX(ct.maxlevel) AS maxLevel,
IF(ct.type_flags & 0x10000, 1, 0) AS exotic
FROM
creature_template ct
JOIN
creature c ON ct.entry = c.id
WHERE
ct.type_flags & 0x1
GROUP BY
ct.family';
protected $tblDependancyAowow = ['icons'];
protected $tblDependancyTC = ['creature_template', 'creature'];
protected $dbcSourceFiles = ['talent', 'spell', 'skilllineability', 'creaturefamily'];
$bonusQuery = '
UPDATE
?_pet p,
dbc_skilllineability sla,
dbc_spell s
SET
armor = s.effect2BasePoints + s.effect2DieSides,
damage = s.effect1BasePoints + s.effect1DieSides,
health = s.effect3BasePoints + s.effect3DieSides
WHERE
p.skillLineId = sla.skillLineId AND
sla.spellId = s.id AND
s.name_loc0 = "Tamed Pet Passive (DND)"';
$spellQuery = '
SELECT
p.id,
MAX(s.id) AS spell
FROM
dbc_skilllineability sla
JOIN
?_pet p ON p.skillLineId = sla.skillLineId
JOIN
dbc_spell s ON sla.spellId = s.id
LEFT OUTER JOIN
dbc_talent t ON s.id = t.rank1
WHERE
(s.attributes0 & 0x40) = 0 AND
t.id IS NULL
GROUP BY
s.name_loc0, p.id';
// basic copy from creaturefamily.dbc
DB::Aowow()->query($baseQuery);
// stats from craeture_template
$spawnInfo = DB::World()->query($spawnQuery);
foreach ($spawnInfo as $id => $info)
DB::Aowow()->query('UPDATE ?_pet SET ?a WHERE id = ?d', $info, $id);
// add petFamilyModifier to health, mana, dmg
DB::Aowow()->query($bonusQuery);
// add expansion manually
DB::Aowow()->query('UPDATE ?_pet SET expansion = 1 WHERE id IN (30, 31, 32, 33, 34)');
DB::Aowow()->query('UPDATE ?_pet SET expansion = 2 WHERE id IN (37, 38, 39, 41, 42, 43, 44, 45, 46)');
// assign pet spells
$pets = DB::Aowow()->select($spellQuery);
$res = [];
foreach ($pets as $set) // convert to usable structure
public function generate(array $ids = []) : bool
{
if (!isset($res[$set['id']]))
$res[$set['id']] = [];
$baseQuery = '
REPLACE INTO
?_pet
SELECT
f.id,
categoryEnumId,
0, -- cuFlags
0, -- minLevel
0, -- maxLevel
petFoodMask,
petTalentType,
0, -- exotic
0, -- expansion
name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8,
ic.id,
skillLine1,
0, 0, 0, 0, -- spell[1-4]
0, 0, 0 -- armor, damage, health
FROM
dbc_creaturefamily f
LEFT JOIN
?_icons ic ON ic.name = LOWER(SUBSTRING_INDEX(f.iconString, "\\\\", -1))
WHERE
petTalentType <> -1';
$res[$set['id']]['spellId'.(count($res[$set['id']]) + 1)] = $set['spell'];
$spawnQuery = '
SELECT
ct.family AS ARRAY_KEY,
MIN(ct.minlevel) AS minLevel,
MAX(ct.maxlevel) AS maxLevel,
IF(ct.type_flags & 0x10000, 1, 0) AS exotic
FROM
creature_template ct
JOIN
creature c ON ct.entry = c.id
WHERE
ct.type_flags & 0x1
GROUP BY
ct.family';
$bonusQuery = '
UPDATE
?_pet p,
dbc_skilllineability sla,
dbc_spell s
SET
armor = s.effect2BasePoints + s.effect2DieSides,
damage = s.effect1BasePoints + s.effect1DieSides,
health = s.effect3BasePoints + s.effect3DieSides
WHERE
p.skillLineId = sla.skillLineId AND
sla.spellId = s.id AND
s.name_loc0 = "Tamed Pet Passive (DND)"';
$spellQuery = '
SELECT
p.id,
MAX(s.id) AS spell
FROM
dbc_skilllineability sla
JOIN
?_pet p ON p.skillLineId = sla.skillLineId
JOIN
dbc_spell s ON sla.spellId = s.id
LEFT OUTER JOIN
dbc_talent t ON s.id = t.rank1
WHERE
(s.attributes0 & 0x40) = 0 AND
t.id IS NULL
GROUP BY
s.name_loc0, p.id';
// basic copy from creaturefamily.dbc
DB::Aowow()->query($baseQuery);
// stats from craeture_template
$spawnInfo = DB::World()->query($spawnQuery);
foreach ($spawnInfo as $id => $info)
DB::Aowow()->query('UPDATE ?_pet SET ?a WHERE id = ?d', $info, $id);
// add petFamilyModifier to health, mana, dmg
DB::Aowow()->query($bonusQuery);
// add expansion manually
DB::Aowow()->query('UPDATE ?_pet SET expansion = 1 WHERE id IN (30, 31, 32, 33, 34)');
DB::Aowow()->query('UPDATE ?_pet SET expansion = 2 WHERE id IN (37, 38, 39, 41, 42, 43, 44, 45, 46)');
// assign pet spells
$pets = DB::Aowow()->select($spellQuery);
$res = [];
foreach ($pets as $set) // convert to usable structure
{
if (!isset($res[$set['id']]))
$res[$set['id']] = [];
$res[$set['id']]['spellId'.(count($res[$set['id']]) + 1)] = $set['spell'];
}
foreach ($res as $pId => $row)
DB::Aowow()->query('UPDATE ?_pet SET ?a WHERE id = ?d', $row, $pId);
return true;
}
foreach ($res as $pId => $row)
DB::Aowow()->query('UPDATE ?_pet SET ?a WHERE id = ?d', $row, $pId);
return true;
}
});
?>

View File

@@ -7,266 +7,260 @@ if (!CLI)
die('not in cli mode');
/* deps:
* quest_template
* quest_template_addon
* quest_template_locale
* game_event
* game_event_seasonal_questrelation
* disables
*/
$customData = array(
);
$reqDBC = ['questxp', 'questfactionreward'];
function quests(array $ids = [])
SqlGen::register(new class extends SetupScript
{
$baseQuery = '
SELECT
q.ID,
QuestType, -- Method
QuestLevel,
MinLevel,
IFNULL(qa.MaxLevel, 0),
QuestSortID,
QuestSortID AS zoneOrSortBak, -- ZoneOrSortBak
QuestInfoID, -- QuestType
SuggestedGroupNum,
TimeAllowed,
IFNULL(gesqr.eventEntry, 0) AS eventId,
IFNULL(qa.PrevQuestId, 0),
IFNULL(qa.NextQuestId, 0),
IFNULL(qa.ExclusiveGroup, 0),
RewardNextQuest,
q.Flags,
IFNULL(qa.SpecialFlags, 0),
(
IF(d.entry IS NULL, 0, 134217728) + -- disabled
IF(q.Flags & 16384, 536870912, 0) -- unavailable
) AS cuFlags, -- cuFlags
IFNULL(qa.AllowableClasses, 0),
AllowableRaces,
IFNULL(qa.RequiredSkillId, 0), IFNULL(qa.RequiredSkillPoints, 0),
RequiredFactionId1, RequiredFactionId2,
RequiredFactionValue1, RequiredFactionValue2,
IFNULL(qa.RequiredMinRepFaction, 0),IFNULL(qa.RequiredMaxRepFaction, 0),
IFNULL(qa.RequiredMinRepValue, 0), IFNULL(qa.RequiredMaxRepValue, 0),
RequiredPlayerKills,
StartItem,
IFNULL(qa.ProvidedItemCount, 0),
IFNULL(qa.SourceSpellId, 0),
RewardXPDifficulty, -- QuestXP.dbc x level
RewardMoney,
RewardBonusMoney,
RewardDisplaySpell, RewardSpell,
RewardHonor * 124 * RewardKillHonor, -- alt calculation in QuestDef.cpp -> Quest::CalculateHonorGain(playerLevel)
IFNULL(qa.RewardMailTemplateId, 0), IFNULL(qa.RewardMailDelay, 0),
RewardTitle,
RewardTalents,
RewardArenaPoints,
RewardItem1, RewardItem2, RewardItem3, RewardItem4,
RewardAmount1, RewardAmount2, RewardAmount3, RewardAmount4,
RewardChoiceItemID1, RewardChoiceItemID2, RewardChoiceItemID3, RewardChoiceItemID4, RewardChoiceItemID5, RewardChoiceItemID6,
RewardChoiceItemQuantity1, RewardChoiceItemQuantity2, RewardChoiceItemQuantity3, RewardChoiceItemQuantity4, RewardChoiceItemQuantity5, RewardChoiceItemQuantity6,
RewardFactionID1, RewardFactionID2, RewardFactionID3, RewardFactionID4, RewardFactionID5,
IF (RewardFactionOverride1 <> 0, RewardFactionOverride1 / 100, RewardFactionValue1),
IF (RewardFactionOverride2 <> 0, RewardFactionOverride2 / 100, RewardFactionValue2),
IF (RewardFactionOverride3 <> 0, RewardFactionOverride3 / 100, RewardFactionValue3),
IF (RewardFactionOverride4 <> 0, RewardFactionOverride4 / 100, RewardFactionValue4),
IF (RewardFactionOverride5 <> 0, RewardFactionOverride5 / 100, RewardFactionValue5),
q.LogTitle, IFNULL(qtl2.Title, ""), IFNULL(qtl3.Title, ""), IFNULL(qtl4.Title, ""), IFNULL(qtl6.Title, ""), IFNULL(qtl8.Title, ""),
q.LogDescription, IFNULL(qtl2.Objectives, ""), IFNULL(qtl3.Objectives, ""), IFNULL(qtl4.Objectives, ""), IFNULL(qtl6.Objectives, ""), IFNULL(qtl8.Objectives, ""),
q.QuestDescription, IFNULL(qtl2.Details, ""), IFNULL(qtl3.Details, ""), IFNULL(qtl4.Details, ""), IFNULL(qtl6.Details, ""), IFNULL(qtl8.Details, ""),
q.AreaDescription, IFNULL(qtl2.EndText, ""), IFNULL(qtl3.EndText, ""), IFNULL(qtl4.EndText, ""), IFNULL(qtl6.EndText, ""), IFNULL(qtl8.EndText, ""),
IFNULL(qor.RewardText, ""), IFNULL(qorl2.RewardText, ""), IFNULL(qorl3.RewardText, ""), IFNULL(qorl4.RewardText, ""), IFNULL(qorl6.RewardText, ""), IFNULL(qorl8.RewardText, ""),
IFNULL(qri.CompletionText, ""), IFNULL(qril2.CompletionText, ""), IFNULL(qril3.CompletionText, ""), IFNULL(qril4.CompletionText, ""), IFNULL(qril6.CompletionText, ""), IFNULL(qril8.CompletionText, ""),
q.QuestCompletionLog, IFNULL(qtl2.CompletedText, ""), IFNULL(qtl3.CompletedText, ""), IFNULL(qtl4.CompletedText, ""), IFNULL(qtl6.CompletedText, ""), IFNULL(qtl8.CompletedText, ""),
RequiredNpcOrGo1, RequiredNpcOrGo2, RequiredNpcOrGo3, RequiredNpcOrGo4,
RequiredNpcOrGoCount1, RequiredNpcOrGoCount2, RequiredNpcOrGoCount3, RequiredNpcOrGoCount4,
ItemDrop1, ItemDrop2, ItemDrop3, ItemDrop4,
ItemDropQuantity1, ItemDropQuantity2, ItemDropQuantity3, ItemDropQuantity4,
RequiredItemId1, RequiredItemId2, RequiredItemId3, RequiredItemId4, RequiredItemId5, RequiredItemId6,
RequiredItemCount1, RequiredItemCount2, RequiredItemCount3, RequiredItemCount4, RequiredItemCount5, RequiredItemCount6,
q.ObjectiveText1, IFNULL(qtl2.ObjectiveText1, ""), IFNULL(qtl3.ObjectiveText1, ""), IFNULL(qtl4.ObjectiveText1, ""), IFNULL(qtl6.ObjectiveText1, ""), IFNULL(qtl8.ObjectiveText1, ""),
q.ObjectiveText2, IFNULL(qtl2.ObjectiveText2, ""), IFNULL(qtl3.ObjectiveText2, ""), IFNULL(qtl4.ObjectiveText2, ""), IFNULL(qtl6.ObjectiveText2, ""), IFNULL(qtl8.ObjectiveText2, ""),
q.ObjectiveText3, IFNULL(qtl2.ObjectiveText3, ""), IFNULL(qtl3.ObjectiveText3, ""), IFNULL(qtl4.ObjectiveText3, ""), IFNULL(qtl6.ObjectiveText3, ""), IFNULL(qtl8.ObjectiveText3, ""),
q.ObjectiveText4, IFNULL(qtl2.ObjectiveText4, ""), IFNULL(qtl3.ObjectiveText4, ""), IFNULL(qtl4.ObjectiveText4, ""), IFNULL(qtl6.ObjectiveText4, ""), IFNULL(qtl8.ObjectiveText4, "")
FROM
quest_template q
LEFT JOIN
quest_template_locale qtl2 ON q.ID = qtl2.ID AND qtl2.locale = "frFR"
LEFT JOIN
quest_template_locale qtl3 ON q.ID = qtl3.ID AND qtl3.locale = "deDE"
LEFT JOIN
quest_template_locale qtl4 ON q.ID = qtl4.ID AND qtl4.locale = "zhCN"
LEFT JOIN
quest_template_locale qtl6 ON q.ID = qtl6.ID AND qtl6.locale = "esES"
LEFT JOIN
quest_template_locale qtl8 ON q.ID = qtl8.ID AND qtl8.locale = "ruRU"
LEFT JOIN
quest_offer_reward qor ON q.ID = qor.ID
LEFT JOIN
quest_offer_reward_locale qorl2 ON q.ID = qorl2.ID AND qorl2.locale = "frFR"
LEFT JOIN
quest_offer_reward_locale qorl3 ON q.ID = qorl3.ID AND qorl3.locale = "deDE"
LEFT JOIN
quest_offer_reward_locale qorl4 ON q.ID = qorl4.ID AND qorl4.locale = "zhCN"
LEFT JOIN
quest_offer_reward_locale qorl6 ON q.ID = qorl6.ID AND qorl6.locale = "esES"
LEFT JOIN
quest_offer_reward_locale qorl8 ON q.ID = qorl8.ID AND qorl8.locale = "ruRU"
LEFT JOIN
quest_request_items qri ON q.ID = qri.ID
LEFT JOIN
quest_request_items_locale qril2 ON q.ID = qril2.ID AND qril2.locale = "frFR"
LEFT JOIN
quest_request_items_locale qril3 ON q.ID = qril3.ID AND qril3.locale = "deDE"
LEFT JOIN
quest_request_items_locale qril4 ON q.ID = qril4.ID AND qril4.locale = "zhCN"
LEFT JOIN
quest_request_items_locale qril6 ON q.ID = qril6.ID AND qril6.locale = "esES"
LEFT JOIN
quest_request_items_locale qril8 ON q.ID = qril8.ID AND qril8.locale = "ruRU"
LEFT JOIN
quest_template_addon qa ON q.ID = qa.ID
LEFT JOIN
game_event_seasonal_questrelation gesqr ON gesqr.questId = q.ID
LEFT JOIN
disables d ON d.entry = q.ID AND d.sourceType = 1
WHERE
q.id > ?d
{
AND q.id IN (?a)
}
ORDER BY
q.ID ASC
LIMIT
?d';
protected $command = 'quests';
$xpQuery = '
UPDATE
?_quests q,
dbc_questxp xp
SET
rewardXP = (CASE rewardXP
WHEN 0 THEN xp.Field1 WHEN 1 THEN xp.Field2 WHEN 2 THEN xp.Field3 WHEN 3 THEN xp.Field4 WHEN 4 THEN xp.Field5
WHEN 5 THEN xp.Field6 WHEN 6 THEN xp.Field7 WHEN 7 THEN xp.Field8 WHEN 8 THEN xp.Field9 WHEN 9 THEN xp.Field10
ELSE 0
END)
WHERE
xp.id = q.level { AND
q.id IN(?a)
}';
protected $tblDependancyTC = ['quest_template', 'quest_template_addon', 'quest_template_locale', 'game_event', 'game_event_seasonal_questrelation', 'disables'];
protected $dbcSourceFiles = ['questxp', 'questfactionreward'];
$repQuery = '
UPDATE
?_quests q
LEFT JOIN
dbc_questfactionreward rep ON rep.id = IF(rewardFactionValue?d > 0, 1, 2)
SET
rewardFactionValue?d = (CASE ABS(rewardFactionValue?d)
WHEN 0 THEN rep.Field1 WHEN 1 THEN rep.Field2 WHEN 2 THEN rep.Field3 WHEN 3 THEN rep.Field4 WHEN 4 THEN rep.Field5
WHEN 5 THEN rep.Field6 WHEN 6 THEN rep.Field7 WHEN 7 THEN rep.Field8 WHEN 8 THEN rep.Field9 WHEN 9 THEN rep.Field10
ELSE 0
END)
WHERE
ABS(rewardFactionValue?d) BETWEEN 1 AND 10 { AND
q.id IN(?a)
}';
$lastMax = 0;
while ($quests = DB::World()->select($baseQuery, $lastMax, $ids ?: DBSIMPLE_SKIP, SqlGen::$stepSize))
public function generate(array $ids = []) : bool
{
$newMax = max(array_column($quests, 'ID'));
$baseQuery = '
SELECT
q.ID,
QuestType, -- Method
QuestLevel,
MinLevel,
IFNULL(qa.MaxLevel, 0),
QuestSortID,
QuestSortID AS zoneOrSortBak, -- ZoneOrSortBak
QuestInfoID, -- QuestType
SuggestedGroupNum,
TimeAllowed,
IFNULL(gesqr.eventEntry, 0) AS eventId,
IFNULL(qa.PrevQuestId, 0),
IFNULL(qa.NextQuestId, 0),
IFNULL(qa.ExclusiveGroup, 0),
RewardNextQuest,
q.Flags,
IFNULL(qa.SpecialFlags, 0),
(
IF(d.entry IS NULL, 0, 134217728) + -- disabled
IF(q.Flags & 16384, 536870912, 0) -- unavailable
) AS cuFlags, -- cuFlags
IFNULL(qa.AllowableClasses, 0),
AllowableRaces,
IFNULL(qa.RequiredSkillId, 0), IFNULL(qa.RequiredSkillPoints, 0),
RequiredFactionId1, RequiredFactionId2,
RequiredFactionValue1, RequiredFactionValue2,
IFNULL(qa.RequiredMinRepFaction, 0),IFNULL(qa.RequiredMaxRepFaction, 0),
IFNULL(qa.RequiredMinRepValue, 0), IFNULL(qa.RequiredMaxRepValue, 0),
RequiredPlayerKills,
StartItem,
IFNULL(qa.ProvidedItemCount, 0),
IFNULL(qa.SourceSpellId, 0),
RewardXPDifficulty, -- QuestXP.dbc x level
RewardMoney,
RewardBonusMoney,
RewardDisplaySpell, RewardSpell,
RewardHonor * 124 * RewardKillHonor, -- alt calculation in QuestDef.cpp -> Quest::CalculateHonorGain(playerLevel)
IFNULL(qa.RewardMailTemplateId, 0), IFNULL(qa.RewardMailDelay, 0),
RewardTitle,
RewardTalents,
RewardArenaPoints,
RewardItem1, RewardItem2, RewardItem3, RewardItem4,
RewardAmount1, RewardAmount2, RewardAmount3, RewardAmount4,
RewardChoiceItemID1, RewardChoiceItemID2, RewardChoiceItemID3, RewardChoiceItemID4, RewardChoiceItemID5, RewardChoiceItemID6,
RewardChoiceItemQuantity1, RewardChoiceItemQuantity2, RewardChoiceItemQuantity3, RewardChoiceItemQuantity4, RewardChoiceItemQuantity5, RewardChoiceItemQuantity6,
RewardFactionID1, RewardFactionID2, RewardFactionID3, RewardFactionID4, RewardFactionID5,
IF (RewardFactionOverride1 <> 0, RewardFactionOverride1 / 100, RewardFactionValue1),
IF (RewardFactionOverride2 <> 0, RewardFactionOverride2 / 100, RewardFactionValue2),
IF (RewardFactionOverride3 <> 0, RewardFactionOverride3 / 100, RewardFactionValue3),
IF (RewardFactionOverride4 <> 0, RewardFactionOverride4 / 100, RewardFactionValue4),
IF (RewardFactionOverride5 <> 0, RewardFactionOverride5 / 100, RewardFactionValue5),
q.LogTitle, IFNULL(qtl2.Title, ""), IFNULL(qtl3.Title, ""), IFNULL(qtl4.Title, ""), IFNULL(qtl6.Title, ""), IFNULL(qtl8.Title, ""),
q.LogDescription, IFNULL(qtl2.Objectives, ""), IFNULL(qtl3.Objectives, ""), IFNULL(qtl4.Objectives, ""), IFNULL(qtl6.Objectives, ""), IFNULL(qtl8.Objectives, ""),
q.QuestDescription, IFNULL(qtl2.Details, ""), IFNULL(qtl3.Details, ""), IFNULL(qtl4.Details, ""), IFNULL(qtl6.Details, ""), IFNULL(qtl8.Details, ""),
q.AreaDescription, IFNULL(qtl2.EndText, ""), IFNULL(qtl3.EndText, ""), IFNULL(qtl4.EndText, ""), IFNULL(qtl6.EndText, ""), IFNULL(qtl8.EndText, ""),
IFNULL(qor.RewardText, ""), IFNULL(qorl2.RewardText, ""), IFNULL(qorl3.RewardText, ""), IFNULL(qorl4.RewardText, ""), IFNULL(qorl6.RewardText, ""), IFNULL(qorl8.RewardText, ""),
IFNULL(qri.CompletionText, ""), IFNULL(qril2.CompletionText, ""), IFNULL(qril3.CompletionText, ""), IFNULL(qril4.CompletionText, ""), IFNULL(qril6.CompletionText, ""), IFNULL(qril8.CompletionText, ""),
q.QuestCompletionLog, IFNULL(qtl2.CompletedText, ""), IFNULL(qtl3.CompletedText, ""), IFNULL(qtl4.CompletedText, ""), IFNULL(qtl6.CompletedText, ""), IFNULL(qtl8.CompletedText, ""),
RequiredNpcOrGo1, RequiredNpcOrGo2, RequiredNpcOrGo3, RequiredNpcOrGo4,
RequiredNpcOrGoCount1, RequiredNpcOrGoCount2, RequiredNpcOrGoCount3, RequiredNpcOrGoCount4,
ItemDrop1, ItemDrop2, ItemDrop3, ItemDrop4,
ItemDropQuantity1, ItemDropQuantity2, ItemDropQuantity3, ItemDropQuantity4,
RequiredItemId1, RequiredItemId2, RequiredItemId3, RequiredItemId4, RequiredItemId5, RequiredItemId6,
RequiredItemCount1, RequiredItemCount2, RequiredItemCount3, RequiredItemCount4, RequiredItemCount5, RequiredItemCount6,
q.ObjectiveText1, IFNULL(qtl2.ObjectiveText1, ""), IFNULL(qtl3.ObjectiveText1, ""), IFNULL(qtl4.ObjectiveText1, ""), IFNULL(qtl6.ObjectiveText1, ""), IFNULL(qtl8.ObjectiveText1, ""),
q.ObjectiveText2, IFNULL(qtl2.ObjectiveText2, ""), IFNULL(qtl3.ObjectiveText2, ""), IFNULL(qtl4.ObjectiveText2, ""), IFNULL(qtl6.ObjectiveText2, ""), IFNULL(qtl8.ObjectiveText2, ""),
q.ObjectiveText3, IFNULL(qtl2.ObjectiveText3, ""), IFNULL(qtl3.ObjectiveText3, ""), IFNULL(qtl4.ObjectiveText3, ""), IFNULL(qtl6.ObjectiveText3, ""), IFNULL(qtl8.ObjectiveText3, ""),
q.ObjectiveText4, IFNULL(qtl2.ObjectiveText4, ""), IFNULL(qtl3.ObjectiveText4, ""), IFNULL(qtl4.ObjectiveText4, ""), IFNULL(qtl6.ObjectiveText4, ""), IFNULL(qtl8.ObjectiveText4, "")
FROM
quest_template q
LEFT JOIN
quest_template_locale qtl2 ON q.ID = qtl2.ID AND qtl2.locale = "frFR"
LEFT JOIN
quest_template_locale qtl3 ON q.ID = qtl3.ID AND qtl3.locale = "deDE"
LEFT JOIN
quest_template_locale qtl4 ON q.ID = qtl4.ID AND qtl4.locale = "zhCN"
LEFT JOIN
quest_template_locale qtl6 ON q.ID = qtl6.ID AND qtl6.locale = "esES"
LEFT JOIN
quest_template_locale qtl8 ON q.ID = qtl8.ID AND qtl8.locale = "ruRU"
LEFT JOIN
quest_offer_reward qor ON q.ID = qor.ID
LEFT JOIN
quest_offer_reward_locale qorl2 ON q.ID = qorl2.ID AND qorl2.locale = "frFR"
LEFT JOIN
quest_offer_reward_locale qorl3 ON q.ID = qorl3.ID AND qorl3.locale = "deDE"
LEFT JOIN
quest_offer_reward_locale qorl4 ON q.ID = qorl4.ID AND qorl4.locale = "zhCN"
LEFT JOIN
quest_offer_reward_locale qorl6 ON q.ID = qorl6.ID AND qorl6.locale = "esES"
LEFT JOIN
quest_offer_reward_locale qorl8 ON q.ID = qorl8.ID AND qorl8.locale = "ruRU"
LEFT JOIN
quest_request_items qri ON q.ID = qri.ID
LEFT JOIN
quest_request_items_locale qril2 ON q.ID = qril2.ID AND qril2.locale = "frFR"
LEFT JOIN
quest_request_items_locale qril3 ON q.ID = qril3.ID AND qril3.locale = "deDE"
LEFT JOIN
quest_request_items_locale qril4 ON q.ID = qril4.ID AND qril4.locale = "zhCN"
LEFT JOIN
quest_request_items_locale qril6 ON q.ID = qril6.ID AND qril6.locale = "esES"
LEFT JOIN
quest_request_items_locale qril8 ON q.ID = qril8.ID AND qril8.locale = "ruRU"
LEFT JOIN
quest_template_addon qa ON q.ID = qa.ID
LEFT JOIN
game_event_seasonal_questrelation gesqr ON gesqr.questId = q.ID
LEFT JOIN
disables d ON d.entry = q.ID AND d.sourceType = 1
WHERE
q.id > ?d
{
AND q.id IN (?a)
}
ORDER BY
q.ID ASC
LIMIT
?d';
CLI::write(' * sets '.($lastMax + 1).' - '.$newMax);
$xpQuery = '
UPDATE
?_quests q,
dbc_questxp xp
SET
rewardXP = (CASE rewardXP
WHEN 0 THEN xp.Field1 WHEN 1 THEN xp.Field2 WHEN 2 THEN xp.Field3 WHEN 3 THEN xp.Field4 WHEN 4 THEN xp.Field5
WHEN 5 THEN xp.Field6 WHEN 6 THEN xp.Field7 WHEN 7 THEN xp.Field8 WHEN 8 THEN xp.Field9 WHEN 9 THEN xp.Field10
ELSE 0
END)
WHERE
xp.id = q.level { AND
q.id IN(?a)
}';
$lastMax = $newMax;
$repQuery = '
UPDATE
?_quests q
LEFT JOIN
dbc_questfactionreward rep ON rep.id = IF(rewardFactionValue?d > 0, 1, 2)
SET
rewardFactionValue?d = (CASE ABS(rewardFactionValue?d)
WHEN 0 THEN rep.Field1 WHEN 1 THEN rep.Field2 WHEN 2 THEN rep.Field3 WHEN 3 THEN rep.Field4 WHEN 4 THEN rep.Field5
WHEN 5 THEN rep.Field6 WHEN 6 THEN rep.Field7 WHEN 7 THEN rep.Field8 WHEN 8 THEN rep.Field9 WHEN 9 THEN rep.Field10
ELSE 0
END)
WHERE
ABS(rewardFactionValue?d) BETWEEN 1 AND 10 { AND
q.id IN(?a)
}';
foreach ($quests as $q)
DB::Aowow()->query('REPLACE INTO ?_quests VALUES (?a)', array_values($q));
$lastMax = 0;
while ($quests = DB::World()->select($baseQuery, $lastMax, $ids ?: DBSIMPLE_SKIP, SqlGen::$sqlBatchSize))
{
$newMax = max(array_column($quests, 'ID'));
CLI::write(' * sets '.($lastMax + 1).' - '.$newMax);
$lastMax = $newMax;
foreach ($quests as $q)
DB::Aowow()->query('REPLACE INTO ?_quests VALUES (?a)', array_values($q));
}
/*
just some random thoughts here ..
quest-custom-flags are derived from flags and specialFlags
since they are not used further than being sent to JS as wFlags this is fine..
should they be saved to db anyway..?
same with QUEST_FLAG_UNAVAILABLE => CUSTOM_EXCLUDE_FOR_LISTVIEW
*/
// unpack XP-reward
DB::Aowow()->query($xpQuery, $ids ?: DBSIMPLE_SKIP);
// unpack Rep-rewards
for ($i = 1; $i < 6; $i++)
DB::Aowow()->query($repQuery, $i, $i, $i, $i, $ids ?: DBSIMPLE_SKIP);
// zoneorsort for quests need updating
// partially points non-instanced area with identic name for instance quests
$subcats = array(
-221 => 440, // Treasure Map => Tanaris
-284 => 0, // Special => Misc (some quests get shuffled into seasonal)
151 => 0, // Designer Island => Misc
22 => 0, // Programmer Isle
35 => 33, // Booty Bay => Stranglethorn Vale
131 => 132, // Kharanos => Coldridge Valley
24 => 9, // Northshire Abbey => Northshire Valley
279 => 36, // Dalaran Crater => Alterac Mountains
4342 => 4298, // Acherus: The Ebon Hold => The Scarlet Enclave
2079 => 15, // Alcaz Island => Dustwallow Marsh
1939 => 440, // Abyssal Sands => Tanaris
393 => 363, // Darkspeer Strand => Valley of Trials
702 => 141, // Rut'theran Village => Teldrassil
221 => 220, // Camp Narache => Red Cloud Mesa
1116 => 357, // Feathermoon Stronghold => Feralas
236 => 209, // Shadowfang Keep
4769 => 4742, // Hrothgar's Landing => Hrothgar's Landing
4613 => 4395, // Dalaran City => Dalaran
4522 => 210, // Icecrown Citadell => Icecrown
3896 => 3703, // Aldor Rise => Shattrath City
3696 => 3522, // The Barrier Hills => Blade's Edge Mountains
2839 => 2597, // Alterac Valley
19 => 1977, // Zul'Gurub
4445 => 4273, // Ulduar
2300 => 1941, // Caverns of Time
3545 => 3535, // Hellfire Citadel
2562 => 3457, // Karazhan
3840 => 3959, // Black Temple
1717 => 491, // Razorfen Kraul
978 => 1176, // Zul'Farrak
133 => 721, // Gnomeregan
3607 => 3905, // Serpentshrine Cavern
3845 => 3842, // Tempest Keep
1517 => 1337 // Uldaman
);
foreach ($subcats as $child => $parent)
DB::Aowow()->query('UPDATE ?_quests SET zoneOrSort = ?d WHERE zoneOrSortBak = ?d', $parent, $child);
// move quests liked to holidays into appropirate quests-sorts. create dummy sorts as needed
$eventSet = DB::World()->selectCol('SELECT holiday AS ARRAY_KEY, eventEntry FROM game_event WHERE holiday <> 0');
$holidaySorts = array(
141 => -1001, 181 => -374, 201 => -1002, // Winter Veil Noblegarden Childrens Week
321 => -1005, 324 => -1003, 404 => -375, // Harvest Fest. Hallows End Pilgrims Bounty
327 => -366, 341 => -369, 372 => -370, // Lunar Fest. Midsummer Brewfest
423 => -376 // Love is in the Air
);
foreach ($holidaySorts as $hId => $sort)
if (!empty($eventSet[$hId]))
DB::Aowow()->query('UPDATE ?_quests SET zoneOrSort = ?d WHERE eventId = ?d{ AND id IN (?a)}', $sort, $eventSet[$hId], $ids ?: DBSIMPLE_SKIP);
// 'special' special cases
// fishing quests to stranglethorn extravaganza
DB::Aowow()->query('UPDATE ?_quests SET zoneOrSort = ?d WHERE id IN (?a){ AND id IN (?a)}', -101, [8228, 8229], $ids ?: DBSIMPLE_SKIP);
// dungeon quests to Misc/Dungeon Finder
DB::Aowow()->query('UPDATE ?_quests SET zoneOrSort = ?d WHERE (specialFlags & ?d OR id IN (?a)){ AND id IN (?a)}', -1010, QUEST_FLAG_SPECIAL_DUNGEON_FINDER, [24789, 24791, 24923], $ids ?: DBSIMPLE_SKIP);
return true;
}
/*
just some random thoughts here ..
quest-custom-flags are derived from flags and specialFlags
since they are not used further than being sent to JS as wFlags this is fine..
should they be saved to db anyway..?
same with QUEST_FLAG_UNAVAILABLE => CUSTOM_EXCLUDE_FOR_LISTVIEW
*/
// unpack XP-reward
DB::Aowow()->query($xpQuery, $ids ?: DBSIMPLE_SKIP);
// unpack Rep-rewards
for ($i = 1; $i < 6; $i++)
DB::Aowow()->query($repQuery, $i, $i, $i, $i, $ids ?: DBSIMPLE_SKIP);
// zoneorsort for quests need updating
// partially points non-instanced area with identic name for instance quests
$subcats = array(
-221 => 440, // Treasure Map => Tanaris
-284 => 0, // Special => Misc (some quests get shuffled into seasonal)
151 => 0, // Designer Island => Misc
22 => 0, // Programmer Isle
35 => 33, // Booty Bay => Stranglethorn Vale
131 => 132, // Kharanos => Coldridge Valley
24 => 9, // Northshire Abbey => Northshire Valley
279 => 36, // Dalaran Crater => Alterac Mountains
4342 => 4298, // Acherus: The Ebon Hold => The Scarlet Enclave
2079 => 15, // Alcaz Island => Dustwallow Marsh
1939 => 440, // Abyssal Sands => Tanaris
393 => 363, // Darkspeer Strand => Valley of Trials
702 => 141, // Rut'theran Village => Teldrassil
221 => 220, // Camp Narache => Red Cloud Mesa
1116 => 357, // Feathermoon Stronghold => Feralas
236 => 209, // Shadowfang Keep
4769 => 4742, // Hrothgar's Landing => Hrothgar's Landing
4613 => 4395, // Dalaran City => Dalaran
4522 => 210, // Icecrown Citadell => Icecrown
3896 => 3703, // Aldor Rise => Shattrath City
3696 => 3522, // The Barrier Hills => Blade's Edge Mountains
2839 => 2597, // Alterac Valley
19 => 1977, // Zul'Gurub
4445 => 4273, // Ulduar
2300 => 1941, // Caverns of Time
3545 => 3535, // Hellfire Citadel
2562 => 3457, // Karazhan
3840 => 3959, // Black Temple
1717 => 491, // Razorfen Kraul
978 => 1176, // Zul'Farrak
133 => 721, // Gnomeregan
3607 => 3905, // Serpentshrine Cavern
3845 => 3842, // Tempest Keep
1517 => 1337 // Uldaman
);
foreach ($subcats as $child => $parent)
DB::Aowow()->query('UPDATE ?_quests SET zoneOrSort = ?d WHERE zoneOrSortBak = ?d', $parent, $child);
// move quests liked to holidays into appropirate quests-sorts. create dummy sorts as needed
$eventSet = DB::World()->selectCol('SELECT holiday AS ARRAY_KEY, eventEntry FROM game_event WHERE holiday <> 0');
$holidaySorts = array(
141 => -1001, 181 => -374, 201 => -1002, // Winter Veil Noblegarden Childrens Week
321 => -1005, 324 => -1003, 404 => -375, // Harvest Fest. Hallows End Pilgrims Bounty
327 => -366, 341 => -369, 372 => -370, // Lunar Fest. Midsummer Brewfest
423 => -376 // Love is in the Air
);
foreach ($holidaySorts as $hId => $sort)
if (!empty($eventSet[$hId]))
DB::Aowow()->query('UPDATE ?_quests SET zoneOrSort = ?d WHERE eventId = ?d{ AND id IN (?a)}', $sort, $eventSet[$hId], $ids ?: DBSIMPLE_SKIP);
// 'special' special cases
// fishing quests to stranglethorn extravaganza
DB::Aowow()->query('UPDATE ?_quests SET zoneOrSort = ?d WHERE id IN (?a){ AND id IN (?a)}', -101, [8228, 8229], $ids ?: DBSIMPLE_SKIP);
// dungeon quests to Misc/Dungeon Finder
DB::Aowow()->query('UPDATE ?_quests SET zoneOrSort = ?d WHERE (specialFlags & ?d OR id IN (?a)){ AND id IN (?a)}', -1010, QUEST_FLAG_SPECIAL_DUNGEON_FINDER, [24789, 24791, 24923], $ids ?: DBSIMPLE_SKIP);
return true;
}
});
?>

View File

@@ -7,51 +7,42 @@ if (!CLI)
die('not in cli mode');
/* deps:
* creature_queststarter
* creature_questender
* game_event_creature_quest
* gameobject_queststarter
* gameobject_questender
* game_event_gameobject_quest
* item_template
*/
$customData = array(
);
$reqDBC = array(
);
function quests_startend(/* array $ids = [] */)
SqlGen::register(new class extends SetupScript
{
$query['creature'] = '
SELECT 1 AS type, id AS typeId, quest AS questId, 1 AS method, 0 AS eventId FROM creature_queststarter UNION
SELECT 1 AS type, id AS typeId, quest AS questId, 2 AS method, 0 AS eventId FROM creature_questender UNION
SELECT 1 AS type, id AS typeId, quest AS questId, 1 AS method, eventEntry AS eventId FROM game_event_creature_quest';
protected $command = 'quests_startend';
$query['object'] = '
SELECT 2 AS type, id AS typeId, quest AS questId, 1 AS method, 0 AS eventId FROM gameobject_queststarter UNION
SELECT 2 AS type, id AS typeId, quest AS questId, 2 AS method, 0 AS eventId FROM gameobject_questender UNION
SELECT 2 AS type, id AS typeId, quest AS questId, 1 AS method, eventEntry AS eventId FROM game_event_gameobject_quest';
protected $tblDependancyTC = ['creature_queststarter', 'creature_questender', 'game_event_creature_quest', 'gameobject_queststarter', 'gameobject_questender', 'game_event_gameobject_quest', 'item_template'];
$query['item'] = 'SELECT 3 AS type, entry AS typeId, startquest AS questId, 1 AS method, 0 AS eventId FROM item_template WHERE startquest <> 0';
// always rebuild this table from scratch
// or how would i know what to fetch specifically
DB::Aowow()->query('TRUNCATE TABLE ?_quests_startend');
foreach ($query as $q)
public function generate(array $ids = []) : bool
{
$data = DB::World()->select($q);
foreach ($data as $d)
DB::Aowow()->query('INSERT INTO ?_quests_startend (?#) VALUES (?a) ON DUPLICATE KEY UPDATE method = method | VALUES(method), eventId = IF(eventId = 0, VALUES(eventId), eventId)', array_keys($d), array_values($d));
$query['creature'] = '
SELECT 1 AS type, id AS typeId, quest AS questId, 1 AS method, 0 AS eventId FROM creature_queststarter UNION
SELECT 1 AS type, id AS typeId, quest AS questId, 2 AS method, 0 AS eventId FROM creature_questender UNION
SELECT 1 AS type, id AS typeId, quest AS questId, 1 AS method, eventEntry AS eventId FROM game_event_creature_quest';
$query['object'] = '
SELECT 2 AS type, id AS typeId, quest AS questId, 1 AS method, 0 AS eventId FROM gameobject_queststarter UNION
SELECT 2 AS type, id AS typeId, quest AS questId, 2 AS method, 0 AS eventId FROM gameobject_questender UNION
SELECT 2 AS type, id AS typeId, quest AS questId, 1 AS method, eventEntry AS eventId FROM game_event_gameobject_quest';
$query['item'] = 'SELECT 3 AS type, entry AS typeId, startquest AS questId, 1 AS method, 0 AS eventId FROM item_template WHERE startquest <> 0';
// always rebuild this table from scratch
// or how would i know what to fetch specifically
DB::Aowow()->query('TRUNCATE TABLE ?_quests_startend');
foreach ($query as $q)
{
$data = DB::World()->select($q);
foreach ($data as $d)
DB::Aowow()->query('INSERT INTO ?_quests_startend (?#) VALUES (?a) ON DUPLICATE KEY UPDATE method = method | VALUES(method), eventId = IF(eventId = 0, VALUES(eventId), eventId)', array_keys($d), array_values($d));
}
// update quests without start as unavailable
Db::Aowow()->query('UPDATE ?_quests q LEFT JOIN ?_quests_startend qse ON qse.questId = q.id AND qse.method & 1 SET q.cuFlags = q.cuFlags | ?d WHERE qse.questId IS NULL', CUSTOM_UNAVAILABLE);
return true;
}
// update quests without start as unavailable
Db::Aowow()->query('UPDATE ?_quests q LEFT JOIN ?_quests_startend qse ON qse.questId = q.id AND qse.method & 1 SET q.cuFlags = q.cuFlags | ?d WHERE qse.questId IS NULL', CUSTOM_UNAVAILABLE);
return true;
}
});
?>

View File

@@ -7,45 +7,53 @@ if (!CLI)
die('not in cli mode');
$customData = array(
null,
['leader' => 29611, 'factionId' => 72, 'startAreaId' => 12],
['leader' => 4949, 'factionId' => 76, 'startAreaId' => 14],
['leader' => 2784, 'factionId' => 47, 'startAreaId' => 1],
['leader' => 7999, 'factionId' => 69, 'startAreaId' => 141],
['leader' => 10181, 'factionId' => 68, 'startAreaId' => 85],
['leader' => 3057, 'factionId' => 81, 'startAreaId' => 215],
['leader' => 7937, 'factionId' => 54, 'startAreaId' => 1],
['leader' => 10540, 'factionId' => 530, 'startAreaId' => 14],
null,
['leader' => 16802, 'factionId' => 911, 'startAreaId' => 3430],
['leader' => 17468, 'factionId' => 930, 'startAreaId' => 3524]
);
$reqDBC = ['chrraces', 'charbaseinfo'];
function races()
SqlGen::register(new class extends SetupScript
{
/**********/
/* Basics */
/**********/
use TrCustomData;
$baseQuery = '
REPLACE 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
FROM
dbc_chrraces';
protected $command = 'races';
DB::Aowow()->query($baseQuery);
protected $dbcSourceFiles = ['chrraces', 'charbaseinfo'];
// 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');
private $customData = array(
null,
['leader' => 29611, 'factionId' => 72, 'startAreaId' => 12],
['leader' => 4949, 'factionId' => 76, 'startAreaId' => 14],
['leader' => 2784, 'factionId' => 47, 'startAreaId' => 1],
['leader' => 7999, 'factionId' => 69, 'startAreaId' => 141],
['leader' => 10181, 'factionId' => 68, 'startAreaId' => 85],
['leader' => 3057, 'factionId' => 81, 'startAreaId' => 215],
['leader' => 7937, 'factionId' => 54, 'startAreaId' => 1],
['leader' => 10540, 'factionId' => 530, 'startAreaId' => 14],
null,
['leader' => 16802, 'factionId' => 911, 'startAreaId' => 3430],
['leader' => 17468, 'factionId' => 930, 'startAreaId' => 3524]
);
// add cuFlags
DB::Aowow()->query('UPDATE ?_races SET cuFlags = ?d WHERE flags & ?d', CUSTOM_EXCLUDE_FOR_LISTVIEW, 0x1);
public function generate(array $ids = []) : bool
{
/**********/
/* Basics */
/**********/
return true;
}
$baseQuery = '
REPLACE 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
FROM
dbc_chrraces';
DB::Aowow()->query($baseQuery);
// 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');
// add cuFlags
DB::Aowow()->query('UPDATE ?_races SET cuFlags = ?d WHERE flags & ?d', CUSTOM_EXCLUDE_FOR_LISTVIEW, 0x1);
return true;
}
});
?>

View File

@@ -0,0 +1,18 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
if (!CLI)
die('not in cli mode');
SqlGen::register(new class extends SetupScript
{
use TrDBCcopy;
protected $command = 'scalingstatdistribution';
protected $dbcSourceFiles = ['scalingstatdistribution'];
});
?>

View File

@@ -0,0 +1,18 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
if (!CLI)
die('not in cli mode');
SqlGen::register(new class extends SetupScript
{
use TrDBCcopy;
protected $command = 'scalingstatvalues';
protected $dbcSourceFiles = ['scalingstatvalues'];
});
?>

View File

@@ -7,22 +7,40 @@ if (!CLI)
die('not in cli mode');
$customData = array(
1 => ['displayIdH' => 8571],
15 => ['displayIdH' => 8571],
5 => ['displayIdH' => 2289],
8 => ['displayIdH' => 2289],
14 => ['displayIdH' => 2289],
27 => ['displayIdH' => 21244],
29 => ['displayIdH' => 20872],
);
$reqDBC = ['spellshapeshiftform'];
function shapeshiftforms()
SqlGen::register(new class extends SetupScript
{
DB::Aowow()->query('REPLACE INTO ?_shapeshiftforms SELECT id, flags, creatureType, displayIdA, displayIdH, spellId1, spellId2, spellId3, spellId4, spellId5, spellId6, spellId7, spellId8, IF(name_loc0 = "", IF(name_loc2 = "", IF(name_loc3 = "", IF(name_loc6 = "", IF(name_loc8 = "", "???", name_loc8), name_loc6), name_loc3), name_loc2), name_loc0) FROM dbc_spellshapeshiftform');
use TrCustomData;
return true;
}
protected $command = 'shapeshiftforms';
protected $dbcSourceFiles = ['spellshapeshiftform'];
private $customData = array(
1 => ['displayIdH' => 8571],
15 => ['displayIdH' => 8571],
5 => ['displayIdH' => 2289],
8 => ['displayIdH' => 2289],
14 => ['displayIdH' => 2289],
27 => ['displayIdH' => 21244],
29 => ['displayIdH' => 20872]
);
public function generate(array $ids = []) : bool
{
DB::Aowow()->query('
REPLACE INTO
?_shapeshiftforms
SELECT
id, flags, creatureType,
displayIdA, displayIdH,
spellId1, spellId2, spellId3, spellId4, spellId5, spellId6, spellId7, spellId8,
IF(name_loc0 = "", IF(name_loc2 = "", IF(name_loc3 = "", IF(name_loc6 = "", IF(name_loc8 = "", "???", name_loc8), name_loc6), name_loc3), name_loc2), name_loc0)
FROM
dbc_spellshapeshiftform'
);
return true;
}
});
?>

View File

@@ -6,71 +6,81 @@ if (!defined('AOWOW_REVISION'))
if (!CLI)
die('not in cli mode');
$customData = array(
393 => ['professionMask' => 0x0000], // Skinning
171 => ['professionMask' => 0x0001, 'recipeSubClass' => 6, 'specializations' => '28677 28675 28672'], // Alchemy
164 => ['professionMask' => 0x0002, 'recipeSubClass' => 4, 'specializations' => '9788 9787 17041 17040 17039'], // Blacksmithing
185 => ['professionMask' => 0x0004, 'recipeSubClass' => 5], // Cooking
333 => ['professionMask' => 0x0008, 'recipeSubClass' => 8], // Enchanting
202 => ['professionMask' => 0x0010, 'recipeSubClass' => 3, 'specializations' => '20219 20222'], // Engineering
129 => ['professionMask' => 0x0020, 'recipeSubClass' => 7], // First Aid
755 => ['professionMask' => 0x0040, 'recipeSubClass' => 10], // Jewelcrafting
165 => ['professionMask' => 0x0080, 'recipeSubClass' => 1, 'specializations' => '10656 10658 10660'], // Leatherworking
186 => ['professionMask' => 0x0100], // Mining
197 => ['professionMask' => 0x0200, 'recipeSubClass' => 2, 'specializations' => '26798 26801 26797'], // Tailoring
356 => ['professionMask' => 0x0400, 'recipeSubClass' => 9], // Fishing
182 => ['professionMask' => 0x0800], // Herbalism
773 => ['professionMask' => 0x1000, 'recipeSubClass' => 11], // Inscription
785 => ['name_loc0' => 'Pet - Wasp'], // Pet - Wasp
781 => ['name_loc2' => 'Familier - diablosaure exotique'], // Pet - Exotic Devilsaur
758 => ['name_loc6' => 'Mascota: Evento - Control remoto', 'name_loc3' => 'Tier - Ereignis Ferngesteuert', 'categoryId' => 7], // Pet - Event - Remote Control
788 => ['categoryId' => 7], // Pet - Exotic Spirit Beast
);
$reqDBC = ['skillline', 'spell', 'skilllineability'];
function skillline()
SqlGen::register(new class extends SetupScript
{
$baseQuery = '
REPLACE INTO
?_skillline
SELECT
id, categoryId, 0, categoryId, name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8, description_loc0, description_loc2, description_loc3, description_loc4, description_loc6, description_loc8, 0, iconId, 0, 0, ""
FROM
dbc_skillline';
use TrCustomData;
DB::Aowow()->query($baseQuery);
protected $command = 'skillline';
// categorization
DB::Aowow()->query('UPDATE ?_skillline SET typeCat = -5 WHERE id = 777 OR (categoryId = 9 AND id NOT IN (356, 129, 185, 142, 155))');
DB::Aowow()->query('UPDATE ?_skillline SET typeCat = -4 WHERE categoryId = 9 AND name_loc0 LIKE "%racial%"');
DB::Aowow()->query('UPDATE ?_skillline SET typeCat = -6 WHERE id IN (778, 788, 758) OR (categoryId = 7 AND name_loc0 LIKE "%pet%")');
protected $tblDependancyAowow = ['icons'];
protected $dbcSourceFiles = ['skillline', 'spell', 'skilllineability'];
// more complex fixups
DB::Aowow()->query('UPDATE ?_skillline SET name_loc8 = REPLACE(name_loc8, " - ", ": ") WHERE categoryId = 7 OR id IN (758, 788)');
DB::Aowow()->query('UPDATE ?_skillline SET cuFlags = ?d WHERE id IN (?a)', CUSTOM_EXCLUDE_FOR_LISTVIEW, [142, 148, 149, 150, 152, 155, 183, 533, 553, 554, 713, 769]);
private $customData = array(
393 => ['professionMask' => 0x0000], // Skinning
171 => ['professionMask' => 0x0001, 'recipeSubClass' => 6, 'specializations' => '28677 28675 28672'], // Alchemy
164 => ['professionMask' => 0x0002, 'recipeSubClass' => 4, 'specializations' => '9788 9787 17041 17040 17039'], // Blacksmithing
185 => ['professionMask' => 0x0004, 'recipeSubClass' => 5], // Cooking
333 => ['professionMask' => 0x0008, 'recipeSubClass' => 8], // Enchanting
202 => ['professionMask' => 0x0010, 'recipeSubClass' => 3, 'specializations' => '20219 20222'], // Engineering
129 => ['professionMask' => 0x0020, 'recipeSubClass' => 7], // First Aid
755 => ['professionMask' => 0x0040, 'recipeSubClass' => 10], // Jewelcrafting
165 => ['professionMask' => 0x0080, 'recipeSubClass' => 1, 'specializations' => '10656 10658 10660'], // Leatherworking
186 => ['professionMask' => 0x0100], // Mining
197 => ['professionMask' => 0x0200, 'recipeSubClass' => 2, 'specializations' => '26798 26801 26797'], // Tailoring
356 => ['professionMask' => 0x0400, 'recipeSubClass' => 9], // Fishing
182 => ['professionMask' => 0x0800], // Herbalism
773 => ['professionMask' => 0x1000, 'recipeSubClass' => 11], // Inscription
785 => ['name_loc0' => 'Pet - Wasp'], // Pet - Wasp
781 => ['name_loc2' => 'Familier - diablosaure exotique'], // Pet - Exotic Devilsaur
758 => ['name_loc6' => 'Mascota: Evento - Control remoto', 'name_loc3' => 'Tier - Ereignis Ferngesteuert', 'categoryId' => 7], // Pet - Event - Remote Control
788 => ['categoryId' => 7], // Pet - Exotic Spirit Beast
);
// apply icons
DB::Aowow()->query('UPDATE ?_skillline sl, ?_icons ic, dbc_spellicon si SET sl.iconId = ic.id WHERE sl.iconIdBak = si.id AND ic.name = LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1))');
DB::Aowow()->query('
UPDATE
?_skillline sl,
dbc_spell s,
dbc_skilllineability sla,
?_icons ic,
dbc_spellicon si
SET
sl.iconId = ic.id
WHERE
(s.effect1Id IN (25, 26, 40) OR s.effect2Id = 60) AND
ic.name = LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1)) AND
s.iconId = si.id AND
sla.spellId = s.id AND
sl.id = sla.skillLineId
');
DB::Aowow()->query('UPDATE ?_skillline sl, ?_icons ic SET sl.iconId = ic.id WHERE ic.name = ? AND sl.id = ?d', 'inv_misc_pelt_wolf_01', 393);
DB::Aowow()->query('UPDATE ?_skillline sl, ?_icons ic SET sl.iconId = ic.id WHERE ic.name = ? AND sl.id = ?d', 'inv_misc_key_03', 633);
public function generate(array $ids = []) : bool
{
$baseQuery = '
REPLACE INTO
?_skillline
SELECT
id, categoryId, 0, categoryId, name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8, description_loc0, description_loc2, description_loc3, description_loc4, description_loc6, description_loc8, 0, iconId, 0, 0, ""
FROM
dbc_skillline';
return true;
}
DB::Aowow()->query($baseQuery);
// categorization
DB::Aowow()->query('UPDATE ?_skillline SET typeCat = -5 WHERE id = 777 OR (categoryId = 9 AND id NOT IN (356, 129, 185, 142, 155))');
DB::Aowow()->query('UPDATE ?_skillline SET typeCat = -4 WHERE categoryId = 9 AND name_loc0 LIKE "%racial%"');
DB::Aowow()->query('UPDATE ?_skillline SET typeCat = -6 WHERE id IN (778, 788, 758) OR (categoryId = 7 AND name_loc0 LIKE "%pet%")');
// more complex fixups
DB::Aowow()->query('UPDATE ?_skillline SET name_loc8 = REPLACE(name_loc8, " - ", ": ") WHERE categoryId = 7 OR id IN (758, 788)');
DB::Aowow()->query('UPDATE ?_skillline SET cuFlags = ?d WHERE id IN (?a)', CUSTOM_EXCLUDE_FOR_LISTVIEW, [142, 148, 149, 150, 152, 155, 183, 533, 553, 554, 713, 769]);
// apply icons
DB::Aowow()->query('UPDATE ?_skillline sl, ?_icons ic, dbc_spellicon si SET sl.iconId = ic.id WHERE sl.iconIdBak = si.id AND ic.name = LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1))');
DB::Aowow()->query('
UPDATE
?_skillline sl,
dbc_spell s,
dbc_skilllineability sla,
?_icons ic,
dbc_spellicon si
SET
sl.iconId = ic.id
WHERE
(s.effect1Id IN (25, 26, 40) OR s.effect2Id = 60) AND
ic.name = LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1)) AND
s.iconId = si.id AND
sla.spellId = s.id AND
sl.id = sla.skillLineId
');
DB::Aowow()->query('UPDATE ?_skillline sl, ?_icons ic SET sl.iconId = ic.id WHERE ic.name = ? AND sl.id = ?d', 'inv_misc_pelt_wolf_01', 393);
DB::Aowow()->query('UPDATE ?_skillline sl, ?_icons ic SET sl.iconId = ic.id WHERE ic.name = ? AND sl.id = ?d', 'inv_misc_key_03', 633);
return true;
}
});
?>

View File

@@ -7,421 +7,427 @@ if (!CLI)
die('not in cli mode');
$customData = array(
15407 => ['cat' => 10] // UR_Algalon_Summon03 (this is not an item pickup)
);
$reqDBC = array(
// base emotes race
'soundentries', 'emotestextsound', 'vocaluisounds',
// creatures
'npcsounds', 'creaturesounddata', 'creaturedisplayinfo', 'creaturemodeldata',
// spells
'spell', 'spellvisual', 'spellvisualkit',
// zones
'soundambience', 'zonemusic', 'zoneintromusictable', 'worldstatezonesounds', 'areatable',
// items
'material', 'itemgroupsounds', 'itemdisplayinfo', 'weaponimpactsounds', 'itemsubclass', 'weaponswingsounds2' /*, 'sheathesoundlookups' data is redundant with material..? */
);
function sounds(/*array $ids = [] */)
SqlGen::register(new class extends SetupScript
{
/*
okay, here's the thing. WMOAreaTable.dbc references WMO-files to get its position in the world (AreTable) and has sparse information on the related AreaTables themself.
Though it has sets for ZoneAmbience, ZoneMusic and ZoneIntroMusic, these can't be linked for this very reason and are omitted for now.
content: e.g. Tavern Music
*/
use TrCustomData;
// WMOAreaTable.dbc/id => AreaTable.dbc/id
$worldStateZoneSoundFix = array(
18153 => 2119,
18154 => 2119,
47321 => 4273, // The Spark of Imagination
43600 => 4273, // The Celestial Planetarium
47478 => 4273 // The Prison of Yogg-Saron
protected $command = 'sounds';
protected $dbcSourceFiles = array(
// base emotes race
'soundentries', 'emotestextsound', 'vocaluisounds',
// creatures
'npcsounds', 'creaturesounddata', 'creaturedisplayinfo', 'creaturemodeldata',
// spells
'spell', 'spellvisual', 'spellvisualkit',
// zones
'soundambience', 'zonemusic', 'zoneintromusictable', 'worldstatezonesounds', 'areatable',
// items
'material', 'itemgroupsounds', 'itemdisplayinfo', 'weaponimpactsounds', 'itemsubclass', 'weaponswingsounds2' /*, 'sheathesoundlookups' data is redundant with material..? */
);
private $customData = array(
15407 => ['cat' => 10] // UR_Algalon_Summon03 (this is not an item pickup)
);
/***********/
/* M A I N */
/***********/
CLI::write(' - sounds main data');
// file extraction and conversion manually
// moving files in build step. data here is purely structural
// reality check ... thats probably gigabytes worth of sound.. only growing in size with every locale added on top (RedRocketSite didn't do it. Should i then?)
// .wav => audio/ogg; codecs="vorbis"
// .mp3 => audio/mpeg
$query = '
SELECT id AS `id`, `type` AS `cat`, `name`, 0 AS cuFlags,
`file1` AS soundFile1, `file2` AS soundFile2, `file3` AS soundFile3, `file4` AS soundFile4, `file5` AS soundFile5,
`file6` AS soundFile6, `file7` AS soundFile7, `file8` AS soundFile8, `file9` AS soundFile9, `file10` AS soundFile10,
path, flags
FROM dbc_soundentries
WHERE id > ?d LIMIT ?d
';
DB::Aowow()->query('TRUNCATE ?_sounds');
DB::Aowow()->query('TRUNCATE ?_sounds_files');
$lastMax = 0;
$soundFileIdx = 0;
$soundIndex = [];
while ($sounds = DB::Aowow()->select($query, $lastMax, SqlGen::$stepSize))
public function generate(array $ids = []) : bool
{
$newMax = max(array_column($sounds, 'id'));
/*
okay, here's the thing. WMOAreaTable.dbc references WMO-files to get its position in the world (AreTable) and has sparse information on the related AreaTables themself.
Though it has sets for ZoneAmbience, ZoneMusic and ZoneIntroMusic, these can't be linked for this very reason and are omitted for now.
content: e.g. Tavern Music
*/
CLI::write(' * sets '.($lastMax + 1).' - '.$newMax);
// WMOAreaTable.dbc/id => AreaTable.dbc/id
$worldStateZoneSoundFix = array(
18153 => 2119,
18154 => 2119,
47321 => 4273, // The Spark of Imagination
43600 => 4273, // The Celestial Planetarium
47478 => 4273 // The Prison of Yogg-Saron
);
$lastMax = $newMax;
$groupSets = [];
foreach ($sounds as $s)
/***********/
/* M A I N */
/***********/
CLI::write(' - sounds main data');
// file extraction and conversion manually
// moving files in build step. data here is purely structural
// reality check ... thats probably gigabytes worth of sound.. only growing in size with every locale added on top (RedRocketSite didn't do it. Should i then?)
// .wav => audio/ogg; codecs="vorbis"
// .mp3 => audio/mpeg
$query = '
SELECT id AS `id`, `type` AS `cat`, `name`, 0 AS cuFlags,
`file1` AS soundFile1, `file2` AS soundFile2, `file3` AS soundFile3, `file4` AS soundFile4, `file5` AS soundFile5,
`file6` AS soundFile6, `file7` AS soundFile7, `file8` AS soundFile8, `file9` AS soundFile9, `file10` AS soundFile10,
path, flags
FROM dbc_soundentries
WHERE id > ?d LIMIT ?d
';
DB::Aowow()->query('TRUNCATE ?_sounds');
DB::Aowow()->query('TRUNCATE ?_sounds_files');
$lastMax = 0;
$soundFileIdx = 0;
$soundIndex = [];
while ($sounds = DB::Aowow()->select($query, $lastMax, SqlGen::$sqlBatchSize))
{
/* attention!
$newMax = max(array_column($sounds, 'id'));
one sound can be used in 20 or more locations but may appear as multiple files,
because of different cases, path being attached to file and other shenanigans
CLI::write(' * sets '.($lastMax + 1).' - '.$newMax);
build a usable path and create full index to compensate
25.6k raw files => expect ~21k filtered files
*/
$lastMax = $newMax;
$fileSets = [];
$hasDupes = false;
for ($i = 1; $i < 11; $i++)
$groupSets = [];
foreach ($sounds as $s)
{
$nicePath = CLI::nicePath($s['soundFile'.$i], $s['path']);
if ($s['soundFile'.$i] && array_key_exists($nicePath, $soundIndex))
/* attention!
one sound can be used in 20 or more locations but may appear as multiple files,
because of different cases, path being attached to file and other shenanigans
build a usable path and create full index to compensate
25.6k raw files => expect ~21k filtered files
*/
$fileSets = [];
$hasDupes = false;
for ($i = 1; $i < 11; $i++)
{
$s['soundFile'.$i] = $soundIndex[$nicePath];
$hasDupes = true;
$nicePath = CLI::nicePath($s['soundFile'.$i], $s['path']);
if ($s['soundFile'.$i] && array_key_exists($nicePath, $soundIndex))
{
$s['soundFile'.$i] = $soundIndex[$nicePath];
$hasDupes = true;
continue;
}
// convert to something web friendly => ogg
if (stristr($s['soundFile'.$i], '.wav'))
{
$soundIndex[$nicePath] = ++$soundFileIdx;
$fileSets[] = array(
$soundFileIdx,
$s['soundFile'.$i],
$s['path'],
SOUND_TYPE_OGG
);
$s['soundFile'.$i] = $soundFileIdx;
}
// mp3 .. keep as is
else if (stristr($s['soundFile'.$i], '.mp3'))
{
$soundIndex[$nicePath] = ++$soundFileIdx;
$fileSets[] = array(
$soundFileIdx,
$s['soundFile'.$i],
$s['path'],
SOUND_TYPE_MP3
);
$s['soundFile'.$i] = $soundFileIdx;
}
// i call bullshit
else if ($s['soundFile'.$i])
{
CLI::write(' - sound group #'.$s['id'].' "'.$s['name'].'" has invalid sound file "'.$s['soundFile'.$i].'" on index '.$i.'! Skipping...', CLI::LOG_WARN);
$s['soundFile'.$i] = null;
}
// empty case
else
$s['soundFile'.$i] = null;
}
if (!$fileSets && !$hasDupes)
{
CLI::write(' - sound group #'.$s['id'].' "'.$s['name'].'" contains no sound files! Skipping...', CLI::LOG_WARN);
continue;
}
else if ($fileSets)
DB::Aowow()->query('INSERT INTO ?_sounds_files VALUES (?a)', array_values($fileSets));
// convert to something web friendly => ogg
if (stristr($s['soundFile'.$i], '.wav'))
{
$soundIndex[$nicePath] = ++$soundFileIdx;
unset($s['path']);
$fileSets[] = array(
$soundFileIdx,
$s['soundFile'.$i],
$s['path'],
SOUND_TYPE_OGG
);
$s['soundFile'.$i] = $soundFileIdx;
}
// mp3 .. keep as is
else if (stristr($s['soundFile'.$i], '.mp3'))
{
$soundIndex[$nicePath] = ++$soundFileIdx;
$fileSets[] = array(
$soundFileIdx,
$s['soundFile'.$i],
$s['path'],
SOUND_TYPE_MP3
);
$s['soundFile'.$i] = $soundFileIdx;
}
// i call bullshit
else if ($s['soundFile'.$i])
{
CLI::write(' - sound group #'.$s['id'].' "'.$s['name'].'" has invalid sound file "'.$s['soundFile'.$i].'" on index '.$i.'! Skipping...', CLI::LOG_WARN);
$s['soundFile'.$i] = null;
}
// empty case
else
$s['soundFile'.$i] = null;
$groupSets[] = array_values($s);
}
if (!$fileSets && !$hasDupes)
{
CLI::write(' - sound group #'.$s['id'].' "'.$s['name'].'" contains no sound files! Skipping...', CLI::LOG_WARN);
continue;
}
else if ($fileSets)
DB::Aowow()->query('INSERT INTO ?_sounds_files VALUES (?a)', array_values($fileSets));
unset($s['path']);
$groupSets[] = array_values($s);
DB::Aowow()->query('REPLACE INTO ?_sounds VALUES (?a)', array_values($groupSets));
}
DB::Aowow()->query('REPLACE INTO ?_sounds VALUES (?a)', array_values($groupSets));
}
/******************/
/* VocalUI Sounds */
/******************/
CLI::write(' - linking to race');
DB::Aowow()->query('TRUNCATE ?_races_sounds');
DB::Aowow()->query('INSERT IGNORE INTO ?_races_sounds SELECT raceId, soundIdMale, 1 FROM dbc_vocaluisounds WHERE soundIdMale <> soundIdFemale AND soundIdMale > 0');
DB::Aowow()->query('INSERT IGNORE INTO ?_races_sounds SELECT raceId, soundIdFemale, 2 FROM dbc_vocaluisounds WHERE soundIdMale <> soundIdFemale AND soundIdFemale > 0');
// ps: im too dumb to union this
/******************/
/* VocalUI Sounds */
/******************/
/***************/
/* Emote Sound */
/***************/
CLI::write(' - linking to race');
CLI::write(' - linking to emotes');
DB::Aowow()->query('TRUNCATE ?_races_sounds');
DB::Aowow()->query('INSERT IGNORE INTO ?_races_sounds SELECT raceId, soundIdMale, 1 FROM dbc_vocaluisounds WHERE soundIdMale <> soundIdFemale AND soundIdMale > 0');
DB::Aowow()->query('INSERT IGNORE INTO ?_races_sounds SELECT raceId, soundIdFemale, 2 FROM dbc_vocaluisounds WHERE soundIdMale <> soundIdFemale AND soundIdFemale > 0');
// ps: im too dumb to union this
DB::Aowow()->query('TRUNCATE ?_emotes_sounds');
DB::Aowow()->query('INSERT IGNORE INTO ?_emotes_sounds SELECT emotesTextId, raceId, gender + 1, soundId FROM dbc_emotestextsound');
/***************/
/* Emote Sound */
/***************/
/*******************/
/* Creature Sounds */
/*******************/
CLI::write(' - linking to emotes');
CLI::write(' - linking to creatures');
DB::Aowow()->query('TRUNCATE ?_emotes_sounds');
DB::Aowow()->query('INSERT IGNORE INTO ?_emotes_sounds SELECT emotesTextId, raceId, gender + 1, soundId FROM dbc_emotestextsound');
// currently ommitting:
// * footsteps (matrix of: creature + terrain + humidity)
// * fidget2 through 5
// * customattack2 through 3
// in case of conflicting data CreatureDisplayInfo overrides CreatureModelData (seems to be more specialized (Thral > MaleOrc / Maiden > FemaleTitan))
DB::Aowow()->query('TRUNCATE ?_creature_sounds');
DB::Aowow()->query('
INSERT INTO
?_creature_sounds (`id`, `greeting`, `farewell`, `angry`, `exertion`, `exertioncritical`, `injury`, `injurycritical`, `death`, `stun`, `stand`, `aggro`, `wingflap`, `wingglide`, `alert`, `fidget`, `customattack`, `loop`, `jumpstart`, `jumpend`, `petattack`, `petorder`, `petdismiss`, `birth`, `spellcast`, `submerge`, `submerged`)
SELECT
cdi.id,
IFNULL(ns.greetSoundId, 0),
IFNULL(ns.byeSoundId, 0),
IFNULL(ns.angrySoundId, 0),
IF(csdA.exertion, csdA.exertion, IFNULL(csdB.exertion, 0)),
IF(csdA.exertionCritical, csdA.exertionCritical, IFNULL(csdB.exertionCritical, 0)),
IF(csdA.injury, csdA.injury, IFNULL(csdB.injury, 0)),
IF(csdA.injuryCritical, csdA.injuryCritical, IFNULL(csdB.injuryCritical, 0)),
IF(csdA.death, csdA.death, IFNULL(csdB.death, 0)),
IF(csdA.stun, csdA.stun, IFNULL(csdB.stun, 0)),
IF(csdA.stand, csdA.stand, IFNULL(csdB.stand, 0)),
IF(csdA.aggro, csdA.aggro, IFNULL(csdB.aggro, 0)),
IF(csdA.wingFlap, csdA.wingFlap, IFNULL(csdB.wingFlap, 0)),
IF(csdA.wingGlide, csdA.wingGlide, IFNULL(csdB.wingGlide, 0)),
IF(csdA.alert, csdA.alert, IFNULL(csdB.alert, 0)),
IF(csdA.fidget, csdA.fidget, IFNULL(csdB.fidget, 0)),
IF(csdA.customAttack, csdA.customAttack, IFNULL(csdB.customAttack, 0)),
IF(csdA.loop, csdA.loop, IFNULL(csdB.loop, 0)),
IF(csdA.jumpStart, csdA.jumpStart, IFNULL(csdB.jumpStart, 0)),
IF(csdA.jumpEnd, csdA.jumpEnd, IFNULL(csdB.jumpEnd, 0)),
IF(csdA.petAttack, csdA.petAttack, IFNULL(csdB.petAttack, 0)),
IF(csdA.petOrder, csdA.petOrder, IFNULL(csdB.petOrder, 0)),
IF(csdA.petDismiss, csdA.petDismiss, IFNULL(csdB.petDismiss, 0)),
IF(csdA.birth, csdA.birth, IFNULL(csdB.birth, 0)),
IF(csdA.spellcast, csdA.spellcast, IFNULL(csdB.spellcast, 0)),
IF(csdA.submerge, csdA.submerge, IFNULL(csdB.submerge, 0)),
IF(csdA.submerged, csdA.submerged, IFNULL(csdB.submerged, 0))
FROM
dbc_creaturedisplayinfo cdi
LEFT JOIN
dbc_creaturemodeldata cmd ON cmd.id = cdi.modelId
LEFT JOIN
dbc_creaturesounddata csdA ON cdi.creatureSoundId = csdA.id
LEFT JOIN
dbc_creaturesounddata csdB ON cmd.creatureSoundId = csdB.id
LEFT JOIN
dbc_npcsounds ns ON cdi.npcSoundId = ns.id
');
/*******************/
/* Creature Sounds */
/*******************/
/****************/
/* Spell Sounds */
/****************/
CLI::write(' - linking to creatures');
CLI::write(' - linking to spells');
// currently ommitting:
// * footsteps (matrix of: creature + terrain + humidity)
// * fidget2 through 5
// * customattack2 through 3
// in case of conflicting data CreatureDisplayInfo overrides CreatureModelData (seems to be more specialized (Thral > MaleOrc / Maiden > FemaleTitan))
// issues: (probably because of 335-data)
// * animate is probably wrong
// * missile and impactarea not in js
// * ready, castertargeting, casterstate and targetstate not in dbc
DB::Aowow()->query('TRUNCATE ?_creature_sounds');
DB::Aowow()->query('
INSERT INTO
?_creature_sounds (`id`, `greeting`, `farewell`, `angry`, `exertion`, `exertioncritical`, `injury`, `injurycritical`, `death`, `stun`, `stand`, `aggro`, `wingflap`, `wingglide`, `alert`, `fidget`, `customattack`, `loop`, `jumpstart`, `jumpend`, `petattack`, `petorder`, `petdismiss`, `birth`, `spellcast`, `submerge`, `submerged`)
SELECT
cdi.id,
IFNULL(ns.greetSoundId, 0),
IFNULL(ns.byeSoundId, 0),
IFNULL(ns.angrySoundId, 0),
IF(csdA.exertion, csdA.exertion, IFNULL(csdB.exertion, 0)),
IF(csdA.exertionCritical, csdA.exertionCritical, IFNULL(csdB.exertionCritical, 0)),
IF(csdA.injury, csdA.injury, IFNULL(csdB.injury, 0)),
IF(csdA.injuryCritical, csdA.injuryCritical, IFNULL(csdB.injuryCritical, 0)),
IF(csdA.death, csdA.death, IFNULL(csdB.death, 0)),
IF(csdA.stun, csdA.stun, IFNULL(csdB.stun, 0)),
IF(csdA.stand, csdA.stand, IFNULL(csdB.stand, 0)),
IF(csdA.aggro, csdA.aggro, IFNULL(csdB.aggro, 0)),
IF(csdA.wingFlap, csdA.wingFlap, IFNULL(csdB.wingFlap, 0)),
IF(csdA.wingGlide, csdA.wingGlide, IFNULL(csdB.wingGlide, 0)),
IF(csdA.alert, csdA.alert, IFNULL(csdB.alert, 0)),
IF(csdA.fidget, csdA.fidget, IFNULL(csdB.fidget, 0)),
IF(csdA.customAttack, csdA.customAttack, IFNULL(csdB.customAttack, 0)),
IF(csdA.loop, csdA.loop, IFNULL(csdB.loop, 0)),
IF(csdA.jumpStart, csdA.jumpStart, IFNULL(csdB.jumpStart, 0)),
IF(csdA.jumpEnd, csdA.jumpEnd, IFNULL(csdB.jumpEnd, 0)),
IF(csdA.petAttack, csdA.petAttack, IFNULL(csdB.petAttack, 0)),
IF(csdA.petOrder, csdA.petOrder, IFNULL(csdB.petOrder, 0)),
IF(csdA.petDismiss, csdA.petDismiss, IFNULL(csdB.petDismiss, 0)),
IF(csdA.birth, csdA.birth, IFNULL(csdB.birth, 0)),
IF(csdA.spellcast, csdA.spellcast, IFNULL(csdB.spellcast, 0)),
IF(csdA.submerge, csdA.submerge, IFNULL(csdB.submerge, 0)),
IF(csdA.submerged, csdA.submerged, IFNULL(csdB.submerged, 0))
FROM
dbc_creaturedisplayinfo cdi
LEFT JOIN
dbc_creaturemodeldata cmd ON cmd.id = cdi.modelId
LEFT JOIN
dbc_creaturesounddata csdA ON cdi.creatureSoundId = csdA.id
LEFT JOIN
dbc_creaturesounddata csdB ON cmd.creatureSoundId = csdB.id
LEFT JOIN
dbc_npcsounds ns ON cdi.npcSoundId = ns.id
');
DB::Aowow()->query('TRUNCATE ?_spell_sounds');
DB::Aowow()->query('
INSERT INTO
?_spell_sounds (`id`, `precast`, `cast`, `impact`, `state`, `statedone`, `channel`, `missile`, `animation`, `casterimpact`, `targetimpact`, `missiletargeting`, `instantarea`, `impactarea`, `persistentarea`)
SELECT
sv.id,
IFNULL(svk1.soundId, 0),
IFNULL(svk2.soundId, 0),
IFNULL(svk3.soundId, 0),
IFNULL(svk4.soundId, 0),
IFNULL(svk5.soundId, 0),
IFNULL(svk6.soundId, 0),
missileSoundId,
animationSoundId,
IFNULL(svk7.soundId, 0),
IFNULL(svk8.soundId, 0),
IFNULL(svk9.soundId, 0),
IFNULL(svk10.soundId, 0),
IFNULL(svk11.soundId, 0),
IFNULL(svk12.soundId, 0)
FROM
dbc_spellvisual sv
LEFT JOIN
dbc_spellvisualkit svk1 ON svk1.id = sv.precastKitId
LEFT JOIN
dbc_spellvisualkit svk2 ON svk2.id = sv.castKitId
LEFT JOIN
dbc_spellvisualkit svk3 ON svk3.id = sv.impactKitId
LEFT JOIN
dbc_spellvisualkit svk4 ON svk4.id = sv.stateKitId
LEFT JOIN
dbc_spellvisualkit svk5 ON svk5.id = sv.statedoneKitId
LEFT JOIN
dbc_spellvisualkit svk6 ON svk6.id = sv.channelKitId
LEFT JOIN
dbc_spellvisualkit svk7 ON svk7.id = sv.casterImpactKitId
LEFT JOIN
dbc_spellvisualkit svk8 ON svk8.id = sv.targetImpactKitId
LEFT JOIN
dbc_spellvisualkit svk9 ON svk9.id = sv.missileTargetingKitId
LEFT JOIN
dbc_spellvisualkit svk10 ON svk10.id = sv.instantAreaKitId
LEFT JOIN
dbc_spellvisualkit svk11 ON svk11.id = sv.impactAreaKitId
LEFT JOIN
dbc_spellvisualkit svk12 ON svk12.id = sv.persistentAreaKitId
');
/****************/
/* Spell Sounds */
/****************/
/***************/
/* Zone Sounds */
/***************/
CLI::write(' - linking to spells');
CLI::write(' - linking to zones');
// issues: (probably because of 335-data)
// * animate is probably wrong
// * missile and impactarea not in js
// * ready, castertargeting, casterstate and targetstate not in dbc
// omiting data from WMOAreaTable, as its at the moment impossible to link to actual zones
DB::Aowow()->query('TRUNCATE ?_spell_sounds');
DB::Aowow()->query('
INSERT INTO
?_spell_sounds (`id`, `precast`, `cast`, `impact`, `state`, `statedone`, `channel`, `missile`, `animation`, `casterimpact`, `targetimpact`, `missiletargeting`, `instantarea`, `impactarea`, `persistentarea`)
SELECT
sv.id,
IFNULL(svk1.soundId, 0),
IFNULL(svk2.soundId, 0),
IFNULL(svk3.soundId, 0),
IFNULL(svk4.soundId, 0),
IFNULL(svk5.soundId, 0),
IFNULL(svk6.soundId, 0),
missileSoundId,
animationSoundId,
IFNULL(svk7.soundId, 0),
IFNULL(svk8.soundId, 0),
IFNULL(svk9.soundId, 0),
IFNULL(svk10.soundId, 0),
IFNULL(svk11.soundId, 0),
IFNULL(svk12.soundId, 0)
FROM
dbc_spellvisual sv
LEFT JOIN
dbc_spellvisualkit svk1 ON svk1.id = sv.precastKitId
LEFT JOIN
dbc_spellvisualkit svk2 ON svk2.id = sv.castKitId
LEFT JOIN
dbc_spellvisualkit svk3 ON svk3.id = sv.impactKitId
LEFT JOIN
dbc_spellvisualkit svk4 ON svk4.id = sv.stateKitId
LEFT JOIN
dbc_spellvisualkit svk5 ON svk5.id = sv.statedoneKitId
LEFT JOIN
dbc_spellvisualkit svk6 ON svk6.id = sv.channelKitId
LEFT JOIN
dbc_spellvisualkit svk7 ON svk7.id = sv.casterImpactKitId
LEFT JOIN
dbc_spellvisualkit svk8 ON svk8.id = sv.targetImpactKitId
LEFT JOIN
dbc_spellvisualkit svk9 ON svk9.id = sv.missileTargetingKitId
LEFT JOIN
dbc_spellvisualkit svk10 ON svk10.id = sv.instantAreaKitId
LEFT JOIN
dbc_spellvisualkit svk11 ON svk11.id = sv.impactAreaKitId
LEFT JOIN
dbc_spellvisualkit svk12 ON svk12.id = sv.persistentAreaKitId
');
DB::Aowow()->query('TRUNCATE ?_zones_sounds');
DB::Aowow()->query('
INSERT INTO
?_zones_sounds (id, ambienceDay, ambienceNight, musicDay, musicNight, intro, worldStateId, worldStateValue)
SELECT
a.id,
IFNULL(sa1.soundIdDay, 0),
IFNULL(sa1.soundIdNight, 0),
IFNULL(zm1.soundIdDay, 0),
IFNULL(zm1.soundIdNight, 0),
IFNULL(zimt1.soundId, 0),
0,
0
FROM
dbc_areatable a
LEFT JOIN
dbc_soundambience sa1 ON sa1.id = a.soundAmbience
LEFT JOIN
dbc_zonemusic zm1 ON zm1.id = a.zoneMusic
LEFT JOIN
dbc_zoneintromusictable zimt1 ON zimt1.id = a.zoneIntroMusic
WHERE
a.soundAmbience > 0 OR a.zoneMusic > 0 OR a.zoneIntroMusic
UNION
SELECT
IF(wszs.areaId, wszs.areaId, wszs.wmoAreaId),
IFNULL(sa2.soundIdDay, 0),
IFNULL(sa2.soundIdNight, 0),
IFNULL(zm2.soundIdDay, 0),
IFNULL(zm2.soundIdNight, 0),
IFNULL(zimt2.soundId, 0),
wszs.stateId,
wszs.value
FROM
dbc_worldstatezonesounds wszs
LEFT JOIN
dbc_soundambience sa2 ON sa2.id = wszs.soundAmbienceId
LEFT JOIN
dbc_zonemusic zm2 ON zm2.id = wszs.zoneMusicId
LEFT JOIN
dbc_zoneintromusictable zimt2 ON zimt2.id = wszs.zoneIntroMusicId
WHERE
wszs.zoneMusicId > 0 AND (wszs.areaId OR wszs.wmoAreaId IN (?a))
', array_keys($worldStateZoneSoundFix));
// apply post-fix
foreach ($worldStateZoneSoundFix as $old => $new)
DB::Aowow()->query('UPDATE ?_zones_sounds SET id = ?d WHERE id = ?d', $new, $old);
/***************/
/* Zone Sounds */
/***************/
/***************/
/* Item Sounds */
/***************/
CLI::write(' - linking to zones');
CLI::write(' - linking to items');
// omiting data from WMOAreaTable, as its at the moment impossible to link to actual zones
DB::Aowow()->query('
UPDATE
?_items i
LEFT JOIN
dbc_itemdisplayinfo idi ON
idi.id = i.displayId
LEFT JOIN
dbc_itemgroupsounds igs ON
igs.id = idi.groupSoundId
LEFT JOIN
dbc_material m ON
m.id = i.material
SET
i.spellVisualId = IFNULL(idi.spellVisualId, 0),
i.pickUpSoundId = IFNULL(igs.pickUpSoundId, 0),
i.dropDownSoundId = IFNULL(igs.dropDownSoundId, 0),
i.sheatheSoundId = IFNULL(m.sheatheSoundId, 0),
i.unsheatheSoundId = IFNULL(m.unsheatheSoundId, 0)
');
DB::Aowow()->query('TRUNCATE ?_zones_sounds');
DB::Aowow()->query('
INSERT INTO
?_zones_sounds (id, ambienceDay, ambienceNight, musicDay, musicNight, intro, worldStateId, worldStateValue)
SELECT
a.id,
IFNULL(sa1.soundIdDay, 0),
IFNULL(sa1.soundIdNight, 0),
IFNULL(zm1.soundIdDay, 0),
IFNULL(zm1.soundIdNight, 0),
IFNULL(zimt1.soundId, 0),
0,
0
FROM
dbc_areatable a
LEFT JOIN
dbc_soundambience sa1 ON sa1.id = a.soundAmbience
LEFT JOIN
dbc_zonemusic zm1 ON zm1.id = a.zoneMusic
LEFT JOIN
dbc_zoneintromusictable zimt1 ON zimt1.id = a.zoneIntroMusic
WHERE
a.soundAmbience > 0 OR a.zoneMusic > 0 OR a.zoneIntroMusic
UNION
SELECT
IF(wszs.areaId, wszs.areaId, wszs.wmoAreaId),
IFNULL(sa2.soundIdDay, 0),
IFNULL(sa2.soundIdNight, 0),
IFNULL(zm2.soundIdDay, 0),
IFNULL(zm2.soundIdNight, 0),
IFNULL(zimt2.soundId, 0),
wszs.stateId,
wszs.value
FROM
dbc_worldstatezonesounds wszs
LEFT JOIN
dbc_soundambience sa2 ON sa2.id = wszs.soundAmbienceId
LEFT JOIN
dbc_zonemusic zm2 ON zm2.id = wszs.zoneMusicId
LEFT JOIN
dbc_zoneintromusictable zimt2 ON zimt2.id = wszs.zoneIntroMusicId
WHERE
wszs.zoneMusicId > 0 AND (wszs.areaId OR wszs.wmoAreaId IN (?a))
', array_keys($worldStateZoneSoundFix));
DB::Aowow()->query('TRUNCATE ?_items_sounds');
// apply post-fix
foreach ($worldStateZoneSoundFix as $old => $new)
DB::Aowow()->query('UPDATE ?_zones_sounds SET id = ?d WHERE id = ?d', $new, $old);
/***************/
/* Item Sounds */
/***************/
CLI::write(' - linking to items');
DB::Aowow()->query('
UPDATE
?_items i
LEFT JOIN
dbc_itemdisplayinfo idi ON
idi.id = i.displayId
LEFT JOIN
dbc_itemgroupsounds igs ON
igs.id = idi.groupSoundId
LEFT JOIN
dbc_material m ON
m.id = i.material
SET
i.spellVisualId = IFNULL(idi.spellVisualId, 0),
i.pickUpSoundId = IFNULL(igs.pickUpSoundId, 0),
i.dropDownSoundId = IFNULL(igs.dropDownSoundId, 0),
i.sheatheSoundId = IFNULL(m.sheatheSoundId, 0),
i.unsheatheSoundId = IFNULL(m.unsheatheSoundId, 0)
');
DB::Aowow()->query('TRUNCATE ?_items_sounds');
$fields = ['hit', 'crit'];
foreach ($fields as $f)
{
for ($i = 1; $i <= 10; $i++)
$fields = ['hit', 'crit'];
foreach ($fields as $f)
{
DB::Aowow()->query('
INSERT INTO
?_items_sounds
SELECT
?#,
(1 << wis.subClass)
FROM
dbc_weaponimpactsounds wis
WHERE
?# > 0
ON DUPLICATE KEY UPDATE
subClassMask = subClassMask | (1 << wis.subClass)
', $f.$i, $f.$i);
for ($i = 1; $i <= 10; $i++)
{
DB::Aowow()->query('
INSERT INTO
?_items_sounds
SELECT
?#,
(1 << wis.subClass)
FROM
dbc_weaponimpactsounds wis
WHERE
?# > 0
ON DUPLICATE KEY UPDATE
subClassMask = subClassMask | (1 << wis.subClass)
', $f.$i, $f.$i);
}
}
DB::Aowow()->query('
INSERT INTO
?_items_sounds
SELECT
wss.soundId,
(1 << isc.subClass)
FROM
dbc_itemsubclass isc
JOIN
dbc_weaponswingsounds2 wss ON
wss.weaponSize = isc.weaponSize
WHERE
isc.class = 2
ON DUPLICATE KEY UPDATE
subClassMask = subClassMask | (1 << isc.subClass)
');
return true;
}
DB::Aowow()->query('
INSERT INTO
?_items_sounds
SELECT
wss.soundId,
(1 << isc.subClass)
FROM
dbc_itemsubclass isc
JOIN
dbc_weaponswingsounds2 wss ON
wss.weaponSize = isc.weaponSize
WHERE
isc.class = 2
ON DUPLICATE KEY UPDATE
subClassMask = subClassMask | (1 << isc.subClass)
');
return true;
}
});
?>

File diff suppressed because it is too large Load Diff

View File

@@ -7,28 +7,60 @@ if (!CLI)
die('not in cli mode');
// requires https://github.com/TrinityCore/TrinityCore/commit/f989c7182c4cc30f1d0ffdc566c7624a5e108a2f
// requires https://github.com/TrinityCore/TrinityCore/commit/f989c7182c4cc30f1d0ffdc566c7624a5e108a2f to have been used at least once
/* deps:
* creature
* creature_addon
* gameobject
* gameobject_template
* vehicle_accessory
* vehicle_accessory_template
* script_waypoint
* waypoints
* waypoint_data
*/
$customData = array(
);
$reqDBC = ['worldmaparea', 'map', 'dungeonmap', 'taxipathnode', 'soundemitters', 'areatrigger'];
function spawns() // and waypoints
SqlGen::register(new class extends SetupScript
{
$alphaMapCache = [];
$alphaMapCheck = function ($areaId, array &$set) use (&$alphaMapCache)
protected $command = 'spawns'; // and waypoints
protected $tblDependancyTC = ['creature', 'creature_addon', 'gameobject', 'gameobject_template', 'vehicle_accessory', 'vehicle_accessory_template', 'script_waypoint', 'waypoints', 'waypoint_data'];
protected $dbcSourceFiles = ['worldmaparea', 'map', 'dungeonmap', 'taxipathnode', 'soundemitters', 'areatrigger'];
private $querys = array(
1 => ['SELECT c.guid, 1 AS "type", c.id AS typeId, c.spawntimesecs AS respawn, c.phaseMask, c.zoneId AS areaId, c.map, IFNULL(ca.path_id, 0) AS pathId, c.position_y AS `posX`, c.position_x AS `posY` ' .
'FROM creature c LEFT JOIN creature_addon ca ON ca.guid = c.guid',
' - assembling creature spawns'],
2 => ['SELECT c.guid, 2 AS "type", c.id AS typeId, ABS(c.spawntimesecs) AS respawn, c.phaseMask, c.zoneId AS areaId, c.map, 0 as pathId, c.position_y AS `posX`, c.position_x AS `posY` ' .
'FROM gameobject c',
' - assembling gameobject spawns'],
3 => ['SELECT id AS "guid", 19 AS "type", soundId AS typeId, 0 AS respawn, 0 AS phaseMask, 0 AS areaId, mapId AS "map", 0 AS pathId, posX, posY ' .
'FROM dbc_soundemitters',
' - assembling sound emitter spawns'],
4 => ['SELECT id AS "guid", 503 AS "type", id AS typeId, 0 AS respawn, 0 AS phaseMask, 0 AS areaId, mapId AS "map", 0 AS pathId, posX, posY ' .
'FROM dbc_areatrigger',
' - assembling areatrigger spawns'],
5 => ['SELECT c.guid, w.entry AS "npcOrPath", w.pointId AS "point", c.zoneId AS areaId, c.map, w.waittime AS "wait", w.location_y AS `posX`, w.location_x AS `posY` ' .
'FROM creature c JOIN script_waypoint w ON c.id = w.entry',
' - assembling waypoints from table script_waypoint'],
6 => ['SELECT c.guid, w.entry AS "npcOrPath", w.pointId AS "point", c.zoneId AS areaId, c.map, 0 AS "wait", w.position_y AS `posX`, w.position_x AS `posY` ' .
'FROM creature c JOIN waypoints w ON c.id = w.entry',
' - assembling waypoints from table waypoints'],
7 => ['SELECT c.guid, -w.id AS "npcOrPath", w.point, c.zoneId AS areaId, c.map, w.delay AS "wait", w.position_y AS `posX`, w.position_x AS `posY` ' .
'FROM creature c JOIN creature_addon ca ON ca.guid = c.guid JOIN waypoint_data w ON w.id = ca.path_id WHERE ca.path_id <> 0',
' - assembling waypoints from table waypoint_data']
);
private $queryPost =
'SELECT dm.id, wma.areaId, IFNULL(dm.floor, 0) AS floor, ' .
'100 - ROUND(IF(dm.id IS NOT NULL, (?f - dm.minY) * 100 / (dm.maxY - dm.minY), (?f - wma.right) * 100 / (wma.left - wma.right)), 1) AS `posX`, ' .
'100 - ROUND(IF(dm.id IS NOT NULL, (?f - dm.minX) * 100 / (dm.maxX - dm.minX), (?f - wma.bottom) * 100 / (wma.top - wma.bottom)), 1) AS `posY`, ' .
'((abs(IF(dm.id IS NOT NULL, (?f - dm.minY) * 100 / (dm.maxY - dm.minY), (?f - wma.right) * 100 / (wma.left - wma.right)) - 50) / 50) * ' .
' (abs(IF(dm.id IS NOT NULL, (?f - dm.minX) * 100 / (dm.maxX - dm.minX), (?f - wma.bottom) * 100 / (wma.top - wma.bottom)) - 50) / 50)) AS quality ' .
'FROM dbc_worldmaparea wma ' .
'LEFT JOIN dbc_dungeonmap dm ON dm.mapId = IF(?d AND (wma.mapId NOT IN (0, 1, 530, 571) OR wma.areaId = 4395), wma.mapId, -1) ' .
'WHERE wma.mapId = ?d AND IF(?d, wma.areaId = ?d, wma.areaId <> 0) ' .
'HAVING (`posX` BETWEEN 0.1 AND 99.9 AND `posY` BETWEEN 0.1 AND 99.9) ' . // AND (dm.id IS NULL OR ?d) ' .
'ORDER BY quality ASC';
private $alphaMapCache = [];
private function alphaMapCheck(int $areaId, array &$set) : bool
{
$file = 'setup/generated/alphaMaps/'.$areaId.'.png';
if (!file_exists($file)) // file does not exist (probably instanced area)
@@ -41,28 +73,28 @@ function spawns() // and waypoints
return true;
}
if (empty($alphaMapCache[$areaId]))
$alphaMapCache[$areaId] = imagecreatefrompng($file);
if (empty($this->alphaMapCache[$areaId]))
$this->alphaMapCache[$areaId] = imagecreatefrompng($file);
// alphaMaps are 1000 x 1000, adapt points [black => valid point]
if (!imagecolorat($alphaMapCache[$areaId], $set['posX'] * 10, $set['posY'] * 10))
if (!imagecolorat($this->alphaMapCache[$areaId], $set['posX'] * 10, $set['posY'] * 10))
$set = null;
return true;
};
}
$checkCoords = function ($points) use($alphaMapCheck)
private function checkCoords(array $points) : array
{
$result = [];
$capitals = array( // capitals take precedence over their surroundings
1497, 1637, 1638, 3487, // Undercity, Ogrimmar, Thunder Bluff, Silvermoon City
1519, 1537, 1657, 3557, // Stormwind City, Ironforge, Darnassus, The Exodar
3703, 4395 // Shattrath City, Dalaran
$capitals = array( // capitals take precedence over their surroundings
1497, 1637, 1638, 3487, // Undercity, Ogrimmar, Thunder Bluff, Silvermoon City
1519, 1537, 1657, 3557, // Stormwind City, Ironforge, Darnassus, The Exodar
3703, 4395 // Shattrath City, Dalaran
);
foreach ($points as $res)
{
if ($alphaMapCheck($res['areaId'], $res))
if ($this->alphaMapCheck($res['areaId'], $res))
{
if (!$res)
continue;
@@ -74,9 +106,9 @@ function spawns() // and waypoints
if (empty($result) || $result[0] > $q)
$result = [$q, $res];
}
else if (in_array($res['areaId'], $capitals)) // capitals (auto-discovered) and no hand-made alphaMap available
else if (in_array($res['areaId'], $capitals)) // capitals (auto-discovered) and no hand-made alphaMap available
return $res;
else if (empty($result)) // add with lowest quality if alpha map is missing
else if (empty($result)) // add with lowest quality if alpha map is missing
$result = [1.0, $res];
}
@@ -88,198 +120,161 @@ function spawns() // and waypoints
}
return $result[1];
};
}
$query[1] = ['SELECT c.guid, 1 AS "type", c.id AS typeId, c.spawntimesecs AS respawn, c.phaseMask, c.zoneId AS areaId, c.map, IFNULL(ca.path_id, 0) AS pathId, c.position_y AS `posX`, c.position_x AS `posY` ' .
'FROM creature c LEFT JOIN creature_addon ca ON ca.guid = c.guid',
' - assembling '.CLI::bold('creature').' spawns'];
$query[2] = ['SELECT c.guid, 2 AS "type", c.id AS typeId, ABS(c.spawntimesecs) AS respawn, c.phaseMask, c.zoneId AS areaId, c.map, 0 as pathId, c.position_y AS `posX`, c.position_x AS `posY` ' .
'FROM gameobject c',
' - assembling '.CLI::bold('gameobject').' spawns'];
$query[3] = ['SELECT id AS "guid", 19 AS "type", soundId AS typeId, 0 AS respawn, 0 AS phaseMask, 0 AS areaId, mapId AS "map", 0 AS pathId, posX, posY ' .
'FROM dbc_soundemitters',
' - assembling '.CLI::bold('sound emitter').' spawns'];
$query[4] = ['SELECT id AS "guid", 503 AS "type", id AS typeId, 0 AS respawn, 0 AS phaseMask, 0 AS areaId, mapId AS "map", 0 AS pathId, posX, posY ' .
'FROM dbc_areatrigger',
' - assembling '.CLI::bold('areatrigger').' spawns'];
$query[5] = ['SELECT c.guid, w.entry AS "npcOrPath", w.pointId AS "point", c.zoneId AS areaId, c.map, w.waittime AS "wait", w.location_y AS `posX`, w.location_x AS `posY` ' .
'FROM creature c JOIN script_waypoint w ON c.id = w.entry',
' - assembling waypoints from '.CLI::bold('script_waypoint')];
$query[6] = ['SELECT c.guid, w.entry AS "npcOrPath", w.pointId AS "point", c.zoneId AS areaId, c.map, 0 AS "wait", w.position_y AS `posX`, w.position_x AS `posY` ' .
'FROM creature c JOIN waypoints w ON c.id = w.entry',
' - assembling waypoints from '.CLI::bold('waypoints')];
$query[7] = ['SELECT c.guid, -w.id AS "npcOrPath", w.point, c.zoneId AS areaId, c.map, w.delay AS "wait", w.position_y AS `posX`, w.position_x AS `posY` ' .
'FROM creature c JOIN creature_addon ca ON ca.guid = c.guid JOIN waypoint_data w ON w.id = ca.path_id WHERE ca.path_id <> 0',
' - assembling waypoints from '.CLI::bold('waypoint_data')];
$queryPost = 'SELECT dm.id, wma.areaId, IFNULL(dm.floor, 0) AS floor, ' .
'100 - ROUND(IF(dm.id IS NOT NULL, (?f - dm.minY) * 100 / (dm.maxY - dm.minY), (?f - wma.right) * 100 / (wma.left - wma.right)), 1) AS `posX`, ' .
'100 - ROUND(IF(dm.id IS NOT NULL, (?f - dm.minX) * 100 / (dm.maxX - dm.minX), (?f - wma.bottom) * 100 / (wma.top - wma.bottom)), 1) AS `posY`, ' .
'((abs(IF(dm.id IS NOT NULL, (?f - dm.minY) * 100 / (dm.maxY - dm.minY), (?f - wma.right) * 100 / (wma.left - wma.right)) - 50) / 50) * ' .
' (abs(IF(dm.id IS NOT NULL, (?f - dm.minX) * 100 / (dm.maxX - dm.minX), (?f - wma.bottom) * 100 / (wma.top - wma.bottom)) - 50) / 50)) AS quality ' .
'FROM dbc_worldmaparea wma ' .
'LEFT JOIN dbc_dungeonmap dm ON dm.mapId = IF(?d AND (wma.mapId NOT IN (0, 1, 530, 571) OR wma.areaId = 4395), wma.mapId, -1) ' .
'WHERE wma.mapId = ?d AND IF(?d, wma.areaId = ?d, wma.areaId <> 0) ' .
'HAVING (`posX` BETWEEN 0.1 AND 99.9 AND `posY` BETWEEN 0.1 AND 99.9) ' . // AND (dm.id IS NULL OR ?d) ' .
'ORDER BY quality ASC';
/*********************/
/* truncate old data */
/*********************/
DB::Aowow()->query('TRUNCATE TABLE ?_spawns');
DB::Aowow()->query('TRUNCATE TABLE ?_creature_waypoints');
/**************************/
/* offsets for transports */
/**************************/
$transports = DB::World()->selectCol('SELECT Data0 AS pathId, Data6 AS ARRAY_KEY FROM gameobject_template WHERE type = 15 AND Data6 <> 0');
foreach ($transports as &$t)
$t = DB::Aowow()->selectRow('SELECT posX, posY, mapId FROM dbc_taxipathnode tpn WHERE tpn.pathId = ?d AND nodeIdx = 0', $t);
/**************/
/* perform... */
/**************/
foreach ($query as $idx => $q)
public function generate(array $ids = []) : bool
{
CLI::write($q[1]);
/*********************/
/* truncate old data */
/*********************/
$n = 0;
$sum = 0;
DB::Aowow()->query('TRUNCATE TABLE ?_spawns');
DB::Aowow()->query('TRUNCATE TABLE ?_creature_waypoints');
if ($idx == 3 || $idx == 4)
$queryResult = DB::Aowow()->select($q[0]);
else
$queryResult = DB::World()->select($q[0]);
foreach ($queryResult as $spawn)
/**************************/
/* offsets for transports */
/**************************/
$transports = DB::World()->selectCol('SELECT Data0 AS pathId, Data6 AS ARRAY_KEY FROM gameobject_template WHERE type = 15 AND Data6 <> 0');
foreach ($transports as &$t)
$t = DB::Aowow()->selectRow('SELECT posX, posY, mapId FROM dbc_taxipathnode tpn WHERE tpn.pathId = ?d AND nodeIdx = 0', $t);
/**************/
/* perform... */
/**************/
foreach ($this->querys as $idx => $q)
{
if (!$n)
CLI::write(' * sets '.($sum + 1).' - '.($sum += SqlGen::$stepSize));
CLI::write($q[1]);
if ($n++ > SqlGen::$stepSize)
$n = 0;
$n = 0;
$sum = 0;
// npc/object is on a transport -> apply offsets to path of transport
// note, that the coordinates are mixed up .. again
// also note, that transport DO spawn outside of displayable area maps .. another todo i guess..
if (isset($transports[$spawn['map']]))
{
$spawn['posX'] += $transports[$spawn['map']]['posY'];
$spawn['posY'] += $transports[$spawn['map']]['posX'];
$spawn['map'] = $transports[$spawn['map']]['mapId'];
}
$points = DB::Aowow()->select($queryPost, $spawn['posX'], $spawn['posX'], $spawn['posY'], $spawn['posY'], $spawn['posX'], $spawn['posX'], $spawn['posY'], $spawn['posY'], 1, $spawn['map'], $spawn['areaId'], $spawn['areaId'] /*, $spawn['areaId'] ? 1 : 0*/);
if (!$points) // retry: TC counts pre-instance subareas as instance-maps .. which have no map file
$points = DB::Aowow()->select($queryPost, $spawn['posX'], $spawn['posX'], $spawn['posY'], $spawn['posY'], $spawn['posX'], $spawn['posX'], $spawn['posY'], $spawn['posY'], 0, $spawn['map'], 0, 0 /*, 1*/);
if (!$points) // still impossible (there are areas that are intentionally off the map (e.g. the isles south of tanaris))
{
CLI::write('GUID '.$spawn['guid'].($idx < 5 ? '' : ' on path/point '.$spawn['npcOrPath'].'/'.$spawn['point']).' could not be matched to displayable area [A:'.$spawn['areaId'].'; X:'.$spawn['posY'].'; Y:'.$spawn['posX'].']', CLI::LOG_WARN);
continue;
}
// if areaId is set, area was determined by TC .. we're fine .. mostly
$final = $spawn['areaId'] ? $points[0] : $checkCoords($points);
if ($idx < 5)
{
$set = array(
'guid' => $spawn['guid'],
'type' => $spawn['type'],
'typeId' => $spawn['typeId'],
'respawn' => $spawn['respawn'],
'phaseMask' => $spawn['phaseMask'],
'pathId' => $spawn['pathId'],
'areaId' => $final['areaId'],
'floor' => $final['floor'],
'posX' => $final['posX'],
'posY' => $final['posY']
);
DB::Aowow()->query('REPLACE INTO ?_spawns (?#) VALUES (?a)', array_keys($set), array_values($set));
}
if ($idx == 3 || $idx == 4)
$queryResult = DB::Aowow()->select($q[0]);
else
{
$set = array(
'creatureOrPath' => $spawn['npcOrPath'],
'point' => $spawn['point'],
'wait' => $spawn['wait'],
'areaId' => $final['areaId'],
'floor' => $final['floor'],
'posX' => $final['posX'],
'posY' => $final['posY']
);
$queryResult = DB::World()->select($q[0]);
DB::Aowow()->query('REPLACE INTO ?_creature_waypoints (?#) VALUES (?a)', array_keys($set), array_values($set));
foreach ($queryResult as $spawn)
{
if (!$n)
CLI::write(' * sets '.($sum + 1).' - '.($sum += SqlGen::$sqlBatchSize));
if ($n++ > SqlGen::$sqlBatchSize)
$n = 0;
// npc/object is on a transport -> apply offsets to path of transport
// note, that the coordinates are mixed up .. again
// also note, that transport DO spawn outside of displayable area maps .. another todo i guess..
if (isset($transports[$spawn['map']]))
{
$spawn['posX'] += $transports[$spawn['map']]['posY'];
$spawn['posY'] += $transports[$spawn['map']]['posX'];
$spawn['map'] = $transports[$spawn['map']]['mapId'];
}
$points = DB::Aowow()->select($this->queryPost, $spawn['posX'], $spawn['posX'], $spawn['posY'], $spawn['posY'], $spawn['posX'], $spawn['posX'], $spawn['posY'], $spawn['posY'], 1, $spawn['map'], $spawn['areaId'], $spawn['areaId'] /*, $spawn['areaId'] ? 1 : 0*/);
if (!$points) // retry: TC counts pre-instance subareas as instance-maps .. which have no map file
$points = DB::Aowow()->select($this->queryPost, $spawn['posX'], $spawn['posX'], $spawn['posY'], $spawn['posY'], $spawn['posX'], $spawn['posX'], $spawn['posY'], $spawn['posY'], 0, $spawn['map'], 0, 0 /*, 1*/);
if (!$points) // still impossible (there are areas that are intentionally off the map (e.g. the isles south of tanaris))
{
CLI::write('GUID '.$spawn['guid'].($idx < 5 ? '' : ' on path/point '.$spawn['npcOrPath'].'/'.$spawn['point']).' could not be matched to displayable area [A:'.$spawn['areaId'].'; X:'.$spawn['posY'].'; Y:'.$spawn['posX'].']', CLI::LOG_WARN);
continue;
}
// if areaId is set, area was determined by TC .. we're fine .. mostly
$final = $spawn['areaId'] ? $points[0] : $checkCoords($points);
if ($idx < 5)
{
$set = array(
'guid' => $spawn['guid'],
'type' => $spawn['type'],
'typeId' => $spawn['typeId'],
'respawn' => $spawn['respawn'],
'phaseMask' => $spawn['phaseMask'],
'pathId' => $spawn['pathId'],
'areaId' => $final['areaId'],
'floor' => $final['floor'],
'posX' => $final['posX'],
'posY' => $final['posY']
);
DB::Aowow()->query('REPLACE INTO ?_spawns (?#) VALUES (?a)', array_keys($set), array_values($set));
}
else
{
$set = array(
'creatureOrPath' => $spawn['npcOrPath'],
'point' => $spawn['point'],
'wait' => $spawn['wait'],
'areaId' => $final['areaId'],
'floor' => $final['floor'],
'posX' => $final['posX'],
'posY' => $final['posY']
);
DB::Aowow()->query('REPLACE INTO ?_creature_waypoints (?#) VALUES (?a)', array_keys($set), array_values($set));
}
}
}
}
/*****************************/
/* spawn vehicle accessories */
/*****************************/
/*****************************/
/* spawn vehicle accessories */
/*****************************/
// get vehicle template accessories
$accessories = DB::World()->select('
SELECT vta.accessory_entry AS typeId, c.guid, vta.entry, count(1) AS nSeats FROM vehicle_template_accessory vta LEFT JOIN creature c ON c.id = vta.entry GROUP BY accessory_entry, c.guid UNION
SELECT va.accessory_entry AS typeId, va.guid, 0 AS entry, count(1) AS nSeats FROM vehicle_accessory va GROUP BY accessory_entry, va.guid');
// get vehicle template accessories
$accessories = DB::World()->select('
SELECT vta.accessory_entry AS typeId, c.guid, vta.entry, count(1) AS nSeats FROM vehicle_template_accessory vta LEFT JOIN creature c ON c.id = vta.entry GROUP BY accessory_entry, c.guid UNION
SELECT va.accessory_entry AS typeId, va.guid, 0 AS entry, count(1) AS nSeats FROM vehicle_accessory va GROUP BY accessory_entry, va.guid');
// accessories may also be vehicles (e.g. "Kor'kron Infiltrator" is seated on "Kor'kron Suppression Turret" is seated on "Kor'kron Troop Transport")
// so we will retry finding a spawned vehicle if none were found on the previous pass and a change occured
$vGuid = 0; // not really used, but we need some kind of index
$n = 0;
$matches = -1;
while ($matches)
{
$matches = 0;
foreach ($accessories as $idx => $data)
// accessories may also be vehicles (e.g. "Kor'kron Infiltrator" is seated on "Kor'kron Suppression Turret" is seated on "Kor'kron Troop Transport")
// so we will retry finding a spawned vehicle if none were found on the previous pass and a change occured
$vGuid = 0; // not really used, but we need some kind of index
$n = 0;
$matches = -1;
while ($matches)
{
$vehicles = [];
if ($data['guid']) // vehicle already spawned
$vehicles = DB::Aowow()->select('SELECT s.areaId, s.posX, s.posY, s.floor FROM ?_spawns s WHERE s.guid = ?d AND s.type = ?d', $data['guid'], TYPE_NPC);
else if ($data['entry']) // vehicle on unspawned vehicle action
$vehicles = DB::Aowow()->select('SELECT s.areaId, s.posX, s.posY, s.floor FROM ?_spawns s WHERE s.typeId = ?d AND s.type = ?d', $data['entry'], TYPE_NPC);
if ($vehicles)
$matches = 0;
foreach ($accessories as $idx => $data)
{
$matches++;
foreach ($vehicles as $v) // if there is more than one vehicle, its probably due to overlapping zones
for ($i = 0; $i < $data['nSeats']; $i++)
DB::Aowow()->query('
REPLACE INTO ?_spawns (`guid`, `type`, `typeId`, `respawn`, `spawnMask`, `phaseMask`, `areaId`, `floor`, `posX`, `posY`, `pathId`) VALUES
(?d, ?d, ?d, 0, 0, 1, ?d, ?d, ?d, ?d, 0)', --$vGuid, TYPE_NPC, $data['typeId'], $v['areaId'], $v['floor'], $v['posX'], $v['posY']);
$vehicles = [];
if ($data['guid']) // vehicle already spawned
$vehicles = DB::Aowow()->select('SELECT s.areaId, s.posX, s.posY, s.floor FROM ?_spawns s WHERE s.guid = ?d AND s.type = ?d', $data['guid'], TYPE_NPC);
else if ($data['entry']) // vehicle on unspawned vehicle action
$vehicles = DB::Aowow()->select('SELECT s.areaId, s.posX, s.posY, s.floor FROM ?_spawns s WHERE s.typeId = ?d AND s.type = ?d', $data['entry'], TYPE_NPC);
unset($accessories[$idx]);
if ($vehicles)
{
$matches++;
foreach ($vehicles as $v) // if there is more than one vehicle, its probably due to overlapping zones
for ($i = 0; $i < $data['nSeats']; $i++)
DB::Aowow()->query('
REPLACE INTO ?_spawns (`guid`, `type`, `typeId`, `respawn`, `spawnMask`, `phaseMask`, `areaId`, `floor`, `posX`, `posY`, `pathId`) VALUES
(?d, ?d, ?d, 0, 0, 1, ?d, ?d, ?d, ?d, 0)', --$vGuid, TYPE_NPC, $data['typeId'], $v['areaId'], $v['floor'], $v['posX'], $v['posY']);
unset($accessories[$idx]);
}
}
if ($matches)
CLI::write(' * assigned '.$matches.' accessories on '.++$n.'. pass on vehicle accessories');
}
if ($matches)
CLI::write(' * assigned '.$matches.' accessories on '.++$n.'. pass on vehicle accessories');
if ($accessories)
CLI::write(count($accessories).' accessories could not be fitted onto a spawned vehicle.', CLI::LOG_WARN);
/********************************/
/* restrict difficulty displays */
/********************************/
DB::Aowow()->query('UPDATE ?_spawns s, dbc_worldmaparea wma, dbc_map m SET s.spawnMask = 0 WHERE s.areaId = wma.areaId AND wma.mapId = m.id AND m.areaType IN (0, 3, 4)');
return true;
}
if ($accessories)
CLI::write(count($accessories).' accessories could not be fitted onto a spawned vehicle.', CLI::LOG_WARN);
/********************************/
/* restrict difficulty displays */
/********************************/
DB::Aowow()->query('UPDATE ?_spawns s, dbc_worldmaparea wma, dbc_map m SET s.spawnMask = 0 WHERE s.areaId = wma.areaId AND wma.mapId = m.id AND m.areaType IN (0, 3, 4)');
return true;
}
});
?>

File diff suppressed because it is too large Load Diff

View File

@@ -7,26 +7,26 @@ if (!CLI)
die('not in cli mode');
/* deps:
* spelldifficulty_dbc
*/
$customData = array(
);
$reqDBC = ['spelldifficulty'];
function spelldifficulty(array $ids = [])
SqlGen::register(new class extends SetupScript
{
// has no unique keys..
DB::Aowow()->query('TRUNCATE TABLE ?_spelldifficulty');
protected $command = 'spelldifficulty';
DB::Aowow()->query('INSERT INTO ?_spelldifficulty SELECT * FROM dbc_spelldifficulty');
protected $tblDependancyTC = ['spelldifficulty_dbc'];
protected $dbcSourceFiles = ['spelldifficulty'];
$rows = DB::World()->select('SELECT spellid0, spellid1, spellid2, spellid3 FROM spelldifficulty_dbc');
foreach ($rows as $r)
DB::Aowow()->query('INSERT INTO ?_spelldifficulty VALUES (?a)', array_values($r));
public function generate(array $ids = []) : bool
{
// has no unique keys..
DB::Aowow()->query('TRUNCATE TABLE ?_spelldifficulty');
return true;
}
DB::Aowow()->query('INSERT INTO ?_spelldifficulty SELECT * FROM dbc_spelldifficulty');
$rows = DB::World()->select('SELECT spellid0, spellid1, spellid2, spellid3 FROM spelldifficulty_dbc');
foreach ($rows as $r)
DB::Aowow()->query('INSERT INTO ?_spelldifficulty VALUES (?a)', array_values($r));
return true;
}
});
?>

View File

@@ -0,0 +1,18 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
if (!CLI)
die('not in cli mode');
SqlGen::register(new class extends SetupScript
{
use TrDBCcopy;
protected $command = 'spellfocusobject';
protected $dbcSourceFiles = ['spellfocusobject'];
});
?>

View File

@@ -0,0 +1,18 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
if (!CLI)
die('not in cli mode');
SqlGen::register(new class extends SetupScript
{
use TrDBCcopy;
protected $command = 'spelloverride';
protected $dbcSourceFiles = ['overridespelldata'];
});
?>

View File

@@ -0,0 +1,18 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
if (!CLI)
die('not in cli mode');
SqlGen::register(new class extends SetupScript
{
use TrDBCcopy;
protected $command = 'spellrange';
protected $dbcSourceFiles = ['spellrange'];
});
?>

View File

@@ -0,0 +1,18 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
if (!CLI)
die('not in cli mode');
SqlGen::register(new class extends SetupScript
{
use TrDBCcopy;
protected $command = 'spellvariables';
protected $dbcSourceFiles = ['spelldescriptionvariables'];
});
?>

View File

@@ -7,35 +7,38 @@ if (!CLI)
die('not in cli mode');
$customData = array(
);
$reqDBC = ['talent', 'talenttab'];
function talents()
SqlGen::register(new class extends SetupScript
{
// class: 0 => hunter pets
for ($i = 1; $i < 6; $i++)
DB::Aowow()->query('
REPLACE INTO
?_talents
SELECT
t.id,
IF(tt.classMask <> 0, LOG(2, tt.classMask) + 1, 0),
tt.creatureFamilyMask,
IF(tt.creaturefamilyMask <> 0, LOG(2, tt.creaturefamilyMask), tt.tabNumber),
t.row,
t.column,
t.rank?d,
?d
FROM
dbc_talenttab tt
JOIN
dbc_talent t ON tt.id = t.tabId
WHERE
t.rank?d <> 0
', $i, $i, $i);
protected $command = 'talents';
return true;
}
protected $dbcSourceFiles = ['talent', 'talenttab'];
public function generate(array $ids = []) : bool
{
// class: 0 => hunter pets
for ($i = 1; $i < 6; $i++)
DB::Aowow()->query('
REPLACE INTO
?_talents
SELECT
t.id,
IF(tt.classMask <> 0, LOG(2, tt.classMask) + 1, 0),
tt.creatureFamilyMask,
IF(tt.creaturefamilyMask <> 0, LOG(2, tt.creaturefamilyMask), tt.tabNumber),
t.row,
t.column,
t.rank?d,
?d
FROM
dbc_talenttab tt
JOIN
dbc_talent t ON tt.id = t.tabId
WHERE
t.rank?d <> 0
', $i, $i, $i);
return true;
}
});
?>

View File

@@ -7,170 +7,169 @@ if (!CLI)
die('not in cli mode');
/* deps
* creature_template
* creature
*/
$customData = array(
);
$reqDBC = ['taxipath', 'taxinodes', 'worldmaparea', 'worldmaptransforms', 'factiontemplate'];
function taxi() // path & nodes
SqlGen::register(new class extends SetupScript
{
/*********/
/* paths */
/*********/
protected $command = 'taxi'; // path & nodes
DB::Aowow()->query('REPLACE INTO ?_taxipath SELECT tp.id, tp.startNodeId, tp.endNodeId FROM dbc_taxipath tp WHERE tp.startNodeId > 0 AND tp.EndNodeId > 0');
protected $tblDependancyTC = ['creature', 'creature_template'];
protected $dbcSourceFiles = ['taxipath', 'taxinodes', 'worldmaparea', 'worldmaptransforms', 'factiontemplate'];
// paths are monodirectional and thus exist twice for regular flight travel (which is bidirectional)
$paths = DB::Aowow()->select('SELECT id AS ARRAY_KEY, tp.* FROM ?_taxipath tp');
foreach ($paths as $i => $p)
public function generate(array $ids = []) : bool
{
foreach ($paths as $j => $_)
/*********/
/* paths */
/*********/
DB::Aowow()->query('REPLACE INTO ?_taxipath SELECT tp.id, tp.startNodeId, tp.endNodeId FROM dbc_taxipath tp WHERE tp.startNodeId > 0 AND tp.EndNodeId > 0');
// paths are monodirectional and thus exist twice for regular flight travel (which is bidirectional)
$paths = DB::Aowow()->select('SELECT id AS ARRAY_KEY, tp.* FROM ?_taxipath tp');
foreach ($paths as $i => $p)
{
if ($_['startNodeId'] == $p['endNodeId'] AND $_['endNodeId'] == $p['startNodeId'])
foreach ($paths as $j => $_)
{
DB::Aowow()->query('DELETE FROM ?_taxipath WHERE id = ?d', $j);
unset($paths[$j]);
unset($paths[$i]);
break;
if ($_['startNodeId'] == $p['endNodeId'] AND $_['endNodeId'] == $p['startNodeId'])
{
DB::Aowow()->query('DELETE FROM ?_taxipath WHERE id = ?d', $j);
unset($paths[$j]);
unset($paths[$i]);
break;
}
}
}
}
/*********/
/* nodes */
/*********/
/*********/
/* nodes */
/*********/
// all sensible nodes
$fNodes = DB::Aowow()->select(
'SELECT
tn.id,
tn.mapId,
100 - ROUND((tn.posY - wma.right) * 100 / (wma.left - wma.right), 1) AS posX,
100 - ROUND((tn.posX - wma.bottom) * 100 / (wma.top - wma.bottom), 1) AS poxY,
1 AS type,
0 AS typeId,
1 AS reactA,
1 AS reactH,
tn.name_loc0, tn.name_loc2, tn.name_loc3, tn.name_loc4, tn.name_loc6, tn.name_loc8,
tn.mapId AS origMap,
tn.posX AS origPosX,
tn.posY AS origPosY,
IF (tn.id NOT IN (15, 148, 225, 235) AND
(
tn.id IN (64, 250) OR
// all sensible nodes
$fNodes = DB::Aowow()->select(
'SELECT
tn.id,
tn.mapId,
100 - ROUND((tn.posY - wma.right) * 100 / (wma.left - wma.right), 1) AS posX,
100 - ROUND((tn.posX - wma.bottom) * 100 / (wma.top - wma.bottom), 1) AS poxY,
1 AS type,
0 AS typeId,
1 AS reactA,
1 AS reactH,
tn.name_loc0, tn.name_loc2, tn.name_loc3, tn.name_loc4, tn.name_loc6, tn.name_loc8,
tn.mapId AS origMap,
tn.posX AS origPosX,
tn.posY AS origPosY,
IF (tn.id NOT IN (15, 148, 225, 235) AND
(
tn.name_loc0 NOT LIKE "%Transport%" AND
tn.name_loc0 NOT LIKE "%Quest%" AND
tn.name_loc0 NOT LIKE "%Start%" AND
tn.name_loc0 NOT LIKE "%End%"
)
), 0, 1) AS scripted
FROM
dbc_taxinodes tn
JOIN
dbc_worldmaparea wma ON ( tn.mapId = wma.mapId AND tn.posX BETWEEN wma.bottom AND wma.top AND tn.posY BETWEEN wma.right AND wma.left)
WHERE
wma.areaId = 0 AND
wma.mapId = tn.mapId
UNION
SELECT
tn.id,
wmt.targetMapId,
100 - ROUND((tn.posY + wmt.offsetY - wma.right) * 100 / (wma.left - wma.right), 1) AS posX,
100 - ROUND((tn.posX + wmt.offsetX - wma.bottom) * 100 / (wma.top - wma.bottom), 1) AS poxY,
1 AS type,
0 AS typeId,
1 AS reactA,
1 AS reactH,
tn.name_loc0, tn.name_loc2, tn.name_loc3, tn.name_loc4, tn.name_loc6, tn.name_loc8,
tn.mapId AS origMap,
tn.posX AS origPosX,
tn.posY AS origPosY,
IF (tn.name_loc0 NOT LIKE "%Transport%" AND tn.name_loc0 NOT LIKE "%Quest%" AND tn.name_loc0 NOT LIKE "%Start%" AND tn.name_loc0 NOT LIKE "%End%",
0,
1
) AS scripted
FROM
dbc_taxinodes tn
JOIN
dbc_worldmaptransforms wmt ON ( tn.mapId = wmt.sourceMapId AND tn.posX BETWEEN wmt.minX AND wmt.maxX AND tn.posY BETWEEN wmt.minY AND wmt.maxY)
JOIN
dbc_worldmaparea wma ON ( wmt.targetMapId = wma.mapId AND tn.posX + wmt.offsetX BETWEEN wma.bottom AND wma.top AND tn.posY + wmt.offsetY BETWEEN wma.right AND wma.left)
WHERE
wma.areaId = 0 AND
wmt.sourcemapId = tn.mapId'
);
tn.id IN (64, 250) OR
(
tn.name_loc0 NOT LIKE "%Transport%" AND
tn.name_loc0 NOT LIKE "%Quest%" AND
tn.name_loc0 NOT LIKE "%Start%" AND
tn.name_loc0 NOT LIKE "%End%"
)
), 0, 1) AS scripted
FROM
dbc_taxinodes tn
JOIN
dbc_worldmaparea wma ON ( tn.mapId = wma.mapId AND tn.posX BETWEEN wma.bottom AND wma.top AND tn.posY BETWEEN wma.right AND wma.left)
WHERE
wma.areaId = 0 AND
wma.mapId = tn.mapId
UNION
SELECT
tn.id,
wmt.targetMapId,
100 - ROUND((tn.posY + wmt.offsetY - wma.right) * 100 / (wma.left - wma.right), 1) AS posX,
100 - ROUND((tn.posX + wmt.offsetX - wma.bottom) * 100 / (wma.top - wma.bottom), 1) AS poxY,
1 AS type,
0 AS typeId,
1 AS reactA,
1 AS reactH,
tn.name_loc0, tn.name_loc2, tn.name_loc3, tn.name_loc4, tn.name_loc6, tn.name_loc8,
tn.mapId AS origMap,
tn.posX AS origPosX,
tn.posY AS origPosY,
IF (tn.name_loc0 NOT LIKE "%Transport%" AND tn.name_loc0 NOT LIKE "%Quest%" AND tn.name_loc0 NOT LIKE "%Start%" AND tn.name_loc0 NOT LIKE "%End%",
0,
1
) AS scripted
FROM
dbc_taxinodes tn
JOIN
dbc_worldmaptransforms wmt ON ( tn.mapId = wmt.sourceMapId AND tn.posX BETWEEN wmt.minX AND wmt.maxX AND tn.posY BETWEEN wmt.minY AND wmt.maxY)
JOIN
dbc_worldmaparea wma ON ( wmt.targetMapId = wma.mapId AND tn.posX + wmt.offsetX BETWEEN wma.bottom AND wma.top AND tn.posY + wmt.offsetY BETWEEN wma.right AND wma.left)
WHERE
wma.areaId = 0 AND
wmt.sourcemapId = tn.mapId'
);
// all available flightmaster
$fMaster = DB::World()->select(
'SELECT ct.entry, ct.faction, c.map, c.position_x AS posX, c.position_y AS posY FROM creature_template ct JOIN creature c ON c.id = ct.entry WHERE ct.npcflag & ?d OR c.npcflag & ?d',
NPC_FLAG_FLIGHT_MASTER, NPC_FLAG_FLIGHT_MASTER
);
// all available flightmaster
$fMaster = DB::World()->select(
'SELECT ct.entry, ct.faction, c.map, c.position_x AS posX, c.position_y AS posY FROM creature_template ct JOIN creature c ON c.id = ct.entry WHERE ct.npcflag & ?d OR c.npcflag & ?d',
NPC_FLAG_FLIGHT_MASTER, NPC_FLAG_FLIGHT_MASTER
);
// assign nearest flightmaster to node
foreach ($fNodes as &$n)
{
foreach ($fMaster as &$c)
// assign nearest flightmaster to node
foreach ($fNodes as &$n)
{
if ($c['map'] != $n['origMap'])
continue;
$dist = pow($c['posX'] - $n['origPosX'], 2) + pow($c['posY'] - $n['origPosY'], 2);
if ($dist > 1000)
continue;
if (!isset($n['dist']) || $n['dist'] < $dist)
foreach ($fMaster as &$c)
{
$n['dist'] = $dist;
$n['typeId'] = $c['entry'];
$n['faction'] = $c['faction'];
if ($c['map'] != $n['origMap'])
continue;
$dist = pow($c['posX'] - $n['origPosX'], 2) + pow($c['posY'] - $n['origPosY'], 2);
if ($dist > 1000)
continue;
if (!isset($n['dist']) || $n['dist'] < $dist)
{
$n['dist'] = $dist;
$n['typeId'] = $c['entry'];
$n['faction'] = $c['faction'];
}
}
}
}
unset($n);
unset($n);
// fetch reactions per faction
$factions = DB::Aowow()->query('
SELECT
id AS ARRAY_KEY,
IF(enemyFactionId1 = 1 OR enemyFactionId2 = 1 OR enemyFactionId3 = 1 OR enemyFactionId4 = 1 OR hostileMask & 0x3, -1, 1) AS reactA,
IF(enemyFactionId1 = 2 OR enemyFactionId2 = 2 OR enemyFactionId3 = 2 OR enemyFactionId4 = 2 OR hostileMask & 0x5, -1, 1) AS reactH
FROM
dbc_factiontemplate
WHERE
id IN (?a)',
array_column($fNodes, 'faction')
);
// fetch reactions per faction
$factions = DB::Aowow()->query('
SELECT
id AS ARRAY_KEY,
IF(enemyFactionId1 = 1 OR enemyFactionId2 = 1 OR enemyFactionId3 = 1 OR enemyFactionId4 = 1 OR hostileMask & 0x3, -1, 1) AS reactA,
IF(enemyFactionId1 = 2 OR enemyFactionId2 = 2 OR enemyFactionId3 = 2 OR enemyFactionId4 = 2 OR hostileMask & 0x5, -1, 1) AS reactH
FROM
dbc_factiontemplate
WHERE
id IN (?a)',
array_column($fNodes, 'faction')
);
foreach ($fNodes as $n)
{
// if (empty($n['faction']))
// {
// CLI::write(' - ['.$n['id'].'] "'.$n['name_loc0'].'" has no NPC assigned ... skipping', CLI::LOG_WARN);
// continue;
// }
if ($n['scripted'] || empty($n['faction']))
$n['type'] = $n['typeId'] = 0;
else if (isset($factions[$n['faction']]))
foreach ($fNodes as $n)
{
$n['reactA'] = $factions[$n['faction']]['reactA'];
$n['reactH'] = $factions[$n['faction']]['reactH'];
// if (empty($n['faction']))
// {
// CLI::write(' - ['.$n['id'].'] "'.$n['name_loc0'].'" has no NPC assigned ... skipping', CLI::LOG_WARN);
// continue;
// }
if ($n['scripted'] || empty($n['faction']))
$n['type'] = $n['typeId'] = 0;
else if (isset($factions[$n['faction']]))
{
$n['reactA'] = $factions[$n['faction']]['reactA'];
$n['reactH'] = $factions[$n['faction']]['reactH'];
}
unset($n['faction'], $n['origMap'], $n['origPosX'], $n['origPosY'], $n['dist'], $n['scripted']);
DB::Aowow()->query('REPLACE INTO ?_taxinodes VALUES (?a)', array_values($n));
}
unset($n['faction'], $n['origMap'], $n['origPosX'], $n['origPosY'], $n['dist'], $n['scripted']);
DB::Aowow()->query('REPLACE INTO ?_taxinodes VALUES (?a)', array_values($n));
return true;
}
return true;
}
});
?>

View File

@@ -6,22 +6,22 @@ if (!defined('AOWOW_REVISION'))
if (!CLI)
die('not in cli mode');
/* deps:
* quest_template
* game_event_seasonal_questrelation
* game_event
* achievement_reward
*/
$customData = array(
137 => ['gender' => 2],
138 => ['gender' => 1],
);
$reqDBC = ['chartitles'];
function titles()
SqlGen::register(new class extends SetupScript
{
$titleHoliday = array(
use TrCustomData;
protected $command = 'titles';
protected $tblDependancyTC = ['quest_template', 'game_event_seasonal_questrelation', 'game_event', 'achievement_reward'];
protected $dbcSourceFiles = ['chartitles'];
private $customData = array(
137 => ['gender' => 2],
138 => ['gender' => 1]
);
private $titleHoliday = array(
137 => 201,
138 => 201,
124 => 324,
@@ -35,69 +35,72 @@ function titles()
168 => 404
);
$questQuery = '
SELECT
qt.RewardTitle AS ARRAY_KEY,
qt.AllowableRaces,
IFNULL(ge.eventEntry, 0) AS eventEntry
FROM
quest_template qt
LEFT JOIN
game_event_seasonal_questrelation sq ON sq.questId = qt.ID
LEFT JOIN
game_event ge ON ge.eventEntry = sq.eventEntry
WHERE
qt.RewardTitle <> 0';
DB::Aowow()->query('REPLACE INTO ?_titles SELECT id, 0, 0, 0, 0, 0, 0, 0, bitIdx, male_loc0, male_loc2, male_loc3, male_loc4, male_loc6, male_loc8, female_loc0, female_loc2, female_loc3, female_loc4, female_loc6, female_loc8 FROM dbc_chartitles');
// hide unused titles
DB::Aowow()->query('UPDATE ?_titles SET cuFlags = ?d WHERE id BETWEEN 85 AND 123 AND id NOT IN (113, 120, 121, 122)', CUSTOM_EXCLUDE_FOR_LISTVIEW);
// set expansion
DB::Aowow()->query('UPDATE ?_titles SET expansion = 2 WHERE id >= 72 AND id <> 80');
DB::Aowow()->query('UPDATE ?_titles SET expansion = 1 WHERE id >= 42 AND id <> 46 AND expansion = 0');
// set category
DB::Aowow()->query('UPDATE ?_titles SET category = 1 WHERE id <= 28 OR id IN (42, 43, 44, 45, 47, 48, 62, 71, 72, 80, 82, 126, 127, 128, 157, 163, 167, 169, 177)');
DB::Aowow()->query('UPDATE ?_titles SET category = 5 WHERE id BETWEEN 96 AND 109 OR id IN (83, 84)');
DB::Aowow()->query('UPDATE ?_titles SET category = 2 WHERE id BETWEEN 144 AND 156 OR id IN (63, 77, 79, 113, 123, 130, 131, 132, 176)');
DB::Aowow()->query('UPDATE ?_titles SET category = 6 WHERE id IN (46, 74, 75, 76, 124, 133, 134, 135, 137, 138, 155, 168)');
DB::Aowow()->query('UPDATE ?_titles SET category = 4 WHERE id IN (81, 125)');
DB::Aowow()->query('UPDATE ?_titles SET category = 3 WHERE id IN (53, 64, 120, 121, 122, 129, 139, 140, 141, 142) OR (id >= 158 AND category = 0)');
// update event
if ($assoc = DB::World()->selectCol('SELECT holiday AS ARRAY_KEY, eventEntry FROM game_event WHERE holiday IN (?a)', array_values($titleHoliday)))
foreach ($titleHoliday as $tId => $hId)
if (!empty($assoc[$hId]))
DB::Aowow()->query('UPDATE ?_titles SET eventId = ?d WHERE id = ?d', $assoc[$hId], $tId);
// update side
$questInfo = DB::World()->select($questQuery);
$sideUpd = DB::World()->selectCol('SELECT IF(TitleA, TitleA, TitleH) AS ARRAY_KEY, BIT_OR(IF(TitleA, 1, 2)) AS side FROM achievement_reward WHERE (TitleA <> 0 AND TitleH = 0) OR (TitleH <> 0 AND TitleA = 0) GROUP BY ARRAY_KEY HAVING side <> 3');
foreach ($questInfo as $tId => $data)
public function generate(array $ids = []) : bool
{
if ($data['eventEntry'])
DB::Aowow()->query('UPDATE ?_titles SET eventId = ?d WHERE id = ?d', $data['eventEntry'], $tId);
$questQuery = '
SELECT
qt.RewardTitle AS ARRAY_KEY,
qt.AllowableRaces,
IFNULL(ge.eventEntry, 0) AS eventEntry
FROM
quest_template qt
LEFT JOIN
game_event_seasonal_questrelation sq ON sq.questId = qt.ID
LEFT JOIN
game_event ge ON ge.eventEntry = sq.eventEntry
WHERE
qt.RewardTitle <> 0';
$side = Game::sideByRaceMask($data['AllowableRaces']);
if ($side == 3)
continue;
DB::Aowow()->query('REPLACE INTO ?_titles SELECT id, 0, 0, 0, 0, 0, 0, 0, bitIdx, male_loc0, male_loc2, male_loc3, male_loc4, male_loc6, male_loc8, female_loc0, female_loc2, female_loc3, female_loc4, female_loc6, female_loc8 FROM dbc_chartitles');
if (!isset($sideUpd[$tId]))
$sideUpd[$tId] = $side;
else
$sideUpd[$tId] |= $side;
// hide unused titles
DB::Aowow()->query('UPDATE ?_titles SET cuFlags = ?d WHERE id BETWEEN 85 AND 123 AND id NOT IN (113, 120, 121, 122)', CUSTOM_EXCLUDE_FOR_LISTVIEW);
// set expansion
DB::Aowow()->query('UPDATE ?_titles SET expansion = 2 WHERE id >= 72 AND id <> 80');
DB::Aowow()->query('UPDATE ?_titles SET expansion = 1 WHERE id >= 42 AND id <> 46 AND expansion = 0');
// set category
DB::Aowow()->query('UPDATE ?_titles SET category = 1 WHERE id <= 28 OR id IN (42, 43, 44, 45, 47, 48, 62, 71, 72, 80, 82, 126, 127, 128, 157, 163, 167, 169, 177)');
DB::Aowow()->query('UPDATE ?_titles SET category = 5 WHERE id BETWEEN 96 AND 109 OR id IN (83, 84)');
DB::Aowow()->query('UPDATE ?_titles SET category = 2 WHERE id BETWEEN 144 AND 156 OR id IN (63, 77, 79, 113, 123, 130, 131, 132, 176)');
DB::Aowow()->query('UPDATE ?_titles SET category = 6 WHERE id IN (46, 74, 75, 76, 124, 133, 134, 135, 137, 138, 155, 168)');
DB::Aowow()->query('UPDATE ?_titles SET category = 4 WHERE id IN (81, 125)');
DB::Aowow()->query('UPDATE ?_titles SET category = 3 WHERE id IN (53, 64, 120, 121, 122, 129, 139, 140, 141, 142) OR (id >= 158 AND category = 0)');
// update event
if ($assoc = DB::World()->selectCol('SELECT holiday AS ARRAY_KEY, eventEntry FROM game_event WHERE holiday IN (?a)', array_values($this->titleHoliday)))
foreach ($this->titleHoliday as $tId => $hId)
if (!empty($assoc[$hId]))
DB::Aowow()->query('UPDATE ?_titles SET eventId = ?d WHERE id = ?d', $assoc[$hId], $tId);
// update side
$questInfo = DB::World()->select($questQuery);
$sideUpd = DB::World()->selectCol('SELECT IF(TitleA, TitleA, TitleH) AS ARRAY_KEY, BIT_OR(IF(TitleA, 1, 2)) AS side FROM achievement_reward WHERE (TitleA <> 0 AND TitleH = 0) OR (TitleH <> 0 AND TitleA = 0) GROUP BY ARRAY_KEY HAVING side <> 3');
foreach ($questInfo as $tId => $data)
{
if ($data['eventEntry'])
DB::Aowow()->query('UPDATE ?_titles SET eventId = ?d WHERE id = ?d', $data['eventEntry'], $tId);
$side = Game::sideByRaceMask($data['AllowableRaces']);
if ($side == 3)
continue;
if (!isset($sideUpd[$tId]))
$sideUpd[$tId] = $side;
else
$sideUpd[$tId] |= $side;
}
foreach ($sideUpd as $tId => $side)
if ($side != 3)
DB::Aowow()->query("UPDATE ?_titles SET side = ?d WHERE id = ?d", $side, $tId);
// update side - sourceless titles (maintain query order)
DB::Aowow()->query('UPDATE ?_titles SET side = 2 WHERE id <= 28 OR id IN (118, 119, 116, 117, 110, 127)');
DB::Aowow()->query('UPDATE ?_titles SET side = 1 WHERE id <= 14 OR id IN (111, 115, 112, 114, 126)');
return true;
}
foreach ($sideUpd as $tId => $side)
if ($side != 3)
DB::Aowow()->query("UPDATE ?_titles SET side = ?d WHERE id = ?d", $side, $tId);
// update side - sourceless titles (maintain query order)
DB::Aowow()->query('UPDATE ?_titles SET side = 2 WHERE id <= 28 OR id IN (118, 119, 116, 117, 110, 127)');
DB::Aowow()->query('UPDATE ?_titles SET side = 1 WHERE id <= 14 OR id IN (111, 115, 112, 114, 126)');
return true;
}
});
?>

View File

@@ -0,0 +1,18 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
if (!CLI)
die('not in cli mode');
SqlGen::register(new class extends SetupScript
{
use TrDBCcopy;
protected $command = 'totemcategory';
protected $dbcSourceFiles = ['totemcategory'];
});
?>

View File

@@ -7,227 +7,232 @@ if (!CLI)
die('not in cli mode');
/* deps
* access_requirement
*/
$customData = array(
2257 => ['cuFlags' => 0, 'category' => 0, 'type' => 1], // deeprun tram => type: transit
3698 => ['expansion' => 1], // arenas
3702 => ['expansion' => 1],
3968 => ['expansion' => 1],
4378 => ['expansion' => 2],
4406 => ['expansion' => 2],
2597 => ['maxPlayer' => 40], // is 5 in battlemasterlist ... dafuque?
4710 => ['maxPlayer' => 40],
3456 => ['parentAreaId' => 65, 'parentX' => 87.3, 'parentY' => 51.1], // has no coordinates set in map.dbc
3849 => ['parentAreaId' => 3523, 'parentX' => 70.5, 'parentY' => 69.6],
3847 => ['parentAreaId' => 3523, 'parentX' => 71.7, 'parentY' => 55.1],
3848 => ['parentAreaId' => 3523, 'parentX' => 74.3, 'parentY' => 57.8],
3845 => ['parentAreaId' => 3523, 'parentX' => 73.5, 'parentY' => 63.7]
);
$reqDBC = ['worldmaptransforms', 'worldmaparea', 'map', 'mapdifficulty', 'areatable', 'lfgdungeons', 'battlemasterlist'];
function zones()
SqlGen::register(new class extends SetupScript
{
// base query
DB::Aowow()->query('
REPLACE INTO ?_zones
SELECT
a.id,
IFNULL(wmt.targetMapId, a.mapId), -- map
a.mapId, -- mapBak
a.areaTable, -- parentArea
IFNULL(wmt.targetMapId, -- g_zone_categories
IF(m.areaType = 1, 2,
IF(m.areaType = 2, 3,
IF(m.areaType = 4, 9,
IF(m.isBG = 1, 6,
IF(a.mapId = 571, 10,
IF(a.mapId = 530, 8, a.mapId))))))),
a.flags,
IF(areaTable <> 0 OR -- cuFlags
(wma.id IS NULL AND pa.areaId IS NULL AND (flags & 0x11000) = 0), ?d, 0),
IF(a.flags & 0x01000000, 5, -- g_zone_territories
IF(m.isBG = 1, 4,
IF(m.areaType = 4, 4,
IF(a.flags & 0x00000800, 3,
IF(a.factionGroupMask = 6, 2,
IF(a.factionGroupMask > 0, LOG2(a.factionGroupMask) - 1, 2)))))),
m.expansion,
IF(m.areaType = 0, 0, -- g_zone_instancetypes
IF(m.isBG = 1, 4,
IF(m.areaType = 4, 6,
IF(md.modeMask & 0xC, 8,
IF(md.minPl = 10 AND md.maxPL = 25, 7,
IF(m.areaType = 2, 3,
IF(m.areaType = 1 AND md.modeMask & 0x2, 5, 2))))))),
IF (md.minPl = 10 AND md.maxPl = 25, -2,
IFNULL(bm.maxPlayers, IFNULL(md.maxPl, m.maxPlayers))),
0, -- itemLevelN
0, -- itemLevelH
0, -- levelReq
IFNULL(lfgIni.levelLFG, 0), -- levelReqLFG
0, -- levelHeroic
IF(a.flags & 0x8, 1, -- levelMin
IFNULL(bm.minLevel,
IFNULL(lfgIni.levelMin,
IFNULL(lfgOpen.levelMin, 0)))),
IF(a.flags & 0x8, ?d, -- levelMax
IFNULL(bm.maxLevel,
IFNULL(lfgIni.levelMax,
IFNULL(lfgOpen.levelMax, 0)))),
"", -- attunements
"", -- heroic attunements
IFNULL(pa.areaId, 0),
IFNULL(pa.posX, 0),
IFNULL(pa.posY, 0),
IF(wma.id IS NULL OR m.areaType = 0 OR a.mapId IN (269, 560) OR a.areaTable, a.name_loc0, m.name_loc0),
IF(wma.id IS NULL OR m.areaType = 0 OR a.mapId IN (269, 560) OR a.areaTable, a.name_loc2, m.name_loc2),
IF(wma.id IS NULL OR m.areaType = 0 OR a.mapId IN (269, 560) OR a.areaTable, a.name_loc3, m.name_loc3),
IF(wma.id IS NULL OR m.areaType = 0 OR a.mapId IN (269, 560) OR a.areaTable, a.name_loc4, m.name_loc4),
IF(wma.id IS NULL OR m.areaType = 0 OR a.mapId IN (269, 560) OR a.areaTable, a.name_loc6, m.name_loc6),
IF(wma.id IS NULL OR m.areaType = 0 OR a.mapId IN (269, 560) OR a.areaTable, a.name_loc8, m.name_loc8)
FROM
dbc_areatable a
JOIN
dbc_map m ON a.mapId = m.id
LEFT JOIN (
SELECT mapId, BIT_OR(1 << difficulty) AS modeMask, MIN(nPlayer) AS minPl, MAX(nPlayer) AS maxPl FROM dbc_mapdifficulty GROUP BY mapId
) md ON md.mapId = a.mapId
LEFT JOIN
dbc_lfgdungeons lfgOpen ON a.mapId IN (0, 1, 530, 571) AND a.name_loc0 LIKE CONCAT("%", lfgOpen.name_loc0) AND lfgOpen.type = 4
LEFT JOIN (
SELECT
mapId, m.id, `left`, `right`, `top`, `bottom`,
IF((abs(((m.parentY - `right`) * 100 / (`left` - `right`)) - 50)) > abs(((m.parentX - `bottom`) * 100 / (`top` - `bottom`)) - 50),
(abs(((m.parentY - `right`) * 100 / (`left` - `right`)) - 50)),
(abs(((m.parentX - `bottom`) * 100 / (`top` - `bottom`)) - 50))) AS diff,
areaId, -- parentArea
100 - ROUND((m.parentY - `right`) * 100 / (`left` - `right`), 1) as posX,
100 - ROUND((m.parentX - `bottom`) * 100 / (`top` - `bottom`), 1) as posY
FROM
dbc_worldmaparea wma
JOIN
dbc_map m ON m.parentMapId = wma.mapid
WHERE
m.parentMapId IN (0, 1, 530, 571) AND areaId <> 0 AND
m.parentY BETWEEN `right` AND `left` AND
m.parentX BETWEEN bottom AND top
ORDER BY
diff ASC
) pa ON pa.id = m.id AND m.parentMapId > -1 AND m.parentX <> 0 AND m.parentY <> 0 AND m.parentMapId = pa.mapId AND m.parentY BETWEEN pa.`right` AND pa.`left` AND m.parentX BETWEEN pa.bottom AND pa.top
LEFT JOIN (
SELECT
mapId,
MIN(IF(targetLevelMin, targetLevelMin, levelMin)) AS levelMin,
MAX(IF(targetLevelMax, targetLevelMax, targetLevel)) AS levelMax,
MIN(IF(levelMin, levelMin, targetLevel)) AS levelLFG
FROM
dbc_lfgdungeons
WHERE
type NOT IN (4, 6) AND
groupId <> 11
GROUP BY
mapId
) lfgIni ON lfgIni.mapId = a.mapId
LEFT JOIN
dbc_battlemasterlist bm ON bm.mapId = a.mapId AND bm.moreMapId < 0
LEFT JOIN
dbc_worldmaparea wma ON wma.areaId = a.id
LEFT JOIN
dbc_worldmaptransforms wmt ON
wmt.targetMapId <> wmt.sourceMapId AND
wma.mapId = wmt.sourceMapId AND
wma.left < wmt.maxY AND
wma.right > wmt.minY AND
wma.top < wmt.maxX AND
wma.bottom > wmt.minX
GROUP BY
a.id
', CUSTOM_EXCLUDE_FOR_LISTVIEW, MAX_LEVEL);
use TrCustomData;
// get requirements from world.access_requirement
$zoneReq = DB::World()->select('
SELECT
mapId AS ARRAY_KEY,
MIN(level_min) AS reqLevel,
MAX(IF(difficulty > 0, level_min, 0)) AS heroicLevel,
MAX(IF(difficulty = 0, item_level, 0)) AS reqItemLevelN,
MAX(IF(difficulty > 0, item_level, 0)) AS reqItemLevelH,
CONCAT_WS(" ", GROUP_CONCAT(IF(difficulty = 0 AND item, item, NULL) SEPARATOR " "), GROUP_CONCAT(IF(difficulty = 0 AND item2 AND item2 <> item, item2, NULL) SEPARATOR " ")) AS reqItemN,
CONCAT_WS(" ", GROUP_CONCAT(IF(difficulty > 0 AND item, item, NULL) SEPARATOR " "), GROUP_CONCAT(IF(difficulty > 0 AND item2 AND item2 <> item, item2, NULL) SEPARATOR " ")) AS reqItemH,
CONCAT_WS(" ", GROUP_CONCAT(IF(difficulty = 0 AND quest_done_A, quest_done_A, NULL) SEPARATOR " "), GROUP_CONCAT(IF(difficulty = 0 AND quest_done_H AND quest_done_H <> quest_done_A, quest_done_H, NULL) SEPARATOR " ")) AS reqQuestN,
CONCAT_WS(" ", GROUP_CONCAT(IF(difficulty > 0 AND quest_done_A, quest_done_A, NULL) SEPARATOR " "), GROUP_CONCAT(IF(difficulty > 0 AND quest_done_H AND quest_done_H <> quest_done_A, quest_done_H, NULL) SEPARATOR " ")) AS reqQuestH,
CONCAT_WS(" ", GROUP_CONCAT(IF(difficulty = 0 AND completed_achievement, completed_achievement, NULL) SEPARATOR " ")) AS reqAchievementN,
CONCAT_WS(" ", GROUP_CONCAT(IF(difficulty > 0 AND completed_achievement, completed_achievement, NULL) SEPARATOR " ")) AS reqAchievementH
FROM
access_requirement
GROUP BY
mapId
');
protected $command = 'zones';
foreach ($zoneReq as $mapId => $req)
protected $tblDependancyTC = ['access_requirement'];
protected $dbcSourceFiles = ['worldmaptransforms', 'worldmaparea', 'map', 'mapdifficulty', 'areatable', 'lfgdungeons', 'battlemasterlist'];
private $customData = array(
2257 => ['cuFlags' => 0, 'category' => 0, 'type' => 1], // deeprun tram => type: transit
3698 => ['expansion' => 1], // arenas
3702 => ['expansion' => 1],
3968 => ['expansion' => 1],
4378 => ['expansion' => 2],
4406 => ['expansion' => 2],
2597 => ['maxPlayer' => 40], // is 5 in battlemasterlist ... dafuq?
4710 => ['maxPlayer' => 40],
3456 => ['parentAreaId' => 65, 'parentX' => 87.3, 'parentY' => 51.1], // has no coordinates set in map.dbc
3849 => ['parentAreaId' => 3523, 'parentX' => 70.5, 'parentY' => 69.6],
3847 => ['parentAreaId' => 3523, 'parentX' => 71.7, 'parentY' => 55.1],
3848 => ['parentAreaId' => 3523, 'parentX' => 74.3, 'parentY' => 57.8],
3845 => ['parentAreaId' => 3523, 'parentX' => 73.5, 'parentY' => 63.7]
);
public function generate(array $ids = []) : bool
{
$update = ['levelReq' => $req['reqLevel']];
$aN = $aH = [];
// base query
DB::Aowow()->query('
REPLACE INTO ?_zones
SELECT
a.id,
IFNULL(wmt.targetMapId, a.mapId), -- map
a.mapId, -- mapBak
a.areaTable, -- parentArea
IFNULL(wmt.targetMapId, -- g_zone_categories
IF(m.areaType = 1, 2,
IF(m.areaType = 2, 3,
IF(m.areaType = 4, 9,
IF(m.isBG = 1, 6,
IF(a.mapId = 571, 10,
IF(a.mapId = 530, 8, a.mapId))))))),
a.flags,
IF(areaTable <> 0 OR -- cuFlags
(wma.id IS NULL AND pa.areaId IS NULL AND (flags & 0x11000) = 0), ?d, 0),
IF(a.flags & 0x01000000, 5, -- g_zone_territories
IF(m.isBG = 1, 4,
IF(m.areaType = 4, 4,
IF(a.flags & 0x00000800, 3,
IF(a.factionGroupMask = 6, 2,
IF(a.factionGroupMask > 0, LOG2(a.factionGroupMask) - 1, 2)))))),
m.expansion,
IF(m.areaType = 0, 0, -- g_zone_instancetypes
IF(m.isBG = 1, 4,
IF(m.areaType = 4, 6,
IF(md.modeMask & 0xC, 8,
IF(md.minPl = 10 AND md.maxPL = 25, 7,
IF(m.areaType = 2, 3,
IF(m.areaType = 1 AND md.modeMask & 0x2, 5, 2))))))),
IF (md.minPl = 10 AND md.maxPl = 25, -2,
IFNULL(bm.maxPlayers, IFNULL(md.maxPl, m.maxPlayers))),
0, -- itemLevelN
0, -- itemLevelH
0, -- levelReq
IFNULL(lfgIni.levelLFG, 0), -- levelReqLFG
0, -- levelHeroic
IF(a.flags & 0x8, 1, -- levelMin
IFNULL(bm.minLevel,
IFNULL(lfgIni.levelMin,
IFNULL(lfgOpen.levelMin, 0)))),
IF(a.flags & 0x8, ?d, -- levelMax
IFNULL(bm.maxLevel,
IFNULL(lfgIni.levelMax,
IFNULL(lfgOpen.levelMax, 0)))),
"", -- attunements
"", -- heroic attunements
IFNULL(pa.areaId, 0),
IFNULL(pa.posX, 0),
IFNULL(pa.posY, 0),
IF(wma.id IS NULL OR m.areaType = 0 OR a.mapId IN (269, 560) OR a.areaTable, a.name_loc0, m.name_loc0),
IF(wma.id IS NULL OR m.areaType = 0 OR a.mapId IN (269, 560) OR a.areaTable, a.name_loc2, m.name_loc2),
IF(wma.id IS NULL OR m.areaType = 0 OR a.mapId IN (269, 560) OR a.areaTable, a.name_loc3, m.name_loc3),
IF(wma.id IS NULL OR m.areaType = 0 OR a.mapId IN (269, 560) OR a.areaTable, a.name_loc4, m.name_loc4),
IF(wma.id IS NULL OR m.areaType = 0 OR a.mapId IN (269, 560) OR a.areaTable, a.name_loc6, m.name_loc6),
IF(wma.id IS NULL OR m.areaType = 0 OR a.mapId IN (269, 560) OR a.areaTable, a.name_loc8, m.name_loc8)
FROM
dbc_areatable a
JOIN
dbc_map m ON a.mapId = m.id
LEFT JOIN (
SELECT mapId, BIT_OR(1 << difficulty) AS modeMask, MIN(nPlayer) AS minPl, MAX(nPlayer) AS maxPl FROM dbc_mapdifficulty GROUP BY mapId
) md ON md.mapId = a.mapId
LEFT JOIN
dbc_lfgdungeons lfgOpen ON a.mapId IN (0, 1, 530, 571) AND a.name_loc0 LIKE CONCAT("%", lfgOpen.name_loc0) AND lfgOpen.type = 4
LEFT JOIN (
SELECT
mapId, m.id, `left`, `right`, `top`, `bottom`,
IF((abs(((m.parentY - `right`) * 100 / (`left` - `right`)) - 50)) > abs(((m.parentX - `bottom`) * 100 / (`top` - `bottom`)) - 50),
(abs(((m.parentY - `right`) * 100 / (`left` - `right`)) - 50)),
(abs(((m.parentX - `bottom`) * 100 / (`top` - `bottom`)) - 50))) AS diff,
areaId, -- parentArea
100 - ROUND((m.parentY - `right`) * 100 / (`left` - `right`), 1) as posX,
100 - ROUND((m.parentX - `bottom`) * 100 / (`top` - `bottom`), 1) as posY
FROM
dbc_worldmaparea wma
JOIN
dbc_map m ON m.parentMapId = wma.mapid
WHERE
m.parentMapId IN (0, 1, 530, 571) AND areaId <> 0 AND
m.parentY BETWEEN `right` AND `left` AND
m.parentX BETWEEN bottom AND top
ORDER BY
diff ASC
) pa ON pa.id = m.id AND m.parentMapId > -1 AND m.parentX <> 0 AND m.parentY <> 0 AND m.parentMapId = pa.mapId AND m.parentY BETWEEN pa.`right` AND pa.`left` AND m.parentX BETWEEN pa.bottom AND pa.top
LEFT JOIN (
SELECT
mapId,
MIN(IF(targetLevelMin, targetLevelMin, levelMin)) AS levelMin,
MAX(IF(targetLevelMax, targetLevelMax, targetLevel)) AS levelMax,
MIN(IF(levelMin, levelMin, targetLevel)) AS levelLFG
FROM
dbc_lfgdungeons
WHERE
type NOT IN (4, 6) AND
groupId <> 11
GROUP BY
mapId
) lfgIni ON lfgIni.mapId = a.mapId
LEFT JOIN
dbc_battlemasterlist bm ON bm.mapId = a.mapId AND bm.moreMapId < 0
LEFT JOIN
dbc_worldmaparea wma ON wma.areaId = a.id
LEFT JOIN
dbc_worldmaptransforms wmt ON
wmt.targetMapId <> wmt.sourceMapId AND
wma.mapId = wmt.sourceMapId AND
wma.left < wmt.maxY AND
wma.right > wmt.minY AND
wma.top < wmt.maxX AND
wma.bottom > wmt.minX
GROUP BY
a.id
', CUSTOM_EXCLUDE_FOR_LISTVIEW, MAX_LEVEL);
if ($req['heroicLevel'])
$update['levelHeroic'] = $req['heroicLevel'];
// get requirements from world.access_requirement
$zoneReq = DB::World()->select('
SELECT
mapId AS ARRAY_KEY,
MIN(level_min) AS reqLevel,
MAX(IF(difficulty > 0, level_min, 0)) AS heroicLevel,
MAX(IF(difficulty = 0, item_level, 0)) AS reqItemLevelN,
MAX(IF(difficulty > 0, item_level, 0)) AS reqItemLevelH,
CONCAT_WS(" ", GROUP_CONCAT(IF(difficulty = 0 AND item, item, NULL) SEPARATOR " "), GROUP_CONCAT(IF(difficulty = 0 AND item2 AND item2 <> item, item2, NULL) SEPARATOR " ")) AS reqItemN,
CONCAT_WS(" ", GROUP_CONCAT(IF(difficulty > 0 AND item, item, NULL) SEPARATOR " "), GROUP_CONCAT(IF(difficulty > 0 AND item2 AND item2 <> item, item2, NULL) SEPARATOR " ")) AS reqItemH,
CONCAT_WS(" ", GROUP_CONCAT(IF(difficulty = 0 AND quest_done_A, quest_done_A, NULL) SEPARATOR " "), GROUP_CONCAT(IF(difficulty = 0 AND quest_done_H AND quest_done_H <> quest_done_A, quest_done_H, NULL) SEPARATOR " ")) AS reqQuestN,
CONCAT_WS(" ", GROUP_CONCAT(IF(difficulty > 0 AND quest_done_A, quest_done_A, NULL) SEPARATOR " "), GROUP_CONCAT(IF(difficulty > 0 AND quest_done_H AND quest_done_H <> quest_done_A, quest_done_H, NULL) SEPARATOR " ")) AS reqQuestH,
CONCAT_WS(" ", GROUP_CONCAT(IF(difficulty = 0 AND completed_achievement, completed_achievement, NULL) SEPARATOR " ")) AS reqAchievementN,
CONCAT_WS(" ", GROUP_CONCAT(IF(difficulty > 0 AND completed_achievement, completed_achievement, NULL) SEPARATOR " ")) AS reqAchievementH
FROM
access_requirement
GROUP BY
mapId
');
if ($req['reqItemLevelN'])
$update['itemLevelReqN'] = $req['reqItemLevelN'];
if ($req['reqItemLevelH'] && $req['reqItemLevelH'] > $req['reqItemLevelN'])
$update['itemLevelReqH'] = $req['reqItemLevelH'];
if ($req['reqItemN'] && ($entries = explode(' ', $req['reqItemN'])))
foreach ($entries as $_)
$aN[TYPE_ITEM][] = $_;
if ($req['reqItemH'] && ($entries = explode(' ', $req['reqItemH'])))
if ($entries = array_diff($entries, @(array)$aN[TYPE_ITEM]))
foreach ($entries as $_)
$aH[TYPE_ITEM][] = $_;
if ($req['reqQuestN'] && ($entries = explode(' ', $req['reqQuestN'])))
foreach ($entries as $_)
$aN[TYPE_QUEST][] = $_;
if ($req['reqQuestH'] && ($entries = explode(' ', $req['reqQuestH'])))
if ($entries = array_diff($entries, @(array)$aN[TYPE_QUEST]))
foreach ($entries as $_)
$aH[TYPE_QUEST][] = $_;
if ($req['reqAchievementN'] && ($entries = explode(' ', $req['reqAchievementN'])))
foreach ($entries as $_)
$aN[TYPE_ACHIEVEMENT][] = $_;
if ($req['reqAchievementH'] && ($entries = explode(' ', $req['reqAchievementH'])))
if ($entries = array_diff($entries, @(array)$aN[TYPE_ACHIEVEMENT]))
foreach ($entries as $_)
$aH[TYPE_ACHIEVEMENT][] = $_;
if ($aN)
foreach ($zoneReq as $mapId => $req)
{
foreach ($aN as $type => $entries)
$aN[$type] = $type.':'.implode(' '.$type.':', $entries);
$update = ['levelReq' => $req['reqLevel']];
$aN = $aH = [];
$update['attunementsN'] = implode(' ', $aN);
if ($req['heroicLevel'])
$update['levelHeroic'] = $req['heroicLevel'];
if ($req['reqItemLevelN'])
$update['itemLevelReqN'] = $req['reqItemLevelN'];
if ($req['reqItemLevelH'] && $req['reqItemLevelH'] > $req['reqItemLevelN'])
$update['itemLevelReqH'] = $req['reqItemLevelH'];
if ($req['reqItemN'] && ($entries = explode(' ', $req['reqItemN'])))
foreach ($entries as $_)
$aN[TYPE_ITEM][] = $_;
if ($req['reqItemH'] && ($entries = explode(' ', $req['reqItemH'])))
if ($entries = array_diff($entries, @(array)$aN[TYPE_ITEM]))
foreach ($entries as $_)
$aH[TYPE_ITEM][] = $_;
if ($req['reqQuestN'] && ($entries = explode(' ', $req['reqQuestN'])))
foreach ($entries as $_)
$aN[TYPE_QUEST][] = $_;
if ($req['reqQuestH'] && ($entries = explode(' ', $req['reqQuestH'])))
if ($entries = array_diff($entries, @(array)$aN[TYPE_QUEST]))
foreach ($entries as $_)
$aH[TYPE_QUEST][] = $_;
if ($req['reqAchievementN'] && ($entries = explode(' ', $req['reqAchievementN'])))
foreach ($entries as $_)
$aN[TYPE_ACHIEVEMENT][] = $_;
if ($req['reqAchievementH'] && ($entries = explode(' ', $req['reqAchievementH'])))
if ($entries = array_diff($entries, @(array)$aN[TYPE_ACHIEVEMENT]))
foreach ($entries as $_)
$aH[TYPE_ACHIEVEMENT][] = $_;
if ($aN)
{
foreach ($aN as $type => $entries)
$aN[$type] = $type.':'.implode(' '.$type.':', $entries);
$update['attunementsN'] = implode(' ', $aN);
}
if ($aH)
{
foreach ($aH as $type => $entries)
$aH[$type] = $type.':'.implode(' '.$type.':', $entries);
$update['attunementsH'] = implode(' ', $aH);
}
DB::Aowow()->query('UPDATE ?_zones SET ?a WHERE mapId = ?d', $update, $mapId);
}
if ($aH)
{
foreach ($aH as $type => $entries)
$aH[$type] = $type.':'.implode(' '.$type.':', $entries);
$update['attunementsH'] = implode(' ', $aH);
}
DB::Aowow()->query('UPDATE ?_zones SET ?a WHERE mapId = ?d', $update, $mapId);
return true;
}
return true;
}
});
?>