Stage modern creature assets through WarcraftXL host

This commit is contained in:
2026-07-23 01:36:59 +04:00
parent 7291fff664
commit befdaa456d
3 changed files with 35 additions and 12 deletions
+2 -1
View File
@@ -27,7 +27,8 @@
При обычном запуске `tool.exe`, `run.ps1` или `deploy.ps1` сборщик:
1. читает manifest каждой модели и добавляет все зависимости в `patch-Z.MPQ`;
1. читает manifest каждой модели и размещает retail M2 со всеми зависимостями в loose-каталоге
`Data/Patch-WXL.MPQ`, чтобы WarcraftXL всегда преобразовывал MD21 до загрузки клиентом;
2. генерирует `WXLFileData.csv` для WarcraftXL;
3. дописывает модели в `CreatureModelData.dbc` и `CreatureDisplayInfo.dbc`;
4. сохраняет стабильные ID в `custom-creatures.lock.json`;
+4 -3
View File
@@ -76,11 +76,12 @@ New-Item -ItemType Directory -Path $PackagePath -Force | Out-Null
if (-not $SkipDataBuild) {
Write-Host '[2/5] Building MPQ patches...'
$tool = Join-Path $repoRoot 'tool\target\release\tool.exe'
if (-not (Test-Path -LiteralPath $tool -PathType Leaf)) {
$cargo = Get-Command cargo -ErrorAction SilentlyContinue
if (-not $cargo) { throw 'Cargo was not found and the MPQ builder is not compiled.' }
$cargo = Get-Command cargo -ErrorAction SilentlyContinue
if ($cargo) {
& $cargo.Source build --release --manifest-path (Join-Path $repoRoot 'tool\Cargo.toml')
if ($LASTEXITCODE -ne 0) { throw 'MPQ builder compilation failed.' }
} elseif (-not (Test-Path -LiteralPath $tool -PathType Leaf)) {
throw 'Cargo was not found and the MPQ builder is not compiled.'
}
& $tool (Join-Path $repoRoot 'src') $PackagePath
+29 -8
View File
@@ -43,13 +43,21 @@ fn build_mpq(
.default_compression(flags::ZLIB)
.listfile_option(ListfileOption::Generate);
let mut archive_names = std::collections::HashSet::new();
let loose_sources: std::collections::HashSet<PathBuf> = creatures
.into_iter()
.flat_map(|generated| generated.assets.iter())
.filter_map(|(source, _)| source.canonicalize().ok())
.collect();
for entry in WalkDir::new(&base)
.into_iter()
.filter_map(|e| e.ok())
.filter(|e| e.file_type().is_file())
{
let full_path = entry.path().canonicalize()?;
if loose_sources.contains(&full_path) {
continue;
}
let rel_path = match full_path.strip_prefix(&base) {
Ok(p) => p,
Err(_) => {
@@ -62,17 +70,10 @@ fn build_mpq(
continue;
}
println!(" Adding: {}", archive_path);
archive_names.insert(archive_path.to_ascii_lowercase());
builder = builder.add_file(&full_path, &archive_path);
}
if let Some(generated) = creatures {
for (source, archive_path) in &generated.assets {
if archive_names.insert(archive_path.to_ascii_lowercase()) {
println!(" Adding generated creature asset: {}", archive_path);
builder = builder.add_file(source, archive_path);
}
}
println!(" Adding generated: WXLFileData.csv");
builder = builder.add_file_data(generated.file_data_csv.clone(), "WXLFileData.csv");
println!(" Adding generated: WXLSpellOverrides.tsv");
@@ -94,6 +95,22 @@ fn build_mpq(
Ok(())
}
fn stage_loose_assets(
output_dir: &Path,
creatures: &GeneratedCreatures,
) -> Result<(), Box<dyn Error>> {
let loose_root = output_dir.join("Data").join("Patch-WXL.MPQ");
for (source, archive_path) in &creatures.assets {
let destination = loose_root.join(archive_path.replace('/', "\\"));
if let Some(parent) = destination.parent() {
fs::create_dir_all(parent)?;
}
fs::copy(source, &destination)?;
println!("Staging loose modern asset: {}", archive_path);
}
Ok(())
}
fn main() -> Result<(), Box<dyn Error>> {
let args: Vec<String> = env::args().collect();
@@ -114,6 +131,10 @@ fn main() -> Result<(), Box<dyn Error>> {
.to_path_buf();
let generated_creatures = creatures::prepare(&project_root)?;
if let Some(generated) = generated_creatures.as_ref() {
stage_loose_assets(&output_dir, generated)?;
}
let data_dir = src_dir.join("Data");
if !data_dir.exists() {
return Err(format!("Data/ not found inside src_dir: {}", src_dir.display()).into());