Files
aowow/setup/tools/filegen/talentCalc.func.php
Sarjuuk f77d676a19 Core/Config
* convert configuration from list of constants to object
 * fixes config changes not applying on cli whithout closing and reopening again
 * config variables are no longer embedded in localization text
2024-05-30 20:50:44 +02:00

212 lines
9.2 KiB
PHP

<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
if (!CLI)
die('not in cli mode');
// talents
// i - int talentId (id of aowow_talent)
// n - str name (spellname of aowow_spell for spellID = rank1)
// m - int number of ranks (6+ are empty)
// s - array:int spells to ranks (rank1, rank2, ..., rank5 of aowow_talent)
// d - array:str description of spells
// x - int column (col from aowow_talent)
// y - int row (row of aowow_talent)
// r - array:int on what the talent depends on: "r:[u, v]", u - nth talent in tree, v - required rank of u
// f - array:int [pets only] creatureFamilies, that use this spell
// t - array:str if the talent teaches a spell, this is the upper tooltip-table containing castTime, cost, cooldown
// j - array of modifier-arrays per rank for the Profiler [nyi]
// tabs
// n - name of the tab
// t - array of talent-objects
// f - array:int [pets only] creatureFamilies in that category
// builds talent-tree-data for the talent-calculator
// this script requires the following dbc-files to be available
$reqDBC = ['talenttab', 'talent', 'spell', 'creaturefamily', 'spellicon'];
function talentCalc()
{
$success = true;
$spellMods = (new SpellList(array(['typeCat', -2], Cfg::get('SQL_LIMIT_NONE'))))->getProfilerMods();
$buildTree = function ($class) use (&$petFamIcons, &$tSpells, $spellMods)
{
$petCategories = [];
$mask = $class ? 1 << ($class - 1) : 0;
// All "tabs" of a given class talent
$tabs = DB::Aowow()->select('SELECT * FROM dbc_talenttab WHERE classMask = ?d ORDER BY `tabNumber`, `creatureFamilyMask`', $mask);
$result = [];
for ($tabIdx = 0; $tabIdx < count($tabs); $tabIdx++)
{
$talents = DB::Aowow()->select('SELECT t.id AS tId, t.*, s.name_loc0, s.name_loc2, s.name_loc3, s.name_loc4, s.name_loc6, s.name_loc8, LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1)) AS iconString FROM dbc_talent t, dbc_spell s, dbc_spellicon si WHERE si.`id` = s.`iconId` AND t.`tabId`= ?d AND s.`id` = t.`rank1` ORDER by t.`row`, t.`column`', $tabs[$tabIdx]['id']);
$result[$tabIdx] = array(
'n' => Util::localizedString($tabs[$tabIdx], 'name'),
't' => []
);
if (!$class)
{
$petFamId = log($tabs[$tabIdx]['creatureFamilyMask'], 2);
$result[$tabIdx]['icon'] = $petFamIcons[$petFamId];
$petCategories = DB::Aowow()->SelectCol('SELECT id AS ARRAY_KEY, categoryEnumID FROM dbc_creaturefamily WHERE petTalentType = ?d', $petFamId);
$result[$tabIdx]['f'] = array_keys($petCategories);
}
// talent dependencies go here
$depLinks = [];
$tNums = [];
for ($talentIdx = 0; $talentIdx < count($talents); $talentIdx++)
{
$tNums[$talents[$talentIdx]['tId']] = $talentIdx;
$d = [];
$s = [];
$i = $talents[$talentIdx]['tId'];
$n = Util::localizedString($talents[$talentIdx], 'name');
$x = $talents[$talentIdx]['column'];
$y = $talents[$talentIdx]['row'];
$r = null;
$t = [];
$j = [];
$icon = $talents[$talentIdx]['iconString'];
$m = $talents[$talentIdx]['rank2'] == 0 ? 1 : (
$talents[$talentIdx]['rank3'] == 0 ? 2 : (
$talents[$talentIdx]['rank4'] == 0 ? 3 : (
$talents[$talentIdx]['rank5'] == 0 ? 4 : 5
)
)
);
// duplet handling
$f = [];
foreach ($petCategories as $k => $v)
{
// cant handle 64bit integer .. split
if ($v >= 32 && ((1 << ($v - 32)) & $talents[$talentIdx]['petCategory2']))
$f[] = $k;
else if ($v < 32 && ((1 << $v) & $talents[$talentIdx]['petCategory1']))
$f[] = $k;
}
for ($itr = 0; $itr <= ($m - 1); $itr++)
{
if (!$tSpells->getEntry($talents[$talentIdx]['rank'.($itr + 1)]))
continue;
$d[] = $tSpells->parseText()[0];
$s[] = $talents[$talentIdx]['rank'.($itr + 1)];
if (isset($spellMods[$talents[$talentIdx]['rank'.($itr + 1)]]))
$j[] = $spellMods[$talents[$talentIdx]['rank'.($itr + 1)]];
else
$j[] = null;
if ($talents[$talentIdx]['talentSpell'])
$t[] = $tSpells->getTalentHeadForCurrent();
}
if ($talents[$talentIdx]['reqTalent'])
{
// we didn't encounter the required talent yet => create reference
if (!isset($tNums[$talents[$talentIdx]['reqTalent']]))
$depLinks[$talents[$talentIdx]['reqTalent']] = $talentIdx;
$r = [$tNums[$talents[$talentIdx]['reqTalent']] ?? 0, $talents[$talentIdx]['reqRank'] + 1];
}
$result[$tabIdx]['t'][$talentIdx] = array(
'i' => $i,
'n' => $n,
'm' => $m,
'd' => $d,
's' => $s,
'x' => $x,
'y' => $y,
'j' => $j
);
if (isset($r))
$result[$tabIdx]['t'][$talentIdx]['r'] = $r;
if (!empty($t))
$result[$tabIdx]['t'][$talentIdx]['t'] = $t;
if (!empty($f))
$result[$tabIdx]['t'][$talentIdx]['f'] = $f;
if ($class)
$result[$tabIdx]['t'][$talentIdx]['iconname'] = $icon;
// If this talent is a reference, add it to the array of talent dependencies
if (isset($depLinks[$talents[$talentIdx]['tId']]))
{
$result[$tabIdx]['t'][$depLinks[$talents[$talentIdx]['tId']]]['r'][0] = $talentIdx;
unset($depLinks[$talents[$talentIdx]['tId']]);
}
}
// Remove all dependencies for which the talent has not been found
foreach ($depLinks as $dep_link)
unset($result[$tabIdx]['t'][$dep_link]['r']);
}
return $result;
};
// my neighbour is noisy as fuck and my head hurts, so ..
$petFamIcons = ['Ability_Druid_KingoftheJungle', 'Ability_Druid_DemoralizingRoar', 'Ability_EyeOfTheOwl']; // .. i've no idea where to fetch these from
$classes = [CLASS_WARRIOR, CLASS_PALADIN, CLASS_HUNTER, CLASS_ROGUE, CLASS_PRIEST, CLASS_DEATHKNIGHT, CLASS_SHAMAN, CLASS_MAGE, CLASS_WARLOCK, CLASS_DRUID];
$petIcons = '';
// check directory-structure
foreach (Util::$localeStrings as $dir)
if (!CLISetup::writeDir('datasets/'.$dir))
$success = false;
$tSpellIds = DB::Aowow()->selectCol('SELECT rank1 FROM dbc_talent UNION SELECT rank2 FROM dbc_talent UNION SELECT rank3 FROM dbc_talent UNION SELECT rank4 FROM dbc_talent UNION SELECT rank5 FROM dbc_talent');
$tSpells = new SpellList(array(['s.id', $tSpellIds], Cfg::get('SQL_LIMIT_NONE')));
foreach (CLISetup::$localeIds as $lId)
{
User::useLocale($lId);
Lang::load($lId);
// TalentCalc
foreach ($classes as $cMask)
{
set_time_limit(20);
$cId = log($cMask, 2) + 1;
$file = 'datasets/'.User::$localeString.'/talents-'.$cId;
$toFile = '$WowheadTalentCalculator.registerClass('.$cId.', '.Util::toJSON($buildTree($cId)).')';
if (!CLISetup::writeFile($file, $toFile))
$success = false;
}
// PetCalc
if (empty($petIcons))
{
$pets = DB::Aowow()->SelectCol('SELECT id AS ARRAY_KEY, LOWER(SUBSTRING_INDEX(iconString, "\\\\", -1)) AS iconString FROM dbc_creaturefamily WHERE petTalentType IN (0, 1, 2)');
$petIcons = Util::toJSON($pets);
}
$toFile = "var g_pet_icons = ".$petIcons.";\n\n";
$toFile .= 'var g_pet_talents = '.Util::toJSON($buildTree(0)).';';
$file = 'datasets/'.User::$localeString.'/pet-talents';
if (!CLISetup::writeFile($file, $toFile))
$success = false;
}
return $success;
}
?>