mirror of
https://github.com/Sarjuuk/aowow.git
synced 2025-11-29 15:58:16 +08:00
Core/Setup
* rewritten to be able to dynamicly load it's components
- CLISetup -> checks for UtilityScripts (config, setup, dbc reader, etc.) -> checks for SetupScripts (individual sql/file generators)
- each step may now have a help prompt attached. If none are provided, the containing script may provide it's help.
- all Scripts are self contained modules. No more editing of 3+ files if some component is added/removed
* removed intermediaries FileGen & SqlGen
* functional changes
- allow providing CLI arguments to siteconfig and account UtilityScript and skip the interactive prompts
- set slot for consumable enchantment items so they are filtrable
- zones dataset is now localized and generated from GlobalStrings.lua and DungeonMap.dbc. Related data dumps removed.
- 'aowow' and 'prQueue' executables now have shebangs
WARNING - command line options have been renamed!
This commit is contained in:
385
setup/tools/sqlgen/sounds.ss.php
Normal file
385
setup/tools/sqlgen/sounds.ss.php
Normal file
@@ -0,0 +1,385 @@
|
||||
<?php
|
||||
|
||||
if (!defined('AOWOW_REVISION'))
|
||||
die('illegal access');
|
||||
|
||||
if (!CLI)
|
||||
die('not in cli mode');
|
||||
|
||||
|
||||
CLISetup::registerSetup("sql", new class extends SetupScript
|
||||
{
|
||||
use TrCustomData; // import custom data from DB
|
||||
|
||||
protected $info = array(
|
||||
'sounds' => [[], CLISetup::ARGV_PARAM, 'Compiles data for type: Sound from dbc.']
|
||||
);
|
||||
|
||||
protected $dbcSourceFiles = array(
|
||||
// base emotes race
|
||||
'soundentries', 'emotestextsound', 'vocaluisounds',
|
||||
// creatures
|
||||
'npcsounds', 'creaturesounddata', 'creaturedisplayinfo', 'creaturemodeldata',
|
||||
// spells
|
||||
'spell', 'spellvisual', 'spellvisualkit', 'screeneffect',
|
||||
// zones
|
||||
'soundambience', 'zonemusic', 'zoneintromusictable', 'worldstatezonesounds', 'areatable',
|
||||
// items
|
||||
'material', 'itemgroupsounds', 'itemdisplayinfo', 'weaponimpactsounds', 'itemsubclass', 'weaponswingsounds2' /*, 'sheathesoundlookups' data is redundant with material..? */
|
||||
);
|
||||
|
||||
public function generate(array $ids = []) : bool
|
||||
{
|
||||
/*
|
||||
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
|
||||
*/
|
||||
|
||||
// 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
|
||||
);
|
||||
|
||||
|
||||
/***********/
|
||||
/* M A I N */
|
||||
/***********/
|
||||
|
||||
CLI::write('[sound] - 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
|
||||
LIMIT ?d, ?d';
|
||||
|
||||
DB::Aowow()->query('TRUNCATE ?_sounds');
|
||||
DB::Aowow()->query('TRUNCATE ?_sounds_files');
|
||||
|
||||
$soundFileIdx = 0;
|
||||
$soundIndex = [];
|
||||
$j = 0;
|
||||
while ($sounds = DB::Aowow()->select($query, $j * CLISetup::SQL_BATCH, CLISetup::SQL_BATCH))
|
||||
{
|
||||
CLI::write('[sound] * batch #' . ++$j . ' (' . count($sounds) . ')', CLI::LOG_BLANK, true, true);
|
||||
|
||||
$groupSets = [];
|
||||
foreach ($sounds as $s)
|
||||
{
|
||||
/* 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++)
|
||||
{
|
||||
$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[] = [$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[] = [$soundFileIdx, $s['soundFile'.$i], $s['path'], SOUND_TYPE_MP3];
|
||||
$s['soundFile'.$i] = $soundFileIdx;
|
||||
}
|
||||
// i call bullshit
|
||||
else if ($s['soundFile'.$i])
|
||||
{
|
||||
// todo (low) - file extension may be implied by SoundType, but only two entries (12292, 13401) are affected by this, sooo... eh?
|
||||
CLI::write('[sound] Group '.str_pad('['.$s['id'].']', 7).' '.CLI::bold($s['name']).' has invalid sound file '.CLI::bold($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 '.str_pad('['.$s['id'].']', 7).' '.CLI::bold($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('INSERT INTO ?_sounds VALUES (?a)', array_values($groupSets));
|
||||
}
|
||||
|
||||
|
||||
/******************/
|
||||
/* VocalUI Sounds */
|
||||
/******************/
|
||||
|
||||
CLI::write('[sound] - 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 UNION
|
||||
SELECT `raceId`, `soundIdFemale`, 2 FROM dbc_vocaluisounds WHERE `soundIdMale` <> `soundIdFemale` AND `soundIdFemale` > 0'
|
||||
);
|
||||
|
||||
|
||||
/***************/
|
||||
/* Emote Sound */
|
||||
/***************/
|
||||
|
||||
CLI::write('[sound] - linking to emotes');
|
||||
|
||||
DB::Aowow()->query('TRUNCATE ?_emotes_sounds');
|
||||
DB::Aowow()->query('INSERT IGNORE INTO ?_emotes_sounds SELECT `emotesTextId`, `raceId`, `gender` + 1, `soundId` FROM dbc_emotestextsound');
|
||||
|
||||
|
||||
/*******************/
|
||||
/* Creature Sounds */
|
||||
/*******************/
|
||||
|
||||
CLI::write('[sound] - linking to creatures');
|
||||
|
||||
// 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
|
||||
SELECT cdi.`id`,
|
||||
GREATEST(IFNULL(ns.`greetSoundId`, 0), 0),
|
||||
GREATEST(IFNULL(ns.`byeSoundId`, 0), 0),
|
||||
GREATEST(IFNULL(ns.`angrySoundId`, 0), 0),
|
||||
GREATEST(IF(csdA.`exertion`, csdA.`exertion`, IFNULL(csdB.`exertion`, 0)), 0),
|
||||
GREATEST(IF(csdA.`exertionCritical`, csdA.`exertionCritical`, IFNULL(csdB.`exertionCritical`, 0)), 0),
|
||||
GREATEST(IF(csdA.`injury`, csdA.`injury`, IFNULL(csdB.`injury`, 0)), 0),
|
||||
GREATEST(IF(csdA.`injuryCritical`, csdA.`injuryCritical`, IFNULL(csdB.`injuryCritical`, 0)), 0),
|
||||
GREATEST(IF(csdA.`death`, csdA.`death`, IFNULL(csdB.`death`, 0)), 0),
|
||||
GREATEST(IF(csdA.`stun`, csdA.`stun`, IFNULL(csdB.`stun`, 0)), 0),
|
||||
GREATEST(IF(csdA.`stand`, csdA.`stand`, IFNULL(csdB.`stand`, 0)), 0),
|
||||
0, -- footsteps
|
||||
GREATEST(IF(csdA.`aggro`, csdA.`aggro`, IFNULL(csdB.`aggro`, 0)), 0),
|
||||
GREATEST(IF(csdA.`wingFlap`, csdA.`wingFlap`, IFNULL(csdB.`wingFlap`, 0)), 0),
|
||||
GREATEST(IF(csdA.`wingGlide`, csdA.`wingGlide`, IFNULL(csdB.`wingGlide`, 0)), 0),
|
||||
GREATEST(IF(csdA.`alert`, csdA.`alert`, IFNULL(csdB.`alert`, 0)), 0),
|
||||
GREATEST(IF(csdA.`fidget`, csdA.`fidget`, IFNULL(csdB.`fidget`, 0)), 0),
|
||||
GREATEST(IF(csdA.`customAttack`, csdA.`customAttack`, IFNULL(csdB.`customAttack`, 0)), 0),
|
||||
GREATEST(IF(csdA.`loop`, csdA.`loop`, IFNULL(csdB.`loop`, 0)), 0),
|
||||
GREATEST(IF(csdA.`jumpStart`, csdA.`jumpStart`, IFNULL(csdB.`jumpStart`, 0)), 0),
|
||||
GREATEST(IF(csdA.`jumpEnd`, csdA.`jumpEnd`, IFNULL(csdB.`jumpEnd`, 0)), 0),
|
||||
GREATEST(IF(csdA.`petAttack`, csdA.`petAttack`, IFNULL(csdB.`petAttack`, 0)), 0),
|
||||
GREATEST(IF(csdA.`petOrder`, csdA.`petOrder`, IFNULL(csdB.`petOrder`, 0)), 0),
|
||||
GREATEST(IF(csdA.`petDismiss`, csdA.`petDismiss`, IFNULL(csdB.`petDismiss`, 0)), 0),
|
||||
GREATEST(IF(csdA.`birth`, csdA.`birth`, IFNULL(csdB.`birth`, 0)), 0),
|
||||
GREATEST(IF(csdA.`spellcast`, csdA.`spellcast`, IFNULL(csdB.`spellcast`, 0)), 0),
|
||||
GREATEST(IF(csdA.`submerge`, csdA.`submerge`, IFNULL(csdB.`submerge`, 0)), 0),
|
||||
GREATEST(IF(csdA.`submerged`, csdA.`submerged`, IFNULL(csdB.`submerged`, 0)), 0),
|
||||
0, -- transform
|
||||
0 -- transformanimated
|
||||
FROM dbc_creaturedisplayinfo cdi
|
||||
LEFT JOIN dbc_creaturemodeldata cmd ON cmd.`id` = cdi.`modelId`
|
||||
LEFT JOIN dbc_creaturesounddata csdA ON csdA.`id` = cdi.`creatureSoundId`
|
||||
LEFT JOIN dbc_creaturesounddata csdB ON csdB.`id` = cmd.`creatureSoundId`
|
||||
LEFT JOIN dbc_npcsounds ns ON ns.`id` = cdi.`npcSoundId`'
|
||||
);
|
||||
|
||||
|
||||
/****************/
|
||||
/* Spell Sounds */
|
||||
/****************/
|
||||
|
||||
CLI::write('[sound] - linking to spells');
|
||||
|
||||
// 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 ?_spell_sounds');
|
||||
DB::Aowow()->query(
|
||||
'INSERT INTO ?_spell_sounds
|
||||
SELECT sv.`id`,
|
||||
GREATEST(`animationSoundId`, 0),
|
||||
0, -- ready
|
||||
GREATEST(IFNULL(svk1.`soundId`, 0), 0),
|
||||
GREATEST(IFNULL(svk2.`soundId`, 0), 0),
|
||||
GREATEST(IFNULL(svk3.`soundId`, 0), 0),
|
||||
GREATEST(IFNULL(svk4.`soundId`, 0), 0),
|
||||
GREATEST(IFNULL(svk5.`soundId`, 0), 0),
|
||||
GREATEST(IFNULL(svk6.`soundId`, 0), 0),
|
||||
GREATEST(IFNULL(svk7.`soundId`, 0), 0),
|
||||
GREATEST(IFNULL(svk8.`soundId`, 0), 0),
|
||||
0, -- castertargeting
|
||||
GREATEST(IFNULL(svk9.`soundId`, 0), 0),
|
||||
GREATEST(IFNULL(svk10.`soundId`, 0), 0),
|
||||
GREATEST(IFNULL(svk12.`soundId`, 0), 0),
|
||||
0, -- casterstate
|
||||
0, -- targetstate
|
||||
GREATEST(`missileSoundId`, 0),
|
||||
GREATEST(IFNULL(svk11.`soundId`, 0), 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`'
|
||||
);
|
||||
|
||||
|
||||
/***************/
|
||||
/* Zone Sounds */
|
||||
/***************/
|
||||
|
||||
CLI::write('[sound] - linking to zones');
|
||||
|
||||
// omiting data from WMOAreaTable, as its at the moment impossible to link to actual zones
|
||||
|
||||
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 AS worldStateId,
|
||||
0 AS worldStateValue
|
||||
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);
|
||||
|
||||
|
||||
/***************/
|
||||
/* Item Sounds */
|
||||
/***************/
|
||||
|
||||
CLI::write('[sound] - 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++)
|
||||
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`)'
|
||||
);
|
||||
|
||||
|
||||
/************************/
|
||||
/* Screen Effect Sounds */
|
||||
/************************/
|
||||
|
||||
CLI::write('[sound] - linking to screen effects');
|
||||
|
||||
DB::Aowow()->query('TRUNCATE ?_screeneffect_sounds');
|
||||
DB::Aowow()->query(
|
||||
'INSERT INTO ?_screeneffect_sounds
|
||||
SELECT se.`id`, se.`name`, IFNULL(sa.`soundIdDay`, 0), IFNULL(sa.`soundIdNight`, 0), IFNULL(zm.`soundIdDay`, 0), IFNULL(zm.`soundIdNight`, 0)
|
||||
FROM dbc_screeneffect se
|
||||
LEFT JOIN dbc_soundambience sa ON se.`soundAmbienceId` = sa.`id`
|
||||
LEFT JOIN dbc_zonemusic zm ON se.`zoneMusicId` = zm.`id`'
|
||||
);
|
||||
|
||||
|
||||
$this->reapplyCCFlags('sounds', Type::SOUND);
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user